Merge "[Minimal HUN] hide conversation icon by default" into main
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index e5c059e..8b95679 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -230,6 +230,17 @@
defaults: ["framework-minus-apex-aconfig-java-defaults"],
}
+java_aconfig_library {
+ name: "telephony_flags_core_java_exported_lib",
+ aconfig_declarations: "telephony_flags",
+ mode: "exported",
+ min_sdk_version: "30",
+ apex_available: [
+ "com.android.wifi",
+ ],
+ defaults: ["framework-minus-apex-aconfig-java-defaults"],
+}
+
cc_aconfig_library {
name: "telephony_flags_c_lib",
aconfig_declarations: "telephony_flags",
diff --git a/apct-tests/perftests/core/src/android/os/TracePerfTest.java b/apct-tests/perftests/core/src/android/os/TracePerfTest.java
index bf7c96a..0b941c9 100644
--- a/apct-tests/perftests/core/src/android/os/TracePerfTest.java
+++ b/apct-tests/perftests/core/src/android/os/TracePerfTest.java
@@ -139,6 +139,30 @@
}
}
+ @Test
+ public void testInstantPerfettoWithProto() {
+ PerfettoTrace.begin(FOO_CATEGORY, "message_queue_receive")
+ .beginProto()
+ .beginNested(2004 /* message_queue */)
+ .addField(1 /* sending_thread_name */, "foo")
+ .endNested()
+ .endProto()
+ .addTerminatingFlow(5)
+ .emit();
+
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ PerfettoTrace.begin(FOO_CATEGORY, "message_queue_receive")
+ .beginProto()
+ .beginNested(2004 /* message_queue */)
+ .addField(1 /* sending_thread_name */, "foo")
+ .endNested()
+ .endProto()
+ .addTerminatingFlow(5)
+ .emit();
+ }
+ }
+
private static TraceConfig getTraceConfig(String cat) {
BufferConfig bufferConfig = BufferConfig.newBuilder().setSizeKb(1024).build();
TrackEventConfig trackEventConfig = TrackEventConfig
diff --git a/core/api/current.txt b/core/api/current.txt
index fde139b..f5dcf2d 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -38342,7 +38342,7 @@
field @FlaggedApi("com.android.media.flags.enable_privileged_routing_for_media_routing_control") public static final String ACTION_REQUEST_MEDIA_ROUTING_CONTROL = "android.settings.REQUEST_MEDIA_ROUTING_CONTROL";
field public static final String ACTION_REQUEST_SCHEDULE_EXACT_ALARM = "android.settings.REQUEST_SCHEDULE_EXACT_ALARM";
field public static final String ACTION_REQUEST_SET_AUTOFILL_SERVICE = "android.settings.REQUEST_SET_AUTOFILL_SERVICE";
- field @FlaggedApi("com.android.internal.telephony.flags.carrier_enabled_satellite_flag") public static final String ACTION_SATELLITE_SETTING = "android.settings.SATELLITE_SETTING";
+ field public static final String ACTION_SATELLITE_SETTING = "android.settings.SATELLITE_SETTING";
field public static final String ACTION_SEARCH_SETTINGS = "android.search.action.SEARCH_SETTINGS";
field public static final String ACTION_SECURITY_SETTINGS = "android.settings.SECURITY_SETTINGS";
field public static final String ACTION_SETTINGS = "android.settings.SETTINGS";
@@ -44990,7 +44990,7 @@
field public static final String KEY_CARRIER_SETTINGS_ACTIVITY_COMPONENT_NAME_STRING = "carrier_settings_activity_component_name_string";
field public static final String KEY_CARRIER_SETTINGS_ENABLE_BOOL = "carrier_settings_enable_bool";
field @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") public static final String KEY_CARRIER_SUPPORTED_SATELLITE_NOTIFICATION_HYSTERESIS_SEC_INT = "carrier_supported_satellite_notification_hysteresis_sec_int";
- field @FlaggedApi("com.android.internal.telephony.flags.carrier_enabled_satellite_flag") public static final String KEY_CARRIER_SUPPORTED_SATELLITE_SERVICES_PER_PROVIDER_BUNDLE = "carrier_supported_satellite_services_per_provider_bundle";
+ field public static final String KEY_CARRIER_SUPPORTED_SATELLITE_SERVICES_PER_PROVIDER_BUNDLE = "carrier_supported_satellite_services_per_provider_bundle";
field public static final String KEY_CARRIER_SUPPORTS_OPP_DATA_AUTO_PROVISIONING_BOOL = "carrier_supports_opp_data_auto_provisioning_bool";
field public static final String KEY_CARRIER_SUPPORTS_SS_OVER_UT_BOOL = "carrier_supports_ss_over_ut_bool";
field public static final String KEY_CARRIER_SUPPORTS_TETHERING_BOOL = "carrier_supports_tethering_bool";
@@ -45123,9 +45123,9 @@
field public static final String KEY_MMS_UA_PROF_URL_STRING = "uaProfUrl";
field public static final String KEY_MMS_USER_AGENT_STRING = "userAgent";
field public static final String KEY_MONTHLY_DATA_CYCLE_DAY_INT = "monthly_data_cycle_day_int";
- field @FlaggedApi("com.android.internal.telephony.flags.carrier_enabled_satellite_flag") public static final String KEY_NTN_LTE_RSRP_THRESHOLDS_INT_ARRAY = "ntn_lte_rsrp_thresholds_int_array";
- field @FlaggedApi("com.android.internal.telephony.flags.carrier_enabled_satellite_flag") public static final String KEY_NTN_LTE_RSRQ_THRESHOLDS_INT_ARRAY = "ntn_lte_rsrq_thresholds_int_array";
- field @FlaggedApi("com.android.internal.telephony.flags.carrier_enabled_satellite_flag") public static final String KEY_NTN_LTE_RSSNR_THRESHOLDS_INT_ARRAY = "ntn_lte_rssnr_thresholds_int_array";
+ field public static final String KEY_NTN_LTE_RSRP_THRESHOLDS_INT_ARRAY = "ntn_lte_rsrp_thresholds_int_array";
+ field public static final String KEY_NTN_LTE_RSRQ_THRESHOLDS_INT_ARRAY = "ntn_lte_rsrq_thresholds_int_array";
+ field public static final String KEY_NTN_LTE_RSSNR_THRESHOLDS_INT_ARRAY = "ntn_lte_rssnr_thresholds_int_array";
field public static final String KEY_ONLY_AUTO_SELECT_IN_HOME_NETWORK_BOOL = "only_auto_select_in_home_network";
field public static final String KEY_ONLY_SINGLE_DC_ALLOWED_INT_ARRAY = "only_single_dc_allowed_int_array";
field public static final String KEY_OPERATOR_SELECTION_EXPAND_BOOL = "operator_selection_expand_bool";
@@ -45141,7 +45141,7 @@
field public static final String KEY_OPPORTUNISTIC_NETWORK_MAX_BACKOFF_TIME_LONG = "opportunistic_network_max_backoff_time_long";
field public static final String KEY_OPPORTUNISTIC_NETWORK_PING_PONG_TIME_LONG = "opportunistic_network_ping_pong_time_long";
field @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") public static final String KEY_OVERRIDE_WFC_ROAMING_MODE_WHILE_USING_NTN_BOOL = "override_wfc_roaming_mode_while_using_ntn_bool";
- field @FlaggedApi("com.android.internal.telephony.flags.carrier_enabled_satellite_flag") public static final String KEY_PARAMETERS_USED_FOR_NTN_LTE_SIGNAL_BAR_INT = "parameters_used_for_ntn_lte_signal_bar_int";
+ field public static final String KEY_PARAMETERS_USED_FOR_NTN_LTE_SIGNAL_BAR_INT = "parameters_used_for_ntn_lte_signal_bar_int";
field public static final String KEY_PING_TEST_BEFORE_DATA_SWITCH_BOOL = "ping_test_before_data_switch_bool";
field public static final String KEY_PREFER_2G_BOOL = "prefer_2g_bool";
field @FlaggedApi("com.android.internal.telephony.flags.hide_prefer_3g_item") public static final String KEY_PREFER_3G_VISIBILITY_BOOL = "prefer_3g_visibility_bool";
@@ -45170,14 +45170,14 @@
field public static final String KEY_RTT_SUPPORTED_WHILE_ROAMING_BOOL = "rtt_supported_while_roaming_bool";
field public static final String KEY_RTT_UPGRADE_SUPPORTED_BOOL = "rtt_upgrade_supported_bool";
field public static final String KEY_RTT_UPGRADE_SUPPORTED_FOR_DOWNGRADED_VT_CALL_BOOL = "rtt_upgrade_supported_for_downgraded_vt_call";
- field @FlaggedApi("com.android.internal.telephony.flags.carrier_enabled_satellite_flag") public static final String KEY_SATELLITE_ATTACH_SUPPORTED_BOOL = "satellite_attach_supported_bool";
+ field public static final String KEY_SATELLITE_ATTACH_SUPPORTED_BOOL = "satellite_attach_supported_bool";
field @FlaggedApi("com.android.internal.telephony.flags.satellite_25q4_apis") public static final String KEY_SATELLITE_CONNECTED_NOTIFICATION_THROTTLE_MILLIS_INT = "satellite_connected_notification_throttle_millis_int";
- field @FlaggedApi("com.android.internal.telephony.flags.carrier_enabled_satellite_flag") public static final String KEY_SATELLITE_CONNECTION_HYSTERESIS_SEC_INT = "satellite_connection_hysteresis_sec_int";
+ field public static final String KEY_SATELLITE_CONNECTION_HYSTERESIS_SEC_INT = "satellite_connection_hysteresis_sec_int";
field @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") public static final String KEY_SATELLITE_DATA_SUPPORT_MODE_INT = "satellite_data_support_mode_int";
field @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") public static final String KEY_SATELLITE_DISPLAY_NAME_STRING = "satellite_display_name_string";
field @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") public static final String KEY_SATELLITE_ENTITLEMENT_APP_NAME_STRING = "satellite_entitlement_app_name_string";
- field @FlaggedApi("com.android.internal.telephony.flags.carrier_enabled_satellite_flag") public static final String KEY_SATELLITE_ENTITLEMENT_STATUS_REFRESH_DAYS_INT = "satellite_entitlement_status_refresh_days_int";
- field @FlaggedApi("com.android.internal.telephony.flags.carrier_enabled_satellite_flag") public static final String KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL = "satellite_entitlement_supported_bool";
+ field public static final String KEY_SATELLITE_ENTITLEMENT_STATUS_REFRESH_DAYS_INT = "satellite_entitlement_status_refresh_days_int";
+ field public static final String KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL = "satellite_entitlement_supported_bool";
field @FlaggedApi("com.android.internal.telephony.flags.carrier_roaming_nb_iot_ntn") public static final String KEY_SATELLITE_ESOS_SUPPORTED_BOOL = "satellite_esos_supported_bool";
field @FlaggedApi("com.android.internal.telephony.flags.satellite_25q4_apis") public static final String KEY_SATELLITE_IGNORE_DATA_ROAMING_SETTING_BOOL = "satellite_ignore_data_roaming_setting_bool";
field @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") public static final String KEY_SATELLITE_INFORMATION_REDIRECT_URL_STRING = "satellite_information_redirect_url_string";
@@ -46484,7 +46484,7 @@
method public boolean isNetworkRegistered();
method public boolean isNetworkRoaming();
method public boolean isNetworkSearching();
- method @FlaggedApi("com.android.internal.telephony.flags.carrier_enabled_satellite_flag") public boolean isNonTerrestrialNetwork();
+ method public boolean isNonTerrestrialNetwork();
method @Deprecated public boolean isRegistered();
method @Deprecated public boolean isRoaming();
method @Deprecated public boolean isSearching();
@@ -46500,7 +46500,7 @@
field public static final int NR_STATE_RESTRICTED = 1; // 0x1
field public static final int SERVICE_TYPE_DATA = 2; // 0x2
field public static final int SERVICE_TYPE_EMERGENCY = 5; // 0x5
- field @FlaggedApi("com.android.internal.telephony.flags.carrier_enabled_satellite_flag") public static final int SERVICE_TYPE_MMS = 6; // 0x6
+ field public static final int SERVICE_TYPE_MMS = 6; // 0x6
field public static final int SERVICE_TYPE_SMS = 3; // 0x3
field public static final int SERVICE_TYPE_UNKNOWN = 0; // 0x0
field public static final int SERVICE_TYPE_VIDEO = 4; // 0x4
@@ -46721,7 +46721,7 @@
method public boolean getRoaming();
method public int getState();
method public boolean isSearching();
- method @FlaggedApi("com.android.internal.telephony.flags.carrier_enabled_satellite_flag") public boolean isUsingNonTerrestrialNetwork();
+ method public boolean isUsingNonTerrestrialNetwork();
method public void setIsManualSelection(boolean);
method public void setOperatorName(String, String, String);
method public void setRoaming(boolean);
@@ -47860,7 +47860,7 @@
field public static final int TYPE_MMS = 2; // 0x2
field @FlaggedApi("com.android.internal.telephony.flags.oem_paid_private") public static final int TYPE_OEM_PAID = 65536; // 0x10000
field @FlaggedApi("com.android.internal.telephony.flags.oem_paid_private") public static final int TYPE_OEM_PRIVATE = 131072; // 0x20000
- field @FlaggedApi("com.android.internal.telephony.flags.carrier_enabled_satellite_flag") public static final int TYPE_RCS = 32768; // 0x8000
+ field public static final int TYPE_RCS = 32768; // 0x8000
field public static final int TYPE_SUPL = 4; // 0x4
field public static final int TYPE_VSIM = 4096; // 0x1000
field public static final int TYPE_XCAP = 2048; // 0x800
@@ -48744,6 +48744,7 @@
@FlaggedApi("com.android.internal.telephony.flags.satellite_state_change_listener") public final class SatelliteManager {
method @FlaggedApi("com.android.internal.telephony.flags.satellite_state_change_listener") @RequiresPermission(anyOf={android.Manifest.permission.READ_BASIC_PHONE_STATE, "android.permission.READ_PRIVILEGED_PHONE_STATE", android.Manifest.permission.READ_PHONE_STATE, "carrier privileges"}) public void registerStateChangeListener(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.satellite.SatelliteStateChangeListener);
method @FlaggedApi("com.android.internal.telephony.flags.satellite_state_change_listener") @RequiresPermission(anyOf={android.Manifest.permission.READ_BASIC_PHONE_STATE, "android.permission.READ_PRIVILEGED_PHONE_STATE", android.Manifest.permission.READ_PHONE_STATE, "carrier privileges"}) public void unregisterStateChangeListener(@NonNull android.telephony.satellite.SatelliteStateChangeListener);
+ field @FlaggedApi("com.android.internal.telephony.flags.satellite_25q4_apis") public static final String PROPERTY_SATELLITE_DATA_OPTIMIZED = "android.telephony.PROPERTY_SATELLITE_DATA_OPTIMIZED";
}
@FlaggedApi("com.android.internal.telephony.flags.satellite_state_change_listener") public interface SatelliteStateChangeListener {
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 03607d4..137c967 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -2938,6 +2938,14 @@
}
+package android.app.supervision {
+
+ @FlaggedApi("android.app.supervision.flags.supervision_manager_apis") public class SupervisionManager {
+ method @FlaggedApi("android.app.supervision.flags.supervision_manager_apis") @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.QUERY_USERS}) public boolean isSupervisionEnabled();
+ }
+
+}
+
package android.app.time {
public final class Capabilities {
@@ -3801,6 +3809,7 @@
field public static final String SHARED_CONNECTIVITY_SERVICE = "shared_connectivity";
field public static final String SMARTSPACE_SERVICE = "smartspace";
field public static final String STATS_MANAGER = "stats";
+ field @FlaggedApi("android.app.supervision.flags.supervision_manager_apis") public static final String SUPERVISION_SERVICE = "supervision";
field public static final String SYSTEM_CONFIG_SERVICE = "system_config";
field public static final String SYSTEM_UPDATE_SERVICE = "system_update";
field @FlaggedApi("com.android.net.thread.platform.flags.thread_enabled_platform") public static final String THREAD_NETWORK_SERVICE = "thread_network";
@@ -4190,7 +4199,7 @@
method public void setInstallAsInstantApp(boolean);
method public void setInstallAsVirtualPreload();
method public void setRequestDowngrade(boolean);
- method @FlaggedApi("android.content.pm.recoverability_detection") @RequiresPermission(android.Manifest.permission.MANAGE_ROLLBACKS) public void setRollbackImpactLevel(int);
+ method @RequiresPermission(android.Manifest.permission.MANAGE_ROLLBACKS) public void setRollbackImpactLevel(int);
method @FlaggedApi("android.content.pm.rollback_lifetime") @RequiresPermission(android.Manifest.permission.MANAGE_ROLLBACKS) public void setRollbackLifetimeMillis(long);
method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setStaged();
}
@@ -4365,9 +4374,9 @@
field public static final int ROLLBACK_DATA_POLICY_RESTORE = 0; // 0x0
field public static final int ROLLBACK_DATA_POLICY_RETAIN = 2; // 0x2
field public static final int ROLLBACK_DATA_POLICY_WIPE = 1; // 0x1
- field @FlaggedApi("android.content.pm.recoverability_detection") public static final int ROLLBACK_USER_IMPACT_HIGH = 1; // 0x1
- field @FlaggedApi("android.content.pm.recoverability_detection") public static final int ROLLBACK_USER_IMPACT_LOW = 0; // 0x0
- field @FlaggedApi("android.content.pm.recoverability_detection") public static final int ROLLBACK_USER_IMPACT_ONLY_MANUAL = 2; // 0x2
+ field public static final int ROLLBACK_USER_IMPACT_HIGH = 1; // 0x1
+ field public static final int ROLLBACK_USER_IMPACT_LOW = 0; // 0x0
+ field public static final int ROLLBACK_USER_IMPACT_ONLY_MANUAL = 2; // 0x2
field public static final int SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN = 0; // 0x0
field public static final int SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_VISIBLE = 1; // 0x1
field public static final int SYSTEM_APP_STATE_INSTALLED = 2; // 0x2
@@ -15276,7 +15285,7 @@
method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setCellIdentity(@Nullable android.telephony.CellIdentity);
method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setDomain(int);
method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setEmergencyOnly(boolean);
- method @FlaggedApi("com.android.internal.telephony.flags.carrier_enabled_satellite_flag") @NonNull public android.telephony.NetworkRegistrationInfo.Builder setIsNonTerrestrialNetwork(boolean);
+ method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setIsNonTerrestrialNetwork(boolean);
method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRegisteredPlmn(@Nullable String);
method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRegistrationState(int);
method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRejectCause(int);
@@ -16413,7 +16422,7 @@
field public static final String TYPE_MMS_STRING = "mms";
field @FlaggedApi("com.android.internal.telephony.flags.oem_paid_private") public static final String TYPE_OEM_PAID_STRING = "oem_paid";
field @FlaggedApi("com.android.internal.telephony.flags.oem_paid_private") public static final String TYPE_OEM_PRIVATE_STRING = "oem_private";
- field @FlaggedApi("com.android.internal.telephony.flags.carrier_enabled_satellite_flag") public static final String TYPE_RCS_STRING = "rcs";
+ field public static final String TYPE_RCS_STRING = "rcs";
field public static final String TYPE_SUPL_STRING = "supl";
field public static final String TYPE_VSIM_STRING = "vsim";
field public static final String TYPE_XCAP_STRING = "xcap";
@@ -18580,12 +18589,13 @@
}
@FlaggedApi("com.android.internal.telephony.flags.satellite_state_change_listener") public final class SatelliteManager {
- method @FlaggedApi("com.android.internal.telephony.flags.carrier_enabled_satellite_flag") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void addAttachRestrictionForCarrier(int, int, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
+ method @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void addAttachRestrictionForCarrier(int, int, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
method @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void deprovisionSatellite(@NonNull java.util.List<android.telephony.satellite.SatelliteSubscriberInfo>, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Void,android.telephony.satellite.SatelliteManager.SatelliteException>);
method @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void deprovisionService(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
- method @FlaggedApi("com.android.internal.telephony.flags.carrier_enabled_satellite_flag") @NonNull @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public java.util.Set<java.lang.Integer> getAttachRestrictionReasonsForCarrier(int);
+ method @NonNull @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public java.util.Set<java.lang.Integer> getAttachRestrictionReasonsForCarrier(int);
+ method @FlaggedApi("com.android.internal.telephony.flags.satellite_25q4_apis") @NonNull @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public java.util.List<java.lang.String> getSatelliteDataOptimizedApps();
method @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") @NonNull @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public int[] getSatelliteDisallowedReasons();
- method @FlaggedApi("com.android.internal.telephony.flags.carrier_enabled_satellite_flag") @NonNull @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public java.util.List<java.lang.String> getSatellitePlmnsForCarrier(int);
+ method @NonNull @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public java.util.List<java.lang.String> getSatellitePlmnsForCarrier(int);
method @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void pollPendingDatagrams(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
method @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void provisionSatellite(@NonNull java.util.List<android.telephony.satellite.SatelliteSubscriberInfo>, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Void,android.telephony.satellite.SatelliteManager.SatelliteException>);
method @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void provisionService(@NonNull String, @NonNull byte[], @Nullable android.os.CancellationSignal, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
@@ -18598,11 +18608,11 @@
method @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void registerForSatelliteDisallowedReasonsChanged(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.satellite.SatelliteDisallowedReasonsCallback);
method @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public int registerForSelectedNbIotSatelliteSubscriptionChanged(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.satellite.SelectedNbIotSatelliteSubscriptionCallback);
method @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public int registerForSupportedStateChanged(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>);
- method @FlaggedApi("com.android.internal.telephony.flags.carrier_enabled_satellite_flag") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void removeAttachRestrictionForCarrier(int, int, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
- method @FlaggedApi("com.android.internal.telephony.flags.carrier_enabled_satellite_flag") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void requestAttachEnabledForCarrier(int, boolean, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
+ method @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void removeAttachRestrictionForCarrier(int, int, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
+ method @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void requestAttachEnabledForCarrier(int, boolean, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
method @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void requestCapabilities(@NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.telephony.satellite.SatelliteCapabilities,android.telephony.satellite.SatelliteManager.SatelliteException>);
method @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void requestEnabled(@NonNull android.telephony.satellite.EnableRequestAttributes, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
- method @FlaggedApi("com.android.internal.telephony.flags.carrier_enabled_satellite_flag") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void requestIsAttachEnabledForCarrier(int, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Boolean,android.telephony.satellite.SatelliteManager.SatelliteException>);
+ method @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void requestIsAttachEnabledForCarrier(int, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Boolean,android.telephony.satellite.SatelliteManager.SatelliteException>);
method @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void requestIsCommunicationAllowedForCurrentLocation(@NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Boolean,android.telephony.satellite.SatelliteManager.SatelliteException>);
method @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void requestIsDemoModeEnabled(@NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Boolean,android.telephony.satellite.SatelliteManager.SatelliteException>);
method @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void requestIsEmergencyModeEnabled(@NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Boolean,android.telephony.satellite.SatelliteManager.SatelliteException>);
@@ -18646,15 +18656,15 @@
field @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") public static final int DISPLAY_MODE_OPENED = 2; // 0x2
field @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") public static final int DISPLAY_MODE_UNKNOWN = 0; // 0x0
field @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") public static final int EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_SOS = 1; // 0x1
- field @FlaggedApi("com.android.internal.telephony.flags.carrier_enabled_satellite_flag") public static final int EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T911 = 2; // 0x2
+ field public static final int EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T911 = 2; // 0x2
field @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") public static final int NT_RADIO_TECHNOLOGY_EMTC_NTN = 3; // 0x3
field @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") public static final int NT_RADIO_TECHNOLOGY_NB_IOT_NTN = 1; // 0x1
field @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") public static final int NT_RADIO_TECHNOLOGY_NR_NTN = 2; // 0x2
field @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") public static final int NT_RADIO_TECHNOLOGY_PROPRIETARY = 4; // 0x4
field @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") public static final int NT_RADIO_TECHNOLOGY_UNKNOWN = 0; // 0x0
field @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") public static final String PROPERTY_SATELLITE_MANUAL_CONNECT_P2P_SUPPORT = "android.telephony.satellite.PROPERTY_SATELLITE_MANUAL_CONNECT_P2P_SUPPORT";
- field @FlaggedApi("com.android.internal.telephony.flags.carrier_enabled_satellite_flag") public static final int SATELLITE_COMMUNICATION_RESTRICTION_REASON_ENTITLEMENT = 2; // 0x2
- field @FlaggedApi("com.android.internal.telephony.flags.carrier_enabled_satellite_flag") public static final int SATELLITE_COMMUNICATION_RESTRICTION_REASON_GEOLOCATION = 1; // 0x1
+ field public static final int SATELLITE_COMMUNICATION_RESTRICTION_REASON_ENTITLEMENT = 2; // 0x2
+ field public static final int SATELLITE_COMMUNICATION_RESTRICTION_REASON_GEOLOCATION = 1; // 0x1
field @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") public static final int SATELLITE_COMMUNICATION_RESTRICTION_REASON_USER = 0; // 0x0
field @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") public static final int SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE = 0; // 0x0
field @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") public static final int SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_FAILED = 7; // 0x7
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 85b65bb..89b3773 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -850,6 +850,14 @@
}
+package android.app.supervision {
+
+ @FlaggedApi("android.app.supervision.flags.supervision_manager_apis") public class SupervisionManager {
+ method public void setSupervisionEnabled(boolean);
+ }
+
+}
+
package android.app.usage {
public class StorageStatsManager {
@@ -1907,6 +1915,10 @@
package android.hardware.usb {
+ public class UsbManager {
+ method public boolean isUvcGadgetSupportEnabled();
+ }
+
public final class UsbPort {
method @FlaggedApi("android.hardware.usb.flags.enable_is_mode_change_supported_api") @RequiresPermission(android.Manifest.permission.MANAGE_USB) public boolean isModeChangeSupported();
}
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 252d23f..ee9c64f 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -292,13 +292,15 @@
* to the user, it must be completely restarted and restored to its previous state.</li>
* </ul>
*
- * <p>The following diagram shows the important state paths of an Activity.
+ * <p>The following diagram shows the important state paths of an activity.
* The square rectangles represent callback methods you can implement to
- * perform operations when the Activity moves between states. The colored
- * ovals are major states the Activity can be in.</p>
+ * perform operations when the activity moves between states. The colored
+ * ovals are major states the activity can be in.</p>
*
- * <p><img src="../../../images/activity_lifecycle.png"
- * alt="State diagram for an Android Activity Lifecycle." border="0" /></p>
+ * <p><img class="invert"
+ * style="display: block; margin: auto;"
+ * src="../../../images/activity_lifecycle.png"
+ * alt="State diagram for the Android activity lifecycle." /></p>
*
* <p>There are three key loops you may be interested in monitoring within your
* activity:
@@ -505,7 +507,7 @@
* changes.</p>
*
* <p>Unless you specify otherwise, a configuration change (such as a change
- * in screen orientation, language, input devices, etc) will cause your
+ * in screen orientation, language, input devices, etc.) will cause your
* current activity to be <em>destroyed</em>, going through the normal activity
* lifecycle process of {@link #onPause},
* {@link #onStop}, and {@link #onDestroy} as appropriate. If the activity
@@ -1838,7 +1840,7 @@
*
* <p>You can call {@link #finish} from within this function, in
* which case onDestroy() will be immediately called after {@link #onCreate} without any of the
- * rest of the activity lifecycle ({@link #onStart}, {@link #onResume}, {@link #onPause}, etc)
+ * rest of the activity lifecycle ({@link #onStart}, {@link #onResume}, {@link #onPause}, etc.)
* executing.
*
* <p><em>Derived classes must call through to the super class's
@@ -2132,7 +2134,7 @@
*
* <p>You can call {@link #finish} from within this function, in
* which case {@link #onStop} will be immediately called after {@link #onStart} without the
- * lifecycle transitions in-between ({@link #onResume}, {@link #onPause}, etc) executing.
+ * lifecycle transitions in-between ({@link #onResume}, {@link #onPause}, etc.) executing.
*
* <p><em>Derived classes must call through to the super class's
* implementation of this method. If they do not, an exception will be
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index f63170a..c765298 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -101,6 +101,7 @@
import android.content.pm.ProviderInfo;
import android.content.pm.ProviderInfoList;
import android.content.pm.ServiceInfo;
+import android.content.pm.SystemFeaturesCache;
import android.content.res.AssetManager;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
@@ -387,7 +388,7 @@
@UnsupportedAppUsage
private ContextImpl mSystemContext;
@GuardedBy("this")
- private ArrayList<WeakReference<ContextImpl>> mDisplaySystemUiContexts;
+ private ArrayList<WeakReference<Context>> mDisplaySystemUiContexts;
@UnsupportedAppUsage
static volatile IPackageManager sPackageManager;
@@ -1342,6 +1343,10 @@
ApplicationSharedMemory instance =
ApplicationSharedMemory.fromFileDescriptor(
applicationSharedMemoryFd, /* mutable= */ false);
+ if (android.content.pm.Flags.cacheSdkSystemFeatures()) {
+ SystemFeaturesCache.setInstance(
+ new SystemFeaturesCache(instance.readSystemFeaturesCache()));
+ }
instance.closeFileDescriptor();
ApplicationSharedMemory.setInstance(instance);
}
@@ -3204,7 +3209,7 @@
}
@NonNull
- public ContextImpl getSystemUiContext() {
+ public Context getSystemUiContext() {
return getSystemUiContext(DEFAULT_DISPLAY);
}
@@ -3214,7 +3219,7 @@
* @see ContextImpl#createSystemUiContext(ContextImpl, int)
*/
@NonNull
- public ContextImpl getSystemUiContext(int displayId) {
+ public Context getSystemUiContext(int displayId) {
synchronized (this) {
if (mDisplaySystemUiContexts == null) {
mDisplaySystemUiContexts = new ArrayList<>();
@@ -3222,7 +3227,7 @@
mDisplaySystemUiContexts.removeIf(contextRef -> contextRef.refersTo(null));
- ContextImpl context = getSystemUiContextNoCreateLocked(displayId);
+ Context context = getSystemUiContextNoCreateLocked(displayId);
if (context != null) {
return context;
}
@@ -3233,9 +3238,20 @@
}
}
+ /**
+ * Creates a {@code SystemUiContext} for testing.
+ * <p>
+ * DO NOT use it in production code.
+ */
+ @VisibleForTesting
+ @NonNull
+ public Context createSystemUiContextForTesting(int displayId) {
+ return ContextImpl.createSystemUiContext(getSystemContext(), displayId);
+ }
+
@Nullable
@Override
- public ContextImpl getSystemUiContextNoCreate() {
+ public Context getSystemUiContextNoCreate() {
synchronized (this) {
if (mDisplaySystemUiContexts == null) {
return null;
@@ -3246,9 +3262,9 @@
@GuardedBy("this")
@Nullable
- private ContextImpl getSystemUiContextNoCreateLocked(int displayId) {
+ private Context getSystemUiContextNoCreateLocked(int displayId) {
for (int i = 0; i < mDisplaySystemUiContexts.size(); i++) {
- ContextImpl context = mDisplaySystemUiContexts.get(i).get();
+ Context context = mDisplaySystemUiContexts.get(i).get();
if (context != null && context.getDisplayId() == displayId) {
return context;
}
@@ -3267,7 +3283,8 @@
public void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
synchronized (this) {
getSystemContext().installSystemApplicationInfo(info, classLoader);
- getSystemUiContext().installSystemApplicationInfo(info, classLoader);
+ final ContextImpl sysUiContextImpl = ContextImpl.getImpl(getSystemUiContext());
+ sysUiContextImpl.installSystemApplicationInfo(info, classLoader);
// give ourselves a default profiler
mProfiler = new Profiler();
@@ -4759,6 +4776,7 @@
// frame.
final SurfaceControl.Transaction transaction = new SurfaceControl.Transaction();
transaction.hide(startingWindowLeash);
+ startingWindowLeash.release();
view.syncTransferSurfaceOnDraw();
diff --git a/core/java/android/app/ActivityThreadInternal.java b/core/java/android/app/ActivityThreadInternal.java
index 72506b9..70876da 100644
--- a/core/java/android/app/ActivityThreadInternal.java
+++ b/core/java/android/app/ActivityThreadInternal.java
@@ -17,6 +17,7 @@
package android.app;
import android.content.ComponentCallbacks2;
+import android.content.Context;
import java.util.ArrayList;
@@ -28,7 +29,7 @@
interface ActivityThreadInternal {
ContextImpl getSystemContext();
- ContextImpl getSystemUiContextNoCreate();
+ Context getSystemUiContextNoCreate();
boolean isInDensityCompatMode();
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index f2e7e85..1ed64f9 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -78,6 +78,7 @@
import android.content.pm.ServiceInfo;
import android.content.pm.SharedLibraryInfo;
import android.content.pm.SuspendDialogInfo;
+import android.content.pm.SystemFeaturesCache;
import android.content.pm.VerifierDeviceIdentity;
import android.content.pm.VersionedPackage;
import android.content.pm.dex.ArtManager;
@@ -803,16 +804,6 @@
@Override
public Boolean recompute(HasSystemFeatureQuery query) {
try {
- // As an optimization, check first to see if the feature was defined at
- // compile-time as either available or unavailable.
- // TODO(b/203143243): Consider hoisting this optimization out of the cache
- // after the trunk stable (build) flag has soaked and more features are
- // defined at compile-time.
- Boolean maybeHasSystemFeature =
- RoSystemFeatures.maybeHasFeature(query.name, query.version);
- if (maybeHasSystemFeature != null) {
- return maybeHasSystemFeature.booleanValue();
- }
return ActivityThread.currentActivityThread().getPackageManager().
hasSystemFeature(query.name, query.version);
} catch (RemoteException e) {
@@ -823,15 +814,28 @@
@Override
public boolean hasSystemFeature(String name, int version) {
+ // We check for system features in the following order:
+ // * Build time-defined system features (constant, very efficient)
+ // * SDK-defined system features (cached at process start, very efficient)
+ // * IPC-retrieved system features (lazily cached, requires per-feature IPC)
+ // TODO(b/375000483): Refactor all of this logic, including flag queries, into
+ // the SystemFeaturesCache class after initial rollout and validation.
+ Boolean maybeHasSystemFeature = RoSystemFeatures.maybeHasFeature(name, version);
+ if (maybeHasSystemFeature != null) {
+ return maybeHasSystemFeature;
+ }
+ if (com.android.internal.os.Flags.applicationSharedMemoryEnabled()
+ && android.content.pm.Flags.cacheSdkSystemFeatures()) {
+ maybeHasSystemFeature =
+ SystemFeaturesCache.getInstance().maybeHasFeature(name, version);
+ if (maybeHasSystemFeature != null) {
+ return maybeHasSystemFeature;
+ }
+ }
return mHasSystemFeatureCache.query(new HasSystemFeatureQuery(name, version));
}
/** @hide */
- public void disableHasSystemFeatureCache() {
- mHasSystemFeatureCache.disableLocal();
- }
-
- /** @hide */
public static void invalidateHasSystemFeatureCache() {
mHasSystemFeatureCache.invalidateCache();
}
diff --git a/core/java/android/app/ApplicationStartInfo.java b/core/java/android/app/ApplicationStartInfo.java
index 3214bd8..2e8031d 100644
--- a/core/java/android/app/ApplicationStartInfo.java
+++ b/core/java/android/app/ApplicationStartInfo.java
@@ -840,7 +840,9 @@
* @hide
*/
// LINT.IfChange(write_proto)
- public void writeToProto(ProtoOutputStream proto, long fieldId) throws IOException {
+ public void writeToProto(ProtoOutputStream proto, long fieldId,
+ ByteArrayOutputStream byteArrayOutputStream, ObjectOutputStream objectOutputStream,
+ TypedXmlSerializer typedXmlSerializer) throws IOException {
final long token = proto.start(fieldId);
proto.write(ApplicationStartInfoProto.PID, mPid);
proto.write(ApplicationStartInfoProto.REAL_UID, mRealUid);
@@ -850,38 +852,38 @@
proto.write(ApplicationStartInfoProto.STARTUP_STATE, mStartupState);
proto.write(ApplicationStartInfoProto.REASON, mReason);
if (mStartupTimestampsNs != null && mStartupTimestampsNs.size() > 0) {
- ByteArrayOutputStream timestampsBytes = new ByteArrayOutputStream();
- ObjectOutputStream timestampsOut = new ObjectOutputStream(timestampsBytes);
- TypedXmlSerializer serializer = Xml.resolveSerializer(timestampsOut);
- serializer.startDocument(null, true);
- serializer.startTag(null, PROTO_SERIALIZER_ATTRIBUTE_TIMESTAMPS);
+ byteArrayOutputStream = new ByteArrayOutputStream();
+ objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
+ typedXmlSerializer = Xml.resolveSerializer(objectOutputStream);
+ typedXmlSerializer.startDocument(null, true);
+ typedXmlSerializer.startTag(null, PROTO_SERIALIZER_ATTRIBUTE_TIMESTAMPS);
for (int i = 0; i < mStartupTimestampsNs.size(); i++) {
- serializer.startTag(null, PROTO_SERIALIZER_ATTRIBUTE_TIMESTAMP);
- serializer.attributeInt(null, PROTO_SERIALIZER_ATTRIBUTE_KEY,
+ typedXmlSerializer.startTag(null, PROTO_SERIALIZER_ATTRIBUTE_TIMESTAMP);
+ typedXmlSerializer.attributeInt(null, PROTO_SERIALIZER_ATTRIBUTE_KEY,
mStartupTimestampsNs.keyAt(i));
- serializer.attributeLong(null, PROTO_SERIALIZER_ATTRIBUTE_TS,
+ typedXmlSerializer.attributeLong(null, PROTO_SERIALIZER_ATTRIBUTE_TS,
mStartupTimestampsNs.valueAt(i));
- serializer.endTag(null, PROTO_SERIALIZER_ATTRIBUTE_TIMESTAMP);
+ typedXmlSerializer.endTag(null, PROTO_SERIALIZER_ATTRIBUTE_TIMESTAMP);
}
- serializer.endTag(null, PROTO_SERIALIZER_ATTRIBUTE_TIMESTAMPS);
- serializer.endDocument();
+ typedXmlSerializer.endTag(null, PROTO_SERIALIZER_ATTRIBUTE_TIMESTAMPS);
+ typedXmlSerializer.endDocument();
proto.write(ApplicationStartInfoProto.STARTUP_TIMESTAMPS,
- timestampsBytes.toByteArray());
- timestampsOut.close();
+ byteArrayOutputStream.toByteArray());
+ objectOutputStream.close();
}
proto.write(ApplicationStartInfoProto.START_TYPE, mStartType);
if (mStartIntent != null) {
- ByteArrayOutputStream intentBytes = new ByteArrayOutputStream();
- ObjectOutputStream intentOut = new ObjectOutputStream(intentBytes);
- TypedXmlSerializer serializer = Xml.resolveSerializer(intentOut);
- serializer.startDocument(null, true);
- serializer.startTag(null, PROTO_SERIALIZER_ATTRIBUTE_INTENT);
- mStartIntent.saveToXml(serializer);
- serializer.endTag(null, PROTO_SERIALIZER_ATTRIBUTE_INTENT);
- serializer.endDocument();
+ byteArrayOutputStream = new ByteArrayOutputStream();
+ objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
+ typedXmlSerializer = Xml.resolveSerializer(objectOutputStream);
+ typedXmlSerializer.startDocument(null, true);
+ typedXmlSerializer.startTag(null, PROTO_SERIALIZER_ATTRIBUTE_INTENT);
+ mStartIntent.saveToXml(typedXmlSerializer);
+ typedXmlSerializer.endTag(null, PROTO_SERIALIZER_ATTRIBUTE_INTENT);
+ typedXmlSerializer.endDocument();
proto.write(ApplicationStartInfoProto.START_INTENT,
- intentBytes.toByteArray());
- intentOut.close();
+ byteArrayOutputStream.toByteArray());
+ objectOutputStream.close();
}
proto.write(ApplicationStartInfoProto.LAUNCH_MODE, mLaunchMode);
proto.write(ApplicationStartInfoProto.WAS_FORCE_STOPPED, mWasForceStopped);
@@ -900,7 +902,9 @@
* @hide
*/
// LINT.IfChange(read_proto)
- public void readFromProto(ProtoInputStream proto, long fieldId)
+ public void readFromProto(ProtoInputStream proto, long fieldId,
+ ByteArrayInputStream byteArrayInputStream, ObjectInputStream objectInputStream,
+ TypedXmlPullParser typedXmlPullParser)
throws IOException, WireTypeMismatchException, ClassNotFoundException {
final long token = proto.start(fieldId);
while (proto.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
@@ -927,19 +931,21 @@
mReason = proto.readInt(ApplicationStartInfoProto.REASON);
break;
case (int) ApplicationStartInfoProto.STARTUP_TIMESTAMPS:
- ByteArrayInputStream timestampsBytes = new ByteArrayInputStream(proto.readBytes(
+ byteArrayInputStream = new ByteArrayInputStream(proto.readBytes(
ApplicationStartInfoProto.STARTUP_TIMESTAMPS));
- ObjectInputStream timestampsIn = new ObjectInputStream(timestampsBytes);
+ objectInputStream = new ObjectInputStream(byteArrayInputStream);
mStartupTimestampsNs = new ArrayMap<Integer, Long>();
try {
- TypedXmlPullParser parser = Xml.resolvePullParser(timestampsIn);
- XmlUtils.beginDocument(parser, PROTO_SERIALIZER_ATTRIBUTE_TIMESTAMPS);
- int depth = parser.getDepth();
- while (XmlUtils.nextElementWithin(parser, depth)) {
- if (PROTO_SERIALIZER_ATTRIBUTE_TIMESTAMP.equals(parser.getName())) {
- int key = parser.getAttributeInt(null,
+ typedXmlPullParser = Xml.resolvePullParser(objectInputStream);
+ XmlUtils.beginDocument(typedXmlPullParser,
+ PROTO_SERIALIZER_ATTRIBUTE_TIMESTAMPS);
+ int depth = typedXmlPullParser.getDepth();
+ while (XmlUtils.nextElementWithin(typedXmlPullParser, depth)) {
+ if (PROTO_SERIALIZER_ATTRIBUTE_TIMESTAMP.equals(
+ typedXmlPullParser.getName())) {
+ int key = typedXmlPullParser.getAttributeInt(null,
PROTO_SERIALIZER_ATTRIBUTE_KEY);
- long ts = parser.getAttributeLong(null,
+ long ts = typedXmlPullParser.getAttributeLong(null,
PROTO_SERIALIZER_ATTRIBUTE_TS);
mStartupTimestampsNs.put(key, ts);
}
@@ -947,23 +953,24 @@
} catch (XmlPullParserException e) {
// Timestamps lost
}
- timestampsIn.close();
+ objectInputStream.close();
break;
case (int) ApplicationStartInfoProto.START_TYPE:
mStartType = proto.readInt(ApplicationStartInfoProto.START_TYPE);
break;
case (int) ApplicationStartInfoProto.START_INTENT:
- ByteArrayInputStream intentBytes = new ByteArrayInputStream(proto.readBytes(
+ byteArrayInputStream = new ByteArrayInputStream(proto.readBytes(
ApplicationStartInfoProto.START_INTENT));
- ObjectInputStream intentIn = new ObjectInputStream(intentBytes);
+ objectInputStream = new ObjectInputStream(byteArrayInputStream);
try {
- TypedXmlPullParser parser = Xml.resolvePullParser(intentIn);
- XmlUtils.beginDocument(parser, PROTO_SERIALIZER_ATTRIBUTE_INTENT);
- mStartIntent = Intent.restoreFromXml(parser);
+ typedXmlPullParser = Xml.resolvePullParser(objectInputStream);
+ XmlUtils.beginDocument(typedXmlPullParser,
+ PROTO_SERIALIZER_ATTRIBUTE_INTENT);
+ mStartIntent = Intent.restoreFromXml(typedXmlPullParser);
} catch (XmlPullParserException e) {
// Intent lost
}
- intentIn.close();
+ objectInputStream.close();
break;
case (int) ApplicationStartInfoProto.LAUNCH_MODE:
mLaunchMode = proto.readInt(ApplicationStartInfoProto.LAUNCH_MODE);
diff --git a/core/java/android/app/ConfigurationController.java b/core/java/android/app/ConfigurationController.java
index 62a50db..f491e3d 100644
--- a/core/java/android/app/ConfigurationController.java
+++ b/core/java/android/app/ConfigurationController.java
@@ -169,7 +169,7 @@
// Get theme outside of synchronization to avoid nested lock.
final Resources.Theme systemTheme = mActivityThread.getSystemContext().getTheme();
- final ContextImpl systemUiContext = mActivityThread.getSystemUiContextNoCreate();
+ final Context systemUiContext = mActivityThread.getSystemUiContextNoCreate();
final Resources.Theme systemUiTheme =
systemUiContext != null ? systemUiContext.getTheme() : null;
synchronized (mResourcesManager) {
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index d8aa8b3..0519695 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -97,6 +97,7 @@
import android.view.Display;
import android.view.DisplayAdjustments;
import android.view.autofill.AutofillManager.AutofillClient;
+import android.window.SystemUiContext;
import android.window.WindowContext;
import android.window.WindowTokenClient;
import android.window.WindowTokenClientController;
@@ -3477,15 +3478,28 @@
* {@link #createSystemContext(ActivityThread)}.
* @param displayId The ID of the display where the UI is shown.
*/
- static ContextImpl createSystemUiContext(ContextImpl systemContext, int displayId) {
+ static Context createSystemUiContext(ContextImpl systemContext, int displayId) {
+ // Step 1. Create a ContextImpl associated with its own resources.
final WindowTokenClient token = new WindowTokenClient();
final ContextImpl context = systemContext.createWindowContextBase(token, displayId);
- token.attachContext(context);
+
+ // Step 2. Create a SystemUiContext to wrap the ContextImpl, which enables to listen to
+ // its config updates.
+ final Context systemUiContext;
+ if (com.android.window.flags.Flags.trackSystemUiContextBeforeWms()) {
+ systemUiContext = new SystemUiContext(context);
+ context.setOuterContext(systemUiContext);
+ } else {
+ systemUiContext = context;
+ }
+ token.attachContext(systemUiContext);
+
+ // Step 3. Associate the SystemUiContext with the display specified with ID.
WindowTokenClientController.getInstance().attachToDisplayContent(token, displayId);
context.mContextType = CONTEXT_TYPE_SYSTEM_OR_SYSTEM_UI;
context.mOwnsToken = true;
- return context;
+ return systemUiContext;
}
@UnsupportedAppUsage
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 0ca4a32..5dca1c7 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -6002,7 +6002,7 @@
// HUNS, which use a different layout that already accounts for that). Templates that
// have content that will be displayed under the small icon also use a different margin.
if (Flags.notificationsRedesignTemplates()
- && !p.mHeaderless && !p.mHasContentInLeftMargin) {
+ && !p.mHeaderless && !p.mSkipTopLineAlignment) {
int margin = getContentMarginTop(mContext,
R.dimen.notification_2025_content_margin_top);
contentView.setViewLayoutMargin(R.id.notification_main_column,
@@ -6594,13 +6594,8 @@
int notifMargin = resources.getDimensionPixelSize(R.dimen.notification_2025_margin);
// Spacing between the text lines, scaling with the font size (originally in sp)
int spacing = resources.getDimensionPixelSize(spacingRes);
-
// Size of the text in the notification top line (originally in sp)
- int[] textSizeAttr = new int[] { android.R.attr.textSize };
- TypedArray typedArray = context.obtainStyledAttributes(
- R.style.TextAppearance_DeviceDefault_Notification_Info, textSizeAttr);
- int textSize = typedArray.getDimensionPixelSize(0 /* index */, -1 /* default */);
- typedArray.recycle();
+ int textSize = resources.getDimensionPixelSize(R.dimen.notification_subtext_size);
// Adding up all the values as pixels
return notifMargin + spacing + textSize;
@@ -9503,7 +9498,7 @@
.hideLeftIcon(isOneToOne)
.hideRightIcon(hideRightIcons || isOneToOne)
.headerTextSecondary(isHeaderless ? null : conversationTitle)
- .hasContentInLeftMargin(true);
+ .skipTopLineAlignment(true);
RemoteViews contentView = mBuilder.applyStandardTemplateWithActions(
isConversationLayout
? mBuilder.getConversationLayoutResource()
@@ -14681,7 +14676,7 @@
Icon mPromotedPicture;
boolean mCallStyleActions;
boolean mAllowTextWithProgress;
- boolean mHasContentInLeftMargin;
+ boolean mSkipTopLineAlignment;
int mTitleViewId;
int mTextViewId;
@Nullable CharSequence mTitle;
@@ -14707,7 +14702,7 @@
mPromotedPicture = null;
mCallStyleActions = false;
mAllowTextWithProgress = false;
- mHasContentInLeftMargin = false;
+ mSkipTopLineAlignment = false;
mTitleViewId = R.id.title;
mTextViewId = R.id.text;
mTitle = null;
@@ -14774,8 +14769,8 @@
return this;
}
- public StandardTemplateParams hasContentInLeftMargin(boolean hasContentInLeftMargin) {
- mHasContentInLeftMargin = hasContentInLeftMargin;
+ public StandardTemplateParams skipTopLineAlignment(boolean skipTopLineAlignment) {
+ mSkipTopLineAlignment = skipTopLineAlignment;
return this;
}
diff --git a/core/java/android/app/UiAutomation.java b/core/java/android/app/UiAutomation.java
index 464bcc0..3615326 100644
--- a/core/java/android/app/UiAutomation.java
+++ b/core/java/android/app/UiAutomation.java
@@ -122,7 +122,7 @@
private static final String LOG_TAG = UiAutomation.class.getSimpleName();
private static final boolean DEBUG = false;
- private static final boolean VERBOSE = Build.IS_DEBUGGABLE;
+ private static final boolean VERBOSE = false;
private static final int CONNECTION_ID_UNDEFINED = -1;
diff --git a/core/java/android/app/backup/BackupRestoreEventLogger.java b/core/java/android/app/backup/BackupRestoreEventLogger.java
index 112c5fd..8bde3a5 100644
--- a/core/java/android/app/backup/BackupRestoreEventLogger.java
+++ b/core/java/android/app/backup/BackupRestoreEventLogger.java
@@ -34,9 +34,11 @@
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
/**
* Class to log B&R stats for each data type that is backed up and restored by the calling app.
@@ -325,6 +327,21 @@
}
}
+ /** @hide */
+ public static String toString(DataTypeResult result) {
+ Objects.requireNonNull(result, "result cannot be null");
+ StringBuilder string = new StringBuilder("type=").append(result.mDataType)
+ .append(", successCount=").append(result.mSuccessCount)
+ .append(", failCount=").append(result.mFailCount);
+ if (!result.mErrors.isEmpty()) {
+ string.append(", errors=").append(result.mErrors);
+ }
+ if (result.mMetadataHash != null) {
+ string.append(", metadataHash=").append(Arrays.toString(result.mMetadataHash));
+ }
+ return string.toString();
+ }
+
/**
* Encapsulate logging results for a single data type.
*/
diff --git a/core/java/android/app/jank/JankDataProcessor.java b/core/java/android/app/jank/JankDataProcessor.java
index b4c293e..7718d15 100644
--- a/core/java/android/app/jank/JankDataProcessor.java
+++ b/core/java/android/app/jank/JankDataProcessor.java
@@ -34,11 +34,13 @@
/**
* This class is responsible for associating frames received from SurfaceFlinger to active widget
* states and logging those states back to the platform.
+ *
* @hide
*/
@FlaggedApi(Flags.FLAG_DETAILED_APP_JANK_METRICS_API)
public class JankDataProcessor {
-
+ private static final String TAG = "JankDataProcessor";
+ private static final boolean DEBUG_LOGGING = false;
private static final int MAX_IN_MEMORY_STATS = 25;
private static final int LOG_BATCH_FREQUENCY = 50;
private int mCurrentBatchCount = 0;
@@ -54,9 +56,10 @@
/**
* Called once per batch of JankData.
- * @param jankData data received from SurfaceFlinger to be processed
+ *
+ * @param jankData data received from SurfaceFlinger to be processed
* @param activityName name of the activity that is tracking jank metrics.
- * @param appUid the uid of the app.
+ * @param appUid the uid of the app.
*/
public void processJankData(List<JankData> jankData, String activityName, int appUid) {
// add all the previous and active states to the pending states list.
@@ -211,8 +214,6 @@
* clear any pending widget states.
*/
public void logMetricCounts() {
- //TODO b/374607503 when api changes are in add enum mapping for category and state.
-
try {
mPendingJankStats.values().forEach(stat -> {
FrameworkStatsLog.write(
@@ -221,15 +222,16 @@
/*activity name*/ stat.getActivityName(),
/*widget id*/ stat.getWidgetId(),
/*refresh rate*/ stat.getRefreshRate(),
- /*widget category*/ 0,
- /*widget state*/ 0,
+ /*widget category*/ widgetCategoryToInt(stat.getWidgetCategory()),
+ /*widget state*/ widgetStateToInt(stat.getWidgetState()),
/*total frames*/ stat.getTotalFrames(),
/*janky frames*/ stat.getJankyFrames(),
- /*histogram*/ stat.mFrameOverrunBuckets);
+ /*histogram*/ stat.getFrameOverrunBuckets());
Log.d(stat.mActivityName, stat.toString());
// return the pending stat to the pool it will be reset the next time its
// used.
mPendingJankStatsPool.release(stat);
+
}
);
// All stats have been recorded and added back to the pool for reuse, clear the pending
@@ -241,6 +243,96 @@
}
}
+ private int widgetCategoryToInt(String widgetCategory) {
+ switch (widgetCategory) {
+ case AppJankStats.WIDGET_CATEGORY_SCROLL -> {
+ return FrameworkStatsLog
+ .JANK_FRAME_COUNT_BY_WIDGET_REPORTED__WIDGET_STATE__SCROLLING;
+ }
+ case AppJankStats.WIDGET_CATEGORY_ANIMATION -> {
+ return FrameworkStatsLog
+ .JANK_FRAME_COUNT_BY_WIDGET_REPORTED__WIDGET_TYPE__ANIMATION;
+ }
+ case AppJankStats.WIDGET_CATEGORY_MEDIA -> {
+ return FrameworkStatsLog
+ .JANK_FRAME_COUNT_BY_WIDGET_REPORTED__WIDGET_TYPE__MEDIA;
+ }
+ case AppJankStats.WIDGET_CATEGORY_NAVIGATION -> {
+ return FrameworkStatsLog
+ .JANK_FRAME_COUNT_BY_WIDGET_REPORTED__WIDGET_TYPE__NAVIGATION;
+ }
+ case AppJankStats.WIDGET_CATEGORY_KEYBOARD -> {
+ return FrameworkStatsLog
+ .JANK_FRAME_COUNT_BY_WIDGET_REPORTED__WIDGET_TYPE__KEYBOARD;
+ }
+ case AppJankStats.WIDGET_CATEGORY_OTHER -> {
+ return FrameworkStatsLog
+ .JANK_FRAME_COUNT_BY_WIDGET_REPORTED__WIDGET_TYPE__OTHER;
+ }
+ default -> {
+ if (DEBUG_LOGGING) {
+ Log.d(TAG, "Default Category Logged: "
+ + AppJankStats.WIDGET_CATEGORY_UNSPECIFIED);
+ }
+ return FrameworkStatsLog
+ .JANK_FRAME_COUNT_BY_WIDGET_REPORTED__WIDGET_TYPE__WIDGET_CATEGORY_UNSPECIFIED;
+ }
+ }
+ }
+
+ private int widgetStateToInt(String widgetState) {
+ switch (widgetState) {
+ case AppJankStats.WIDGET_STATE_NONE -> {
+ return FrameworkStatsLog
+ .JANK_FRAME_COUNT_BY_WIDGET_REPORTED__WIDGET_STATE__NONE;
+ }
+ case AppJankStats.WIDGET_STATE_SCROLLING -> {
+ return FrameworkStatsLog
+ .JANK_FRAME_COUNT_BY_WIDGET_REPORTED__WIDGET_STATE__SCROLLING;
+ }
+ case AppJankStats.WIDGET_STATE_FLINGING -> {
+ return FrameworkStatsLog
+ .JANK_FRAME_COUNT_BY_WIDGET_REPORTED__WIDGET_STATE__FLINGING;
+ }
+ case AppJankStats.WIDGET_STATE_SWIPING -> {
+ return FrameworkStatsLog
+ .JANK_FRAME_COUNT_BY_WIDGET_REPORTED__WIDGET_STATE__SWIPING;
+ }
+ case AppJankStats.WIDGET_STATE_DRAGGING -> {
+ return FrameworkStatsLog
+ .JANK_FRAME_COUNT_BY_WIDGET_REPORTED__WIDGET_STATE__DRAGGING;
+ }
+ case AppJankStats.WIDGET_STATE_ZOOMING -> {
+ return FrameworkStatsLog
+ .JANK_FRAME_COUNT_BY_WIDGET_REPORTED__WIDGET_STATE__ZOOMING;
+ }
+ case AppJankStats.WIDGET_STATE_ANIMATING -> {
+ return FrameworkStatsLog
+ .JANK_FRAME_COUNT_BY_WIDGET_REPORTED__WIDGET_STATE__ANIMATING;
+ }
+ case AppJankStats.WIDGET_STATE_PLAYBACK -> {
+ return FrameworkStatsLog
+ .JANK_FRAME_COUNT_BY_WIDGET_REPORTED__WIDGET_STATE__PLAYBACK;
+ }
+ case AppJankStats.WIDGET_STATE_TAPPING -> {
+ return FrameworkStatsLog
+ .JANK_FRAME_COUNT_BY_WIDGET_REPORTED__WIDGET_STATE__TAPPING;
+ }
+ case AppJankStats.WIDGET_STATE_PREDICTIVE_BACK -> {
+ return FrameworkStatsLog
+ .JANK_FRAME_COUNT_BY_WIDGET_REPORTED__WIDGET_STATE__PREDICTIVE_BACK;
+ }
+ default -> {
+ if (DEBUG_LOGGING) {
+ Log.d(TAG, "Default State Logged: "
+ + AppJankStats.WIDGET_STATE_UNSPECIFIED);
+ }
+ return FrameworkStatsLog
+ .JANK_FRAME_COUNT_BY_WIDGET_REPORTED__WIDGET_STATE__WIDGET_STATE_UNSPECIFIED;
+ }
+ }
+ }
+
public static final class PendingJankStat {
private static final int NANOS_PER_MS = 1000000;
public long processedVsyncId = -1;
@@ -268,7 +360,7 @@
private int mRefreshRate;
- private static final int[] sFrameOverrunHistogramBounds = {
+ private static final int[] sFrameOverrunHistogramBounds = {
Integer.MIN_VALUE, -200, -150, -100, -90, -80, -70, -60, -50, -40, -30, -25, -20,
-18, -16, -14, -12, -10, -8, -6, -4, -2, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 25,
30, 40, 50, 60, 70, 80, 90, 100, 150, 200, 300, 400, 500, 600, 700, 800, 900, 1000,
@@ -279,6 +371,7 @@
// Histogram of frame duration overruns encoded in predetermined buckets.
public PendingJankStat() {
}
+
public long getProcessedVsyncId() {
return processedVsyncId;
}
@@ -422,4 +515,4 @@
}
}
-}
+}
\ No newline at end of file
diff --git a/core/java/android/app/jank/JankTracker.java b/core/java/android/app/jank/JankTracker.java
index a04f96a..9c85b09 100644
--- a/core/java/android/app/jank/JankTracker.java
+++ b/core/java/android/app/jank/JankTracker.java
@@ -20,6 +20,7 @@
import android.annotation.NonNull;
import android.os.Handler;
import android.os.HandlerThread;
+import android.util.Log;
import android.view.AttachedSurfaceControl;
import android.view.Choreographer;
import android.view.SurfaceControl;
@@ -30,16 +31,22 @@
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
/**
* This class is responsible for registering callbacks that will receive JankData batches.
* It handles managing the background thread that JankData will be processed on. As well as acting
* as an intermediary between widgets and the state tracker, routing state changes to the tracker.
+ *
* @hide
*/
@FlaggedApi(Flags.FLAG_DETAILED_APP_JANK_METRICS_API)
public class JankTracker {
-
+ private static final boolean DEBUG = false;
+ private static final String DEBUG_KEY = "JANKTRACKER";
+ // How long to delay the JankData listener registration.
+ //TODO b/394956095 see if this can be reduced or eliminated.
+ private static final int REGISTRATION_DELAY_MS = 1000;
// Tracks states reported by widgets.
private StateTracker mStateTracker;
// Processes JankData batches and associates frames to widget states.
@@ -49,9 +56,6 @@
private HandlerThread mHandlerThread = new HandlerThread("AppJankTracker");
private Handler mHandler = null;
- // Needed so we know when the view is attached to a window.
- private ViewTreeObserver mViewTreeObserver;
-
// Handle to a registered OnJankData listener.
private SurfaceControl.OnJankDataListenerRegistration mJankDataListenerRegistration;
@@ -76,6 +80,40 @@
*/
private boolean mListenersRegistered = false;
+ @FlaggedApi(com.android.window.flags.Flags.FLAG_JANK_API)
+ private final SurfaceControl.OnJankDataListener mJankDataListener =
+ new SurfaceControl.OnJankDataListener() {
+ @Override
+ public void onJankDataAvailable(
+ @androidx.annotation.NonNull List<SurfaceControl.JankData> jankData) {
+ if (mJankDataProcessor == null) return;
+ mJankDataProcessor.processJankData(jankData, mActivityName, mAppUid);
+ }
+ };
+
+ private final ViewTreeObserver.OnWindowAttachListener mOnWindowAttachListener =
+ new ViewTreeObserver.OnWindowAttachListener() {
+ @Override
+ public void onWindowAttached() {
+ getHandler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ mDecorView.getViewTreeObserver()
+ .removeOnWindowAttachListener(mOnWindowAttachListener);
+ registerForJankData();
+ }
+ }, REGISTRATION_DELAY_MS);
+ }
+
+ // Leave this empty. Only need to know when the DecorView is attached to the Window
+ // in order to get a handle to AttachedSurfaceControl. There is no need to tie
+ // anything to when the view is detached as all un-registration code is tied to
+ // the lifecycle of the enclosing activity.
+ @Override
+ public void onWindowDetached() {
+
+ }
+ };
public JankTracker(Choreographer choreographer, View decorView) {
mStateTracker = new StateTracker(choreographer);
@@ -108,9 +146,10 @@
/**
* Will add the widget category, id and state as a UI state to associate frames to it.
+ *
* @param widgetCategory preselected general widget category
- * @param widgetId developer defined widget id if available.
- * @param widgetState the current active widget state.
+ * @param widgetId developer defined widget id if available.
+ * @param widgetState the current active widget state.
*/
public void addUiState(String widgetCategory, String widgetId, String widgetState) {
if (!shouldTrack()) return;
@@ -121,9 +160,10 @@
/**
* Will remove the widget category, id and state as a ui state and no longer attribute frames
* to it.
+ *
* @param widgetCategory preselected general widget category
- * @param widgetId developer defined widget id if available.
- * @param widgetState no longer active widget state.
+ * @param widgetId developer defined widget id if available.
+ * @param widgetState no longer active widget state.
*/
public void removeUiState(String widgetCategory, String widgetId, String widgetState) {
if (!shouldTrack()) return;
@@ -133,10 +173,11 @@
/**
* Call to update a jank state to a different state.
+ *
* @param widgetCategory preselected general widget category.
- * @param widgetId developer defined widget id if available.
- * @param currentState current state of the widget.
- * @param nextState the state the widget will be in.
+ * @param widgetId developer defined widget id if available.
+ * @param currentState current state of the widget.
+ * @param nextState the state the widget will be in.
*/
public void updateUiState(String widgetCategory, String widgetId, String currentState,
String nextState) {
@@ -150,10 +191,11 @@
*/
public void enableAppJankTracking() {
// Add the activity as a state, this will ensure we track frames to the activity without the
- // need of a decorated widget to be used.
+ // need for a decorated widget to be used.
// TODO b/376116199 replace "NONE" with UNSPECIFIED once the API changes are merged.
mStateTracker.putState("NONE", mActivityName, "NONE");
mTrackingEnabled = true;
+ registerForJankData();
}
/**
@@ -163,10 +205,12 @@
mTrackingEnabled = false;
// TODO b/376116199 replace "NONE" with UNSPECIFIED once the API changes are merged.
mStateTracker.removeState("NONE", mActivityName, "NONE");
+ unregisterForJankData();
}
/**
* Retrieve all pending widget states, this is intended for testing purposes only.
+ *
* @param stateDataList the ArrayList that will be populated with the pending states.
*/
@VisibleForTesting
@@ -190,16 +234,35 @@
@VisibleForTesting
public void forceListenerRegistration() {
mSurfaceControl = mDecorView.getRootSurfaceControl();
- registerForJankData();
- // TODO b/376116199 Check if registration is good.
- mListenersRegistered = true;
+ registerJankDataListener();
+ }
+
+ private void unregisterForJankData() {
+ if (mJankDataListenerRegistration == null) return;
+
+ if (com.android.window.flags.Flags.jankApi()) {
+ mJankDataListenerRegistration.release();
+ }
+ mJankDataListenerRegistration = null;
+ mListenersRegistered = false;
}
private void registerForJankData() {
- if (mSurfaceControl == null) return;
- /*
- TODO b/376115668 Register for JankData batches from new JankTracking API
- */
+ if (mDecorView == null) return;
+
+ mSurfaceControl = mDecorView.getRootSurfaceControl();
+
+ if (mSurfaceControl == null || mListenersRegistered) return;
+
+ // Wait a short time before registering the listener. During development it was observed
+ // that if a listener is registered too quickly after a hot or warm start no data is
+ // received b/394956095.
+ getHandler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ registerJankDataListener();
+ }
+ }, REGISTRATION_DELAY_MS);
}
/**
@@ -218,23 +281,30 @@
*/
private void registerWindowListeners() {
if (mDecorView == null) return;
- mViewTreeObserver = mDecorView.getViewTreeObserver();
- mViewTreeObserver.addOnWindowAttachListener(new ViewTreeObserver.OnWindowAttachListener() {
- @Override
- public void onWindowAttached() {
- getHandler().postDelayed(new Runnable() {
- @Override
- public void run() {
- forceListenerRegistration();
- }
- }, 1000);
- }
+ mDecorView.getViewTreeObserver().addOnWindowAttachListener(mOnWindowAttachListener);
+ }
- @Override
- public void onWindowDetached() {
- // TODO b/376116199 do we un-register the callback or just not process the data.
+ private void registerJankDataListener() {
+ if (mSurfaceControl == null) {
+ if (DEBUG) {
+ Log.d(DEBUG_KEY, "SurfaceControl is Null");
}
- });
+ return;
+ }
+
+ if (com.android.window.flags.Flags.jankApi()) {
+ mJankDataListenerRegistration = mSurfaceControl.registerOnJankDataListener(
+ mHandlerThread.getThreadExecutor(), mJankDataListener);
+
+ if (mJankDataListenerRegistration
+ == SurfaceControl.OnJankDataListenerRegistration.NONE) {
+ if (DEBUG) {
+ Log.d(DEBUG_KEY, "OnJankDataListenerRegistration is assigned NONE");
+ }
+ return;
+ }
+ mListenersRegistered = true;
+ }
}
private Handler getHandler() {
diff --git a/core/java/android/app/notification.aconfig b/core/java/android/app/notification.aconfig
index bb4f556..8e6b88c 100644
--- a/core/java/android/app/notification.aconfig
+++ b/core/java/android/app/notification.aconfig
@@ -83,6 +83,13 @@
}
flag {
+ name: "modes_cleanup_implicit"
+ namespace: "systemui"
+ description: "Deletes implicit modes if never customized and not used for some time. Depends on MODES_UI"
+ bug: "394087495"
+}
+
+flag {
name: "api_tvextender"
is_exported: true
namespace: "systemui"
diff --git a/core/java/android/app/supervision/ISupervisionManager.aidl b/core/java/android/app/supervision/ISupervisionManager.aidl
index e583302..2f67a8a 100644
--- a/core/java/android/app/supervision/ISupervisionManager.aidl
+++ b/core/java/android/app/supervision/ISupervisionManager.aidl
@@ -16,11 +16,14 @@
package android.app.supervision;
+import android.content.Intent;
+
/**
* Internal IPC interface to the supervision service.
* {@hide}
*/
interface ISupervisionManager {
+ Intent createConfirmSupervisionCredentialsIntent();
boolean isSupervisionEnabledForUser(int userId);
void setSupervisionEnabledForUser(int userId, boolean enabled);
String getActiveSupervisionAppPackage(int userId);
diff --git a/core/java/android/app/supervision/SupervisionManager.java b/core/java/android/app/supervision/SupervisionManager.java
index d307055..0270edf 100644
--- a/core/java/android/app/supervision/SupervisionManager.java
+++ b/core/java/android/app/supervision/SupervisionManager.java
@@ -16,13 +16,22 @@
package android.app.supervision;
+import static android.Manifest.permission.INTERACT_ACROSS_USERS;
+import static android.Manifest.permission.MANAGE_USERS;
+import static android.Manifest.permission.QUERY_USERS;
+
+import android.annotation.FlaggedApi;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
import android.annotation.SystemService;
+import android.annotation.TestApi;
import android.annotation.UserHandleAware;
import android.annotation.UserIdInt;
+import android.app.supervision.flags.Flags;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
+import android.content.Intent;
import android.os.RemoteException;
/**
@@ -31,6 +40,8 @@
* @hide
*/
@SystemService(Context.SUPERVISION_SERVICE)
+@SystemApi
+@FlaggedApi(Flags.FLAG_SUPERVISION_MANAGER_APIS)
public class SupervisionManager {
private final Context mContext;
@Nullable private final ISupervisionManager mService;
@@ -47,7 +58,8 @@
*
* @hide
*/
- public static final String ACTION_ENABLE_SUPERVISION = "android.app.action.ENABLE_SUPERVISION";
+ public static final String ACTION_ENABLE_SUPERVISION =
+ "android.app.supervision.action.ENABLE_SUPERVISION";
/**
* Activity action: ask the human user to disable supervision for this user. Only the app that
@@ -62,7 +74,7 @@
* @hide
*/
public static final String ACTION_DISABLE_SUPERVISION =
- "android.app.action.DISABLE_SUPERVISION";
+ "android.app.supervision.action.DISABLE_SUPERVISION";
/** @hide */
@UnsupportedAppUsage
@@ -72,11 +84,46 @@
}
/**
+ * Creates an {@link Intent} that can be used with {@link Context#startActivity(Intent)} to
+ * launch the activity to verify supervision credentials.
+ *
+ * <p>A valid {@link Intent} is always returned if supervision is enabled at the time this API
+ * is called, the launched activity still need to perform validity checks as the supervision
+ * state can change when the activity is launched. A null intent is returned if supervision is
+ * disabled at the time of this API call.
+ *
+ * <p>A result code of {@link android.app.Activity#RESULT_OK} indicates successful verification
+ * of the supervision credentials.
+ *
+ * @hide
+ */
+ @RequiresPermission(value = android.Manifest.permission.QUERY_USERS)
+ @Nullable
+ public Intent createConfirmSupervisionCredentialsIntent() {
+ if (mService != null) {
+ try {
+ Intent result = mService.createConfirmSupervisionCredentialsIntent();
+ if (result != null) {
+ result.prepareToEnterProcess(
+ Intent.LOCAL_FLAG_FROM_SYSTEM, mContext.getAttributionSource());
+ }
+ return result;
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ return null;
+ }
+
+ /**
* Returns whether the device is supervised.
*
* @hide
*/
- @UserHandleAware
+ @SystemApi
+ @FlaggedApi(Flags.FLAG_SUPERVISION_MANAGER_APIS)
+ @RequiresPermission(anyOf = {MANAGE_USERS, QUERY_USERS})
+ @UserHandleAware(requiresPermissionIfNotCaller = INTERACT_ACROSS_USERS)
public boolean isSupervisionEnabled() {
return isSupervisionEnabledForUser(mContext.getUserId());
}
@@ -84,14 +131,10 @@
/**
* Returns whether the device is supervised.
*
- * <p>The caller must be from the same user as the target or hold the {@link
- * android.Manifest.permission#INTERACT_ACROSS_USERS} permission.
- *
* @hide
*/
- @RequiresPermission(
- value = android.Manifest.permission.INTERACT_ACROSS_USERS,
- conditional = true)
+ @RequiresPermission(anyOf = {MANAGE_USERS, QUERY_USERS})
+ @UserHandleAware(requiresPermissionIfNotCaller = INTERACT_ACROSS_USERS)
public boolean isSupervisionEnabledForUser(@UserIdInt int userId) {
if (mService != null) {
try {
@@ -108,7 +151,8 @@
*
* @hide
*/
- @UserHandleAware
+ @TestApi
+ @UserHandleAware(requiresPermissionIfNotCaller = INTERACT_ACROSS_USERS)
public void setSupervisionEnabled(boolean enabled) {
setSupervisionEnabledForUser(mContext.getUserId(), enabled);
}
@@ -116,14 +160,9 @@
/**
* Sets whether the device is supervised for a given user.
*
- * <p>The caller must be from the same user as the target or hold the {@link
- * android.Manifest.permission#INTERACT_ACROSS_USERS} permission.
- *
* @hide
*/
- @RequiresPermission(
- value = android.Manifest.permission.INTERACT_ACROSS_USERS,
- conditional = true)
+ @UserHandleAware(requiresPermissionIfNotCaller = INTERACT_ACROSS_USERS)
public void setSupervisionEnabledForUser(@UserIdInt int userId, boolean enabled) {
if (mService != null) {
try {
diff --git a/core/java/android/app/supervision/flags.aconfig b/core/java/android/app/supervision/flags.aconfig
index 232883c..94de038 100644
--- a/core/java/android/app/supervision/flags.aconfig
+++ b/core/java/android/app/supervision/flags.aconfig
@@ -64,3 +64,11 @@
description: "Flag that enables the Supervision pin recovery screen with Supervision settings entry point"
bug: "390500290"
}
+
+flag {
+ name: "supervision_manager_apis"
+ is_exported: true
+ namespace: "supervision"
+ description: "Flag that enables system APIs in Supervision Manager"
+ bug: "382034839"
+}
diff --git a/core/java/android/companion/virtual/flags/flags.aconfig b/core/java/android/companion/virtual/flags/flags.aconfig
index fcdb02a..ba1473c 100644
--- a/core/java/android/companion/virtual/flags/flags.aconfig
+++ b/core/java/android/companion/virtual/flags/flags.aconfig
@@ -120,6 +120,16 @@
}
flag {
+ name: "correct_virtual_display_power_state"
+ namespace: "virtual_devices"
+ description: "Fix the virtual display power state"
+ bug: "371125136"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "vdm_settings"
namespace: "virtual_devices"
description: "Show virtual devices in Settings"
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 3391e79..55d78f9b 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -17,8 +17,8 @@
package android.content;
import static android.app.appfunctions.flags.Flags.FLAG_ENABLE_APP_FUNCTION_MANAGER;
-import static android.content.flags.Flags.FLAG_ENABLE_BIND_PACKAGE_ISOLATED_PROCESS;
import static android.app.ondeviceintelligence.flags.Flags.FLAG_ENABLE_ON_DEVICE_INTELLIGENCE_MODULE;
+import static android.content.flags.Flags.FLAG_ENABLE_BIND_PACKAGE_ISOLATED_PROCESS;
import static android.security.Flags.FLAG_SECURE_LOCKDOWN;
import android.annotation.AttrRes;
@@ -6858,6 +6858,8 @@
* @see android.app.supervision.SupervisionManager
* @hide
*/
+ @SystemApi
+ @FlaggedApi(android.app.supervision.flags.Flags.FLAG_SUPERVISION_MANAGER_APIS)
public static final String SUPERVISION_SERVICE = "supervision";
/**
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index d64ef75..4bbbad4 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -3250,7 +3250,6 @@
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.MANAGE_ROLLBACKS)
- @FlaggedApi(Flags.FLAG_RECOVERABILITY_DETECTION)
public void setRollbackImpactLevel(@PackageManager.RollbackImpactLevel int impactLevel) {
if ((installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) == 0) {
throw new IllegalArgumentException(
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 6ae2df2..f91b247 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1619,7 +1619,6 @@
* @hide
*/
@SystemApi
- @FlaggedApi(android.content.pm.Flags.FLAG_RECOVERABILITY_DETECTION)
public static final int ROLLBACK_USER_IMPACT_LOW = 0;
/**
@@ -1629,7 +1628,6 @@
* @hide
*/
@SystemApi
- @FlaggedApi(android.content.pm.Flags.FLAG_RECOVERABILITY_DETECTION)
public static final int ROLLBACK_USER_IMPACT_HIGH = 1;
/**
@@ -1638,7 +1636,6 @@
* @hide
*/
@SystemApi
- @FlaggedApi(android.content.pm.Flags.FLAG_RECOVERABILITY_DETECTION)
public static final int ROLLBACK_USER_IMPACT_ONLY_MANUAL = 2;
/** @hide */
diff --git a/core/java/android/content/pm/SystemFeaturesCache.java b/core/java/android/content/pm/SystemFeaturesCache.java
index c41a7ab..b3d70fa 100644
--- a/core/java/android/content/pm/SystemFeaturesCache.java
+++ b/core/java/android/content/pm/SystemFeaturesCache.java
@@ -16,9 +16,8 @@
package android.content.pm;
+import android.annotation.MainThread;
import android.annotation.NonNull;
-import android.os.Parcel;
-import android.os.Parcelable;
import android.util.ArrayMap;
import com.android.internal.annotations.VisibleForTesting;
@@ -35,16 +34,53 @@
*
* @hide
*/
-public final class SystemFeaturesCache implements Parcelable {
+public final class SystemFeaturesCache {
// Sentinel value used for SDK-declared features that are unavailable on the current device.
private static final int UNAVAILABLE_FEATURE_VERSION = Integer.MIN_VALUE;
+ // This will be initialized just once, from the process main thread, but ready from any thread.
+ private static volatile SystemFeaturesCache sInstance;
+
// An array of versions for SDK-defined features, from [0, PackageManager.SDK_FEATURE_COUNT).
@NonNull
private final int[] mSdkFeatureVersions;
/**
+ * Installs the process-global cache instance.
+ *
+ * <p>Note: Usage should be gated on android.content.pm.Flags.cacheSdkSystemFeature(). In
+ * practice, this should only be called from 1) SystemServer init, or 2) bindApplication.
+ */
+ @MainThread
+ public static void setInstance(SystemFeaturesCache instance) {
+ if (sInstance != null) {
+ throw new IllegalStateException("SystemFeaturesCache instance already initialized.");
+ }
+ sInstance = instance;
+ }
+
+ /**
+ * Gets the process-global cache instance.
+ *
+ * Note: Usage should be gated on android.content.pm.Flags.cacheSdkSystemFeature(), and should
+ * always occur after the instance has been installed early in the process lifecycle.
+ */
+ public static @NonNull SystemFeaturesCache getInstance() {
+ SystemFeaturesCache instance = sInstance;
+ if (instance == null) {
+ throw new IllegalStateException("SystemFeaturesCache not initialized");
+ }
+ return instance;
+ }
+
+ /** Clears the process-global cache instance for testing. */
+ @VisibleForTesting
+ public static void clearInstance() {
+ sInstance = null;
+ }
+
+ /**
* Populates the cache from the set of all available {@link FeatureInfo} definitions.
*
* System features declared in {@link PackageManager} will be entered into the cache based on
@@ -69,20 +105,28 @@
}
}
- /** Only used by @{code CREATOR.createFromParcel(...)} */
- private SystemFeaturesCache(@NonNull Parcel parcel) {
- final int[] featureVersions = parcel.createIntArray();
- if (featureVersions == null) {
- throw new IllegalArgumentException(
- "Parceled SDK feature versions should never be null");
- }
- if (featureVersions.length != PackageManager.SDK_FEATURE_COUNT) {
+ /**
+ * Populates the cache from an array of SDK feature versions originally obtained via {@link
+ * #getSdkFeatureVersions()} from another instance.
+ */
+ public SystemFeaturesCache(@NonNull int[] sdkFeatureVersions) {
+ if (sdkFeatureVersions.length != PackageManager.SDK_FEATURE_COUNT) {
throw new IllegalArgumentException(
String.format(
"Unexpected cached SDK feature count: %d (expected %d)",
- featureVersions.length, PackageManager.SDK_FEATURE_COUNT));
+ sdkFeatureVersions.length, PackageManager.SDK_FEATURE_COUNT));
}
- mSdkFeatureVersions = featureVersions;
+ mSdkFeatureVersions = sdkFeatureVersions;
+ }
+
+ /**
+ * Gets the raw cached feature versions.
+ *
+ * <p>Note: This should generally only be neded for (de)serialization purposes.
+ */
+ // TODO(b/375000483): Consider reusing the ApplicationSharedMemory mapping for version lookup.
+ public int[] getSdkFeatureVersions() {
+ return mSdkFeatureVersions;
}
/**
@@ -105,29 +149,4 @@
return mSdkFeatureVersions[sdkFeatureIndex] >= version;
}
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(@NonNull Parcel parcel, int flags) {
- parcel.writeIntArray(mSdkFeatureVersions);
- }
-
- @NonNull
- public static final Parcelable.Creator<SystemFeaturesCache> CREATOR =
- new Parcelable.Creator<SystemFeaturesCache>() {
-
- @Override
- public SystemFeaturesCache createFromParcel(Parcel parcel) {
- return new SystemFeaturesCache(parcel);
- }
-
- @Override
- public SystemFeaturesCache[] newArray(int size) {
- return new SystemFeaturesCache[size];
- }
- };
}
diff --git a/core/java/android/content/res/XmlBlock.java b/core/java/android/content/res/XmlBlock.java
index 40c5324..36fa059 100644
--- a/core/java/android/content/res/XmlBlock.java
+++ b/core/java/android/content/res/XmlBlock.java
@@ -29,6 +29,8 @@
import android.util.TypedValue;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.pm.pkg.component.AconfigFlags;
+import com.android.internal.pm.pkg.parsing.ParsingPackageUtils;
import com.android.internal.util.XmlUtils;
import dalvik.annotation.optimization.CriticalNative;
@@ -50,6 +52,7 @@
@RavenwoodClassLoadHook(RavenwoodClassLoadHook.LIBANDROID_LOADING_HOOK)
public final class XmlBlock implements AutoCloseable {
private static final boolean DEBUG=false;
+ public static final String ANDROID_RESOURCES = "http://schemas.android.com/apk/res/android";
@UnsupportedAppUsage
public XmlBlock(byte[] data) {
@@ -343,6 +346,23 @@
if (ev == ERROR_BAD_DOCUMENT) {
throw new XmlPullParserException("Corrupt XML binary file");
}
+ if (useLayoutReadwrite() && ev == START_TAG) {
+ AconfigFlags flags = ParsingPackageUtils.getAconfigFlags();
+ if (flags.skipCurrentElement(/* pkg= */ null, this)) {
+ int depth = 1;
+ while (depth > 0) {
+ int ev2 = nativeNext(mParseState);
+ if (ev2 == ERROR_BAD_DOCUMENT) {
+ throw new XmlPullParserException("Corrupt XML binary file");
+ } else if (ev2 == START_TAG) {
+ depth++;
+ } else if (ev2 == END_TAG) {
+ depth--;
+ }
+ }
+ return next();
+ }
+ }
if (mDecNextDepth) {
mDepth--;
mDecNextDepth = false;
@@ -368,6 +388,18 @@
}
return ev;
}
+
+ // Until ravenwood supports AconfigFlags, we just don't do layoutReadwriteFlags().
+ @android.ravenwood.annotation.RavenwoodReplace(
+ bug = 396458006, blockedBy = AconfigFlags.class)
+ private static boolean useLayoutReadwrite() {
+ return Flags.layoutReadwriteFlags();
+ }
+
+ private static boolean useLayoutReadwrite$ravenwood() {
+ return false;
+ }
+
public void require(int type, String namespace, String name) throws XmlPullParserException,IOException {
if (type != getEventType()
|| (namespace != null && !namespace.equals( getNamespace () ) )
diff --git a/core/java/android/hardware/fingerprint/FingerprintSensorConfigurations.java b/core/java/android/hardware/fingerprint/FingerprintSensorConfigurations.java
index 48c5887..586830c 100644
--- a/core/java/android/hardware/fingerprint/FingerprintSensorConfigurations.java
+++ b/core/java/android/hardware/fingerprint/FingerprintSensorConfigurations.java
@@ -224,6 +224,10 @@
} catch (RemoteException e) {
Log.d(TAG, "Unable to get sensor properties!");
}
+
+ if (props == null) {
+ props = new SensorProps[]{};
+ }
return props;
}
}
diff --git a/core/java/android/hardware/input/InputSettings.java b/core/java/android/hardware/input/InputSettings.java
index 3d4b885..7c82abe0 100644
--- a/core/java/android/hardware/input/InputSettings.java
+++ b/core/java/android/hardware/input/InputSettings.java
@@ -386,7 +386,7 @@
*/
public static boolean isTouchpadAccelerationEnabled(@NonNull Context context) {
if (!isPointerAccelerationFeatureFlagEnabled()) {
- return false;
+ return true;
}
return Settings.System.getIntForUser(context.getContentResolver(),
@@ -833,7 +833,7 @@
*/
public static boolean isMousePointerAccelerationEnabled(@NonNull Context context) {
if (!isPointerAccelerationFeatureFlagEnabled()) {
- return false;
+ return true;
}
return Settings.System.getIntForUser(context.getContentResolver(),
diff --git a/core/java/android/hardware/usb/IUsbManager.aidl b/core/java/android/hardware/usb/IUsbManager.aidl
index c0e506b..21d3ef0 100644
--- a/core/java/android/hardware/usb/IUsbManager.aidl
+++ b/core/java/android/hardware/usb/IUsbManager.aidl
@@ -126,6 +126,9 @@
/* Returns true if the specified USB function is enabled. */
boolean isFunctionEnabled(String function);
+ /* Returns true if UVC gadget support is enabled. */
+ boolean isUvcGadgetSupportEnabled();
+
/* Sets the current USB function. */
@EnforcePermission("MANAGE_USB")
void setCurrentFunctions(long functions, int operationId);
diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java
index d2e232a..a005e33 100644
--- a/core/java/android/hardware/usb/UsbManager.java
+++ b/core/java/android/hardware/usb/UsbManager.java
@@ -30,8 +30,10 @@
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
+import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.annotation.SystemService;
+import android.annotation.TestApi;
import android.app.PendingIntent;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
@@ -1437,6 +1439,21 @@
}
/**
+ * Returns true if the specified UVC gadget function support is enabled.
+ * <p>
+ * @hide
+ */
+ @TestApi
+ @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
+ public boolean isUvcGadgetSupportEnabled() {
+ try {
+ return mService.isUvcGadgetSupportEnabled();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Sets the current USB functions when in device mode.
* <p>
* USB functions represent interfaces which are published to the host to access
@@ -1641,6 +1658,7 @@
}
}
+ // TODO: b/396680593 Deprecate to de-dup with isUvcGadgetSupportEnabled()
/**
* Returns whether UVC is advertised to be supported or not. SELinux
* enforces that this function returns {@code false} when called from a
diff --git a/core/java/android/os/CombinedMessageQueue/MessageQueue.java b/core/java/android/os/CombinedMessageQueue/MessageQueue.java
index 349a2f0..3c03bb5 100644
--- a/core/java/android/os/CombinedMessageQueue/MessageQueue.java
+++ b/core/java/android/os/CombinedMessageQueue/MessageQueue.java
@@ -178,11 +178,6 @@
// We can lift these restrictions in the future after we've made it possible for test
// authors to test Looper and MessageQueue without resorting to reflection.
-
- // Holdback study.
- if (sIsProcessAllowedToUseConcurrent && Flags.messageQueueForceLegacy()) {
- sIsProcessAllowedToUseConcurrent = false;
- }
}
@RavenwoodReplace
@@ -238,9 +233,13 @@
traceMessageCount();
PerfettoTrace.instant(PerfettoTrace.MQ_CATEGORY, "message_queue_send")
.addFlow(msg.mEventId.get())
- .addArg("receiving_thread", mThread.getName())
- .addArg("delay", when - SystemClock.uptimeMillis())
- .addArg("what", msg.what)
+ .beginProto()
+ .beginNested(2004 /* message_queue */)
+ .addField(2 /* receiving_thread_name */, mThread.getName())
+ .addField(3 /* message_code */, msg.what)
+ .addField(4 /* message_delay_ms */, when - SystemClock.uptimeMillis())
+ .endNested()
+ .endProto()
.emit();
}
diff --git a/core/java/android/os/Looper.java b/core/java/android/os/Looper.java
index d16e447..1329b90 100644
--- a/core/java/android/os/Looper.java
+++ b/core/java/android/os/Looper.java
@@ -200,7 +200,11 @@
}
PerfettoTrace.begin(PerfettoTrace.MQ_CATEGORY, "message_queue_receive")
- .addArg("sending_thread", msg.mSendingThreadName)
+ .beginProto()
+ .beginNested(2004 /* message_queue */)
+ .addField(1 /* sending_thread_name */, msg.mSendingThreadName)
+ .endNested()
+ .endProto()
.addTerminatingFlow(msg.mEventId.get())
.emit();
diff --git a/core/java/android/os/SystemVibratorManager.java b/core/java/android/os/SystemVibratorManager.java
index f9935d2..1c3dd9e 100644
--- a/core/java/android/os/SystemVibratorManager.java
+++ b/core/java/android/os/SystemVibratorManager.java
@@ -217,7 +217,7 @@
new VendorVibrationSessionCallbackDelegate(executor, callback);
if (mService == null) {
Log.w(TAG, "Failed to start vibration session; no vibrator manager service.");
- callbackDelegate.onFinished(VendorVibrationSession.STATUS_UNKNOWN_ERROR);
+ callbackDelegate.onFinished(VendorVibrationSession.STATUS_UNSUPPORTED);
return;
}
try {
diff --git a/core/java/android/os/flags.aconfig b/core/java/android/os/flags.aconfig
index 9e7c9f6..d3c677b 100644
--- a/core/java/android/os/flags.aconfig
+++ b/core/java/android/os/flags.aconfig
@@ -4,15 +4,6 @@
# keep-sorted start block=yes newline_separated=yes
flag {
- # Holdback study for concurrent MessageQueue.
- # Do not promote beyond trunkfood.
- namespace: "system_performance"
- name: "message_queue_force_legacy"
- description: "Whether to holdback concurrent MessageQueue (force legacy)."
- bug: "336880969"
-}
-
-flag {
name: "adpf_gpu_report_actual_work_duration"
is_exported: true
namespace: "game"
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 1a9b42e..4ebfe53 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -153,7 +153,6 @@
* Output: Nothing.
*/
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- @FlaggedApi(com.android.internal.telephony.flags.Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
public static final String ACTION_SATELLITE_SETTING = "android.settings.SATELLITE_SETTING";
/**
diff --git a/core/java/android/service/credentials/CredentialProviderInfoFactory.java b/core/java/android/service/credentials/CredentialProviderInfoFactory.java
index 3cd705a..2266e96 100644
--- a/core/java/android/service/credentials/CredentialProviderInfoFactory.java
+++ b/core/java/android/service/credentials/CredentialProviderInfoFactory.java
@@ -88,7 +88,7 @@
int userId,
boolean isSystemProvider,
boolean isPrimary)
- throws PackageManager.NameNotFoundException {
+ throws PackageManager.NameNotFoundException, SecurityException, NullPointerException {
return create(
context,
getServiceInfoOrThrow(serviceComponent, userId),
@@ -117,7 +117,7 @@
boolean disableSystemAppVerificationForTests,
boolean isEnabled,
boolean isPrimary)
- throws SecurityException {
+ throws SecurityException, NullPointerException {
verifyProviderPermission(serviceInfo);
if (isSystemProvider) {
if (!isValidSystemProvider(
@@ -199,7 +199,7 @@
}
private static CredentialProviderInfo.Builder populateMetadata(
- @NonNull Context context, ServiceInfo serviceInfo) {
+ @NonNull Context context, ServiceInfo serviceInfo) throws NullPointerException {
requireNonNull(context, "context must not be null");
final PackageManager pm = context.getPackageManager();
CredentialProviderInfo.Builder builder = new CredentialProviderInfo.Builder(serviceInfo);
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index 4011574..6f94c1b 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -309,6 +309,7 @@
private static final String RULE_ATT_DISABLED_ORIGIN = "disabledOrigin";
private static final String RULE_ATT_LEGACY_SUPPRESSED_EFFECTS = "legacySuppressedEffects";
private static final String RULE_ATT_CONDITION_OVERRIDE = "conditionOverride";
+ private static final String RULE_ATT_LAST_ACTIVATION = "lastActivation";
private static final String DEVICE_EFFECT_DISPLAY_GRAYSCALE = "zdeDisplayGrayscale";
private static final String DEVICE_EFFECT_SUPPRESS_AMBIENT_DISPLAY =
@@ -1187,11 +1188,7 @@
rt.zenPolicyUserModifiedFields = safeInt(parser, POLICY_USER_MODIFIED_FIELDS, 0);
rt.zenDeviceEffectsUserModifiedFields = safeInt(parser,
DEVICE_EFFECT_USER_MODIFIED_FIELDS, 0);
- Long deletionInstant = tryParseLong(
- parser.getAttributeValue(null, RULE_ATT_DELETION_INSTANT), null);
- if (deletionInstant != null) {
- rt.deletionInstant = Instant.ofEpochMilli(deletionInstant);
- }
+ rt.deletionInstant = safeInstant(parser, RULE_ATT_DELETION_INSTANT, null);
if (Flags.modesUi()) {
rt.disabledOrigin = safeInt(parser, RULE_ATT_DISABLED_ORIGIN,
ORIGIN_UNKNOWN);
@@ -1199,6 +1196,9 @@
RULE_ATT_LEGACY_SUPPRESSED_EFFECTS, 0);
rt.conditionOverride = safeInt(parser, RULE_ATT_CONDITION_OVERRIDE,
ZenRule.OVERRIDE_NONE);
+ if (Flags.modesCleanupImplicit()) {
+ rt.lastActivation = safeInstant(parser, RULE_ATT_LAST_ACTIVATION, null);
+ }
}
return rt;
@@ -1249,10 +1249,7 @@
out.attributeInt(null, POLICY_USER_MODIFIED_FIELDS, rule.zenPolicyUserModifiedFields);
out.attributeInt(null, DEVICE_EFFECT_USER_MODIFIED_FIELDS,
rule.zenDeviceEffectsUserModifiedFields);
- if (rule.deletionInstant != null) {
- out.attributeLong(null, RULE_ATT_DELETION_INSTANT,
- rule.deletionInstant.toEpochMilli());
- }
+ writeXmlAttributeInstant(out, RULE_ATT_DELETION_INSTANT, rule.deletionInstant);
if (Flags.modesUi()) {
out.attributeInt(null, RULE_ATT_DISABLED_ORIGIN, rule.disabledOrigin);
out.attributeInt(null, RULE_ATT_LEGACY_SUPPRESSED_EFFECTS,
@@ -1260,6 +1257,16 @@
if (rule.conditionOverride == ZenRule.OVERRIDE_ACTIVATE && !forBackup) {
out.attributeInt(null, RULE_ATT_CONDITION_OVERRIDE, rule.conditionOverride);
}
+ if (Flags.modesCleanupImplicit()) {
+ writeXmlAttributeInstant(out, RULE_ATT_LAST_ACTIVATION, rule.lastActivation);
+ }
+ }
+ }
+
+ private static void writeXmlAttributeInstant(TypedXmlSerializer out, String att,
+ @Nullable Instant instant) throws IOException {
+ if (instant != null) {
+ out.attributeLong(null, att, instant.toEpochMilli());
}
}
@@ -1600,6 +1607,19 @@
return values;
}
+ @Nullable
+ private static Instant safeInstant(TypedXmlPullParser parser, String att,
+ @Nullable Instant defValue) {
+ final String strValue = parser.getAttributeValue(null, att);
+ if (!TextUtils.isEmpty(strValue)) {
+ Long longValue = tryParseLong(strValue, null);
+ if (longValue != null) {
+ return Instant.ofEpochMilli(longValue);
+ }
+ }
+ return defValue;
+ }
+
@Override
public int describeContents() {
return 0;
@@ -2598,6 +2618,18 @@
@ConditionOverride
int conditionOverride = OVERRIDE_NONE;
+ /**
+ * Last time at which the rule was activated (for any reason, including overrides).
+ * If {@code null}, the rule has never been activated since its creation.
+ *
+ * <p>Note that this was previously untracked, so it will also be {@code null} for rules
+ * created before we started tracking and never activated since -- make sure to account for
+ * it, for example by falling back to {@link #creationTime} in logic involving this field.
+ */
+ @Nullable
+ @FlaggedApi(Flags.FLAG_MODES_CLEANUP_IMPLICIT)
+ public Instant lastActivation;
+
public ZenRule() { }
public ZenRule(Parcel source) {
@@ -2635,24 +2667,29 @@
disabledOrigin = source.readInt();
legacySuppressedEffects = source.readInt();
conditionOverride = source.readInt();
+ if (Flags.modesCleanupImplicit()) {
+ if (source.readInt() == 1) {
+ lastActivation = Instant.ofEpochMilli(source.readLong());
+ }
+ }
}
}
/**
- * Whether this ZenRule can be updated by an app. In general, rules that have been
- * customized by the user cannot be further updated by an app, with some exceptions:
+ * Whether this ZenRule has been customized by the user in any way.
+
+ * <p>In general, rules that have been customized by the user cannot be further updated by
+ * an app, with some exceptions:
* <ul>
* <li>Non user-configurable fields, like type, icon, configurationActivity, etc.
* <li>Name, if the name was not specifically modified by the user (to support language
* switches).
* </ul>
*/
- public boolean canBeUpdatedByApp() {
- // The rule is considered updateable if its bitmask has no user modifications, and
- // the bitmasks of the policy and device effects have no modification.
- return userModifiedFields == 0
- && zenPolicyUserModifiedFields == 0
- && zenDeviceEffectsUserModifiedFields == 0;
+ public boolean isUserModified() {
+ return userModifiedFields != 0
+ || zenPolicyUserModifiedFields != 0
+ || zenDeviceEffectsUserModifiedFields != 0;
}
@Override
@@ -2708,6 +2745,14 @@
dest.writeInt(disabledOrigin);
dest.writeInt(legacySuppressedEffects);
dest.writeInt(conditionOverride);
+ if (Flags.modesCleanupImplicit()) {
+ if (lastActivation != null) {
+ dest.writeInt(1);
+ dest.writeLong(lastActivation.toEpochMilli());
+ } else {
+ dest.writeInt(0);
+ }
+ }
}
}
@@ -2760,6 +2805,9 @@
if (Flags.modesUi()) {
sb.append(",disabledOrigin=").append(disabledOrigin);
sb.append(",legacySuppressedEffects=").append(legacySuppressedEffects);
+ if (Flags.modesCleanupImplicit()) {
+ sb.append(",lastActivation=").append(lastActivation);
+ }
}
return sb.append(']').toString();
@@ -2838,6 +2886,10 @@
&& other.disabledOrigin == disabledOrigin
&& other.legacySuppressedEffects == legacySuppressedEffects
&& other.conditionOverride == conditionOverride;
+ if (Flags.modesCleanupImplicit()) {
+ finalEquals = finalEquals
+ && Objects.equals(other.lastActivation, lastActivation);
+ }
}
return finalEquals;
@@ -2846,13 +2898,23 @@
@Override
public int hashCode() {
if (Flags.modesUi()) {
- return Objects.hash(enabled, snoozing, name, zenMode, conditionId, condition,
- component, configurationActivity, pkg, id, enabler, zenPolicy,
- zenDeviceEffects, allowManualInvocation, iconResName,
- triggerDescription, type, userModifiedFields,
- zenPolicyUserModifiedFields, zenDeviceEffectsUserModifiedFields,
- deletionInstant, disabledOrigin, legacySuppressedEffects,
- conditionOverride);
+ if (Flags.modesCleanupImplicit()) {
+ return Objects.hash(enabled, snoozing, name, zenMode, conditionId, condition,
+ component, configurationActivity, pkg, id, enabler, zenPolicy,
+ zenDeviceEffects, allowManualInvocation, iconResName,
+ triggerDescription, type, userModifiedFields,
+ zenPolicyUserModifiedFields, zenDeviceEffectsUserModifiedFields,
+ deletionInstant, disabledOrigin, legacySuppressedEffects,
+ conditionOverride, lastActivation);
+ } else {
+ return Objects.hash(enabled, snoozing, name, zenMode, conditionId, condition,
+ component, configurationActivity, pkg, id, enabler, zenPolicy,
+ zenDeviceEffects, allowManualInvocation, iconResName,
+ triggerDescription, type, userModifiedFields,
+ zenPolicyUserModifiedFields, zenDeviceEffectsUserModifiedFields,
+ deletionInstant, disabledOrigin, legacySuppressedEffects,
+ conditionOverride);
+ }
} else {
return Objects.hash(enabled, snoozing, name, zenMode, conditionId, condition,
component, configurationActivity, pkg, id, enabler, zenPolicy,
diff --git a/core/java/android/telephony/TelephonyCallback.java b/core/java/android/telephony/TelephonyCallback.java
index d05fa9e..daa4e89 100644
--- a/core/java/android/telephony/TelephonyCallback.java
+++ b/core/java/android/telephony/TelephonyCallback.java
@@ -2330,8 +2330,6 @@
}
public void onCarrierRoamingNtnModeChanged(boolean active) {
- if (!Flags.carrierEnabledSatelliteFlag()) return;
-
CarrierRoamingNtnListener listener =
(CarrierRoamingNtnListener) mTelephonyCallbackWeakRef.get();
if (listener == null) return;
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index ca0959a..231aa68 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -1599,7 +1599,6 @@
mGlobal.registerDisplayListener(toRegister, executor,
DisplayManagerGlobal
.INTERNAL_EVENT_FLAG_DISPLAY_BASIC_CHANGED
- | DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_REFRESH_RATE
| DisplayManagerGlobal
.INTERNAL_EVENT_FLAG_DISPLAY_HDR_SDR_RATIO_CHANGED,
ActivityThread.currentPackageName());
diff --git a/core/java/android/view/NotificationHeaderView.java b/core/java/android/view/NotificationHeaderView.java
index 73cd5ec..df680c0 100644
--- a/core/java/android/view/NotificationHeaderView.java
+++ b/core/java/android/view/NotificationHeaderView.java
@@ -32,7 +32,6 @@
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.util.AttributeSet;
-import android.util.TypedValue;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
import android.widget.RemoteViews;
@@ -266,20 +265,14 @@
? R.style.TextAppearance_DeviceDefault_Notification_Title
: R.style.TextAppearance_DeviceDefault_Notification_Info;
// Most of the time, we're showing text in the minimized state
- if (findViewById(R.id.header_text) instanceof TextView headerText) {
- headerText.setTextAppearance(styleResId);
- if (notificationsRedesignTemplates()) {
- // TODO: b/378660052 - When inlining the redesign flag, this should be updated
- // directly in TextAppearance_DeviceDefault_Notification_Title so we won't need to
- // override it here.
- float textSize = getContext().getResources().getDimension(
- R.dimen.notification_2025_title_text_size);
- headerText.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
- }
+ View headerText = findViewById(R.id.header_text);
+ if (headerText instanceof TextView) {
+ ((TextView) headerText).setTextAppearance(styleResId);
}
// If there's no summary or text, we show the app name instead of nothing
- if (findViewById(R.id.app_name_text) instanceof TextView appNameText) {
- appNameText.setTextAppearance(styleResId);
+ View appNameText = findViewById(R.id.app_name_text);
+ if (appNameText instanceof TextView) {
+ ((TextView) appNameText).setTextAppearance(styleResId);
}
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index de3e45b..6b6147a 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -118,6 +118,7 @@
import static android.view.flags.Flags.disableDrawWakeLock;
import static android.view.flags.Flags.sensitiveContentAppProtection;
import static android.view.flags.Flags.sensitiveContentPrematureProtectionRemovedFix;
+import static android.view.flags.Flags.toolkitFrameRateDebug;
import static android.view.flags.Flags.toolkitFrameRateFunctionEnablingReadOnly;
import static android.view.flags.Flags.toolkitFrameRateTouchBoost25q1;
import static android.view.flags.Flags.toolkitFrameRateTypingReadOnly;
@@ -1227,6 +1228,7 @@
com.android.graphics.surfaceflinger.flags.Flags.vrrBugfix24q4();
private static final boolean sEnableVrr = ViewProperties.vrr_enabled().orElse(true);
private static final boolean sToolkitInitialTouchBoostFlagValue = toolkitInitialTouchBoost();
+ private static boolean sToolkitFrameRateDebugFlagValue = toolkitFrameRateDebug();
static {
sToolkitSetFrameRateReadOnlyFlagValue = toolkitSetFrameRateReadOnly();
@@ -13139,6 +13141,11 @@
if (sToolkitFrameRateFunctionEnablingReadOnlyFlagValue) {
mFrameRateTransaction.setFrameRateCategory(mSurfaceControl,
frameRateCategory, false).applyAsyncUnsafe();
+
+ if (sToolkitFrameRateDebugFlagValue) {
+ Log.v(mTag, "### ViewRootImpl setFrameRateCategory '"
+ + categoryToString(frameRateCategory) + "'");
+ }
}
mLastPreferredFrameRateCategory = frameRateCategory;
}
@@ -13201,8 +13208,15 @@
if (preferredFrameRate > 0) {
mFrameRateTransaction.setFrameRate(mSurfaceControl, preferredFrameRate,
mFrameRateCompatibility);
+ if (sToolkitFrameRateDebugFlagValue) {
+ Log.v(mTag, "### ViewRootImpl setFrameRate '"
+ + preferredFrameRate + "'");
+ }
} else {
mFrameRateTransaction.clearFrameRate(mSurfaceControl);
+ if (sToolkitFrameRateDebugFlagValue) {
+ Log.v(mTag, "### ViewRootImpl setFrameRate 0 Hz");
+ }
}
mFrameRateTransaction.applyAsyncUnsafe();
}
@@ -13256,6 +13270,12 @@
// mFrameRateCategoryView = view == null ? "-" : view.getClass().getSimpleName();
}
mDrawnThisFrame = true;
+
+ if (sToolkitFrameRateDebugFlagValue) {
+ String viewName = view == null ? "-" : view.getClass().getSimpleName();
+ Log.v(mTag, "### View: " + viewName + " votes '"
+ + categoryToString(frameRateCategory) + "'");
+ }
}
/**
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 578b7b6..ede0b3c 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -2684,9 +2684,10 @@
* <p><b>Note:</b> The start and end {@link SelectionPosition} of the provided {@link Selection}
* should be constructed with {@code this} node or a descendant of it.
*
- * <p><b>Note:</b> {@link AccessibilityNodeInfo#setFocusable} and {@link
- * AccessibilityNodeInfo#setFocused} should both be called with {@code true} before setting the
- * selection in order to make {@code this} node a candidate to contain a selection.
+ * <p><b>Note:</b> {@link AccessibilityNodeInfo#setFocusable} and
+ * {@link AccessibilityNodeInfo#setFocused} should both be called with {@code true}
+ * before setting the selection in order to make {@code this} node a candidate to
+ * contain a selection.
*
* <p><b>Note:</b> Cannot be called from an AccessibilityService. This class is made immutable
* before being delivered to an AccessibilityService.
@@ -2706,12 +2707,10 @@
* Gets the extended selection, which is a representation of selection that spans multiple nodes
* that exist within the subtree of the node defining selection.
*
- * <p><b>Note:</b> The start and end {@link SelectionPosition} of the provided {@link Selection}
- * should be constructed with {@code this} node or a descendant of it.
- *
- * <p><b>Note:</b> In order for a node to be a candidate to contain a selection, {@link
- * AccessibilityNodeInfo#isFocusable()} ()} and {@link AccessibilityNodeInfo#isFocused()} should
- * both be return with {@code true}.
+ * <p><b>Note:</b> Nodes that are candidates to contain a selection should return
+ * {@code true} from {@link #isFocusable()} and {@link #isFocused()}.
+ * The start and end {@link SelectionPosition}s of this {@link Selection}
+ * should exist within {@code this} node or its descendants.
*
* @return The extended selection within the node's subtree, or {@code null} if no selection
* exists.
@@ -5840,8 +5839,8 @@
/**
* Instantiates a new SelectionPosition.
*
- * @param view The {@link View} containing the virtual descendant associated with the
- * selection position.
+ * @param view The {@link View} containing the text associated with this selection
+ * position.
* @param offset The offset for a selection position within {@code view}'s text content,
* which should be a value between 0 and the length of {@code view}'s text.
*/
diff --git a/core/java/android/view/flags/refresh_rate_flags.aconfig b/core/java/android/view/flags/refresh_rate_flags.aconfig
index 3bc2205..18fa0f3 100644
--- a/core/java/android/view/flags/refresh_rate_flags.aconfig
+++ b/core/java/android/view/flags/refresh_rate_flags.aconfig
@@ -143,4 +143,11 @@
namespace: "toolkit"
description: "Feature flag to update initial touch boost logic"
bug: "393004744"
+}
+
+flag {
+ name: "toolkit_frame_rate_debug"
+ namespace: "toolkit"
+ description: "Feature flag to ennable ARR debug message"
+ bug: "394614443"
}
\ No newline at end of file
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 56f0415..421001f 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -466,6 +466,26 @@
private static final long USE_ASYNC_SHOW_HIDE_METHOD = 352594277L; // This is a bug id.
/**
+ * Always return {@code true} when {@link #hideSoftInputFromWindow(IBinder, int)} and
+ * {@link #hideSoftInputFromWindow(IBinder, int, ResultReceiver, int, ImeTracker.Token)} is
+ * called.
+ * <p>
+ * Apps can incorrectly rely on the return value of
+ * {@link #hideSoftInputFromWindow(IBinder, int)} to guess whether the IME was hidden.
+ * However, it was never a guarantee that the IME will actually hide.
+ * Therefore, it was recommended using the {@link View.OnApplyWindowInsetsListener}.
+ * <p>
+ * Starting Android {@link Build.VERSION_CODES.BAKLAVA}, the return value will always be
+ * true, independent from whether the request was eventually sent to system server or not.
+ * Apps that need to know when the IME visibility changes should use
+ * {@link View.OnApplyWindowInsetsListener}. For apps that target earlier releases, it
+ * returns an estimate ({@code true} if the IME was showing before).
+ */
+ @ChangeId
+ @EnabledSince(targetSdkVersion = Build.VERSION_CODES.BAKLAVA)
+ private static final long ALWAYS_RETURN_TRUE_HIDE_SOFT_INPUT_FROM_WINDOW = 395521150L; // bug id
+
+ /**
* If {@code true}, avoid calling the
* {@link com.android.server.inputmethod.InputMethodManagerService InputMethodManagerService}
* by skipping the call to {@link IInputMethodManager#startInputOrWindowGainedFocus}
@@ -2531,9 +2551,14 @@
*
* @param windowToken The token of the window that is making the request,
* as returned by {@link View#getWindowToken() View.getWindowToken()}.
- * @return {@code true} if a request was sent to system_server, {@code false} otherwise. Note:
- * this does not return result of the request. For result use {@link ResultReceiver} in
- * {@link #hideSoftInputFromWindow(IBinder, int, ResultReceiver)} instead.
+ * @return <p>For apps targeting Android {@link Build.VERSION_CODES.BAKLAVA}, onwards, it
+ * will always return {@code true}. To see when the IME is hidden, use
+ * {@link View.OnApplyWindowInsetsListener} and verify the provided {@link WindowInsets} for
+ * the visibility of IME.
+ *
+ * <p>For apps targeting releases before Android Baklava: returns {@code true} if a request
+ * was sent to system_server, {@code false} otherwise. Note: This does not return the result
+ * of that request (i.e. whether the IME was actually hidden).
*/
public boolean hideSoftInputFromWindow(IBinder windowToken, @HideFlags int flags) {
return hideSoftInputFromWindow(windowToken, flags, null);
@@ -2563,7 +2588,8 @@
* {@link #RESULT_UNCHANGED_HIDDEN}, {@link #RESULT_SHOWN}, or
* {@link #RESULT_HIDDEN}.
* @return {@code true} if a request was sent to system_server, {@code false} otherwise. Note:
- * this does not return result of the request. For result use {@param resultReceiver} instead.
+ * This does not return the result of that request (i.e. whether the IME was actually hidden).
+ * For result use {@param resultReceiver} instead.
*
* @deprecated The {@link ResultReceiver} is not a reliable way of determining whether the
* Input Method is actually shown or hidden. If result is needed, use
@@ -2603,7 +2629,10 @@
ImeTracker.forLogging().onFailed(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
ImeTracker.forLatency().onHideFailed(statsToken,
ImeTracker.PHASE_CLIENT_VIEW_SERVED, ActivityThread::currentApplication);
- return false;
+ // with the flag enabled and targeting Android Baklava onwards, the return value
+ // should be always true (was false before).
+ return Flags.refactorInsetsController() && CompatChanges.isChangeEnabled(
+ ALWAYS_RETURN_TRUE_HIDE_SOFT_INPUT_FROM_WINDOW);
}
ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
@@ -2618,15 +2647,18 @@
// under us. The current input has been closed before (from checkFocus).
ImeTracker.forLogging().onFailed(statsToken,
ImeTracker.PHASE_CLIENT_VIEW_HANDLER_AVAILABLE);
- return false;
+ // with the flag enabled and targeting Android Baklava onwards, the
+ // return value should be always true (was false before).
+ return Flags.refactorInsetsController() && CompatChanges.isChangeEnabled(
+ ALWAYS_RETURN_TRUE_HIDE_SOFT_INPUT_FROM_WINDOW);
}
ImeTracker.forLogging().onProgress(statsToken,
ImeTracker.PHASE_CLIENT_VIEW_HANDLER_AVAILABLE);
+ final boolean imeReqVisible =
+ (viewRootImpl.getInsetsController().getRequestedVisibleTypes()
+ & WindowInsets.Type.ime()) != 0;
if (resultReceiver != null) {
- final boolean imeReqVisible =
- (viewRootImpl.getInsetsController().getRequestedVisibleTypes()
- & WindowInsets.Type.ime()) != 0;
resultReceiver.send(
!imeReqVisible ? InputMethodManager.RESULT_UNCHANGED_HIDDEN
: InputMethodManager.RESULT_HIDDEN, null);
@@ -2642,8 +2674,16 @@
viewRootImpl.getInsetsController().hide(WindowInsets.Type.ime(),
false /* fromIme */, statsToken);
}
+ if (!CompatChanges.isChangeEnabled(
+ ALWAYS_RETURN_TRUE_HIDE_SOFT_INPUT_FROM_WINDOW)) {
+ // if the IME was not visible before, the additional hide won't change
+ // anything.
+ return imeReqVisible;
+ }
}
- return true;
+ // Targeting Android Baklava onwards, this method will always return true.
+ return CompatChanges.isChangeEnabled(
+ ALWAYS_RETURN_TRUE_HIDE_SOFT_INPUT_FROM_WINDOW);
} else {
return IInputMethodManagerGlobalInvoker.hideSoftInput(mClient, windowToken,
statsToken, flags, resultReceiver, reason, mAsyncShowHideMethodEnabled);
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 0f5476f..0a5c14e 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -8565,12 +8565,16 @@
return context;
}
try {
- // Use PackageManager as the source of truth for application information, rather
- // than the parceled ApplicationInfo provided by the app.
- ApplicationInfo sanitizedApplication =
- context.getPackageManager().getApplicationInfoAsUser(
- mApplication.packageName, 0,
- UserHandle.getUserId(mApplication.uid));
+ ApplicationInfo sanitizedApplication = mApplication;
+ try {
+ // Use PackageManager as the source of truth for application information, rather
+ // than the parceled ApplicationInfo provided by the app.
+ sanitizedApplication = context.getPackageManager().getApplicationInfoAsUser(
+ mApplication.packageName, 0, UserHandle.getUserId(mApplication.uid));
+ } catch(SecurityException se) {
+ Log.d(LOG_TAG, "Unable to fetch appInfo for " + mApplication.packageName);
+ }
+
Context applicationContext = context.createApplicationContext(
sanitizedApplication,
Context.CONTEXT_RESTRICTED);
diff --git a/core/java/android/window/DesktopModeFlags.java b/core/java/android/window/DesktopModeFlags.java
index d43469f..b44620f 100644
--- a/core/java/android/window/DesktopModeFlags.java
+++ b/core/java/android/window/DesktopModeFlags.java
@@ -96,10 +96,12 @@
ENABLE_DESKTOP_WINDOWING_TASK_LIMIT(Flags::enableDesktopWindowingTaskLimit, true),
ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY(Flags::enableDesktopWindowingWallpaperActivity,
true),
+ ENABLE_DRAG_RESIZE_SET_UP_IN_BG_THREAD(Flags::enableDragResizeSetUpInBgThread, false),
ENABLE_FULLY_IMMERSIVE_IN_DESKTOP(Flags::enableFullyImmersiveInDesktop, true),
ENABLE_HANDLE_INPUT_FIX(Flags::enableHandleInputFix, true),
ENABLE_HOLD_TO_DRAG_APP_HANDLE(Flags::enableHoldToDragAppHandle, true),
ENABLE_MINIMIZE_BUTTON(Flags::enableMinimizeButton, true),
+ ENABLE_MODALS_FULLSCREEN_WITH_PERMISSIONS(Flags::enableModalsFullscreenWithPermission, false),
ENABLE_RESIZING_METRICS(Flags::enableResizingMetrics, true),
ENABLE_RESTORE_TO_PREVIOUS_SIZE_FROM_DESKTOP_IMMERSIVE(
Flags::enableRestoreToPreviousSizeFromDesktopImmersive, true),
@@ -114,6 +116,7 @@
ENABLE_WINDOWING_SCALED_RESIZING(Flags::enableWindowingScaledResizing, true),
ENABLE_WINDOWING_TRANSITION_HANDLERS_OBSERVERS(
Flags::enableWindowingTransitionHandlersObservers, false),
+ EXCLUDE_CAPTION_FROM_APP_BOUNDS(Flags::excludeCaptionFromAppBounds, false),
INCLUDE_TOP_TRANSPARENT_FULLSCREEN_TASK_IN_DESKTOP_HEURISTIC(
Flags::includeTopTransparentFullscreenTaskInDesktopHeuristic, true)
// go/keep-sorted end
diff --git a/core/java/android/window/SystemUiContext.java b/core/java/android/window/SystemUiContext.java
new file mode 100644
index 0000000..1e9a720
--- /dev/null
+++ b/core/java/android/window/SystemUiContext.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2025 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.window;
+
+import android.annotation.NonNull;
+import android.content.ComponentCallbacks;
+import android.content.ComponentCallbacksController;
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.res.Configuration;
+
+import com.android.window.flags.Flags;
+
+/**
+ * System Context to be used for UI. This Context has resources that can be themed.
+ *
+ * @see android.app.ActivityThread#getSystemUiContext(int)
+ *
+ * @hide
+ */
+public class SystemUiContext extends ContextWrapper implements ConfigurationDispatcher {
+
+ private final ComponentCallbacksController mCallbacksController =
+ new ComponentCallbacksController();
+
+ public SystemUiContext(Context base) {
+ super(base);
+ if (!Flags.trackSystemUiContextBeforeWms()) {
+ throw new UnsupportedOperationException("SystemUiContext can only be used after"
+ + " flag is enabled.");
+ }
+ }
+
+ @Override
+ public void registerComponentCallbacks(@NonNull ComponentCallbacks callback) {
+ mCallbacksController.registerCallbacks(callback);
+ }
+
+ @Override
+ public void unregisterComponentCallbacks(@NonNull ComponentCallbacks callback) {
+ mCallbacksController.unregisterCallbacks(callback);
+ }
+
+ /** Dispatch {@link Configuration} to each {@link ComponentCallbacks}. */
+ @Override
+ public void dispatchConfigurationChanged(@NonNull Configuration newConfig) {
+ mCallbacksController.dispatchConfigurationChanged(newConfig);
+ }
+
+ @Override
+ public boolean shouldReportPrivateChanges() {
+ // We should report all config changes to update fields obtained from resources.
+ return true;
+ }
+}
diff --git a/core/java/android/window/flags/lse_desktop_experience.aconfig b/core/java/android/window/flags/lse_desktop_experience.aconfig
index e358540..891c5e3 100644
--- a/core/java/android/window/flags/lse_desktop_experience.aconfig
+++ b/core/java/android/window/flags/lse_desktop_experience.aconfig
@@ -16,6 +16,17 @@
}
flag {
+ name: "enable_modals_fullscreen_with_permission"
+ namespace: "lse_desktop_experience"
+ description: "Uses permissions to understand if modal fullscreen is allowed for /n"
+ "transparent activities."
+ bug: "394714626"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "include_top_transparent_fullscreen_task_in_desktop_heuristic"
namespace: "lse_desktop_experience"
description: "Whether to include any top transparent fullscreen task launched in desktop /n"
@@ -79,6 +90,16 @@
}
flag {
+ name: "enable_drag_resize_set_up_in_bg_thread"
+ namespace: "lse_desktop_experience"
+ description: "Enables setting up the drag-resize input listener in a bg thread"
+ bug: "396445663"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "enable_desktop_windowing_wallpaper_activity"
namespace: "lse_desktop_experience"
description: "Enables desktop wallpaper activity to show wallpaper in the desktop mode"
diff --git a/core/java/android/window/flags/windowing_frontend.aconfig b/core/java/android/window/flags/windowing_frontend.aconfig
index 25dc672..60f2c81 100644
--- a/core/java/android/window/flags/windowing_frontend.aconfig
+++ b/core/java/android/window/flags/windowing_frontend.aconfig
@@ -40,6 +40,17 @@
}
flag {
+ name: "cache_window_style"
+ namespace: "windowing_frontend"
+ description: "Cache common window styles"
+ bug: "350394503"
+ is_fixed_read_only: true
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "edge_to_edge_by_default"
namespace: "windowing_frontend"
description: "Make app go edge-to-edge by default when targeting SDK 35 or greater"
diff --git a/core/java/com/android/internal/app/MediaRouteControllerContentManager.java b/core/java/com/android/internal/app/MediaRouteControllerContentManager.java
new file mode 100644
index 0000000..83ae7ed
--- /dev/null
+++ b/core/java/com/android/internal/app/MediaRouteControllerContentManager.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2025 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.app;
+
+import android.content.Context;
+import android.media.MediaRouter;
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.SeekBar;
+
+import com.android.internal.R;
+
+/**
+ * This class manages the content display within the media route controller UI.
+ */
+public class MediaRouteControllerContentManager {
+ // Time to wait before updating the volume when the user lets go of the seek bar
+ // to allow the route provider time to propagate the change and publish a new
+ // route descriptor.
+ private static final int VOLUME_UPDATE_DELAY_MILLIS = 250;
+
+ private final MediaRouter.RouteInfo mRoute;
+
+ private LinearLayout mVolumeLayout;
+ private SeekBar mVolumeSlider;
+ private boolean mVolumeSliderTouched;
+
+ public MediaRouteControllerContentManager(Context context) {
+ MediaRouter mRouter = context.getSystemService(MediaRouter.class);
+ mRoute = mRouter.getSelectedRoute();
+ }
+
+ /**
+ * Starts binding all the views (volume layout, slider, etc.) using the
+ * given container view.
+ */
+ public void bindViews(View containerView) {
+ mVolumeLayout = containerView.findViewById(R.id.media_route_volume_layout);
+ mVolumeSlider = containerView.findViewById(R.id.media_route_volume_slider);
+ mVolumeSlider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+ private final Runnable mStopTrackingTouch = new Runnable() {
+ @Override
+ public void run() {
+ if (mVolumeSliderTouched) {
+ mVolumeSliderTouched = false;
+ updateVolume();
+ }
+ }
+ };
+
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {
+ if (mVolumeSliderTouched) {
+ mVolumeSlider.removeCallbacks(mStopTrackingTouch);
+ } else {
+ mVolumeSliderTouched = true;
+ }
+ }
+
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {
+ // Defer resetting mVolumeSliderTouched to allow the media route provider
+ // a little time to settle into its new state and publish the final
+ // volume update.
+ mVolumeSlider.postDelayed(mStopTrackingTouch, VOLUME_UPDATE_DELAY_MILLIS);
+ }
+
+ @Override
+ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+ if (fromUser) {
+ mRoute.requestSetVolume(progress);
+ }
+ }
+ });
+ }
+
+ /**
+ * Updates the volume layout and slider.
+ */
+ public void updateVolume() {
+ if (!mVolumeSliderTouched) {
+ if (isVolumeControlAvailable()) {
+ mVolumeLayout.setVisibility(View.VISIBLE);
+ mVolumeSlider.setMax(mRoute.getVolumeMax());
+ mVolumeSlider.setProgress(mRoute.getVolume());
+ } else {
+ mVolumeLayout.setVisibility(View.GONE);
+ }
+ }
+ }
+
+ private boolean isVolumeControlAvailable() {
+ return mRoute.getVolumeHandling() == MediaRouter.RouteInfo.PLAYBACK_VOLUME_VARIABLE;
+ }
+}
diff --git a/core/java/com/android/internal/app/MediaRouteControllerDialog.java b/core/java/com/android/internal/app/MediaRouteControllerDialog.java
index 61e63d1..c79f3c7 100644
--- a/core/java/com/android/internal/app/MediaRouteControllerDialog.java
+++ b/core/java/com/android/internal/app/MediaRouteControllerDialog.java
@@ -16,13 +16,10 @@
package com.android.internal.app;
-import com.android.internal.R;
-
import android.app.AlertDialog;
import android.app.MediaRouteActionProvider;
import android.app.MediaRouteButton;
import android.content.Context;
-import android.content.DialogInterface;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.drawable.AnimationDrawable;
@@ -35,9 +32,8 @@
import android.util.TypedValue;
import android.view.KeyEvent;
import android.view.View;
-import android.widget.FrameLayout;
-import android.widget.LinearLayout;
-import android.widget.SeekBar;
+
+import com.android.internal.R;
/**
* This class implements the route controller dialog for {@link MediaRouter}.
@@ -51,166 +47,56 @@
* TODO: Move this back into the API, as in the support library media router.
*/
public class MediaRouteControllerDialog extends AlertDialog {
- // Time to wait before updating the volume when the user lets go of the seek bar
- // to allow the route provider time to propagate the change and publish a new
- // route descriptor.
- private static final int VOLUME_UPDATE_DELAY_MILLIS = 250;
-
private final MediaRouter mRouter;
private final MediaRouterCallback mCallback;
private final MediaRouter.RouteInfo mRoute;
- private boolean mCreated;
private Drawable mMediaRouteButtonDrawable;
private int[] mMediaRouteConnectingState = { R.attr.state_checked, R.attr.state_enabled };
private int[] mMediaRouteOnState = { R.attr.state_activated, R.attr.state_enabled };
private Drawable mCurrentIconDrawable;
- private boolean mVolumeControlEnabled = true;
- private LinearLayout mVolumeLayout;
- private SeekBar mVolumeSlider;
- private boolean mVolumeSliderTouched;
-
- private View mControlView;
private boolean mAttachedToWindow;
+ private final MediaRouteControllerContentManager mContentManager;
+
public MediaRouteControllerDialog(Context context, int theme) {
super(context, theme);
+ mContentManager = new MediaRouteControllerContentManager(context);
mRouter = (MediaRouter) context.getSystemService(Context.MEDIA_ROUTER_SERVICE);
mCallback = new MediaRouterCallback();
mRoute = mRouter.getSelectedRoute();
}
- /**
- * Gets the route that this dialog is controlling.
- */
- public MediaRouter.RouteInfo getRoute() {
- return mRoute;
- }
-
- /**
- * Provides the subclass an opportunity to create a view that will
- * be included within the body of the dialog to offer additional media controls
- * for the currently playing content.
- *
- * @param savedInstanceState The dialog's saved instance state.
- * @return The media control view, or null if none.
- */
- public View onCreateMediaControlView(Bundle savedInstanceState) {
- return null;
- }
-
- /**
- * Gets the media control view that was created by {@link #onCreateMediaControlView(Bundle)}.
- *
- * @return The media control view, or null if none.
- */
- public View getMediaControlView() {
- return mControlView;
- }
-
- /**
- * Sets whether to enable the volume slider and volume control using the volume keys
- * when the route supports it.
- * <p>
- * The default value is true.
- * </p>
- */
- public void setVolumeControlEnabled(boolean enable) {
- if (mVolumeControlEnabled != enable) {
- mVolumeControlEnabled = enable;
- if (mCreated) {
- updateVolume();
- }
- }
- }
-
- /**
- * Returns whether to enable the volume slider and volume control using the volume keys
- * when the route supports it.
- */
- public boolean isVolumeControlEnabled() {
- return mVolumeControlEnabled;
- }
-
@Override
protected void onCreate(Bundle savedInstanceState) {
setTitle(mRoute.getName());
Resources res = getContext().getResources();
setButton(BUTTON_NEGATIVE, res.getString(R.string.media_route_controller_disconnect),
- new OnClickListener() {
- @Override
- public void onClick(DialogInterface dialogInterface, int id) {
- if (mRoute.isSelected()) {
- if (mRoute.isBluetooth()) {
- mRouter.getDefaultRoute().select();
- } else {
- mRouter.getFallbackRoute().select();
- }
+ (dialogInterface, id) -> {
+ if (mRoute.isSelected()) {
+ if (mRoute.isBluetooth()) {
+ mRouter.getDefaultRoute().select();
+ } else {
+ mRouter.getFallbackRoute().select();
}
- dismiss();
}
+ dismiss();
});
View customView = getLayoutInflater().inflate(R.layout.media_route_controller_dialog, null);
setView(customView, 0, 0, 0, 0);
super.onCreate(savedInstanceState);
+ mContentManager.bindViews(customView);
+
View customPanelView = getWindow().findViewById(R.id.customPanel);
if (customPanelView != null) {
customPanelView.setMinimumHeight(0);
}
- mVolumeLayout = (LinearLayout) customView.findViewById(R.id.media_route_volume_layout);
- mVolumeSlider = (SeekBar) customView.findViewById(R.id.media_route_volume_slider);
- mVolumeSlider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
- private final Runnable mStopTrackingTouch = new Runnable() {
- @Override
- public void run() {
- if (mVolumeSliderTouched) {
- mVolumeSliderTouched = false;
- updateVolume();
- }
- }
- };
-
- @Override
- public void onStartTrackingTouch(SeekBar seekBar) {
- if (mVolumeSliderTouched) {
- mVolumeSlider.removeCallbacks(mStopTrackingTouch);
- } else {
- mVolumeSliderTouched = true;
- }
- }
-
- @Override
- public void onStopTrackingTouch(SeekBar seekBar) {
- // Defer resetting mVolumeSliderTouched to allow the media route provider
- // a little time to settle into its new state and publish the final
- // volume update.
- mVolumeSlider.postDelayed(mStopTrackingTouch, VOLUME_UPDATE_DELAY_MILLIS);
- }
-
- @Override
- public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
- if (fromUser) {
- mRoute.requestSetVolume(progress);
- }
- }
- });
mMediaRouteButtonDrawable = obtainMediaRouteButtonDrawable();
- mCreated = true;
- if (update()) {
- mControlView = onCreateMediaControlView(savedInstanceState);
- FrameLayout controlFrame =
- (FrameLayout) customView.findViewById(R.id.media_route_control_frame);
- if (mControlView != null) {
- controlFrame.addView(mControlView);
- controlFrame.setVisibility(View.VISIBLE);
- } else {
- controlFrame.setVisibility(View.GONE);
- }
- }
+ update();
}
@Override
@@ -249,20 +135,18 @@
return super.onKeyUp(keyCode, event);
}
- private boolean update() {
+ private void update() {
if (!mRoute.isSelected() || mRoute.isDefault()) {
dismiss();
- return false;
}
setTitle(mRoute.getName());
- updateVolume();
+ mContentManager.updateVolume();
Drawable icon = getIconDrawable();
if (icon != mCurrentIconDrawable) {
mCurrentIconDrawable = icon;
- if (icon instanceof AnimationDrawable) {
- AnimationDrawable animDrawable = (AnimationDrawable) icon;
+ if (icon instanceof AnimationDrawable animDrawable) {
if (!mAttachedToWindow && !mRoute.isConnecting()) {
// When the route is already connected before the view is attached, show the
// last frame of the connected animation immediately.
@@ -276,7 +160,6 @@
}
setIcon(icon);
}
- return true;
}
private Drawable obtainMediaRouteButtonDrawable() {
@@ -306,23 +189,6 @@
}
}
- private void updateVolume() {
- if (!mVolumeSliderTouched) {
- if (isVolumeControlAvailable()) {
- mVolumeLayout.setVisibility(View.VISIBLE);
- mVolumeSlider.setMax(mRoute.getVolumeMax());
- mVolumeSlider.setProgress(mRoute.getVolume());
- } else {
- mVolumeLayout.setVisibility(View.GONE);
- }
- }
- }
-
- private boolean isVolumeControlAvailable() {
- return mVolumeControlEnabled && mRoute.getVolumeHandling() ==
- MediaRouter.RouteInfo.PLAYBACK_VOLUME_VARIABLE;
- }
-
private final class MediaRouterCallback extends MediaRouter.SimpleCallback {
@Override
public void onRouteUnselected(MediaRouter router, int type, RouteInfo info) {
@@ -337,7 +203,7 @@
@Override
public void onRouteVolumeChanged(MediaRouter router, MediaRouter.RouteInfo route) {
if (route == mRoute) {
- updateVolume();
+ mContentManager.updateVolume();
}
}
diff --git a/core/java/com/android/internal/app/OWNERS b/core/java/com/android/internal/app/OWNERS
index 52f18fb..0bba24d 100644
--- a/core/java/com/android/internal/app/OWNERS
+++ b/core/java/com/android/internal/app/OWNERS
@@ -20,3 +20,6 @@
# System language settings
per-file *Locale* = file:platform/packages/apps/Settings:/src/com/android/settings/localepicker/OWNERS
+
+# Media
+per-file *MediaRoute* = file:/packages/SystemUI/src/com/android/systemui/media/dialog/OWNERS
diff --git a/core/java/com/android/internal/os/ApplicationSharedMemory.java b/core/java/com/android/internal/os/ApplicationSharedMemory.java
index e6ea29e..4c491c8 100644
--- a/core/java/com/android/internal/os/ApplicationSharedMemory.java
+++ b/core/java/com/android/internal/os/ApplicationSharedMemory.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.util.Log;
+
import com.android.internal.annotations.VisibleForTesting;
import dalvik.annotation.optimization.CriticalNative;
@@ -324,4 +325,35 @@
*/
@FastNative
private static native long nativeGetSystemNonceBlock(long ptr);
+
+ /**
+ * Perform a one-time write of cached SDK feature versions.
+ *
+ * @throws IllegalStateException if the feature versions have already been written or the ashmem
+ * is immutable.
+ * @throws IllegalArgumentException if the provided feature version array is too large.
+ */
+ public void writeSystemFeaturesCache(@NonNull int[] featureVersions) {
+ checkMutable();
+ nativeWriteSystemFeaturesCache(mPtr, featureVersions);
+ }
+
+ /**
+ * Read the cached SDK feature versions previously written to shared memory.
+ *
+ * Note: The result should generally be cached elsewhere for global reuse.
+ */
+ // TODO(b/326623529): Consider using a MappedByteBuffer or equivalent to avoid needing a
+ // Java copy of the cached data for potentially frequent reads. Alternatively, the JNI query
+ // lookup for a given feature could be cheap enough to avoid the cached Java copy entirely.
+ public @NonNull int[] readSystemFeaturesCache() {
+ checkMapped();
+ return nativeReadSystemFeaturesCache(mPtr);
+ }
+
+ @FastNative
+ private static native void nativeWriteSystemFeaturesCache(long ptr, int[] cache);
+
+ @FastNative
+ private static native int[] nativeReadSystemFeaturesCache(long ptr);
}
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index d73e2d4..4d77096 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -471,6 +471,20 @@
}
/**
+ * This is similar to {@link #isOptingOutEdgeToEdgeEnforcement} but the caller needs to check
+ * whether the app declares style to opt out.
+ */
+ public static boolean isOptOutEdgeToEdgeEnabled(ApplicationInfo info, boolean local) {
+ final boolean disabled = Flags.disableOptOutEdgeToEdge()
+ && (local
+ // Calling this doesn't require a permission.
+ ? CompatChanges.isChangeEnabled(DISABLE_OPT_OUT_EDGE_TO_EDGE)
+ // Calling this requires permissions.
+ : info.isChangeEnabled(DISABLE_OPT_OUT_EDGE_TO_EDGE));
+ return !disabled;
+ }
+
+ /**
* Returns whether the given application is opting out edge-to-edge enforcement.
*
* @param info The application to query.
@@ -480,13 +494,7 @@
*/
public static boolean isOptingOutEdgeToEdgeEnforcement(ApplicationInfo info, boolean local,
TypedArray windowStyle) {
- final boolean disabled = Flags.disableOptOutEdgeToEdge()
- && (local
- // Calling this doesn't require a permission.
- ? CompatChanges.isChangeEnabled(DISABLE_OPT_OUT_EDGE_TO_EDGE)
- // Calling this requires permissions.
- : info.isChangeEnabled(DISABLE_OPT_OUT_EDGE_TO_EDGE));
- return !disabled && windowStyle.getBoolean(
+ return isOptOutEdgeToEdgeEnabled(info, local) && windowStyle.getBoolean(
R.styleable.Window_windowOptOutEdgeToEdgeEnforcement, false /* default */);
}
diff --git a/core/java/com/android/internal/util/LatencyTracker.java b/core/java/com/android/internal/util/LatencyTracker.java
index f443b0a..c120e67d 100644
--- a/core/java/com/android/internal/util/LatencyTracker.java
+++ b/core/java/com/android/internal/util/LatencyTracker.java
@@ -22,6 +22,7 @@
import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_BACK_SYSTEM_ANIMATION;
import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_CHECK_CREDENTIAL;
import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_CHECK_CREDENTIAL_UNLOCKED;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG;
import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_EXPAND_PANEL;
import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_FACE_WAKE_AND_UNLOCK;
import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_FINGERPRINT_WAKE_AND_UNLOCK;
@@ -266,6 +267,15 @@
*/
public static final int ACTION_SHADE_WINDOW_DISPLAY_CHANGE = 29;
+ /**
+ * Applicable when the user drags a full screen app's handle into the desktop drop zone to enter
+ * desktop mode. This measure the time from when the user releases their finger in the drop zone
+ * to when the animation for entering desktop mode visually begins. During this period, the
+ * home task and app headers for each window are initialized. Both have historically been
+ * expensive. See b/381396057 and b/360452034 respectively.
+ */
+ public static final int ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG = 30;
+
private static final int[] ACTIONS_ALL = {
ACTION_EXPAND_PANEL,
ACTION_TOGGLE_RECENTS,
@@ -297,6 +307,7 @@
ACTION_NOTIFICATIONS_HIDDEN_FOR_MEASURE_WITH_SHADE_OPEN,
ACTION_KEYGUARD_FACE_UNLOCK_TO_HOME,
ACTION_SHADE_WINDOW_DISPLAY_CHANGE,
+ ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG,
};
/** @hide */
@@ -331,10 +342,10 @@
ACTION_NOTIFICATIONS_HIDDEN_FOR_MEASURE_WITH_SHADE_OPEN,
ACTION_KEYGUARD_FACE_UNLOCK_TO_HOME,
ACTION_SHADE_WINDOW_DISPLAY_CHANGE,
+ ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG,
})
@Retention(RetentionPolicy.SOURCE)
- public @interface Action {
- }
+ public @interface Action {}
@VisibleForTesting
public static final int[] STATSD_ACTION = new int[] {
@@ -368,6 +379,7 @@
UIACTION_LATENCY_REPORTED__ACTION__ACTION_NOTIFICATIONS_HIDDEN_FOR_MEASURE_WITH_SHADE_OPEN,
UIACTION_LATENCY_REPORTED__ACTION__ACTION_KEYGUARD_FACE_UNLOCK_TO_HOME,
UIACTION_LATENCY_REPORTED__ACTION__ACTION_SHADE_WINDOW_DISPLAY_CHANGE,
+ UIACTION_LATENCY_REPORTED__ACTION__ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG,
};
private final Object mLock = new Object();
@@ -568,6 +580,8 @@
return "ACTION_KEYGUARD_FACE_UNLOCK_TO_HOME";
case UIACTION_LATENCY_REPORTED__ACTION__ACTION_SHADE_WINDOW_DISPLAY_CHANGE:
return "ACTION_SHADE_WINDOW_DISPLAY_CHANGE";
+ case UIACTION_LATENCY_REPORTED__ACTION__ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG:
+ return "ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG";
default:
throw new IllegalArgumentException("Invalid action");
}
diff --git a/core/java/com/android/internal/widget/LockPatternView.java b/core/java/com/android/internal/widget/LockPatternView.java
index 0ec55f9..1f90760 100644
--- a/core/java/com/android/internal/widget/LockPatternView.java
+++ b/core/java/com/android/internal/widget/LockPatternView.java
@@ -87,10 +87,10 @@
private static final int CELL_ACTIVATE = 0;
private static final int CELL_DEACTIVATE = 1;
- private final int mDotSize;
- private final int mDotSizeActivated;
+ private int mDotSize;
+ private int mDotSizeActivated;
private final float mDotHitFactor;
- private final int mPathWidth;
+ private int mPathWidth;
private final int mLineFadeOutAnimationDurationMs;
private final int mLineFadeOutAnimationDelayMs;
private final int mFadePatternAnimationDurationMs;
@@ -1341,6 +1341,38 @@
invalidate();
}
+ /**
+ * Change dot colors
+ */
+ public void setDotColors(int dotColor, int dotActivatedColor) {
+ mDotColor = dotColor;
+ mDotActivatedColor = dotActivatedColor;
+ invalidate();
+ }
+
+ /**
+ * Keeps dot activated until the next dot gets activated.
+ */
+ public void setKeepDotActivated(boolean keepDotActivated) {
+ mKeepDotActivated = keepDotActivated;
+ }
+
+ /**
+ * Set dot sizes in dp
+ */
+ public void setDotSizes(int dotSizeDp, int dotSizeActivatedDp) {
+ mDotSize = dotSizeDp;
+ mDotSizeActivated = dotSizeActivatedDp;
+ }
+
+ /**
+ * Set the stroke width of the pattern line.
+ */
+ public void setPathWidth(int pathWidthDp) {
+ mPathWidth = pathWidthDp;
+ mPathPaint.setStrokeWidth(mPathWidth);
+ }
+
private float getCenterXForColumn(int column) {
return mPaddingLeft + column * mSquareWidth + mSquareWidth / 2f;
}
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index 2ba6bc4..b679688 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -664,14 +664,16 @@
static jint android_media_AudioSystem_setDeviceConnectionState(JNIEnv *env, jobject thiz,
jint state, jobject jParcel,
- jint codec) {
+ jint codec, jboolean deviceSwitch) {
int status;
if (Parcel *parcel = parcelForJavaObject(env, jParcel); parcel != nullptr) {
android::media::audio::common::AudioPort port{};
if (status_t statusOfParcel = port.readFromParcel(parcel); statusOfParcel == OK) {
- status = check_AudioSystem_Command(
- AudioSystem::setDeviceConnectionState(static_cast<audio_policy_dev_state_t>(state),
- port, static_cast<audio_format_t>(codec)));
+ status = check_AudioSystem_Command(
+ AudioSystem::setDeviceConnectionState(static_cast<audio_policy_dev_state_t>(
+ state),
+ port, static_cast<audio_format_t>(codec),
+ deviceSwitch));
} else {
ALOGE("Failed to read from parcel: %s", statusToString(statusOfParcel).c_str());
status = kAudioStatusError;
@@ -3457,7 +3459,7 @@
MAKE_AUDIO_SYSTEM_METHOD(newAudioSessionId),
MAKE_AUDIO_SYSTEM_METHOD(newAudioPlayerId),
MAKE_AUDIO_SYSTEM_METHOD(newAudioRecorderId),
- MAKE_JNI_NATIVE_METHOD("setDeviceConnectionState", "(ILandroid/os/Parcel;I)I",
+ MAKE_JNI_NATIVE_METHOD("setDeviceConnectionState", "(ILandroid/os/Parcel;IZ)I",
android_media_AudioSystem_setDeviceConnectionState),
MAKE_AUDIO_SYSTEM_METHOD(getDeviceConnectionState),
MAKE_AUDIO_SYSTEM_METHOD(handleDeviceConfigChange),
diff --git a/core/jni/com_android_internal_os_ApplicationSharedMemory.cpp b/core/jni/com_android_internal_os_ApplicationSharedMemory.cpp
index cc1687c..71d1694 100644
--- a/core/jni/com_android_internal_os_ApplicationSharedMemory.cpp
+++ b/core/jni/com_android_internal_os_ApplicationSharedMemory.cpp
@@ -23,18 +23,67 @@
#include <string.h>
#include <sys/mman.h>
+#include <array>
#include <atomic>
#include <cstddef>
#include <new>
-#include "core_jni_helpers.h"
-
#include "android_app_PropertyInvalidatedCache.h"
+#include "core_jni_helpers.h"
namespace {
using namespace android::app::PropertyInvalidatedCache;
+class alignas(8) SystemFeaturesCache {
+public:
+ // We only need enough space to handle the official set of SDK-defined system features (~200).
+ // TODO(b/326623529): Reuse the exact value defined by PackageManager.SDK_FEATURE_COUNT.
+ static constexpr int32_t kMaxSystemFeatures = 512;
+
+ void writeSystemFeatures(JNIEnv* env, jintArray jfeatures) {
+ if (featuresLength.load(std::memory_order_seq_cst) > 0) {
+ jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
+ "SystemFeaturesCache already written.");
+ return;
+ }
+
+ int32_t jfeaturesLength = env->GetArrayLength(jfeatures);
+ if (jfeaturesLength > kMaxSystemFeatures) {
+ jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
+ "SystemFeaturesCache only supports %d elements (vs %d requested).",
+ kMaxSystemFeatures, jfeaturesLength);
+ return;
+ }
+ env->GetIntArrayRegion(jfeatures, 0, jfeaturesLength, features.data());
+ featuresLength.store(jfeaturesLength, std::memory_order_seq_cst);
+ }
+
+ jintArray readSystemFeatures(JNIEnv* env) const {
+ jint jfeaturesLength = static_cast<jint>(featuresLength.load(std::memory_order_seq_cst));
+ jintArray jfeatures = env->NewIntArray(jfeaturesLength);
+ if (env->ExceptionCheck()) {
+ return nullptr;
+ }
+
+ env->SetIntArrayRegion(jfeatures, 0, jfeaturesLength, features.data());
+ return jfeatures;
+ }
+
+private:
+ // A fixed length array of feature versions, with |featuresLength| dictating the actual size
+ // of features that have been written.
+ std::array<int32_t, kMaxSystemFeatures> features = {};
+ // The atomic acts as a barrier that precedes reads and follows writes, ensuring a
+ // consistent view of |features| across processes. Note that r/w synchronization *within* a
+ // process is handled at a higher level.
+ std::atomic<int64_t> featuresLength = 0;
+};
+
+static_assert(sizeof(SystemFeaturesCache) ==
+ sizeof(int32_t) * SystemFeaturesCache::kMaxSystemFeatures + sizeof(int64_t),
+ "Unexpected SystemFeaturesCache size");
+
// Atomics should be safe to use across processes if they are lock free.
static_assert(std::atomic<int64_t>::is_always_lock_free == true,
"atomic<int64_t> is not always lock free");
@@ -69,14 +118,25 @@
latestNetworkTimeUnixEpochMillisAtZeroElapsedRealtimeMillis = offset;
}
+ // The fixed size cache storage for SDK-defined system features.
+ SystemFeaturesCache systemFeaturesCache;
+
// The nonce storage for pic. The sizing is suitable for the system server module.
SystemCacheNonce systemPic;
};
-// Update the expected value when modifying the members of SharedMemory.
+// Update the expected values when modifying the members of SharedMemory.
// 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(SharedMemory) == 8 + sizeof(SystemCacheNonce), "Unexpected SharedMemory size");
+// TODO(b/396674280): Add an additional fixed size check for SystemCacheNonce after resolving
+// ABI discrepancies.
+static_assert(sizeof(SharedMemory) == 8 + sizeof(SystemFeaturesCache) + sizeof(SystemCacheNonce),
+ "Unexpected SharedMemory size");
+static_assert(offsetof(SharedMemory, systemFeaturesCache) == sizeof(int64_t),
+ "Unexpected SystemFeaturesCache offset in SharedMemory");
+static_assert(offsetof(SharedMemory, systemPic) ==
+ offsetof(SharedMemory, systemFeaturesCache) + sizeof(SystemFeaturesCache),
+ "Unexpected SystemCachceNonce offset in SharedMemory");
static jint nativeCreate(JNIEnv* env, jclass) {
// Create anonymous shared memory region
@@ -146,6 +206,16 @@
return reinterpret_cast<jlong>(&sharedMemory->systemPic);
}
+static void nativeWriteSystemFeaturesCache(JNIEnv* env, jclass*, jlong ptr, jintArray jfeatures) {
+ SharedMemory* sharedMemory = reinterpret_cast<SharedMemory*>(ptr);
+ sharedMemory->systemFeaturesCache.writeSystemFeatures(env, jfeatures);
+}
+
+static jintArray nativeReadSystemFeaturesCache(JNIEnv* env, jclass*, jlong ptr) {
+ SharedMemory* sharedMemory = reinterpret_cast<SharedMemory*>(ptr);
+ return sharedMemory->systemFeaturesCache.readSystemFeatures(env);
+}
+
static const JNINativeMethod gMethods[] = {
{"nativeCreate", "()I", (void*)nativeCreate},
{"nativeMap", "(IZ)J", (void*)nativeMap},
@@ -156,7 +226,9 @@
(void*)nativeSetLatestNetworkTimeUnixEpochMillisAtZeroElapsedRealtimeMillis},
{"nativeGetLatestNetworkTimeUnixEpochMillisAtZeroElapsedRealtimeMillis", "(J)J",
(void*)nativeGetLatestNetworkTimeUnixEpochMillisAtZeroElapsedRealtimeMillis},
- {"nativeGetSystemNonceBlock", "(J)J", (void*) nativeGetSystemNonceBlock},
+ {"nativeGetSystemNonceBlock", "(J)J", (void*)nativeGetSystemNonceBlock},
+ {"nativeWriteSystemFeaturesCache", "(J[I)V", (void*)nativeWriteSystemFeaturesCache},
+ {"nativeReadSystemFeaturesCache", "(J)[I", (void*)nativeReadSystemFeaturesCache},
};
static const char kApplicationSharedMemoryClassName[] =
diff --git a/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp b/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp
index e0cc055..c4259f4 100644
--- a/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp
+++ b/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp
@@ -266,16 +266,24 @@
}
// Picky version of atoi(). No sign or unexpected characters allowed. Return -1 on failure.
static int digitsVal(char* start, char* end) {
+ constexpr int vmax = std::numeric_limits<int>::max();
int result = 0;
- if (end - start > 6) {
- return -1;
- }
for (char* dp = start; dp < end; ++dp) {
if (*dp < '0' || *dp > '9') {
- ALOGW("Argument failed integer format check");
+ ALOGW("Argument contains non-integer characters");
return -1;
}
- result = 10 * result + (*dp - '0');
+ int digit = *dp - '0';
+ if (result > vmax / 10) {
+ ALOGW("Argument exceeds int limit");
+ return -1;
+ }
+ result *= 10;
+ if (result > vmax - digit) {
+ ALOGW("Argument exceeds int limit");
+ return -1;
+ }
+ result += digit;
}
return result;
}
diff --git a/core/proto/android/providers/settings/common.proto b/core/proto/android/providers/settings/common.proto
index 64ffefb6..931192e 100644
--- a/core/proto/android/providers/settings/common.proto
+++ b/core/proto/android/providers/settings/common.proto
@@ -37,6 +37,9 @@
// Whether the default is set by the system
optional bool default_from_system = 6;
+
+ // Whether the value is ignored when restoring from backup
+ optional bool preserved_in_restore = 7;
}
message SettingsOperationProto {
diff --git a/core/res/res/drawable-w192dp/loader_horizontal_watch.xml b/core/res/res/drawable-w192dp/loader_horizontal_watch.xml
new file mode 100644
index 0000000..18cea6e
--- /dev/null
+++ b/core/res/res/drawable-w192dp/loader_horizontal_watch.xml
@@ -0,0 +1,97 @@
+<!--
+ ~ Copyright (C) 2025 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.
+ -->
+
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt">
+ <aapt:attr name="android:drawable">
+ <vector android:height="15dp" android:width="67dp" android:viewportHeight="15" android:viewportWidth="67">
+ <group android:name="_R_G">
+ <group android:name="_R_G_L_1_G" android:translateX="33.5" android:translateY="7.5">
+ <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M33.5 -7.5 C33.5,-7.5 33.5,7.5 33.5,7.5 C33.5,7.5 -33.5,7.5 -33.5,7.5 C-33.5,7.5 -33.5,-7.5 -33.5,-7.5 C-33.5,-7.5 33.5,-7.5 33.5,-7.5c "/>
+ </group>
+ <group android:name="_R_G_L_0_G" android:translateX="-296.5" android:translateY="-62.5" android:pivotX="330" android:pivotY="70" android:scaleX="0.1" android:scaleY="0.1">
+ <group android:name="_R_G_L_0_G_L_6_G" android:translateX="-224.84700000000004" android:translateY="-321.948" android:pivotX="555.09" android:pivotY="-329" android:rotation="28.9" android:scaleY="0">
+ <path android:name="_R_G_L_0_G_L_6_G_D_0_P_0" android:fillColor="#303030" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M194.88 359 C190,359 185.05,357.81 180.48,355.3 C59.86,289.14 -41.55,191.9 -112.79,74.11 C-186.14,-47.16 -224.91,-186.55 -224.91,-329 C-224.91,-345.57 -211.48,-359 -194.91,-359 C-178.34,-359 -164.91,-345.57 -164.91,-329 C-164.91,-197.5 -129.13,-68.84 -61.45,43.06 C4.33,151.82 97.97,241.6 209.33,302.69 C223.86,310.66 229.18,328.9 221.21,343.42 C215.75,353.37 205.48,359 194.88,359c "/>
+ </group>
+ <group android:name="_R_G_L_0_G_L_5_G" android:translateX="744.323" android:translateY="-277.96299999999997" android:pivotX="-414.08" android:pivotY="-372.985" android:rotation="28.9">
+ <path android:name="_R_G_L_0_G_L_5_G_D_0_P_0" android:fillColor="#303030" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-335.95 402.99 C-351.13,402.99 -364.16,391.5 -365.76,376.07 C-367.46,359.59 -355.49,344.85 -339.01,343.14 C-162.93,324.91 -0.15,242.33 119.34,110.62 C239.66,-22.01 305.92,-193.76 305.92,-372.98 C305.92,-389.55 319.35,-402.98 335.92,-402.98 C352.49,-402.98 365.92,-389.55 365.92,-372.98 C365.92,-178.82 294.13,7.24 163.78,150.93 C34.34,293.61 -142.03,383.07 -332.83,402.82 C-333.88,402.93 -334.92,402.99 -335.95,402.99c "/>
+ </group>
+ <group android:name="_R_G_L_0_G_L_2_G" android:translateX="185.385" android:translateY="70.09100000000001" android:pivotX="144.858" android:pivotY="-721.039" android:rotation="28.9" android:scaleY="0">
+ <path android:name="_R_G_L_0_G_L_2_G_D_0_P_0" android:fillColor="#ffffff" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M144.62 58.96 C144.61,58.96 144.61,58.96 144.6,58.96 C40.39,58.93 -60.82,38.66 -156.19,-1.28 C-171.48,-7.68 -178.68,-25.26 -172.28,-40.54 C-165.88,-55.82 -148.3,-63.02 -133.02,-56.62 C-45.02,-19.77 48.4,-1.07 144.63,-1.04 C161.19,-1.03 174.62,12.4 174.62,28.97 C174.61,45.53 161.18,58.96 144.62,58.96c "/>
+ </group>
+ <group android:name="_R_G_L_0_G_L_0_G" android:translateX="330" android:translateY="70">
+ <path android:name="_R_G_L_0_G_L_0_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-660 -313 C-660,-313 -660,313 -660,313 C-660,313 660,313 660,313 C660,313 660,-313 660,-313 C660,-313 -660,-313 -660,-313c M300.74 -1.16 C205.46,38.62 103.22,59.09 -0.03,59.05 C-103.28,59.01 -205.51,38.48 -300.76,-1.37 C-316.05,-7.76 -323.26,-25.34 -316.86,-40.62 C-310.47,-55.91 -292.9,-63.12 -277.61,-56.72 C-189.68,-19.94 -95.32,-0.98 -0.01,-0.95 C95.3,-0.92 189.67,-19.81 277.63,-56.53 C292.92,-62.91 310.49,-55.69 316.87,-40.4 C323.25,-25.11 316.03,-7.54 300.74,-1.16c "/>
+ </group>
+ </group>
+ </group>
+ <group android:name="time_group"/>
+ </vector>
+ </aapt:attr>
+ <target android:name="_R_G_L_0_G_L_6_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.9" android:valueTo="-51.4" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.135 0.202,0.848 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_5_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.9" android:valueTo="-51.4" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.135 0.202,0.848 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_5_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.9" android:valueTo="-51.4" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.135 0.202,0.848 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="133" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="time_group">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:repeatCount="infinite" android:propertyName="translateX" android:duration="1000" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+</animated-vector>
+
diff --git a/core/res/res/drawable-w204dp/loader_horizontal_watch.xml b/core/res/res/drawable-w204dp/loader_horizontal_watch.xml
new file mode 100644
index 0000000..fbc6eab
--- /dev/null
+++ b/core/res/res/drawable-w204dp/loader_horizontal_watch.xml
@@ -0,0 +1,104 @@
+<!--
+ ~ Copyright (C) 2025 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.
+ -->
+
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt">
+ <aapt:attr name="android:drawable">
+ <vector android:height="15dp" android:width="70dp" android:viewportHeight="15" android:viewportWidth="70">
+ <group android:name="_R_G">
+ <group android:name="_R_G_L_1_G" android:translateX="35" android:translateY="7.5">
+ <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M35 -7.5 C35,-7.5 35,7.5 35,7.5 C35,7.5 -35,7.5 -35,7.5 C-35,7.5 -35,-7.5 -35,-7.5 C-35,-7.5 35,-7.5 35,-7.5c "/>
+ </group>
+ <group android:name="_R_G_L_0_G" android:translateX="-310" android:translateY="-64" android:pivotX="345" android:pivotY="71.5" android:scaleX="0.1" android:scaleY="0.1">
+ <group android:name="_R_G_L_0_G_L_6_G" android:translateX="-239.44799999999998" android:translateY="-341.45" android:pivotX="584.448" android:pivotY="-346.55" android:rotation="28.8" android:scaleY="0">
+ <path android:name="_R_G_L_0_G_L_6_G_D_0_P_0" android:fillColor="#303030" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M205.28 376.55 C200.4,376.55 195.46,375.36 190.88,372.85 C64.08,303.29 -42.54,201.07 -117.44,77.24 C-194.55,-50.25 -235.31,-196.79 -235.31,-346.55 C-235.31,-363.12 -221.88,-376.55 -205.31,-376.55 C-188.74,-376.55 -175.31,-363.12 -175.31,-346.55 C-175.31,-207.74 -137.54,-71.93 -66.1,46.19 C3.34,160.99 102.18,255.76 219.73,320.24 C234.26,328.21 239.58,346.45 231.61,360.97 C226.15,370.92 215.88,376.55 205.28,376.55c "/>
+ </group>
+ <group android:name="_R_G_L_0_G_L_5_G" android:translateX="781.413" android:translateY="-295.124" android:pivotX="-436.413" android:pivotY="-392.876" android:rotation="28.8">
+ <path android:name="_R_G_L_0_G_L_5_G_D_0_P_0" android:fillColor="#303030" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-353.86 422.88 C-369.04,422.88 -382.07,411.4 -383.67,395.97 C-385.37,379.49 -373.4,364.74 -356.92,363.03 C-171.06,343.79 0.76,256.62 126.89,117.59 C253.89,-22.41 323.83,-203.7 323.83,-392.88 C323.83,-409.44 337.26,-422.88 353.83,-422.88 C370.4,-422.88 383.83,-409.44 383.83,-392.88 C383.83,-188.76 308.36,6.84 171.32,157.9 C35.25,307.89 -150.15,401.94 -350.74,422.72 C-351.79,422.82 -352.83,422.88 -353.86,422.88c "/>
+ </group>
+ <group android:name="_R_G_L_0_G_L_2_G" android:translateX="192.671" android:translateY="71.49599999999998" android:pivotX="152.329" android:pivotY="-759.496" android:rotation="28.8" android:scaleY="0">
+ <path android:name="_R_G_L_0_G_L_2_G_D_0_P_0" android:fillColor="#ffffff" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M152.33 60.5 C152.33,60.5 152.32,60.5 152.32,60.5 C42.76,60.47 -63.64,39.16 -163.91,-2.82 C-179.19,-9.22 -186.39,-26.8 -179.99,-42.08 C-173.59,-57.36 -156.02,-64.57 -140.73,-58.16 C-47.84,-19.27 50.77,0.47 152.34,0.5 C168.91,0.51 182.33,13.94 182.33,30.51 C182.32,47.08 168.89,60.5 152.33,60.5c "/>
+ </group>
+ <group android:name="_R_G_L_0_G_L_0_G" android:translateX="345" android:translateY="71.5">
+ <path android:name="_R_G_L_0_G_L_0_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-579 -259.5 C-579,-259.5 -579,259.5 -579,259.5 C-579,259.5 579,259.5 579,259.5 C579,259.5 579,-259.5 579,-259.5 C579,-259.5 -579,-259.5 -579,-259.5c M316.17 -2.8 C216,39.02 108.52,60.54 -0.03,60.5 C-108.58,60.46 -216.04,38.87 -316.18,-3.02 C-331.47,-9.41 -338.68,-26.99 -332.28,-42.27 C-325.89,-57.56 -308.32,-64.76 -293.03,-58.37 C-200.22,-19.55 -100.61,0.46 -0.01,0.5 C100.6,0.54 200.22,-19.41 293.06,-58.17 C308.35,-64.55 325.92,-57.33 332.3,-42.04 C338.68,-26.75 331.46,-9.18 316.17,-2.8c "/>
+ </group>
+ </group>
+ </group>
+ <group android:name="time_group"/>
+ </vector>
+ </aapt:attr>
+ <target android:name="_R_G_L_0_G_L_6_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.8" android:valueTo="-51.4" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.136 0.202,0.847 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_6_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="333" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_5_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.8" android:valueTo="-51.4" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.136 0.202,0.847 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_5_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.8" android:valueTo="-51.4" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.136 0.202,0.847 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="133" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="time_group">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:repeatCount="infinite" android:propertyName="translateX" android:duration="1000" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+</animated-vector>
+
diff --git a/core/res/res/drawable-w216dp/loader_horizontal_watch.xml b/core/res/res/drawable-w216dp/loader_horizontal_watch.xml
new file mode 100644
index 0000000..ed4b7ea
--- /dev/null
+++ b/core/res/res/drawable-w216dp/loader_horizontal_watch.xml
@@ -0,0 +1,105 @@
+<!--
+ ~ Copyright (C) 2025 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.
+ -->
+
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt">
+ <aapt:attr name="android:drawable">
+ <vector android:height="16dp" android:width="74dp" android:viewportHeight="16" android:viewportWidth="74">
+ <group android:name="_R_G">
+ <group android:name="_R_G_L_1_G" android:translateX="37" android:translateY="8">
+ <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M37 -8 C37,-8 37,8 37,8 C37,8 -37,8 -37,8 C-37,8 -37,-8 -37,-8 C-37,-8 37,-8 37,-8c "/>
+ </group>
+ <group android:name="_R_G_L_0_G" android:translateX="-328" android:translateY="-65.5" android:pivotX="365" android:pivotY="73.5" android:scaleX="0.1" android:scaleY="0.1">
+ <group android:name="_R_G_L_0_G_L_6_G" android:translateX="-256.447" android:translateY="-365.014" android:pivotX="621.447" android:pivotY="-368.486" android:rotation="28.8" android:scaleY="0">
+ <path android:name="_R_G_L_0_G_L_6_G_D_0_P_0" android:fillColor="#303030" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M218.28 398.49 C213.4,398.49 208.46,397.3 203.88,394.78 C69.34,320.99 -43.78,212.53 -123.25,81.15 C-205.06,-54.11 -248.31,-209.59 -248.31,-368.49 C-248.31,-385.05 -234.88,-398.49 -218.31,-398.49 C-201.74,-398.49 -188.31,-385.05 -188.31,-368.49 C-188.31,-220.54 -148.06,-75.8 -71.91,50.09 C2.1,172.45 107.45,273.45 232.73,342.18 C247.26,350.15 252.58,368.38 244.61,382.91 C239.15,392.86 228.88,398.49 218.28,398.49c "/>
+ </group>
+ <group android:name="_R_G_L_0_G_L_5_G" android:translateX="829.0260000000001" android:translateY="-315.759" android:pivotX="-464.026" android:pivotY="-417.741" android:rotation="28.8">
+ <path android:name="_R_G_L_0_G_L_5_G_D_0_P_0" android:fillColor="#303030" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-376.25 447.74 C-391.43,447.74 -404.46,436.26 -406.05,420.83 C-407.76,404.35 -395.78,389.61 -379.3,387.9 C-181.22,367.38 1.9,274.48 136.32,126.3 C271.67,-22.9 346.22,-216.12 346.22,-417.74 C346.22,-434.31 359.65,-447.74 376.22,-447.74 C392.79,-447.74 406.22,-434.31 406.22,-417.74 C406.22,-201.18 326.15,6.35 180.76,166.61 C36.39,325.75 -160.31,425.54 -373.12,447.58 C-374.17,447.69 -375.22,447.74 -376.25,447.74c "/>
+ </group>
+ <group android:name="_R_G_L_0_G_L_2_G" android:translateX="203.029" android:translateY="74.06899999999996" android:pivotX="161.971" android:pivotY="-807.569" android:rotation="28.8" android:scaleY="0">
+ <path android:name="_R_G_L_0_G_L_2_G_D_0_P_0" android:fillColor="#ffffff" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M161.97 62.43 C161.97,62.43 161.96,62.43 161.96,62.43 C45.71,62.4 -67.17,39.79 -173.55,-4.75 C-188.83,-11.15 -196.03,-28.72 -189.63,-44.01 C-183.24,-59.29 -165.66,-66.49 -150.38,-60.09 C-51.37,-18.64 53.72,2.4 161.98,2.43 C178.55,2.44 191.98,15.87 191.97,32.44 C191.97,49 178.54,62.43 161.97,62.43c "/>
+ </group>
+ <group android:name="_R_G_L_0_G_L_0_G" android:translateX="365" android:translateY="73.5">
+ <path android:name="_R_G_L_0_G_L_0_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-609 -244.5 C-609,-244.5 -609,244.5 -609,244.5 C-609,244.5 609,244.5 609,244.5 C609,244.5 609,-244.5 609,-244.5 C609,-244.5 -609,-244.5 -609,-244.5c M335.44 -4.16 C229.17,40.21 115.13,63.04 -0.04,63 C-115.21,62.96 -229.22,40.05 -335.47,-4.39 C-350.76,-10.79 -357.95,-28.36 -351.56,-43.65 C-345.17,-58.93 -327.59,-66.14 -312.31,-59.74 C-213.39,-18.36 -107.24,2.96 -0.02,3 C107.21,3.04 213.38,-18.22 312.33,-59.53 C327.62,-65.91 345.19,-58.69 351.57,-43.4 C357.95,-28.11 350.73,-10.54 335.44,-4.16c "/>
+ </group>
+ </group>
+ </group>
+ <group android:name="time_group"/>
+ </vector>
+ </aapt:attr>
+ <target android:name="_R_G_L_0_G_L_6_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.8" android:valueTo="-51.3" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.136 0.202,0.847 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_6_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="333" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_5_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.8" android:valueTo="-51.3" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.136 0.202,0.847 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_5_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.8" android:valueTo="-51.3" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.136 0.202,0.847 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="133" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="time_group">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:repeatCount="infinite" android:propertyName="translateX" android:duration="1000" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+</animated-vector>
+
+
diff --git a/core/res/res/drawable-w228dp/loader_horizontal_watch.xml b/core/res/res/drawable-w228dp/loader_horizontal_watch.xml
new file mode 100644
index 0000000..6b86c63
--- /dev/null
+++ b/core/res/res/drawable-w228dp/loader_horizontal_watch.xml
@@ -0,0 +1,103 @@
+<!--
+ ~ Copyright (C) 2025 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.
+ -->
+
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt">
+ <aapt:attr name="android:drawable">
+ <vector android:height="14dp" android:width="76dp" android:viewportHeight="14" android:viewportWidth="76">
+ <group android:name="_R_G">
+ <group android:name="_R_G_L_1_G" android:translateX="39" android:translateY="8">
+ <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M39 -8 C39,-8 39,8 39,8 C39,8 -39,8 -39,8 C-39,8 -39,-8 -39,-8 C-39,-8 39,-8 39,-8c "/>
+ </group>
+ <group android:name="_R_G_L_0_G" android:translateX="-345" android:translateY="-67" android:pivotX="384" android:pivotY="75" android:scaleX="0.1" android:scaleY="0.1">
+ <group android:name="_R_G_L_0_G_L_6_G" android:translateX="-274.19" android:translateY="-390.077" android:pivotX="658.448" android:pivotY="-390.423" android:rotation="28.7" android:scaleY="0">
+ <path android:name="_R_G_L_0_G_L_6_G_D_0_P_0" android:fillColor="#303030" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M231.28 420.42 C226.4,420.42 221.45,419.23 216.88,416.72 C74.61,338.68 -45.02,224 -129.06,85.06 C-171.54,14.82 -204.38,-60.73 -226.66,-139.5 C-249.65,-220.76 -261.31,-305.18 -261.31,-390.42 C-261.31,-406.99 -247.88,-420.42 -231.31,-420.42 C-214.74,-420.42 -201.31,-406.99 -201.31,-390.42 C-201.31,-310.71 -190.42,-231.78 -168.93,-155.83 C-148.11,-82.23 -117.42,-11.63 -77.72,54 C0.86,183.92 112.71,291.15 245.73,364.12 C260.26,372.08 265.58,390.32 257.61,404.85 C252.15,414.79 241.88,420.42 231.28,420.42c "/>
+ </group>
+ <group android:name="_R_G_L_0_G_L_5_G" android:translateX="875.8979999999999" android:translateY="-337.894" android:pivotX="-491.64" android:pivotY="-442.606" android:rotation="28.7">
+ <path android:name="_R_G_L_0_G_L_5_G_D_0_P_0" android:fillColor="#303030" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-398.64 472.61 C-413.82,472.61 -426.84,461.13 -428.44,445.7 C-430.15,429.22 -418.17,414.47 -401.69,412.77 C-191.38,390.98 3.04,292.33 145.75,135.01 C289.46,-23.4 368.6,-228.54 368.6,-442.61 C368.6,-459.17 382.04,-472.61 398.6,-472.61 C415.17,-472.61 428.6,-459.17 428.6,-442.61 C428.6,-213.6 343.93,5.85 190.19,175.33 C37.53,343.61 -170.48,449.13 -395.51,472.44 C-396.56,472.55 -397.6,472.61 -398.64,472.61c "/>
+ </group>
+ <group android:name="_R_G_L_0_G_L_2_G" android:translateX="212.64499999999998" android:translateY="75.14200000000005" android:pivotX="171.613" android:pivotY="-855.642" android:rotation="28.7" android:scaleY="0">
+ <path android:name="_R_G_L_0_G_L_2_G_D_0_P_0" android:fillColor="#ffffff" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M171.61 64.36 C171.61,64.36 171.61,64.36 171.61,64.36 C48.68,64.32 -70.7,40.42 -183.19,-6.68 C-198.47,-13.07 -205.68,-30.65 -199.28,-45.93 C-192.88,-61.22 -175.3,-68.42 -160.02,-62.02 C-54.9,-18.01 56.68,4.33 171.62,4.36 C188.19,4.36 201.62,17.8 201.61,34.36 C201.61,50.93 188.18,64.36 171.61,64.36c "/>
+ </group>
+ <group android:name="_R_G_L_0_G_L_0_G" android:translateX="384" android:translateY="75">
+ <path android:name="_R_G_L_0_G_L_0_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-611 -259 C-611,-259 -611,259 -611,259 C-611,259 611,259 611,259 C611,259 611,-259 611,-259 C611,-259 -611,-259 -611,-259c M354.66 -6.52 C242.36,40.4 121.76,64.54 -0.04,64.5 C-121.84,64.46 -242.44,40.23 -354.74,-6.76 C-370.04,-13.16 -377.24,-30.73 -370.84,-46.02 C-364.44,-61.3 -346.94,-68.51 -331.64,-62.12 C-226.54,-18.18 -113.84,4.46 -0.04,4.5 C113.76,4.54 226.56,-18.02 331.56,-61.89 C346.86,-68.27 364.46,-61.05 370.86,-45.76 C377.26,-30.47 369.96,-12.9 354.66,-6.52c "/>
+ </group>
+ </group>
+ </group>
+ <group android:name="time_group"/>
+ </vector>
+ </aapt:attr>
+ <target android:name="_R_G_L_0_G_L_6_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.7" android:valueTo="-51.4" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.136 0.202,0.847 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_6_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="333" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_5_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.7" android:valueTo="-51.4" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.136 0.202,0.847 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_5_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.7" android:valueTo="-51.4" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.136 0.202,0.847 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="133" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="time_group">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:repeatCount="infinite" android:propertyName="translateX" android:duration="1000" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+</animated-vector>
diff --git a/core/res/res/drawable-w240dp/loader_horizontal_watch.xml b/core/res/res/drawable-w240dp/loader_horizontal_watch.xml
new file mode 100644
index 0000000..ad60bbd
--- /dev/null
+++ b/core/res/res/drawable-w240dp/loader_horizontal_watch.xml
@@ -0,0 +1,104 @@
+<!--
+ ~ Copyright (C) 2025 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.
+ -->
+
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt">
+ <aapt:attr name="android:drawable">
+ <vector android:height="17dp" android:width="82dp" android:viewportHeight="17" android:viewportWidth="82">
+ <group android:name="_R_G">
+ <group android:name="_R_G_L_1_G" android:translateX="41" android:translateY="8.5">
+ <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M41 -8.5 C41,-8.5 41,8.5 41,8.5 C41,8.5 -41,8.5 -41,8.5 C-41,8.5 -41,-8.5 -41,-8.5 C-41,-8.5 41,-8.5 41,-8.5c "/>
+ </group>
+ <group android:name="_R_G_L_0_G" android:translateX="-362.5" android:translateY="-69" android:pivotX="403.5" android:pivotY="77.5" android:scaleX="0.1" android:scaleY="0.1">
+ <group android:name="_R_G_L_0_G_L_6_G" android:translateX="-291.64799999999997" android:translateY="-414.141" android:pivotX="695.448" android:pivotY="-412.359" android:rotation="28.7" android:scaleY="0">
+ <path android:name="_R_G_L_0_G_L_6_G_D_0_P_0" android:fillColor="#303030" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M244.28 442.36 C239.4,442.36 234.45,441.17 229.88,438.66 C79.87,356.38 -46.26,235.46 -134.87,88.96 C-179.66,14.91 -214.28,-64.74 -237.78,-147.79 C-262.02,-233.47 -274.31,-322.49 -274.31,-412.36 C-274.31,-428.93 -260.88,-442.36 -244.31,-442.36 C-227.74,-442.36 -214.31,-428.93 -214.31,-412.36 C-214.31,-328.01 -202.78,-244.49 -180.05,-164.12 C-158.01,-86.24 -125.54,-11.54 -83.53,57.91 C-0.38,195.38 117.97,308.85 258.73,386.05 C273.26,394.02 278.58,412.26 270.61,426.78 C265.15,436.73 254.88,442.36 244.28,442.36c "/>
+ </group>
+ <group android:name="_R_G_L_0_G_L_5_G" android:translateX="923.0530000000001" android:translateY="-359.029" android:pivotX="-519.253" android:pivotY="-467.471" android:rotation="28.7">
+ <path android:name="_R_G_L_0_G_L_5_G_D_0_P_0" android:fillColor="#303030" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-421.02 497.47 C-436.2,497.47 -449.23,485.99 -450.83,470.56 C-452.53,454.08 -440.56,439.34 -424.08,437.63 C-201.54,414.57 4.18,310.19 155.19,143.73 C229.54,61.77 287.7,-31.75 328.04,-134.22 C369.81,-240.3 390.99,-352.42 390.99,-467.47 C390.99,-484.04 404.42,-497.47 420.99,-497.47 C437.56,-497.47 450.99,-484.04 450.99,-467.47 C450.99,-226.02 361.72,5.35 199.63,184.04 C38.67,361.47 -180.63,472.73 -417.89,497.31 C-418.94,497.42 -419.99,497.47 -421.02,497.47c "/>
+ </group>
+ <group android:name="_R_G_L_0_G_L_2_G" android:translateX="222.54600000000002" android:translateY="77.21400000000006" android:pivotX="181.254" android:pivotY="-903.714" android:rotation="28.7" android:scaleY="0">
+ <path android:name="_R_G_L_0_G_L_2_G_D_0_P_0" android:fillColor="#ffffff" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M181.26 66.28 C181.25,66.28 181.25,66.28 181.25,66.28 C51.64,66.25 -74.22,41.06 -192.83,-8.6 C-208.12,-15 -215.32,-32.58 -208.92,-47.86 C-202.52,-63.15 -184.94,-70.35 -169.66,-63.95 C-58.42,-17.38 59.64,6.25 181.26,6.28 C197.83,6.29 211.26,19.72 211.26,36.29 C211.25,52.86 197.82,66.28 181.26,66.28c "/>
+ </group>
+ <group android:name="_R_G_L_0_G_L_0_G" android:translateX="403.5" android:translateY="77.5">
+ <path android:name="_R_G_L_0_G_L_0_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-630.5 -255.5 C-630.5,-255.5 -630.5,255.5 -630.5,255.5 C-630.5,255.5 630.5,255.5 630.5,255.5 C630.5,255.5 630.5,-255.5 630.5,-255.5 C630.5,-255.5 -630.5,-255.5 -630.5,-255.5c M374 -8.88 C255.5,40.59 128.4,66.04 0,66 C-128.4,65.95 -255.6,40.42 -374,-9.14 C-389.3,-15.53 -396.5,-33.11 -390.1,-48.39 C-383.7,-63.68 -366.2,-70.88 -350.9,-64.49 C-239.7,-18 -120.5,5.96 0,6 C120.4,6.04 239.7,-17.84 350.9,-64.25 C366.2,-70.63 383.7,-63.41 390.1,-48.12 C396.5,-32.83 389.3,-15.26 374,-8.88c "/>
+ </group>
+ </group>
+ </group>
+ <group android:name="time_group"/>
+ </vector>
+ </aapt:attr>
+ <target android:name="_R_G_L_0_G_L_6_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.7" android:valueTo="-51.4" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.136 0.202,0.847 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_6_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="333" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_5_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.7" android:valueTo="-51.4" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.136 0.202,0.847 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_5_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.7" android:valueTo="-51.4" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.136 0.202,0.847 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="133" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="time_group">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:repeatCount="infinite" android:propertyName="translateX" android:duration="1000" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+</animated-vector>
+
diff --git a/core/res/res/drawable/accessibility_autoclick_resume.xml b/core/res/res/drawable/accessibility_autoclick_resume.xml
new file mode 100644
index 0000000..ae83e98
--- /dev/null
+++ b/core/res/res/drawable/accessibility_autoclick_resume.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Copyright 2025 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:viewportWidth="24"
+ android:viewportHeight="24"
+ android:width="24dp"
+ android:height="24dp">
+ <group>
+ <clip-path android:pathData="M0 0H24V24H0V0Z" />
+ <path
+ android:pathData="M8 19V5L19 12L8 19Z"
+ android:fillColor="@color/materialColorPrimary" />
+ </group>
+</vector>
diff --git a/core/res/res/drawable/loader_horizontal_watch.xml b/core/res/res/drawable/loader_horizontal_watch.xml
new file mode 100644
index 0000000..6b86c63
--- /dev/null
+++ b/core/res/res/drawable/loader_horizontal_watch.xml
@@ -0,0 +1,103 @@
+<!--
+ ~ Copyright (C) 2025 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.
+ -->
+
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt">
+ <aapt:attr name="android:drawable">
+ <vector android:height="14dp" android:width="76dp" android:viewportHeight="14" android:viewportWidth="76">
+ <group android:name="_R_G">
+ <group android:name="_R_G_L_1_G" android:translateX="39" android:translateY="8">
+ <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M39 -8 C39,-8 39,8 39,8 C39,8 -39,8 -39,8 C-39,8 -39,-8 -39,-8 C-39,-8 39,-8 39,-8c "/>
+ </group>
+ <group android:name="_R_G_L_0_G" android:translateX="-345" android:translateY="-67" android:pivotX="384" android:pivotY="75" android:scaleX="0.1" android:scaleY="0.1">
+ <group android:name="_R_G_L_0_G_L_6_G" android:translateX="-274.19" android:translateY="-390.077" android:pivotX="658.448" android:pivotY="-390.423" android:rotation="28.7" android:scaleY="0">
+ <path android:name="_R_G_L_0_G_L_6_G_D_0_P_0" android:fillColor="#303030" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M231.28 420.42 C226.4,420.42 221.45,419.23 216.88,416.72 C74.61,338.68 -45.02,224 -129.06,85.06 C-171.54,14.82 -204.38,-60.73 -226.66,-139.5 C-249.65,-220.76 -261.31,-305.18 -261.31,-390.42 C-261.31,-406.99 -247.88,-420.42 -231.31,-420.42 C-214.74,-420.42 -201.31,-406.99 -201.31,-390.42 C-201.31,-310.71 -190.42,-231.78 -168.93,-155.83 C-148.11,-82.23 -117.42,-11.63 -77.72,54 C0.86,183.92 112.71,291.15 245.73,364.12 C260.26,372.08 265.58,390.32 257.61,404.85 C252.15,414.79 241.88,420.42 231.28,420.42c "/>
+ </group>
+ <group android:name="_R_G_L_0_G_L_5_G" android:translateX="875.8979999999999" android:translateY="-337.894" android:pivotX="-491.64" android:pivotY="-442.606" android:rotation="28.7">
+ <path android:name="_R_G_L_0_G_L_5_G_D_0_P_0" android:fillColor="#303030" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-398.64 472.61 C-413.82,472.61 -426.84,461.13 -428.44,445.7 C-430.15,429.22 -418.17,414.47 -401.69,412.77 C-191.38,390.98 3.04,292.33 145.75,135.01 C289.46,-23.4 368.6,-228.54 368.6,-442.61 C368.6,-459.17 382.04,-472.61 398.6,-472.61 C415.17,-472.61 428.6,-459.17 428.6,-442.61 C428.6,-213.6 343.93,5.85 190.19,175.33 C37.53,343.61 -170.48,449.13 -395.51,472.44 C-396.56,472.55 -397.6,472.61 -398.64,472.61c "/>
+ </group>
+ <group android:name="_R_G_L_0_G_L_2_G" android:translateX="212.64499999999998" android:translateY="75.14200000000005" android:pivotX="171.613" android:pivotY="-855.642" android:rotation="28.7" android:scaleY="0">
+ <path android:name="_R_G_L_0_G_L_2_G_D_0_P_0" android:fillColor="#ffffff" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M171.61 64.36 C171.61,64.36 171.61,64.36 171.61,64.36 C48.68,64.32 -70.7,40.42 -183.19,-6.68 C-198.47,-13.07 -205.68,-30.65 -199.28,-45.93 C-192.88,-61.22 -175.3,-68.42 -160.02,-62.02 C-54.9,-18.01 56.68,4.33 171.62,4.36 C188.19,4.36 201.62,17.8 201.61,34.36 C201.61,50.93 188.18,64.36 171.61,64.36c "/>
+ </group>
+ <group android:name="_R_G_L_0_G_L_0_G" android:translateX="384" android:translateY="75">
+ <path android:name="_R_G_L_0_G_L_0_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-611 -259 C-611,-259 -611,259 -611,259 C-611,259 611,259 611,259 C611,259 611,-259 611,-259 C611,-259 -611,-259 -611,-259c M354.66 -6.52 C242.36,40.4 121.76,64.54 -0.04,64.5 C-121.84,64.46 -242.44,40.23 -354.74,-6.76 C-370.04,-13.16 -377.24,-30.73 -370.84,-46.02 C-364.44,-61.3 -346.94,-68.51 -331.64,-62.12 C-226.54,-18.18 -113.84,4.46 -0.04,4.5 C113.76,4.54 226.56,-18.02 331.56,-61.89 C346.86,-68.27 364.46,-61.05 370.86,-45.76 C377.26,-30.47 369.96,-12.9 354.66,-6.52c "/>
+ </group>
+ </group>
+ </group>
+ <group android:name="time_group"/>
+ </vector>
+ </aapt:attr>
+ <target android:name="_R_G_L_0_G_L_6_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.7" android:valueTo="-51.4" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.136 0.202,0.847 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_6_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="333" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_5_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.7" android:valueTo="-51.4" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.136 0.202,0.847 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_5_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.7" android:valueTo="-51.4" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.136 0.202,0.847 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="133" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="time_group">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:repeatCount="infinite" android:propertyName="translateX" android:duration="1000" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+</animated-vector>
diff --git a/core/res/res/layout/media_route_controller_dialog.xml b/core/res/res/layout/media_route_controller_dialog.xml
index 24a2535..a5cd83b 100644
--- a/core/res/res/layout/media_route_controller_dialog.xml
+++ b/core/res/res/layout/media_route_controller_dialog.xml
@@ -41,11 +41,5 @@
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp" />
</LinearLayout>
-
- <!-- Optional content view section. -->
- <FrameLayout android:id="@+id/media_route_control_frame"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:visibility="gone" />
</LinearLayout>
</ScrollView>
diff --git a/core/res/res/layout/notification_2025_conversation_header.xml b/core/res/res/layout/notification_2025_conversation_header.xml
index 75bd244..1bde173 100644
--- a/core/res/res/layout/notification_2025_conversation_header.xml
+++ b/core/res/res/layout/notification_2025_conversation_header.xml
@@ -29,7 +29,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Title"
- android:textSize="@dimen/notification_2025_title_text_size"
+ android:textSize="16sp"
android:singleLine="true"
android:layout_weight="1"
/>
diff --git a/core/res/res/layout/notification_2025_template_collapsed_base.xml b/core/res/res/layout/notification_2025_template_collapsed_base.xml
index 05458329..d29b7af 100644
--- a/core/res/res/layout/notification_2025_template_collapsed_base.xml
+++ b/core/res/res/layout/notification_2025_template_collapsed_base.xml
@@ -102,7 +102,6 @@
android:singleLine="true"
android:textAlignment="viewStart"
android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Title"
- android:textSize="@dimen/notification_2025_title_text_size"
/>
<include layout="@layout/notification_2025_top_line_views" />
diff --git a/core/res/res/layout/notification_2025_template_collapsed_media.xml b/core/res/res/layout/notification_2025_template_collapsed_media.xml
index 9959b66..5beab50 100644
--- a/core/res/res/layout/notification_2025_template_collapsed_media.xml
+++ b/core/res/res/layout/notification_2025_template_collapsed_media.xml
@@ -104,7 +104,6 @@
android:singleLine="true"
android:textAlignment="viewStart"
android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Title"
- android:textSize="@dimen/notification_2025_title_text_size"
/>
<include layout="@layout/notification_2025_top_line_views" />
diff --git a/core/res/res/layout/notification_2025_template_collapsed_messaging.xml b/core/res/res/layout/notification_2025_template_collapsed_messaging.xml
index 85ca124..d7c3263 100644
--- a/core/res/res/layout/notification_2025_template_collapsed_messaging.xml
+++ b/core/res/res/layout/notification_2025_template_collapsed_messaging.xml
@@ -130,7 +130,6 @@
android:singleLine="true"
android:textAlignment="viewStart"
android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Title"
- android:textSize="@dimen/notification_2025_title_text_size"
/>
<include layout="@layout/notification_2025_top_line_views" />
diff --git a/core/res/res/layout/notification_2025_template_compact_heads_up_base.xml b/core/res/res/layout/notification_2025_template_compact_heads_up_base.xml
index 11fc486..52bc7b8 100644
--- a/core/res/res/layout/notification_2025_template_compact_heads_up_base.xml
+++ b/core/res/res/layout/notification_2025_template_compact_heads_up_base.xml
@@ -69,7 +69,6 @@
android:singleLine="true"
android:textAlignment="viewStart"
android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Title"
- android:textSize="@dimen/notification_2025_title_text_size"
/>
<include layout="@layout/notification_2025_top_line_views" />
</NotificationTopLineView>
diff --git a/core/res/res/layout/notification_2025_template_compact_heads_up_messaging.xml b/core/res/res/layout/notification_2025_template_compact_heads_up_messaging.xml
index bf70a5e..cf9ff6b 100644
--- a/core/res/res/layout/notification_2025_template_compact_heads_up_messaging.xml
+++ b/core/res/res/layout/notification_2025_template_compact_heads_up_messaging.xml
@@ -90,7 +90,6 @@
android:singleLine="true"
android:textAlignment="viewStart"
android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Title"
- android:textSize="@dimen/notification_2025_title_text_size"
/>
<include layout="@layout/notification_2025_top_line_views" />
</NotificationTopLineView>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 5da0924..788d5f7 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"toegang te verkry tot sensordata oor jou lewenstekens"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Kennisgewings"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"wys kennisgewings"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Venster-inhoud ophaal"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Die inhoud ondersoek van \'n venster waarmee jy interaksie het."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Verken-met-raak aanskakel"</string>
@@ -648,6 +656,38 @@
<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 app toe om liggings in jou mediaversameling te lees."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<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>
@@ -2247,14 +2287,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"D-paneel middel"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"Outoklik-tipe instellingspaneel"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"Linksklik"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"Regsklik"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"Dubbelklik"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"Sleep"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Rollees"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Onderbreek"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Posisie"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> is in die BEPERK-groep geplaas"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index c55f1c6..ca145e5 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"ስለአስፈላጊ ምልክቶችዎ ያሉ የዳሳሽ ውሂብ ይድረሱ"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"ማሳወቂያዎች"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"ማሳወቂያዎች አሳይ"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"የመስኮት ይዘት ሰርስረው ያውጡ"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"መስተጋበር የሚፈጥሩት የመስኮት ይዘት ይመርምሩ።"</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"በመንካት ያስሱን ያብሩ"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"መተግበሪያው የፎቶ ስብስብዎን እንዲቀይረው ያስችለዋል።"</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"አካባቢዎችን ከሚዲያ ስብስብዎ ማንበብ"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"መተግበሪያው አካባቢዎችን ከሚዲያ ስብስብዎ እንዲያነብብ ያስችለዋል።"</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"ባዮሜትሪኮችን ይጠቀሙ"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"ባዮሜትሪክስ ወይም ማያ ገፅ መቆለፊያን ይጠቀሙ"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"እርስዎን መሆንዎን ያረጋግጡ"</string>
@@ -2247,14 +2287,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"የDpad ማዕከል"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"የራስ-ሰር ጠቅ ማድረግ ትየባ ቅንብሮች ፓነል"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"የግራ ጠቅታ"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"የቀኝ ጠቅታ"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"ድርብ ጠቅ አድርግ"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"ጎትት"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"ሸብልል"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"ባለበት አቁም"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"አቀማመጥ"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ወደ የRESTRICTED ባልዲ ተከትቷል"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index f542d439b..24d628a 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -357,6 +357,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"الوصول إلى بيانات المستشعر حول علاماتك الحيوية"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"الإشعارات"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"عرض الإشعارات"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"استرداد محتوى النافذة:"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"فحص محتوى نافذة يتم التفاعل معها."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"تفعيل الاستكشاف باللمس:"</string>
@@ -652,6 +660,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"للسماح للتطبيق بتعديل مجموعة صورك."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"قراءة المواقع من مجموعة الوسائط التابعة لك"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"للسماح للتطبيق بقراءة المواقع من مجموعة الوسائط التابعة لك."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"استخدام المقاييس الحيوية"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"استخدام المقاييس الحيوية أو قفل الشاشة"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"تأكيد هويتك"</string>
@@ -1157,7 +1197,7 @@
<string name="year" msgid="5182610307741238982">"سنة"</string>
<string name="years" msgid="5797714729103773425">"أعوام"</string>
<string name="now_string_shortest" msgid="3684914126941650330">"الآن"</string>
- <string name="duration_minutes_shortest" msgid="5744379079540806690">"<xliff:g id="COUNT">%d</xliff:g> دقيقة"</string>
+ <string name="duration_minutes_shortest" msgid="5744379079540806690">"<xliff:g id="COUNT">%d</xliff:g> د"</string>
<string name="duration_hours_shortest" msgid="1477752094141971675">"<xliff:g id="COUNT">%d</xliff:g> ساعة"</string>
<string name="duration_days_shortest" msgid="4083124701676227233">"<xliff:g id="COUNT">%d</xliff:g> يوم"</string>
<string name="duration_years_shortest" msgid="483982719231145618">"<xliff:g id="COUNT">%d</xliff:g> سنة"</string>
@@ -1973,7 +2013,7 @@
<string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="8009920446193610996">"تصغير"</string>
<string name="zen_mode_feature_name" msgid="3785547207263754500">"عدم الإزعاج"</string>
- <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"التعطل"</string>
+ <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"فترة التوقّف"</string>
<string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"ليلة يوم من أيام الأسبوع"</string>
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"نهاية الأسبوع"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"حدث"</string>
@@ -2251,14 +2291,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"الزرّ المركزي"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"لوحة إعدادات نوع النقر التلقائي"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"النقر بالزر الأيسر"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"النقر بزر الماوس الأيمن"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"النقر مرّتين"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"سحب"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"الانتقال للأسفل أو للأعلى"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"إيقاف مؤقت"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"تعديل الموضع"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"تم وضع <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> في الحزمة \"محظورة\"."</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index b8afd2e..397afe2 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"আপোনাৰ দেহৰ গুৰুত্বপূৰ্ণ অংগসমূহৰ অৱস্থাৰ বিষয়ে ছেন্সৰৰ ডেটা লাভ কৰিব পাৰে"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"জাননী"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"জাননী দেখুৱাওক"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"ৱিণ্ড’ সমল বিচাৰি উলিওৱাৰ"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"আপুনি চাই থকা ৱিণ্ড’খনৰ সমল পৰীক্ষা কৰাৰ।"</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"স্পৰ্শৰ দ্বাৰা অন্বেষণ কৰাৰ সুবিধা অন কৰাৰ"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"এপক আপোনাৰ ফট’ সংগ্ৰহ সালসলনি কৰিবলৈ দিয়ে।"</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"আপোনাৰ মিডিয়া সংগ্ৰহৰ অৱস্থান পঢ়িবলৈ"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"এপক আপোনাৰ মিডিয়া সংগ্ৰহৰ অৱস্থান পঢ়িবলৈ দিয়ে।"</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"বায়\'মেট্ৰিক ব্যৱহাৰ কৰক"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"বায়\'মেট্ৰিক অথবা স্ক্ৰীন লক ব্যৱহাৰ কৰক"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"এইয়া আপুনিয়েই বুলি সত্যাপন কৰক"</string>
@@ -2247,14 +2287,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"ডিপেডৰ মাজৰ বুটাম"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"প্ৰকাৰৰ ছেটিঙৰ পেনেলত স্বয়ংক্ৰিয়ভাৱে ক্লিক কৰক"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"বাওঁফালৰ ক্লিক"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"সোঁফালৰ ক্লিক"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"দুবাৰ ক্লিক"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"টানি আনি এৰক"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"স্ক্ৰ’ল কৰক"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"পজ কৰক"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"স্থান"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>ক সীমাবদ্ধ বাকেটটোত ৰখা হৈছে"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index affa569..96c77e4 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"Həyati əlamətlər haqqında sensor dataya daxil olun"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Bildirişlər"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"bildirişləri göstərmək"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Pəncərənin məzmununu əldə edin"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Əlaqədə olduğunuz pəncərənin məzmununu nəzərdən keçirin."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Toxunuşla öyrənmə funksiyasını aktiv edin"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Tətbiqin foto kolleksiyanıza düzəliş etməsinə icazə verir."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"media kolleksiyanızdan məkanları oxuyun"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Tətbiqin media kolleksiyanızdan məkanları oxumasına icazə verin."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Biometrik məlumatlardan istifadə edin"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Biometrik məlumatlardan və ya ekran kilidindən istifadə edin"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Kimliyinizi doğrulayın"</string>
@@ -2247,14 +2287,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"Dpad Mərkəzə"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"Avtomatik klikləmə növü üzrə ayarlar paneli"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"Sola klik"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"Sağ düymə ilə toxunun"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"İki dəfə toxunun"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"Çəkin"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Sürüşdürün"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Durdurun"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Mövqe"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> MƏHDUDLAŞDIRILMIŞ səbətinə yerləşdirilib"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 3acc8df..6a68f8d 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -354,6 +354,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"pristupa podacima senzora o vitalnim funkcijama"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Obaveštenja"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"prikazivanje obaveštenja"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"da preuzima sadržaj prozora"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Proverava sadržaj prozora sa kojim ostvarujete interakciju."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"da uključi Istraživanja dodirom"</string>
@@ -649,6 +657,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Dozvoljava aplikaciji da menja kolekciju slika."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"čitanje lokacija iz medijske kolekcije"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Dozvoljava aplikaciji da čita lokacije iz medijske kolekcije."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Koristite biometriju"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Koristite biometriju ili otključavanje ekrana"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Potvrdite identitet"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 7c827bb..69271ba 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -355,6 +355,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"атрымліваць з датчыка даныя асноўных фізіялагічных паказчыкаў"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Апавяшчэнні"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"паказваць апавяшчэнні"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Атрымліваць змесціва вакна"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Аналізаваць змесціва актыўнага вакна."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Уключаць Азнаямленне дотыкам"</string>
@@ -650,6 +658,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Праграма зможа змяняць фотакалекцыю."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"паказваць месцазнаходжанне ў калекцыі мультымедыя"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Праграма зможа паказваць месцазнаходжанне ў калекцыі мультымедыя."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Выкарыстоўваць біяметрыю"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Выкарыстоўваць біяметрыю ці блакіроўку экрана"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Спраўдзіце, што гэта вы"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index c3a2712..1581ab8 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"достъп до сензорните данни за жизнените ви показатели"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Известия"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"показване на известията"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Извлича съдържанието от прозореца"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Инспектира съдържанието на прозорец, с който взаимодействате."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Включи изследването чрез докосване"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Разрешава на приложението да променя колекцията ви от снимки."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"да чете местоположенията от мултимедийната ви колекция"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Разрешава на приложението да чете местоположенията от мултимедийната ви колекция."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Използване на биометр. данни"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Използване на биометрични данни или опцията за заключване на екрана"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Потвърдете, че сте вие"</string>
@@ -1409,7 +1449,7 @@
<string name="carrier_app_notification_title" msgid="5815477368072060250">"Поставена е нова SIM карта"</string>
<string name="carrier_app_notification_text" msgid="6567057546341958637">"Докоснете, за да я настроите"</string>
<string name="time_zone_change_notification_title" msgid="5232503069219193218">"Часовата ви зона се промени"</string>
- <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Вече сте в зоната <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string>
+ <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Вече сте във: <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</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>
@@ -2247,14 +2287,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"Контролен пад – център"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"Панел с настройки за типа на автоматичното кликване"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"Кликване с ляв бутон"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"Кликване с десния бутон"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"Кликване два пъти"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"Преместване с плъзгане"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Превъртане"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Пауза"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Позиция"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Пакетът <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> е поставен в ОГРАНИЧЕНИЯ контейнер"</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index f6492c5..c05ea6d 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"আপনার অত্যাবশ্যক লক্ষণগুলির সম্পর্কে সেন্সর ডেটা অ্যাক্সেস করে"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"বিজ্ঞপ্তি"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"বিজ্ঞপ্তি দেখুন"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"উইন্ডোর কন্টেন্ট ফিরিয়ে আনুন"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"ব্যবহার করছেন এমন একটি উইন্ডোর কন্টেন্ট পরীক্ষা করে৷"</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"স্পর্শের মাধ্যমে অন্বেষণ করা চালু করুন"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"অ্যাপকে আপনার ফটো সংগ্রহ পরিবর্তন করার অনুমতি দিন।"</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"ডিয়া সংগ্রহ থেকে লোকেশন দেখতে দিন"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"আপনার মিডিয়া সংগ্রহ থেকে লোকেশন দেখতে অ্যাপকে অনুমতি দিন।"</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"বায়োমেট্রিক্স ব্যবহার করুন"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"বায়োমেট্রিক্স অথবা স্ক্রিন লক ব্যবহার করুন"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"আপনার পরিচয় যাচাই করুন"</string>
@@ -2247,14 +2287,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"ডিপ্যাড (Dpad)-এর মাঝখানে"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"অটোক্লিক টাইপ সেটিংস প্যানেল"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"বাঁদিকের বোতামে ক্লিক করুন"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"মাউসের ডানদিকের বোতামে ক্লিক করুন"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"ডবল ক্লিক করুন"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"টেনে আনুন"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"স্ক্রল করুন"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"পজ করুন"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"পজিশন"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> সীমাবদ্ধ গ্রুপে অন্তর্ভুক্ত করা হয়েছে"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 3ff85ac..ebef234 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -354,6 +354,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"pristupa podacima senzora o vašim vitalnim funkcijama"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Obavještenja"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"prikaz obavještenja"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"preuzimati sadržaj prozora"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Pregleda sadržaj prozora koji trenutno koristite."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"uključiti Istraživanje dodirom"</string>
@@ -649,6 +657,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Omogućava aplikaciji da mijenja vašu kolekciju fotografija."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"čitanje lokacija iz kolekcije medija"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Omogućava aplikaciji da čita lokacije iz vaše kolekcije medija."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Koristi biometriju"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Koristi biometriju ili zaključavanje ekrana"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Potvrdite identitet"</string>
@@ -2250,8 +2290,8 @@
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"Lijevi klik"</string>
<string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"Desni klik"</string>
<string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"Dvostruki klik"</string>
- <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"Povuci"</string>
- <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Pomakni se"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"Prevlačenje"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Klizanje"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pauziraj"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Položaj"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Paket <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> je stavljen u odjeljak OGRANIČENO"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 9b61887..6ddfeaf 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -354,6 +354,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"accedir a les dades del sensor sobre les constants vitals"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Notificacions"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"mostra notificacions"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Recuperar el contingut de la finestra"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Inspeccionar el contingut d\'una finestra amb què estàs interaccionant."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Activar Exploració tàctil"</string>
@@ -649,6 +657,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Permet que l\'aplicació modifiqui la teva col·lecció de fotos."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"llegir les ubicacions de les teves col·leccions multimèdia"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Permet que l\'aplicació llegeixi les ubicacions de les teves col·leccions multimèdia."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Utilitza la biometria"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Fes servir la biometria o el bloqueig de pantalla"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Verifica la teva identitat"</string>
@@ -2248,14 +2288,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"Creu direccional: centre"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"Tauler de configuració del tipus de clic automàtic"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"Clic esquerre"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"Fes clic amb el botó dret"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"Fes doble clic"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"Arrossega"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Desplaça"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Posa en pausa"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Posició"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> s\'ha transferit al segment RESTRINGIT"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 9c8cc9a..5e596fc 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -355,6 +355,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"přístup k datům ze senzorů vašich životních funkcí"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Oznámení"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"zobrazovat oznámení"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Načítat obsah oken"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Může prozkoumávat obsah oken, se kterými pracujete."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Zapnout funkci Prozkoumání dotykem"</string>
@@ -650,6 +658,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Umožňuje aplikaci upravit vaši sbírku fotek."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"čtení míst ze sbírky médií"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Umožňuje aplikaci číst místa z vaší sbírky médií."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Použít biometrii"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Použít biometrii nebo zámek obrazovky"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Potvrďte, že jste to vy"</string>
@@ -2090,12 +2130,9 @@
<string name="unpin_target" msgid="3963318576590204447">"Odepnout"</string>
<string name="unpin_specific_target" msgid="3859828252160908146">"Odepnout: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="app_info" msgid="6113278084877079851">"O aplikaci"</string>
- <!-- no translation found for shortcut_group_a11y_title (2992150163811583865) -->
- <skip />
- <!-- no translation found for suggested_apps_group_a11y_title (2804876567839501831) -->
- <skip />
- <!-- no translation found for all_apps_group_a11y_title (7020352520224108745) -->
- <skip />
+ <string name="shortcut_group_a11y_title" msgid="2992150163811583865">"Přímé sdílení cílů"</string>
+ <string name="suggested_apps_group_a11y_title" msgid="2804876567839501831">"Návrhy aplikací"</string>
+ <string name="all_apps_group_a11y_title" msgid="7020352520224108745">"Seznam aplikací"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Spouštění ukázky…"</string>
<string name="demo_restarting_message" msgid="1160053183701746766">"Resetování zařízení…"</string>
@@ -2252,14 +2289,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"Dpad střed"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"Panel nastavení typu automatického kliknutí"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"Kliknutí levým"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"Kliknutí pravým tlačítkem"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"Dvojité kliknutí"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"Přetažení"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Posunutí"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pozastavit"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Pozice"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Balíček <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> byl vložen do sekce OMEZENO"</string>
@@ -2536,12 +2569,8 @@
<string name="keyboard_shortcut_group_applications_maps" msgid="7950000659522589471">"Mapy"</string>
<string name="keyboard_shortcut_group_applications" msgid="3010389163951364798">"Aplikace"</string>
<string name="fingerprint_loe_notification_msg" msgid="3927447270148854546">"Vaše otisky prstů se nedaří rozpoznat. Nastavte odemknutí otiskem prstu znovu."</string>
- <!-- no translation found for usb_apm_usb_plugged_in_when_locked_notification_title (468577168569874967) -->
- <skip />
- <!-- no translation found for usb_apm_usb_plugged_in_when_locked_notification_text (6695268246267993166) -->
- <skip />
- <!-- no translation found for usb_apm_usb_suspicious_activity_notification_title (3461195995882871461) -->
- <skip />
- <!-- no translation found for usb_apm_usb_suspicious_activity_notification_text (6537085605929303187) -->
- <skip />
+ <string name="usb_apm_usb_plugged_in_when_locked_notification_title" msgid="468577168569874967">"Zařízení USB bylo připojeno, když bylo zařízení zamknuté"</string>
+ <string name="usb_apm_usb_plugged_in_when_locked_notification_text" msgid="6695268246267993166">"Zařízení USB bylo připojeno, když byl Android zamknutý. Pokud zařízení chcete používat, nejdříve Android odemkněte a pak zařízení USB připojte znovu."</string>
+ <string name="usb_apm_usb_suspicious_activity_notification_title" msgid="3461195995882871461">"Podezřelá aktivita USB"</string>
+ <string name="usb_apm_usb_suspicious_activity_notification_text" msgid="6537085605929303187">"Datový signál USB byl deaktivován."</string>
</resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 1b96dbb..8cc1cfe 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"få adgang til sensordata om dine vitale værdier"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Notifikationer"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"vise notifikationer"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Hente indholdet i vinduet"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Undersøge indholdet i et vindue, du interagerer med."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Aktivere Udforsk ved berøring"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Tillader, at appen kan ændre din billedsamling."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"læse lokationer fra din mediesamling"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Tillader, at appen kan læse lokationer fra din mediesamling."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Brug biometri"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Brug biometri eller skærmlås"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Verificer, at det er dig"</string>
@@ -2247,14 +2287,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"D-pad, midten"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"Panel med indstillinger for type af automatisk klik"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"Venstreklik"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"Højreklik"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"Dobbeltklik"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"Træk"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Rul"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Sæt på pause"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Placering"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> er blevet placeret i samlingen BEGRÆNSET"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 73e7b9a..7d5672b 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"auf Sensordaten zu deinen Vitaldaten zugreifen"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Benachrichtigungen"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"Benachrichtigungen anzeigen"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Fensterinhalte abrufen"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Die Inhalte eines Fensters, mit dem du interagierst, werden abgerufen."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"\"Tippen & Entdecken\" aktivieren"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Ermöglicht der App, deine Fotosammlung zu ändern."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"Standorte aus meiner Mediensammlung abrufen"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Ermöglicht der App, Standorte aus deiner Mediensammlung abzurufen."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Biometrisches Verfahren nutzen"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Biometrisches Verfahren oder Displaysperre verwenden"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Deine Identität bestätigen"</string>
@@ -1409,7 +1449,7 @@
<string name="carrier_app_notification_title" msgid="5815477368072060250">"Neue SIM-Karte eingelegt"</string>
<string name="carrier_app_notification_text" msgid="6567057546341958637">"Zum Einrichten tippen"</string>
<string name="time_zone_change_notification_title" msgid="5232503069219193218">"Die Zeitzone hat sich geändert"</string>
- <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Du bist jetzt in <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string>
+ <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Du bist jetzt in: <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string>
<string name="time_picker_dialog_title" msgid="9053376764985220821">"Uhrzeit festlegen"</string>
<string name="date_picker_dialog_title" msgid="5030520449243071926">"Datum festlegen"</string>
<string name="date_time_set" msgid="4603445265164486816">"Speichern"</string>
@@ -2247,14 +2287,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"Steuerkreuz Mitte"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"Bereich mit Einstellungen für automatische Klicks"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"Linksklick"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"Rechtsklicken"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"Doppelklicken"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"Ziehen"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Scrollen"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pausieren"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Position"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> wurde in den BESCHRÄNKT-Bucket gelegt"</string>
@@ -2430,8 +2466,8 @@
<string name="default_card_name" msgid="9198284935962911468">"KARTE <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
<string name="permlab_companionProfileWatch" msgid="2457738382085872542">"Berechtigung für Companion-Smartwatch-Profil zum Verwalten von Smartwatches"</string>
<string name="permdesc_companionProfileWatch" msgid="5655698581110449397">"Ermöglicht einer Companion-App, Smartwatches zu verwalten."</string>
- <string name="permlab_observeCompanionDevicePresence" msgid="9008994909653990465">"Präsenz von Companion-Geräten beobachten"</string>
- <string name="permdesc_observeCompanionDevicePresence" msgid="3011699826788697852">"Ermöglicht einer Companion-App, die Präsenz von Companion-Geräten zu beobachten, wenn sie in der Nähe oder weit entfernt sind."</string>
+ <string name="permlab_observeCompanionDevicePresence" msgid="9008994909653990465">"Präsenz von Begleitgeräten beobachten"</string>
+ <string name="permdesc_observeCompanionDevicePresence" msgid="3011699826788697852">"Ermöglicht einer Companion-App, die Präsenz von Begleitgeräten zu beobachten, wenn sie in der Nähe oder weit entfernt sind."</string>
<string name="permlab_deliverCompanionMessages" msgid="3931552294842980887">"Companion-Nachrichten senden"</string>
<string name="permdesc_deliverCompanionMessages" msgid="2170847384281412850">"Ermöglicht einer Companion-App, Companion-Nachrichten an andere Geräte zu senden."</string>
<string name="permlab_startForegroundServicesFromBackground" msgid="6363004936218638382">"Dienste im Vordergrund aus dem Hintergrund starten"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 25a787c..84ca5b7 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"πρόσβαση στα δεδομένα αισθητήρα σχετικά με τις ζωτικές ενδείξεις σας"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Ειδοποιήσεις"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"εμφάνιση ειδοποιήσεων"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Ανάκτηση του περιεχομένου του παραθύρου"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Έλεγχος του περιεχομένου ενός παραθύρου με το οποίο αλληλεπιδράτε."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Ενεργοποίηση της \"Εξερεύνησης με άγγιγμα\""</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Επιτρέπει στην εφαρμογή να τροποποιήσει τη συλλογή φωτογραφιών σας."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"ανάγνωση τοποθεσιών από τη συλλογή πολυμέσων σας"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Επιτρέπει στην εφαρμογή να διαβάσει τοποθεσίες από τη συλλογή πολυμέσων σας."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Χρήση βιομετρικών"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Χρήση βιομετρικών ή κλειδώματος οθόνης"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Επαλήθευση ταυτότητας"</string>
@@ -2247,14 +2287,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"Dpad κέντρο"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"Πλαίσιο ρυθμίσεων τύπου αυτόματου κλικ"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"Αριστερό κλικ"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"Δεξί κλικ"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"Διπλό κλικ"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"Μεταφορά"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Κύλιση"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Παύση"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Θέση"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Το πακέτο <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> τοποθετήθηκε στον κάδο ΠΕΡΙΟΡΙΣΜΕΝΗΣ ΠΡΟΣΒΑΣΗΣ."</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 886beff..ef7238c 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"access sensor data about your vital signs"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Notifications"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"show notifications"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Retrieve window content"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Inspect the content of a window you\'re interacting with."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Turn on Explore by Touch"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Allows the app to modify your photo collection."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"read locations from your media collection"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Allows the app to read locations from your media collection."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Use biometrics"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Use biometrics or screen lock"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Verify that it’s you"</string>
@@ -2247,14 +2287,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"Dpad centre"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"Autoclick type settings panel"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"Left-click"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"Right-click"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"Double-click"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"Drag"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Scroll"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pause"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Position"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> has been put into the RESTRICTED bucket"</string>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index 33bbc6f..7e83739 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"access sensor data about your vital signs"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Notifications"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"show notifications"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Retrieve window content"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Inspect the content of a window you\'re interacting with."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Turn on Explore by Touch"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Allows the app to modify your photo collection."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"read locations from your media collection"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Allows the app to read locations from your media collection."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Use biometrics"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Use biometrics or screen lock"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Verify it’s you"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index f0a9c2a..5b99b57 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"access sensor data about your vital signs"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Notifications"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"show notifications"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Retrieve window content"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Inspect the content of a window that you\'re interacting with."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Turn on Explore by Touch"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Allows the app to modify your photo collection."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"read locations from your media collection"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Allows the app to read locations from your media collection."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Use biometrics"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Use biometrics or screen lock"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Verify that it’s you"</string>
@@ -2247,14 +2287,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"Dpad centre"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"Autoclick type settings panel"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"Left-click"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"Right-click"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"Double-click"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"Drag"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Scroll"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pause"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Position"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> has been put into the RESTRICTED bucket"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 8fcb412..5ba765b 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"access sensor data about your vital signs"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Notifications"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"show notifications"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Retrieve window content"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Inspect the content of a window you\'re interacting with."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Turn on Explore by Touch"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Allows the app to modify your photo collection."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"read locations from your media collection"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Allows the app to read locations from your media collection."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Use biometrics"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Use biometrics or screen lock"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Verify that it’s you"</string>
@@ -2247,14 +2287,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"Dpad centre"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"Autoclick type settings panel"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"Left-click"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"Right-click"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"Double-click"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"Drag"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Scroll"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pause"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Position"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> has been put into the RESTRICTED bucket"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index f46a4d4..d3258dd 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -354,6 +354,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"acceder a los datos de sensores acerca de tus signos vitales"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Notificaciones"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"mostrar notificaciones"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Recuperar el contenido de las ventanas"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Inspeccionará el contenido de la ventana con la que estés interactuando."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Activar la Exploración táctil"</string>
@@ -649,6 +657,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Permite que la app modifique tu colección de fotos."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"leer ubicaciones de tu colección de contenido multimedia"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Permite que la app lea las ubicaciones de tu colección de contenido multimedia."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Usar datos biométricos"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Usar datos biométricos o bloqueo de pantalla"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Comprueba que eres tú"</string>
@@ -2248,14 +2288,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"Pad direccional: centro"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"Panel de configuración del tipo de clic automático"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"Clic izquierdo"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"Clic con botón derecho"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"Hacer doble clic"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"Arrastrar"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Desplazamiento"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pausar"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Posición"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Se colocó <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> en el bucket RESTRICTED"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index d594897..c021a8a 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -354,6 +354,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"acceder a datos de sensores de tus constantes vitales"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Notificaciones"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"mostrar notificaciones"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Comprobar el contenido de la ventana"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Inspecciona el contenido de una ventana con la que estés interactuando."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Activar la exploración táctil"</string>
@@ -649,6 +657,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Permite que la aplicación modifique tu colección de fotos."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"leer las ubicaciones de tu colección de contenido multimedia"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Permite que la aplicación lea las ubicaciones de tu colección de contenido multimedia."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Usar biometría"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Usar biometría o bloqueo de pantalla"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Verifica que eres tú"</string>
@@ -1410,7 +1450,7 @@
<string name="carrier_app_notification_title" msgid="5815477368072060250">"Nueva SIM insertada"</string>
<string name="carrier_app_notification_text" msgid="6567057546341958637">"Toca para configurar"</string>
<string name="time_zone_change_notification_title" msgid="5232503069219193218">"Tu zona horaria ha cambiado"</string>
- <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Ahora estás en <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string>
+ <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Ahora estás en la <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string>
<string name="time_picker_dialog_title" msgid="9053376764985220821">"Establecer hora"</string>
<string name="date_picker_dialog_title" msgid="5030520449243071926">"Establecer fecha"</string>
<string name="date_time_set" msgid="4603445265164486816">"Establecer"</string>
@@ -2248,14 +2288,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"Cruceta: centro"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"Panel de ajustes del tipo de clic automático"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"Clic izquierdo"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"Hacer clic con el botón derecho"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"Hacer doble clic"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"Arrastrar"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Desplazarse"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pausar"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Posición"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> se ha incluido en el grupo de restringidos"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 5e961f4..ae21583 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"juurdepääs anduri andmetele teie eluliste näitajate kohta"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Märguanded"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"märguannete kuvamine"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Akna sisu toomine"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Kasutatava akna sisu kontrollimine."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Puudutusega sirvimise sisselülitamine"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Võimaldab rakendusel muuta teie fotokogu."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"Lugeda teie meediakogus olevaid asukohti"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Võimaldab rakendusel lugeda teie meediakogus olevaid asukohti."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Biomeetria kasutamine"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Biomeetria või ekraaniluku kasutamine"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Kinnitage oma isik"</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 0e450d1..a78754f 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"atzitu bizi-konstanteei buruzko sentsorearen datuak"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Jakinarazpenak"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"jakinarazpenak erakutsi"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Leihoko edukia eskuratu."</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Arakatu irekita daukazun leihoko edukia."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"\"Arakatu ukituta\" aktibatu."</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Argazki bilduma aldatzeko baimena ematen dio aplikazioari."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"multimedia-edukien bildumako kokapena irakurri"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Multimedia-edukien bildumako kokapena irakurtzeko baimena ematen dio aplikazioari."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Erabili sistema biometrikoak"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Erabili sistema biometrikoak edo pantailaren blokeoa"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Egiaztatu zeu zarela"</string>
@@ -2247,14 +2287,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"Norabide-kontrolagailuko erdiko botoia"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"Automatikoki klik egiteko eginbide motaren ezarpenen panela"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"Egin klik ezkerreko botoiarekin"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"Egin klik eskuineko botoiarekin"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"Egin klik bikoitza"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"Arrastatu"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Egin gora eta behera"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pausatu"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Ezarri posizioan"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Murriztuen edukiontzian ezarri da <xliff:g id="PACKAGE_NAME">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 4334713..ddde0b2 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"دسترسی به دادههای حسگر در رابطه با علائم حیاتی شما"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"اعلانها"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"نمایش اعلان"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"محتوای پنجره را بازیابی کند"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"محتوای پنجرهای را که درحال تعامل با آن هستید بررسی میکند."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"فعالسازی کاوش لمسی"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"به برنامه اجازه میدهد مجموعه عکستان را تغییر دهد."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"خواندن مکانها از مجموعه رسانه شما"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"به برنامه اجازه میدهد مکانها را از مجموعه رسانهتان بخواند."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"استفاده از دادههای زیستسنجشی"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"استفاده از دادههای زیستسنجشی یا قفل صفحه"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"تأیید کنید این شمایید"</string>
@@ -2514,7 +2554,7 @@
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"راهاندازی"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"حالا نه"</string>
<string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"زنگ هشدار برای <xliff:g id="USER_NAME">%s</xliff:g>"</string>
- <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"تغییر کاربر"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"تعویض کاربر"</string>
<string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"بیصدا کردن"</string>
<string name="bg_user_sound_notification_message" msgid="8613881975316976673">"برای بیصدا کردن، تکضرب بزنید"</string>
<string name="keyboard_shortcut_group_applications_browser" msgid="6535007304687100909">"مرورگر"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 5e3913e..b17ab23 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"pääsy anturidataan elintoiminnoistasi"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Ilmoitukset"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"näyttää ilmoituksia"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Noutaa ikkunan sisältöä"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Tarkistaa käyttämäsi ikkunan sisältö."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Ottaa kosketuksella tutkimisen käyttöön"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Antaa sovelluksen muokata kuvakokoelmaasi."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"lukea mediakokoelmasi sijainteja"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Antaa sovelluksen lukea mediakokoelmasi sijainteja."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Käytä biometriikkaa"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Käytä biometriikkaa tai näytön lukitusta"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Vahvista henkilöllisyytesi"</string>
@@ -2247,14 +2287,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"Suuntanäppäimistö: keskipainike"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"Automaattisen klikkaustyypin asetuspaneeli"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"Ykköspainike"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"Klikkaa kakkospainikkeella"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"Kaksoisklikkaa"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"Vedä"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Vieritä"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Keskeytä"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Sijainti"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> on nyt rajoitettujen ryhmässä"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 6ef3e21..7145e57 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -74,7 +74,7 @@
<string name="CLIRDefaultOffNextCallOff" msgid="2491576172356463443">"Par défaut, les numéros des appelants ne sont pas restreints. Appel suivant : non restreint"</string>
<string name="page_size_compat_apk_warning" msgid="2982396798449041224">"Cette appli n\'est pas compatible avec les pages de 16 ko. La vérification de l\'alignement de fichiers APK a échoué. Cette appli sera exécutée en mode compatible avec la taille de la page. Pour une meilleure compatibilité, veuillez recompiler l\'application avec la prise en charge de pages de 16 ko. Pour en savoir plus, consultez la page <a href=\"https://developer.android.com/16kb-page-size\">https://developer.android.com/16kb-page-size</a>"</string>
<string name="page_size_compat_elf_warning" msgid="6753874059564812651">"Cette appli n\'est pas compatible avec les pages de 16 ko. La vérification de l\'alignement de fichiers ELF a échoué. Cette appli sera exécutée en mode compatible avec la taille de la page. Pour une meilleure compatibilité, veuillez recompiler l\'application avec la prise en charge de pages de 16 ko. Pour en savoir plus, consultez la page <a href=\"https://developer.android.com/16kb-page-size\">https://developer.android.com/16kb-page-size</a>"</string>
- <string name="page_size_compat_apk_and_elf_warning" msgid="7628675779500605390">"Cette appli n\'est pas compatible avec les pages de 16 ko. Les vérifications d\'alignement de fichiers APK et ELF ont échoué. Cette appli sera exécutée en mode compatible avec la taille de la page. Pour une meilleure compatibilité, veuillez recompiler l\'application avec la prise en charge de pages de 16 ko. Pour en savoir plus, consultez la page <a href=\"https://developer.android.com/16kb-page-size\">https://developer.android.com/16kb-page-size</a>"</string>
+ <string name="page_size_compat_apk_and_elf_warning" msgid="7628675779500605390">"Cette appli n\'est pas compatible avec les pages de 16 ko. Les vérifications de l\'alignement de fichiers APK et ELF ont échoué. Cette appli sera exécutée dans un mode compatible avec la taille de la page. Pour une compatibilité optimale, veuillez recompiler l\'application afin de prendre en charge les pages de 16 ko. Pour en savoir plus, consultez la page <a href=\"https://developer.android.com/16kb-page-size\">https://developer.android.com/16kb-page-size</a>"</string>
<string name="serviceNotProvisioned" msgid="8289333510236766193">"Ce service n\'est pas pris en charge."</string>
<string name="CLIRPermanent" msgid="166443681876381118">"Impossible de modifier le paramètre relatif au numéro de l\'appelant."</string>
<string name="auto_data_switch_title" msgid="3286350716870518297">"Données changées à <xliff:g id="CARRIERDISPLAY">%s</xliff:g>"</string>
@@ -354,6 +354,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"accéder aux données des capteurs sur vos signes vitaux"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Notifications"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"afficher les notifications"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Récupérer le contenu d\'une fenêtre"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Inspecter le contenu d\'une fenêtre avec laquelle vous interagissez."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Activer la fonctionnalité Explorer au toucher"</string>
@@ -649,6 +657,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Autorise l\'appli à modifier votre collection de photos."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"lire les positions issues de votre collection multimédia"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Autorise l\'appli à lire les positions indiquées dans votre collection multimédia."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Utiliser les données biométriques"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Utiliser les données biométriques ou le verrouillage de l\'écran"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Confirmez que c\'est vous"</string>
@@ -2248,14 +2288,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"Pavé directionnel – centre"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"Panneau de configuration des paramètres de type clic automatique"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"Clic gauche"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"Clic droit"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"Double-cliquer"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"Glisser"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Faire défiler"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pause"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Position"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> a été placé dans le compartiment RESTREINT"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 4fd8601..a71348a 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -354,6 +354,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"accéder aux données des capteurs relatives à vos signes vitaux"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Notifications"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"afficher des notifications"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Récupérer le contenu d\'une fenêtre"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Inspecte le contenu d\'une fenêtre avec laquelle vous interagissez."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Activer la fonctionnalité Explorer au toucher"</string>
@@ -649,6 +657,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Autorise l\'application à modifier votre bibliothèque photo."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"consulter des positions issues de votre bibliothèque multimédia"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Autorise l\'application à consulter des positions issues de votre bibliothèque multimédia."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Utiliser la biométrie"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Utiliser la biométrie ou le verrouillage de l\'écran"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Confirmez votre identité"</string>
@@ -2248,14 +2288,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"Pavé directionnel - Centre"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"Panneau des paramètres du type de clic automatique"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"Clic gauche"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"Clic droit"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"Double-cliquer"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"Faire glisser"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Faire défiler"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pause"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Position"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> a été placé dans le bucket RESTRICTED"</string>
@@ -2486,7 +2522,7 @@
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Retour"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"En attente…"</string>
<string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"SOS par satellite est maintenant disponible"</string>
- <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Vous pouvez envoyer des messages aux services d\'urgence s\'il n\'y a pas de réseau mobile ou Wi-Fi. Google Messages doit être votre application de chat par défaut."</string>
+ <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Vous pouvez envoyer des messages aux services d\'urgence s\'il n\'y a pas de réseau mobile ou Wi-Fi. Google Messages doit être votre application de messagerie par défaut."</string>
<string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"SOS par satellite n\'est pas disponible"</string>
<string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"SOS par satellite n\'est pas disponible sur cet appareil"</string>
<string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"SOS par satellite n\'est pas configuré"</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 4ce3fc3..e8090b8 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"acceder aos datos dos sensores sobre as túas constantes vitais"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Notificacións"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"mostrar notificacións"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Recuperar contido da ventá"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Inspecciona o contido dunha ventá coa que estás interactuando."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Activar a exploración táctil"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Permite que a aplicación modifique a túa colección de fotos."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"ler localizacións da túa colección multimedia"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Permite que a aplicación lea as localizacións da túa colección multimedia."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Utilizar desbloqueo biométrico"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Utilizar desbloqueo biométrico ou credencial do dispositivo"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Verifica a túa identidade"</string>
@@ -2247,14 +2287,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"Cruceta: centro"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"Panel de configuración do tipo de clic automático"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"Clic co botón esquerdo do rato"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"Facer clic co botón dereito"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"Facer dobre clic"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"Arrastrar"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Desprazar"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pausa"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Posición"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> incluíuse no grupo RESTRINXIDO"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index fcba3fe..3ddc9da 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"તમારા મહત્વપૂર્ણ ચિહ્નો વિશે સેન્સર ડેટા ઍક્સેસ કરો"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"નોટિફિકેશન"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"નોટિફિકેશન બતાવો"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"વિંડો કન્ટેન્ટ પુનઃપ્રાપ્ત કરો"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"તમે જેની સાથે ક્રિયા-પ્રતિક્રિયા કરી રહ્યાં છો તે વિંડોનું કન્ટેન્ટ તપાસો."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"સ્પર્શ કરીને શોધખોળ કરવું ચાલુ કરો"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"એપને તમારો ફોટો સંગ્રહ સંશોધિત કરવાની મંજૂરી આપે છે."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"આપના મીડિયા સંગ્રહમાંથી સ્થાનો વાંચવા"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"એપને તમારા મીડિયા સંગ્રહમાંથી સ્થાનો વાંચવાની મંજૂરી આપે છે."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"બાયોમેટ્રિક્સનો ઉપયોગ કરો"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"બાયોમેટ્રિક્સ અથવા સ્ક્રીન લૉકનો ઉપયોગ કરો"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"આ તમે જ છો તેની ચકાસણી કરો"</string>
@@ -1408,7 +1448,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_zone_change_notification_title" msgid="5232503069219193218">"તમારો સમય ઝોન બદલાયો છે"</string>
+ <string name="time_zone_change_notification_title" msgid="5232503069219193218">"તમારો ટાઇમ ઝોન બદલાયો છે"</string>
<string name="time_zone_change_notification_body" msgid="6135793674904665585">"તમે <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)માં છો"</string>
<string name="time_picker_dialog_title" msgid="9053376764985220821">"સમય સેટ કરો"</string>
<string name="date_picker_dialog_title" msgid="5030520449243071926">"તારીખ સેટ કરો"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 66f0ced..a587509 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"अपने महत्वपूर्ण संकेतों के बारे में सेंसर डेटा को ऐक्सेस करें"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"सूचनाएं"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"सूचनाएं दिखाएं"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"विंडो का कॉन्टेंट वापस पाएं"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"विंडो पर नज़र आ रहे कॉन्टेंट की जांच करें."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"छूकर, किसी चीज़ से जुड़ी जानकारी सुनने की सुविधा चालू करें"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"इससे ऐप्लिकेशन को आपके फ़ोटो संग्रह में बदलाव करने की मंज़ूरी दी जाती है."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"अपने मीडिया संग्रह से जगह की जानकारी ऐक्सेस करने की अनुमति दें"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"इससे ऐप्लिकेशन को आपके मीडिया संग्रह से जगह की जानकारी ऐक्सेस करने की अनुमति दी जाती है."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"बायोमेट्रिक्स इस्तेमाल करें"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"बायोमेट्रिक्स या स्क्रीन लॉक का क्रेडेंशियल इस्तेमाल करें"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"अपनी पहचान की पुष्टि करें"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index aadf118..cfea6ab 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -354,6 +354,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"pristupiti podacima senzora o vašim vitalnim znakovima"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Obavijesti"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"prikazati obavijesti"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Dohvaćati sadržaj prozora"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Pregledat će sadržaj prozora koji upotrebljavate."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Uključiti značajku Istraži dodirom"</string>
@@ -649,6 +657,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Omogućuje aplikaciji izmjenu vaše zbirke fotografija."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"čitanje lokacija iz vaše medijske zbirke"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Omogućuje aplikaciji čitanje lokacija iz vaše medijske zbirke."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Upotreba biometrije"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Upotreba biometrijske autentifikacije ili zaključavanja zaslona"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Potvrdite da ste to vi"</string>
@@ -1410,7 +1450,7 @@
<string name="carrier_app_notification_title" msgid="5815477368072060250">"Umetnuta je nova SIM kartica"</string>
<string name="carrier_app_notification_text" msgid="6567057546341958637">"Dodirnite da biste je postavili"</string>
<string name="time_zone_change_notification_title" msgid="5232503069219193218">"Vaša je vremenska zona promijenjena"</string>
- <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Sada ste u vremenskoj zoni <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string>
+ <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Trenutačna vremenska zona: <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string>
<string name="time_picker_dialog_title" msgid="9053376764985220821">"Postavite vrijeme"</string>
<string name="date_picker_dialog_title" msgid="5030520449243071926">"Postavi datum"</string>
<string name="date_time_set" msgid="4603445265164486816">"Postavi"</string>
@@ -2246,7 +2286,7 @@
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Lijevo na plohi za smjerove"</string>
<string name="accessibility_system_action_dpad_right_label" msgid="9180196950365804081">"Desno na plohi za smjerove"</string>
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"U središtu plohe za smjerove"</string>
- <string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"Ploča postavki vrste automatskog klika"</string>
+ <string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"Ploča postavki automatskih klikova"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"Lijevi klik"</string>
<string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"Desni klik"</string>
<string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"Dvostruki klik"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 39a4cfc..24389d6 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"az érzékelők által mért, életjelekkel kapcsolatos adatok elérése"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Értesítések"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"értesítések megjelenítése"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Ablaktartalom lekérdezése"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"A használt ablak tartalmának vizsgálata."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Felfedezés érintéssel bekapcsolása"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Engedélyezi az alkalmazásnak a fényképgyűjtemény módosítását."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"helyek olvasása a médiagyűjteményből"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Engedélyezi az alkalmazásnak a helyek médiagyűjteményből való olvasását."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Biometriai feloldás használata"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"A folytatás biometriai feloldással vagy képernyőzárral lehetséges"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Igazolja, hogy Ön az"</string>
@@ -1765,7 +1805,7 @@
<string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Képernyő megtekintése és kezelése"</string>
<string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Elolvashatja a képernyő tartalmát, és tartalmakat jeleníthet meg más alkalmazások felett."</string>
<string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Műveletek megtekintése és elvégzése"</string>
- <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Követheti az alkalmazásokkal és hardveres érzékelőkkel való interakcióit, és műveleteket végezhet az alkalmazásokkal az Ön nevében."</string>
+ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Követheti az appokkal és hardveres érzékelőkkel való interakcióit, és műveleteket végezhet az appokkal az Ön nevében."</string>
<string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Engedélyezés"</string>
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Tiltás"</string>
<string name="accessibility_dialog_button_uninstall" msgid="2952465517671708108">"Eltávolítás"</string>
@@ -2247,14 +2287,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"D-pad – középre"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"Automatikus kattintás típusának beállításai panel"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"Kattintás bal egérgombbal"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"Kattintás jobb egérgombbal"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"Duplakattintás"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"Húzás"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Görgetés"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Szüneteltetés"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Pozíció"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"A következő csomag a KORLÁTOZOTT csoportba került: <xliff:g id="PACKAGE_NAME">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index f4b83f2..1125dc9 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"օգտագործել սենսորների տվյալները ձեր օրգանիզմի վիճակի մասին"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Ծանուցումներ"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"ցուցադրել ծանուցումներ"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Առբերել պատուհանի բովանդակությունը"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Վերլուծել գործող պատուհանի բովանդակությունը"</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Միացնել Հպման միջոցով հետազոտումը"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Թույլ է տալիս հավելվածին փոփոխել ձեր լուսանկարների հավաքածուն:"</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"ճանաչել տեղադրության մասին տվյալները մեդիա բովանդակության հավաքածուից"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Թույլ է տալիս հավելվածին ճանաչել տեղադրության մասին տվյալները ձեր մեդիա բովանդակության հավաքածուից:"</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Կենսաչափական համակարգեր"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Օգտագործել կենսաչափական համակարգեր կամ էկրանի կողպում"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Հաստատեք ձեր ինքնությունը"</string>
@@ -2088,12 +2128,9 @@
<string name="unpin_target" msgid="3963318576590204447">"Ապամրացնել"</string>
<string name="unpin_specific_target" msgid="3859828252160908146">"Ապամրացնել <xliff:g id="LABEL">%1$s</xliff:g> հավելվածը"</string>
<string name="app_info" msgid="6113278084877079851">"Հավելվածի մասին"</string>
- <!-- no translation found for shortcut_group_a11y_title (2992150163811583865) -->
- <skip />
- <!-- no translation found for suggested_apps_group_a11y_title (2804876567839501831) -->
- <skip />
- <!-- no translation found for all_apps_group_a11y_title (7020352520224108745) -->
- <skip />
+ <string name="shortcut_group_a11y_title" msgid="2992150163811583865">"Direct Share-ի ստացողներ"</string>
+ <string name="suggested_apps_group_a11y_title" msgid="2804876567839501831">"Առաջարկվող հավելվածներ"</string>
+ <string name="all_apps_group_a11y_title" msgid="7020352520224108745">"Հավելվածների ցուցակ"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Ցուցադրական օգտատերը գործարկվում է…"</string>
<string name="demo_restarting_message" msgid="1160053183701746766">"Սարքը վերակայվում է…"</string>
@@ -2250,14 +2287,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"Dpad-ի «Կենտրոն» կոճակ"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"Ավտոմատ սեղմման տեսակի կարգավորումների վահանակ"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"Ձախ սեղմում"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"Սեղմել մկնիկի աջ կոճակը"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"Երկու անգամ սեղմել"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"Քաշել"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Ոլորել"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Դադարեցնել"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Դիրքը"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> փաթեթը գցվեց ՍԱՀՄԱՆԱՓԱԿՎԱԾ զամբյուղի մեջ"</string>
@@ -2534,12 +2567,8 @@
<string name="keyboard_shortcut_group_applications_maps" msgid="7950000659522589471">"Քարտեզներ"</string>
<string name="keyboard_shortcut_group_applications" msgid="3010389163951364798">"Հավելվածներ"</string>
<string name="fingerprint_loe_notification_msg" msgid="3927447270148854546">"Ձեր մատնահետքերն այլևս չեն կարող ճանաչվել։ Նորից կարգավորեք մատնահետքով ապակողպումը։"</string>
- <!-- no translation found for usb_apm_usb_plugged_in_when_locked_notification_title (468577168569874967) -->
- <skip />
- <!-- no translation found for usb_apm_usb_plugged_in_when_locked_notification_text (6695268246267993166) -->
- <skip />
- <!-- no translation found for usb_apm_usb_suspicious_activity_notification_title (3461195995882871461) -->
- <skip />
- <!-- no translation found for usb_apm_usb_suspicious_activity_notification_text (6537085605929303187) -->
- <skip />
+ <string name="usb_apm_usb_plugged_in_when_locked_notification_title" msgid="468577168569874967">"Ապակողպեք Android սարքը"</string>
+ <string name="usb_apm_usb_plugged_in_when_locked_notification_text" msgid="6695268246267993166">"Android սարքը կողպված է։ USB կրիչն օգտագործելու համար նախ ապակողպեք Android սարքը, այնուհետև նորից տեղադրեք կրիչը։"</string>
+ <string name="usb_apm_usb_suspicious_activity_notification_title" msgid="3461195995882871461">"Հայտնաբերվել է կասկածելի USB կրիչ"</string>
+ <string name="usb_apm_usb_suspicious_activity_notification_text" msgid="6537085605929303187">"USB-ով տվյալների փոխանցումն անջատված է։"</string>
</resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index ce9a7f6..2cd5472 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"mengakses data sensor tentang tanda-tanda vital"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Notifikasi"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"tampilkan notifikasi"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Membaca konten di jendela"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Memeriksa konten di jendela yang sedang Anda buka."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Mengaktifkan Jelajahi dengan Sentuhan"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Mengizinkan aplikasi untuk memodifikasi koleksi foto Anda."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"membaca lokasi dari koleksi media Anda"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Mengizinkan aplikasi untuk membaca lokasi dari koleksi media Anda."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Gunakan biometrik"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Gunakan biometrik atau kunci layar"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Verifikasi diri Anda"</string>
@@ -2247,14 +2287,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"Dpad Tengah"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"Panel setelan jenis klik otomatis"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"Klik kiri"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"Klik kanan"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"Klik dua kali"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"Tarik"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Scroll"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Jeda"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Posisi"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> telah dimasukkan ke dalam bucket DIBATASI"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index b80efc7..a89a50f 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"aðgangur að skynjaragögnum um lífsmörk þín"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Tilkynningar"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"sýna tilkynningar"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Sækja innihald glugga"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Kanna innihald glugga sem þú ert að nota."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Kveikja á snertikönnun"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Leyfir forritinu að breyta myndasafninu þínu."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"lesa staðsetningar úr efnissafninu þínu"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Leyfir forritinu að lesa staðsetningar úr efnissafninu þínu."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Nota lífkenni"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Nota lífkenni eða skjálás"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Staðfestu hver þú ert"</string>
@@ -1409,7 +1449,7 @@
<string name="carrier_app_notification_title" msgid="5815477368072060250">"Nýtt SIM-kort sett í"</string>
<string name="carrier_app_notification_text" msgid="6567057546341958637">"Ýttu til að setja það upp"</string>
<string name="time_zone_change_notification_title" msgid="5232503069219193218">"Tímabeltinu þínu var breytt"</string>
- <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Þú ert nú á <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string>
+ <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Tímabeltið þitt er nú <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string>
<string name="time_picker_dialog_title" msgid="9053376764985220821">"Veldu tíma"</string>
<string name="date_picker_dialog_title" msgid="5030520449243071926">"Veldu dagsetningu"</string>
<string name="date_time_set" msgid="4603445265164486816">"Velja"</string>
@@ -2247,14 +2287,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"Miðjuhnappur stýriflatar"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"Stillingasvæði fyrir tegund sjálfvirks smells"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"Vinstrismellur"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"Hægrismella"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"Tvísmella"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"Draga"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Fletta"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Hlé"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Staðsetning"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> var sett í flokkinn TAKMARKAÐ"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 3ca9f7f..47ef283 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -354,6 +354,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"Possono accedere ai dati dei sensori relativi ai tuoi parametri vitali"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Notifiche"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"Visualizzazione di notifiche"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Recuperare contenuti della finestra"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Esamina i contenuti di una finestra con cui interagisci."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Attivare Esplora al tocco"</string>
@@ -649,6 +657,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Consente all\'app di modificare la tua raccolta di foto."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"lettura delle posizioni dalla tua raccolta multimediale"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Consente all\'app di leggere le posizioni dalla tua raccolta multimediale."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Usa la biometria"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Usa la biometria o il blocco schermo"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Verifica la tua identità"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index cfa0987..d58084d 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -354,6 +354,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"גישה אל נתוני חיישנים של הסימנים החיוניים שלך"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"התראות"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"הצגת התראות"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"אחזור תוכן של חלון"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"בדיקת התוכן של חלון שאיתו מתבצעת אינטראקציה."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"הפעלה של \'גילוי באמצעות מגע\'"</string>
@@ -649,6 +657,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"מאפשרת לאפליקציה לשנות את אוסף התמונות שלך."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"לקרוא מיקומים מאוסף המדיה שלך"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"מאפשרת לאפליקציה לקרוא מיקומים מאוסף המדיה שלך."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"שימוש במידע ביומטרי"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"שימוש במידע ביומטרי בנעילת מסך"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"אימות הזהות שלך"</string>
@@ -1433,7 +1473,7 @@
<string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"המכשיר זיהה התקן אודיו אנלוגי"</string>
<string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"ההתקן שחיברת לא תואם לטלפון הזה. יש ללחוץ לקבלת מידע נוסף."</string>
<string name="adb_active_notification_title" msgid="408390247354560331">"ניפוי באגים ב-USB מחובר"</string>
- <string name="adb_active_notification_message" msgid="5617264033476778211">"צריך ללחוץ כדי להשבית את ניפוי הבאגים ב-USB"</string>
+ <string name="adb_active_notification_message" msgid="5617264033476778211">"לוחצים להשבתת ניפוי הבאגים ב-USB"</string>
<string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"יש ללחוץ על ההתראה כדי להשבית ניפוי באגים ב-USB."</string>
<string name="adbwifi_active_notification_title" msgid="6147343659168302473">"ניפוי הבאגים האלחוטי מחובר"</string>
<string name="adbwifi_active_notification_message" msgid="930987922852867972">"יש ללחוץ כדי להשבית ניפוי באגים אלחוטי"</string>
@@ -2089,12 +2129,9 @@
<string name="unpin_target" msgid="3963318576590204447">"ביטול הצמדה"</string>
<string name="unpin_specific_target" msgid="3859828252160908146">"ביטול ההצמדה של <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="app_info" msgid="6113278084877079851">"פרטי האפליקציה"</string>
- <!-- no translation found for shortcut_group_a11y_title (2992150163811583865) -->
- <skip />
- <!-- no translation found for suggested_apps_group_a11y_title (2804876567839501831) -->
- <skip />
- <!-- no translation found for all_apps_group_a11y_title (7020352520224108745) -->
- <skip />
+ <string name="shortcut_group_a11y_title" msgid="2992150163811583865">"יעדים לשיתוף ישיר"</string>
+ <string name="suggested_apps_group_a11y_title" msgid="2804876567839501831">"הצעות לאפליקציות"</string>
+ <string name="all_apps_group_a11y_title" msgid="7020352520224108745">"רשימת האפליקציות"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"תהליך ההדגמה מתחיל…"</string>
<string name="demo_restarting_message" msgid="1160053183701746766">"מתבצע איפוס של המכשיר…"</string>
@@ -2251,14 +2288,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"לחצן אמצעי ב-Dpad"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"חלונית ההגדרות של סוג הקליק האוטומטי"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"לחיצה שמאלית"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"לחיצה ימנית"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"לחיצה כפולה"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"גרירה"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"גלילה"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"השהיה"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"מיקום"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> התווספה לקטגוריה \'מוגבל\'"</string>
@@ -2535,12 +2568,8 @@
<string name="keyboard_shortcut_group_applications_maps" msgid="7950000659522589471">"מפות"</string>
<string name="keyboard_shortcut_group_applications" msgid="3010389163951364798">"אפליקציות"</string>
<string name="fingerprint_loe_notification_msg" msgid="3927447270148854546">"טביעות האצבע שלך נשחקו ואי אפשר לזהות אותן. צריך להגדיר \'פתיחה בטביעת אצבע\' מחדש."</string>
- <!-- no translation found for usb_apm_usb_plugged_in_when_locked_notification_title (468577168569874967) -->
- <skip />
- <!-- no translation found for usb_apm_usb_plugged_in_when_locked_notification_text (6695268246267993166) -->
- <skip />
- <!-- no translation found for usb_apm_usb_suspicious_activity_notification_title (3461195995882871461) -->
- <skip />
- <!-- no translation found for usb_apm_usb_suspicious_activity_notification_text (6537085605929303187) -->
- <skip />
+ <string name="usb_apm_usb_plugged_in_when_locked_notification_title" msgid="468577168569874967">"התקן ה-USB מחובר כשהמכשיר נעול"</string>
+ <string name="usb_apm_usb_plugged_in_when_locked_notification_text" msgid="6695268246267993166">"התקן ה-USB מחובר כשמערכת Android נעולה. כדי להשתמש בהתקן ה-USB, קודם צריך לבטל את הנעילה של Android ואז לחבר את ההתקן מחדש."</string>
+ <string name="usb_apm_usb_suspicious_activity_notification_title" msgid="3461195995882871461">"זוהתה פעילות חשודה בהתקן USB"</string>
+ <string name="usb_apm_usb_suspicious_activity_notification_text" msgid="6537085605929303187">"האות עם הנתונים מהתקן ה-USB הושבת."</string>
</resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index ad770aa..7e37dff 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"バイタルサインに関するセンサーデータへのアクセス"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"通知"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"通知を表示"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"ウィンドウコンテンツの取得"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"ユーザーがアクセスしているウィンドウのコンテンツを検査します。"</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"タッチガイドの有効化"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"写真コレクションの変更をアプリに許可します。"</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"メディア コレクションの位置情報の読み取り"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"メディア コレクションの位置情報の読み取りをアプリに許可します。"</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"生体認証の使用"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"生体認証または画面ロックの使用"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"本人確認"</string>
@@ -1432,7 +1472,7 @@
<string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"アナログのオーディオ アクセサリーを検出"</string>
<string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"接続したデバイスはこのスマートフォンと互換性がありません。タップすると、詳細を確認できます。"</string>
<string name="adb_active_notification_title" msgid="408390247354560331">"USB デバッグが接続されました"</string>
- <string name="adb_active_notification_message" msgid="5617264033476778211">"無効にするにはここをタップしてください"</string>
+ <string name="adb_active_notification_message" msgid="5617264033476778211">"無効にするにはタップしてください"</string>
<string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"USB デバッグを無効にする場合に選択します。"</string>
<string name="adbwifi_active_notification_title" msgid="6147343659168302473">"ワイヤレス デバッグが接続されました"</string>
<string name="adbwifi_active_notification_message" msgid="930987922852867972">"無効にするにはここをタップしてください"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 481c422..5ecf5b7 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"თქვენი სასიცოცხლო ფუნქციების შესახებ სენსორის მონაცემებზე წვდომა"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"შეტყობინებები"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"შეტყობინებების ჩვენება"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"ფანჯრის კონტენტის მოძიება"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"იმ ფანჯრის კონტენტის შემოწმება, რომელშიც მუშაობთ."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"„შეხებით აღმოჩენის“ ჩართვა"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"აპი შეძლებს თქვენი ფოტოკოლექციის შეცვლას."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"მდებარეობების გაცნობა თქვენი მედიაკოლექციიდან"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"აპი შეძლებს მდებარეობების გაცნობას თქვენი მედიაკოლექციიდან."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"გამოიყენეთ ბიომეტრიული სისტემა"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"გამოიყენეთ ბიომეტრიული სისტემა ან ეკრანის დაბლოკვა"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"დაადასტურეთ ვინაობა"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 70412be..98addd0 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"ағза күйінің көрсеткіштері туралы сенсор деректеріне қатынасу"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Хабарландырулар"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"хабарландыруларды көрсету"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Терезе контентін оқып отыру"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Ашық тұрған терезе контентін тексеру."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Түртілген элементтерді дыбыстау функциясын қосу"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Қолданбаға суреттер жинағын өзгертуге мүмкіндік береді."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"медиамазмұн жинағынан геодеректерді оқу"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Қолданбаға медиамазмұн жинағынан геодеректерді оқуға мүмкіндік береді."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Биометриканы пайдалану"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Биометриканы немесе экран құлпын пайдалану"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Cіз екеніңізді растаңыз"</string>
@@ -1409,7 +1449,7 @@
<string name="carrier_app_notification_title" msgid="5815477368072060250">"Жаңа SIM салынды"</string>
<string name="carrier_app_notification_text" msgid="6567057546341958637">"Оны орнату үшін түртіңіз"</string>
<string name="time_zone_change_notification_title" msgid="5232503069219193218">"Уақыт белдеуі өзгертілді"</string>
- <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Қазір <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>) уақыт белдеуіндесіз."</string>
+ <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Қазір <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>) белдеуіндесіз."</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>
@@ -2247,14 +2287,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"Ортаңғы Dpad түймесі"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"Автоматты басу түрі параметрлері панелі"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"Сол жағын басу"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"Тінтуірдің оң жақ түймесін басу"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"Екі рет басу"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"Сүйреу"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Айналдыру"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Кідірту"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Орналастыру"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ШЕКТЕЛГЕН себетке салынды."</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index fdd522b..7d0f7785 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"ចូលដំណើរការទិន្នន័យឧបករណ៍ចាប់សញ្ញាអំពីស្ថានភាពសុខភាពរបស់អ្នក"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"ការជូនដំណឹង"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"បង្ហាញការជូនដំណឹង"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"ទាញយកខ្លឹមសារវិនដូ"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"ពិនិត្យខ្លឹមសារវិនដូដែលអ្នកកំពុងធ្វើអន្តរកម្មជាមួយ។"</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"បើកការរកមើលដោយប៉ះ"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"អនុញ្ញាតឱ្យកម្មវិធីកែប្រែបណ្ដុំរូបថតរបស់អ្នក។"</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"អានទីតាំងពីបណ្ដុំមេឌៀរបស់អ្នក"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"អនុញ្ញាតឱ្យកម្មវិធីអានទីតាំងពីបណ្ដុំមេឌៀរបស់អ្នក។"</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"ប្រើជីវមាត្រ"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"ប្រើជីវមាត្រ ឬការចាក់សោអេក្រង់"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"ផ្ទៀងផ្ទាត់ថាជាអ្នក"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 887938c..e3caae5 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"ನಿಮ್ಮ ಮುಖ್ಯ ಲಕ್ಷಣಗಳ ಕುರಿತು ಸೆನ್ಸಾರ್ ಡೇಟಾವನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"ನೋಟಿಫಿಕೇಶನ್ಗಳು"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"ಅಧಿಸೂಚನೆಗಳನ್ನು ತೋರಿಸಿ"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"ವಿಂಡೋ ವಿಷಯವನ್ನು ಹಿಂಪಡೆಯುತ್ತದೆ"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"ನೀವು ಸಂವಹನ ನಡೆಸುತ್ತಿರುವ ವಿಂಡೋದ ಕಂಟೆಂಟ್ ಅನ್ನು ಪರೀಕ್ಷಿಸಿ."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"ಸ್ಪರ್ಶ-ಎಕ್ಸ್ಪ್ಲೋರ್ ಆನ್ ಮಾಡುತ್ತದೆ"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"ನಿಮ್ಮ ಫೋಟೋ ಸಂಗ್ರಹಣೆಯನ್ನು ಮಾರ್ಪಡಿಸಲು ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"ನಿಮ್ಮ ಮೀಡಿಯಾ ಸಂಗ್ರಹಣೆಯಿಂದ ಸ್ಥಳಗಳನ್ನು ಓದಿ"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"ನಿಮ್ಮ ಮೀಡಿಯಾ ಸಂಗ್ರಹಣೆಯಿಂದ ಸ್ಥಳಗಳನ್ನು ಓದಲು ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"ಬಯೋಮೆಟ್ರಿಕ್ಸ್ ಬಳಸಿ"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"ಬಯೋಮೆಟ್ರಿಕ್ಸ್ ಅಥವಾ ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಅನ್ನು ಬಳಸಿ"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"ಇದು ನೀವೇ ಎಂದು ಪರಿಶೀಲಿಸಿ"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index fc39271..ffbe631 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"생체 신호에 관한 센서 데이터에 액세스"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"알림"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"알림 표시"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"창 콘텐츠 가져오기"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"상호작용 중인 창의 콘텐츠를 검사합니다."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"터치하여 탐색 사용"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"앱에서 사진 컬렉션을 수정하도록 허용합니다."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"미디어 컬렉션에서 위치 읽기"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"앱에서 미디어 컬렉션의 위치를 읽도록 허용합니다."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"생체 인식 사용"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"생체 인식 또는 화면 잠금을 사용"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"본인 확인"</string>
@@ -1027,7 +1067,7 @@
<string name="lockscreen_transport_stop_description" msgid="1449552232598355348">"중지"</string>
<string name="lockscreen_transport_rew_description" msgid="7680106856221622779">"되감기"</string>
<string name="lockscreen_transport_ffw_description" msgid="4763794746640196772">"빨리 감기"</string>
- <string name="emergency_calls_only" msgid="3057351206678279851">"긴급 통화만 허용"</string>
+ <string name="emergency_calls_only" msgid="3057351206678279851">"긴급 전화만 허용"</string>
<string name="lockscreen_network_locked_message" msgid="2814046965899249635">"네트워크 잠김"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="2867953953604224166">"SIM이 PUK 잠김 상태입니다."</string>
<string name="lockscreen_sim_puk_locked_instructions" msgid="5307979043730860995">"사용자 가이드를 참조하거나 고객지원팀에 문의하세요."</string>
@@ -1572,7 +1612,7 @@
<string name="vpn_lockdown_config" msgid="8331697329868252169">"네트워크 또는 VPN 설정 변경"</string>
<string name="upload_file" msgid="8651942222301634271">"파일 선택"</string>
<string name="no_file_chosen" msgid="4146295695162318057">"파일을 선택하지 않았습니다."</string>
- <string name="reset" msgid="3865826612628171429">"초기화"</string>
+ <string name="reset" msgid="3865826612628171429">"재설정"</string>
<string name="submit" msgid="862795280643405865">"제출"</string>
<string name="car_mode_disable_notification_title" msgid="8450693275833142896">"운전 앱 실행 중"</string>
<string name="car_mode_disable_notification_message" msgid="8954550232288567515">"운전 앱을 종료하려면 탭하세요."</string>
@@ -2247,14 +2287,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"방향 패드 가운데"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"자동 클릭 유형 설정 패널"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"왼쪽 클릭"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"오른쪽 클릭"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"더블클릭"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"드래그"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"스크롤"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"일시중지"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"위치"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> 항목이 RESTRICTED 버킷으로 이동함"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index f8c0022..5f19cf7 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"организмдин абалына көз салган сенсордун дайындарына мүмкүнчүлүк алуу"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Билдирмелер"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"билдирмелерди көрсөтүү"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Терезедеги нерселерди алып туруу"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Учурда ачылып турган терезедеги маалыматты талдайт."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"\"Сыйпалап изилдөө\" мүмкүнчүлүгүн иштетет"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Колдонмого сүрөт жыйнагыңызды өзгөртүүгө мүмкүнчүлүк берет."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"медиа жыйнагыңыз сакталган жерлерди окуу"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Колдонмого медиа жыйнагыңыз сакталган жерлерди окууга мүмкүнчүлүк берет."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Биометрикалык параметрлерди колдонуу"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Биометрикалык жөндөөнү же экрандын кулпусун колдонуу"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Өзүңүздү ырастаңыз"</string>
@@ -2247,14 +2287,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"Dpad\'дын ортоңку баскычы"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"Авточыкылдатуу түрүнүн параметрлеринин панели"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"Сол баскычын чыкылдатуу"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"Оң баскычын чыкылдатуу"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"Эки жолу чыкылдатуу"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"Сүйрөө"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Сыдыруу"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Тындыруу"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Орду"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ЧЕКТЕЛГЕН чакага коюлган"</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 429f3f7..fa1ff2b 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"ເຂົ້າຫາຂໍ້ມູນເຊັນເຊີກ່ຽວກັບສັນຍານຊີບຂອງທ່ານ"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"ການແຈ້ງເຕືອນ"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"ສະແດງການແຈ້ງເຕືອນ"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"ດຶງຂໍ້ມູນເນື້ອຫາໃນໜ້າຈໍ"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"ກວດກາເນື້ອຫາຂອງໜ້າຈໍທີ່ທ່ານກຳລັງມີປະຕິສຳພັນນຳ."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"ເປີດໃຊ້ \"ການສຳຫຼວດໂດຍສຳຜັດ\""</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"ອະນຸຍາດໃຫ້ແອັບແກ້ໄຂຄໍເລັກຊັນຮູບຂອງທ່ານ."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"ອ່ານສະຖານທີ່ຈາກຄໍເລັກຊັນມີເດຍຂອງທ່ານ"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"ອະນຸຍາດໃຫ້ແອັບອ່ານສະຖານທີ່ຈາກຄໍເລັກຊັນມີເດຍຂອງທ່ານ."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"ໃຊ້ລະບົບຊີວະມິຕິ"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"ໃຊ້ລະບົບຊີວະມິຕິ ຫຼື ການລັອກໜ້າຈໍ"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"ຢັ້ງຢືນວ່າແມ່ນທ່ານ"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 3ca681b..b9303fa 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -355,6 +355,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"pasiekti jutiklių duomenis apie gyvybinius ženklus"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Pranešimai"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"rodyti pranešimus"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Gauti lango turinį"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Tikrinti lango, su kuriuo sąveikaujate, turinį."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Įjungti „Naršyti paliečiant“"</string>
@@ -650,6 +658,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Programai leidžiama keisti nuotraukų kolekciją."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"skaityti vietoves iš medijos kolekcijos"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Programai leidžiama skaityti vietoves iš medijos kolekcijos."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Naudoti biometrinius duomenis"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Naudoti biometrinius duomenis arba ekrano užraktą"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Patvirtinkite, kad tai jūs"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 1e7ffd1..3a1df4b 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -354,6 +354,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"piekļūt sensoru datiem par jūsu veselības rādījumiem"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Paziņojumi"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"rādīt paziņojumus"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Izgūt loga saturu."</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Skatīt tā loga saturu, ar kuru mijiedarbojaties."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Aktivizēt funkciju “Pārlūkot pieskaroties”."</string>
@@ -649,6 +657,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Ļauj lietotnei pārveidot jūsu fotoattēlu kolekciju."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"Lasīt atrašanās vietas no jūsu multivides kolekcijas"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Ļauj lietotnei lasīt atrašanās vietas no jūsu multivides kolekcijas."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Biometrijas izmantošana"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Biometrijas vai ekrāna bloķēšanas izmantošana"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Apstipriniet, ka tas esat jūs"</string>
@@ -2248,14 +2288,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"Virzienu slēdzis — centrs"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"Automātiskās klikšķināšanas veida iestatījumu panelis"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"Noklikšķināt ar peles kreiso pogu"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"Noklikšķināt ar peles labo pogu"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"Veikt dubultklikšķi"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"Vilkt"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Ritināt"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pārtraukt"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Pozīcija"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Pakotne “<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>” ir ievietota ierobežotā kopā."</string>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index c1a7c1d..c6d51c7 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"пристапува до податоците од сензорите за виталните функции"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Известувања"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"да прикажува известувања"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"да ги вчитува содржините од прозорците"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"да ги проверува содржините од прозорецот што го користите"</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"да вклучи „Истражувај со допир“"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Дозволува апликацијата да ја менува вашата збирка на фотографии."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"да чита локации од вашата збирка на аудиовизуелни содржини"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Дозволува апликацијата да чита локации од вашата збирка на аудиовизуелни содржини."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Користи биометрика"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Користи биометрика или заклучен екран"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Потврдете дека сте вие"</string>
@@ -2247,14 +2287,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"Навигациско копче за средина"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"Табла со поставки за вид автоматско кликнување"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"Кликни со лево копче"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"Кликнување со десно копче"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"Кликнување двапати"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"Повлекување"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Лизгање"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Паузирај"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Позиционирај"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> е ставен во корпата ОГРАНИЧЕНИ"</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index 5c31433..17fa98b 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"നിങ്ങളുടെ ജീവാധാര ലക്ഷണങ്ങളെ കുറിച്ചുള്ള സെൻസർ വിവരങ്ങൾ ആക്സസ് ചെയ്യുക"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"അറിയിപ്പുകൾ"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"അറിയിപ്പുകൾ കാണിക്കുക"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"വിൻഡോ ഉള്ളടക്കം വീണ്ടെടുക്കുക"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"നിങ്ങൾ സംവദിക്കുന്ന ഒരു വിൻഡോയുടെ ഉള്ളടക്കം പരിശോധിക്കുക."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"സ്പർശനം വഴി പര്യവേക്ഷണം ചെയ്യുക, ഓണാക്കുക"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"നിങ്ങളുടെ ഫോട്ടോ ശേഖരം പരിഷ്ക്കരിക്കുന്നതിന് ആപ്പിനെ അനുവദിക്കുന്നു."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"നിങ്ങളുടെ മീഡിയ ശേഖരത്തിൽ നിന്നും ലൊക്കേഷനുകൾ റീഡ് ചെയ്യുക"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"നിങ്ങളുടെ മീഡിയ ശേഖരത്തിൽ നിന്നും ലൊക്കേഷനുകൾ റീഡ് ചെയ്യുന്നതിന് ആപ്പിനെ അനുവദിക്കുന്നു."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"ബയോമെട്രിക്സ് ഉപയോഗിക്കുക"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"ബയോമെട്രിക്സ് അല്ലെങ്കിൽ സ്ക്രീൻ ലോക്ക് ഉപയോഗിക്കുക"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"ഇത് നിങ്ങളാണെന്ന് പരിശോധിച്ചുറപ്പിക്കുക"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 24637fa..48b2aa8 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"таны биеийн байдлын талаарх мэдрэгч бүхий өгөгдөлд нэвтрэх"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Мэдэгдэл"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"мэдэгдэл харуулах"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Цонхны агуулгыг авах"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Таны харилцан үйлчлэх цонхны контентоос шалгах."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Хүрэлтээр сонсохыг асаах"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Таны зургийн цуглуулгыг тохируулах зөвшөөрлийг аппад олгодог."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"медиа цуглуулгаасаа байршлыг унших"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Таны медиа цуглуулгаас байршлыг унших зөвшөөрлийг аппад олгодог."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Биометр ашиглах"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Биометр эсвэл дэлгэцийн түгжээ ашиглах"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Өөрийгөө мөн гэдгийг баталгаажуулаарай"</string>
@@ -2247,14 +2287,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"Dpad гол"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"Автомат товшилтын төрлийн тохиргооны түр зуурын самбар"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"Зүүн талыг товших"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"Баруун талыг товших"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"2 товших"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"Чирэх"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Гүйлгэх"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Түр зогсоох"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Байрлал"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>-г ХЯЗГААРЛАСАН сагс руу орууллаа"</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 0717eb9..03400f2 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"आपल्या महत्त्वाच्या मापनांविषयी सेन्सर डेटा अॅक्सेस करा"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"सूचना"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"सूचना दाखवा"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"विंडोमधील आशय पुन्हा मिळवा"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"तुम्ही वापरत असलेल्या विंडोमधील आशय तपासा."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"स्पर्श करून अन्वेषण सुरू करा"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"ॲपला तुमच्या फोटो संग्रहामध्ये सुधारणा करण्याची अनुमती देते."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"तुमच्या मीडिया संग्रहातून स्थाने वाचा"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"ॲपला तुमच्या मीडिया संग्रहामध्येील स्थाने वाचण्यासाठी अनुमती देते."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"बायोमेट्रिक वापरा"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"बायोमेट्रिक किंवा स्क्रीन लॉक वापरा"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"हे तुम्हीच आहात याची पडताळणी करा"</string>
@@ -1344,13 +1384,13 @@
<string name="volume_call" msgid="7625321655265747433">"कॉल-मधील व्हॉल्यूम"</string>
<string name="volume_bluetooth_call" msgid="2930204618610115061">"ब्लूटूथ कॉल-मधील व्हॉल्यूम"</string>
<string name="volume_alarm" msgid="4486241060751798448">"अलार्म व्हॉल्यूम"</string>
- <string name="volume_notification" msgid="6864412249031660057">"सूचना व्हॉल्यूम"</string>
+ <string name="volume_notification" msgid="6864412249031660057">"नोटिफिकेशन व्हॉल्यूम"</string>
<string name="volume_unknown" msgid="4041914008166576293">"व्हॉल्यूम"</string>
<string name="volume_icon_description_bluetooth" msgid="7540388479345558400">"ब्लूटूथ व्हॉल्यूम"</string>
<string name="volume_icon_description_ringer" msgid="2187800636867423459">"रिंगटोन व्हॉल्यूम"</string>
<string name="volume_icon_description_incall" msgid="4491255105381227919">"कॉल व्हॉल्यूम"</string>
<string name="volume_icon_description_media" msgid="4997633254078171233">"मीडिया व्हॉल्यूम"</string>
- <string name="volume_icon_description_notification" msgid="579091344110747279">"सूचना व्हॉल्यूम"</string>
+ <string name="volume_icon_description_notification" msgid="579091344110747279">"नोटिफिकेशन व्हॉल्यूम"</string>
<string name="ringtone_default" msgid="9118299121288174597">"डीफॉल्ट रिंगटोन"</string>
<string name="ringtone_default_with_actual" msgid="2709686194556159773">"डीफॉल्ट (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="397111123930141876">"काहीही नाही"</string>
@@ -2228,7 +2268,7 @@
<string name="accessibility_system_action_home_label" msgid="3234748160850301870">"होम"</string>
<string name="accessibility_system_action_back_label" msgid="4205361367345537608">"मागे जा"</string>
<string name="accessibility_system_action_recents_label" msgid="4782875610281649728">"अलीकडील ॲप्स"</string>
- <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"सूचना"</string>
+ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"नोटिफिकेशन"</string>
<string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"क्विक सेटिंग्ज"</string>
<string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"पॉवर डायलॉग"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"स्क्रीन लॉक करा"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 5cac65d..889324c 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"akses data penderia tentang tanda vital anda"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Pemberitahuan"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"tunjukkan pemberitahuan"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Dapatkan kembali kandungan tetingkap"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Periksa kandungan tetingkap yang berinteraksi dengan anda."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Hidupkan Teroka melalui Sentuhan"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Membenarkan apl mengubah suai koleksi foto anda."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"baca lokasi daripada koleksi media anda"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Membenarkan apl membaca lokasi daripada koleksi media anda."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Gunakan biometrik"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Gunakan biometrik atau kunci skrin"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Sahkan diri anda"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 10bcd1b..67f0841 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"သင်၏အရေးကြီးသော ကျန်းမာရေးလက္ခဏာဆိုင်ရာ အာရုံခံကိရိယာဒေတာကို ရယူရန်"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"အကြောင်းကြားချက်များ"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"အကြောင်းကြားချက်များ ပြနိုင်သည်"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"ဝင်းဒိုးတွင် ပါရှိသည်များကို ပြန်လည်ရယူရန်"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"သင်အသုံးပြုနေသော ဝင်းဒိုးတွင် ပါရှိသည်များကို ကြည့်ရှုစစ်ဆေးသည်။"</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"တို့ထိခြင်းဖြင့် ရှာဖွေမှုကို ဖွင့်ရန်"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"အက်ပ်အား သင့်ဓာတ်ပုံစုစည်းမှုကို ပြုပြင်ခွင့်ပေးသည်။"</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"သင့်မီဒီယာစုစည်းမှုမှ တည်နေရာများကို ဖတ်ခြင်း"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"အက်ပ်အား သင့်မီဒီယာစုစည်းမှုမှ တည်နေရာများကို ဖတ်ခွင့်ပေးသည်။"</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"ဇီဝမက်ထရစ်အချက်အလက်များ သုံးခြင်း"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"ဇီဝမက်ထရစ်အချက်အလက်များ (သို့) ဖန်သားပြင်လော့ခ်ချခြင်းကို သုံးခြင်း"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"သင်ဖြစ်ကြောင်း အတည်ပြုပါ"</string>
@@ -2247,14 +2287,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"Dpad အလယ်"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"အော်တိုနှိပ်ခြင်း အမျိုးအစား ဆက်တင်အကန့်"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"ဘယ်ကလစ်"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"ညာဘက်ခလုတ်ကို နှိပ်ရန်"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"နှစ်ချက်နှိပ်ရန်"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"ဖိဆွဲရန်"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"လှိမ့်ရန်"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"ခဏရပ်ရန်"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"နေရာ"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ကို တားမြစ်ထားသော သိမ်းဆည်းမှုအတွင်းသို့ ထည့်ပြီးပါပြီ"</string>
@@ -2518,7 +2554,7 @@
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"စနစ်ထည့်သွင်းရန်"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"ယခုမလုပ်ပါ"</string>
<string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> အတွက် နှိုးစက်"</string>
- <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"အသုံးပြုသူ ပြောင်းရန်"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"အသုံးပြုသူပြောင်းရန်"</string>
<string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"အသံပိတ်ရန်"</string>
<string name="bg_user_sound_notification_message" msgid="8613881975316976673">"အသံပိတ်ရန် တို့ပါ"</string>
<string name="keyboard_shortcut_group_applications_browser" msgid="6535007304687100909">"ဘရောင်ဇာ"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 800f118..44458ba 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"få tilgang til sensordata om de vitale tegnene dine"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Varsler"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"vise varsler"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"hente innhold i vinduer"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Appen analyserer innholdet i vinduer du samhandler med."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"slå på berøringsutforsking"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Lar appen gjøre endringer i bildesamlingen din."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"lese posisjoner fra mediesamlingen din"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Lar appen lese posisjoner fra mediesamlingen din."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Bruk biometri"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Bruk biometri eller skjermlås"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Bekreft at det er deg"</string>
@@ -2247,14 +2287,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"Midt på styrepilene"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"Innstillingspanel for type autoklikk"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"Venstreklikk"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"Høyreklikk"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"Dobbeltklikk"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"Dra"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Rull"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Sett på pause"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Plassér"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> er blitt plassert i TILGANGSBEGRENSET-toppmappen"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index ce0c67e..2591a15 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"तपाईंको महत्त्वपूर्ण संकेत बारे सेन्सर डेटा पहुँच गर्नुहोस्"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"नोटिफिकेसनहरू"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"सूचनाहरू देखाउनुहोस्"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"विन्डो सामग्रीको पुनःबहाली गर्नुहोस्।"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"तपाईँको अन्तरक्रिया भइरहेको विन्डोको सामग्रीको निरीक्षण गर्नुहोस्।"</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"छोएर गरिने खोजलाई सुचारु गर्नुहोस्"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"यसले एपलाई तपाईंको तस्बिरको सङ्ग्रह परिमार्जन गर्न दिन्छ।"</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"आफ्नो मिडियाको सङ्ग्रहका स्थानहरू पढ्नुहोस्"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"यसले एपलाई तपाईंको मिडिया सङ्ग्रहका स्थानहरू पढ्न दिन्छ।"</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"बायोमेट्रिक्स प्रयोग गर्नुहोस्"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"बायोमेट्रिक्स वा स्क्रिन लक प्रयोग गर्नुहोस्"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"यो व्यक्ति तपाईं नै हो भन्ने प्रमाणित गर्नुहोस्"</string>
@@ -1344,13 +1384,13 @@
<string name="volume_call" msgid="7625321655265747433">"इन-कल भोल्युम"</string>
<string name="volume_bluetooth_call" msgid="2930204618610115061">"ब्लुटुथ भित्री-कल मात्रा"</string>
<string name="volume_alarm" msgid="4486241060751798448">"आलर्मको भोल्युम"</string>
- <string name="volume_notification" msgid="6864412249031660057">"सूचनाको भोल्युम"</string>
+ <string name="volume_notification" msgid="6864412249031660057">"नोटिफिकेसनको भोल्युम"</string>
<string name="volume_unknown" msgid="4041914008166576293">"मात्रा"</string>
<string name="volume_icon_description_bluetooth" msgid="7540388479345558400">"ब्लुटुथ भोल्युम"</string>
<string name="volume_icon_description_ringer" msgid="2187800636867423459">"घन्टिको आवाज मात्रा"</string>
<string name="volume_icon_description_incall" msgid="4491255105381227919">"कला मात्रा"</string>
<string name="volume_icon_description_media" msgid="4997633254078171233">"मिडियाको भोल्युम"</string>
- <string name="volume_icon_description_notification" msgid="579091344110747279">"सूचनाको भोल्युम"</string>
+ <string name="volume_icon_description_notification" msgid="579091344110747279">"नोटिफिकेसनको भोल्युम"</string>
<string name="ringtone_default" msgid="9118299121288174597">"डिफल्ट रिङटोन"</string>
<string name="ringtone_default_with_actual" msgid="2709686194556159773">"डिफल्ट (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="397111123930141876">"कुनै पनि होइन"</string>
@@ -2088,12 +2128,9 @@
<string name="unpin_target" msgid="3963318576590204447">"अनपिन गर्नुहोस्"</string>
<string name="unpin_specific_target" msgid="3859828252160908146">"<xliff:g id="LABEL">%1$s</xliff:g> लाई अनपिन गर्नुहोस्"</string>
<string name="app_info" msgid="6113278084877079851">"एपका बारे जानकारी"</string>
- <!-- no translation found for shortcut_group_a11y_title (2992150163811583865) -->
- <skip />
- <!-- no translation found for suggested_apps_group_a11y_title (2804876567839501831) -->
- <skip />
- <!-- no translation found for all_apps_group_a11y_title (7020352520224108745) -->
- <skip />
+ <string name="shortcut_group_a11y_title" msgid="2992150163811583865">"सामग्री सीधै सेयर गर्नका निम्ति चयन गरिएका व्यक्ति वा समूहहरू"</string>
+ <string name="suggested_apps_group_a11y_title" msgid="2804876567839501831">"सिफारिस गरिएका एपहरू"</string>
+ <string name="all_apps_group_a11y_title" msgid="7020352520224108745">"एपहरूको सूची"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"डेमो सुरु गर्दै…"</string>
<string name="demo_restarting_message" msgid="1160053183701746766">"यन्त्रलाई रिसेट गर्दै…"</string>
@@ -2250,14 +2287,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"Dpad को बिचको बटन"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"अटोक्लिकको प्रकारसम्बन्धी सेटिङको प्यानल"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"बायाँ क्लिक गर्नुहोस्"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"राइट क्लिक गर्नुहोस्"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"डबल क्लिक गर्नुहोस्"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"ड्र्याग गर्नुहोस्"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"स्क्रोल गर्नुहोस्"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"पज गर्नुहोस्"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"स्थिति"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> लाई प्रतिबन्धित बाल्टीमा राखियो"</string>
@@ -2534,12 +2567,8 @@
<string name="keyboard_shortcut_group_applications_maps" msgid="7950000659522589471">"नक्सा"</string>
<string name="keyboard_shortcut_group_applications" msgid="3010389163951364798">"एपहरू"</string>
<string name="fingerprint_loe_notification_msg" msgid="3927447270148854546">"तपाईंको फिंगरप्रिन्ट अब पहिचान गर्न सकिँदैन। फिंगरप्रिन्ट अनलक फेरि सेटअप गर्नुहोस्।"</string>
- <!-- no translation found for usb_apm_usb_plugged_in_when_locked_notification_title (468577168569874967) -->
- <skip />
- <!-- no translation found for usb_apm_usb_plugged_in_when_locked_notification_text (6695268246267993166) -->
- <skip />
- <!-- no translation found for usb_apm_usb_suspicious_activity_notification_title (3461195995882871461) -->
- <skip />
- <!-- no translation found for usb_apm_usb_suspicious_activity_notification_text (6537085605929303187) -->
- <skip />
+ <string name="usb_apm_usb_plugged_in_when_locked_notification_title" msgid="468577168569874967">"लक भएपछि USB डिभाइस घुसाइएको छ"</string>
+ <string name="usb_apm_usb_plugged_in_when_locked_notification_text" msgid="6695268246267993166">"Android लक भएपछि USB डिभाइस घुसाइएको छ। USB डिभाइस प्रयोग गर्न कृपया सुरुमा Android अनलक गर्नुहोस् र त्यसपछि USB डिभाइस फेरि घुसाउनुहोस्।"</string>
+ <string name="usb_apm_usb_suspicious_activity_notification_title" msgid="3461195995882871461">"USB सम्बन्धी शङ्कास्पद गतिविधि"</string>
+ <string name="usb_apm_usb_suspicious_activity_notification_text" msgid="6537085605929303187">"USB डेटा सिग्नल अफ गरिएको छ।"</string>
</resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 3466641..bbdc1bb 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"toegang krijgen tot sensorgegevens over je vitale functies"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Meldingen"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"meldingen tonen"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Content van vensters ophalen"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"De content inspecteren van een venster waarmee je interactie hebt."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Verkennen via aanraking aanzetten"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Hiermee sta je de app toe je fotocollectie aan te passen."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"locaties van je mediacollecties bekijken"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Hiermee sta je de app toe locaties van je mediacollectie te bekijken."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Biometrische gegevens gebruiken"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Biometrische gegevens of schermvergrendeling gebruiken"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Je identiteit bevestigen"</string>
@@ -1409,7 +1449,7 @@
<string name="carrier_app_notification_title" msgid="5815477368072060250">"Nieuwe simkaart geplaatst"</string>
<string name="carrier_app_notification_text" msgid="6567057546341958637">"Tik om dit in te stellen"</string>
<string name="time_zone_change_notification_title" msgid="5232503069219193218">"Je tijdzone is gewijzigd"</string>
- <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Je bent nu in <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string>
+ <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Je tijdzone is <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string>
<string name="time_picker_dialog_title" msgid="9053376764985220821">"Tijd instellen"</string>
<string name="date_picker_dialog_title" msgid="5030520449243071926">"Datum instellen"</string>
<string name="date_time_set" msgid="4603445265164486816">"Instellen"</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index 418231f..a1b24eb 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"ଆପଣଙ୍କ ଗୁରୁତପୂର୍ଣ୍ଣ ସଂକେତଗୁଡ଼ିକ ବିଷୟରେ ସେନ୍ସର୍ ଡାଟା ଆକ୍ସେସ୍ କରେ"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ଦେଖାନ୍ତୁ"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"ୱିଣ୍ଡୋ କଣ୍ଟେଣ୍ଟ ହାସଲ କରନ୍ତୁ"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"ଆପଣ କାମ କରୁଥିବା ୱିଣ୍ଡୋର କଣ୍ଟେଣ୍ଟକୁ ଯାଞ୍ଚ କରନ୍ତୁ।"</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"ସ୍ପର୍ଶ ଦ୍ୱାରା ଏକ୍ସପ୍ଲୋର୍ ଅନ୍ କରନ୍ତୁ"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"ଆପଣଙ୍କ ଫଟୋ ସଂଗ୍ରହ ପରିବର୍ତ୍ତନ କରିବାକୁ ଆପ୍ ଅନୁମତି ଦେଇଥାଏ।"</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"ଆପଣଙ୍କ ମିଡିଆ ସଂଗ୍ରହ ଠାରୁ ଲୋକେସନ୍ଗୁଡିକୁ ପଢନ୍ତୁ"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"ଆପଣଙ୍କ ମିଡିଆ ସଂଗ୍ରହ ଠାରୁ ଅବସ୍ଥାନଗୁଡିକୁ ପଢିବାକୁ ଆପ୍ ଅନୁମତି ଦେଇଥାଏ।"</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"ବାୟୋମେଟ୍ରିକ୍ସ ବ୍ୟବହାର କରନ୍ତୁ"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"ବାୟୋମେଟ୍ରିକ୍ସ ବା ସ୍କ୍ରିନ୍ ଲକ୍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"ଏହା ଆପଣ ବୋଲି ଯାଞ୍ଚ କରନ୍ତୁ"</string>
@@ -1572,7 +1612,7 @@
<string name="vpn_lockdown_config" msgid="8331697329868252169">"ନେଟ୍ୱର୍କ କିମ୍ବା VPN ସେଟିଙ୍ଗ ବଦଳାନ୍ତୁ"</string>
<string name="upload_file" msgid="8651942222301634271">"ଫାଇଲ୍ ଚୟନ କରନ୍ତୁ"</string>
<string name="no_file_chosen" msgid="4146295695162318057">"କୌଣସି ଫାଇଲ୍ ଚୟନ କରାଯାଇନାହିଁ"</string>
- <string name="reset" msgid="3865826612628171429">"ରିସେଟ୍ କରନ୍ତୁ"</string>
+ <string name="reset" msgid="3865826612628171429">"ରିସେଟ କରନ୍ତୁ"</string>
<string name="submit" msgid="862795280643405865">"ଦାଖଲ କରନ୍ତୁ"</string>
<string name="car_mode_disable_notification_title" msgid="8450693275833142896">"ଡ୍ରାଇଭିଙ୍ଗ ଆପ୍ ଚାଲୁଛି"</string>
<string name="car_mode_disable_notification_message" msgid="8954550232288567515">"ଡ୍ରାଇଭିଙ୍ଗ ଆପ୍ରୁ ବାହାରିବା ପାଇଁ ଟାପ୍ କରନ୍ତୁ।"</string>
@@ -2247,14 +2287,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"Dpad କେନ୍ଦ୍ର"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"ଅଟୋକ୍ଲିକ ପ୍ରକାର ସେଟିଂସ ପେନେଲ"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"ବାମ ବଟନ କ୍ଲିକ କରନ୍ତୁ"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"ଡାହାଣ କ୍ଲିକ କରନ୍ତୁ"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"ଦୁଇ ଥର କ୍ଲିକ କରନ୍ତୁ"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"ଡ୍ରାଗ କରନ୍ତୁ"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"ସ୍କ୍ରୋଲ କରନ୍ତୁ"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"ବିରତ କରନ୍ତୁ"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"ସ୍ଥିତି"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>କୁ ପ୍ରତିବନ୍ଧିତ ବକେଟରେ ରଖାଯାଇଛି"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 26769a6..70dcd66 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"ਆਪਣੇ ਸਰੀਰ ਦੇ ਅਹਿਮ ਚਿੰਨ੍ਹਾਂ ਬਾਰੇ ਸੰਵੇਦਕ ਡਾਟਾ ਤੱਕ ਪਹੁੰਚ ਕਰਨ"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"ਸੂਚਨਾਵਾਂ"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"ਸੂਚਨਾਵਾਂ ਦਿਖਾਓ"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"ਵਿੰਡੋ ਸਮੱਗਰੀ ਮੁੜ-ਪ੍ਰਾਪਤ ਕਰਨਾ"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"ਉਸ ਵਿੰਡੋ ਸਮੱਗਰੀ ਦੀ ਜਾਂਚ ਕਰੋ, ਜਿਸ ਨਾਲ ਤੁਸੀਂ ਅੰਤਰਕਿਰਿਆ ਕਰ ਰਹੇ ਹੋ"</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"\'ਸਪੱਰਸ਼ ਰਾਹੀਂ ਪੜਚੋਲ ਕਰੋ\' ਚਾਲੂ ਕਰਨਾ"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ ਫ਼ੋਟੋ ਸੰਗ੍ਰਹਿ ਨੂੰ ਸੋਧਣ ਦਿੰਦੀ ਹੈ।"</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"ਤੁਹਾਡੇ ਮੀਡੀਆ ਸੰਗ੍ਰਹਿ ਦੇ ਟਿਕਾਣਿਆਂ ਨੂੰ ਪੜ੍ਹਨਾ"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ ਮੀਡੀਆ ਸੰਗ੍ਰਹਿ ਦੇ ਟਿਕਾਣਿਆਂ ਨੂੰ ਪੜ੍ਹਨ ਦਿੰਦੀ ਹੈ।"</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"ਬਾਇਓਮੈਟ੍ਰਿਕ ਦੀ ਵਰਤੋਂ ਕਰੋ"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"ਬਾਇਓਮੈਟ੍ਰਿਕ ਜਾਂ ਸਕ੍ਰੀਨ ਲਾਕ ਦੀ ਵਰਤੋਂ ਕਰੋ"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"ਆਪਣੀ ਪਛਾਣ ਦੀ ਪੁਸ਼ਟੀ ਕਰੋ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index e091700..c92c2bb 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -355,6 +355,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"dostęp do danych czujnika podstawowych funkcji życiowych"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Powiadomienia"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"pokazuj powiadomienia"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Pobieranie zawartości okna"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Sprawdzanie zawartości okna, z którego korzystasz."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Włączenie czytania dotykiem"</string>
@@ -650,6 +658,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Zezwala aplikacji na modyfikowanie kolekcji zdjęć."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"odczytywanie lokalizacji z kolekcji multimediów"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Zezwala aplikacji na odczytywanie lokalizacji z kolekcji multimediów."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Używaj biometrii"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Używaj biometrii lub blokady ekranu"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Potwierdź, że to Ty"</string>
@@ -1411,7 +1451,7 @@
<string name="carrier_app_notification_title" msgid="5815477368072060250">"Włożono nową kartę SIM"</string>
<string name="carrier_app_notification_text" msgid="6567057546341958637">"Kliknij, by skonfigurować"</string>
<string name="time_zone_change_notification_title" msgid="5232503069219193218">"Zmieniła się Twoja strefa czasowa"</string>
- <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Jesteś teraz w strefie <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string>
+ <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Twoja aktualna strefa to <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string>
<string name="time_picker_dialog_title" msgid="9053376764985220821">"Ustaw godzinę"</string>
<string name="date_picker_dialog_title" msgid="5030520449243071926">"Ustaw datę"</string>
<string name="date_time_set" msgid="4603445265164486816">"Ustaw"</string>
@@ -2249,14 +2289,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"Dpad – środek"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"Panel ustawień typu automatycznego kliknięcia"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"Kliknięcie lewym przyciskiem"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"Kliknięcie prawym przyciskiem"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"Dwukrotne kliknięcie"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"Przeciąganie"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Przewijanie"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Wstrzymaj"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Pozycja"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Umieszczono pakiet <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> w zasobniku danych RESTRICTED"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 06b43cb..99c4375 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -354,6 +354,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"acesse dados do sensor sobre seus sinais vitais"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Notificações"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"mostrar notificações"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Acessar conteúdo de uma janela"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Inspeciona o conteúdo de uma janela com a qual você está interagindo."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Ativar Explorar por toque"</string>
@@ -649,6 +657,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Permite que o app modifique sua coleção de fotos."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"ler locais na sua coleção de mídias"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Permite que o app leia os locais na sua coleção de mídias."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Usar biometria"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Usar biometria ou bloqueio de tela"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Confirme que é você"</string>
@@ -1970,7 +2010,7 @@
<string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="8009920446193610996">"Recolher"</string>
<string name="zen_mode_feature_name" msgid="3785547207263754500">"Não perturbe"</string>
- <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Tempo de inatividade"</string>
+ <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Intervalo"</string>
<string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Durante a semana à noite"</string>
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Fim de semana"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Evento"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index f48c326..a453546 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -354,6 +354,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"aceder a dados do sensor acerca dos seus sinais vitais"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Notificações"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"mostrar notificações"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Obter conteúdo da janela"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Inspecionar o conteúdo de uma janela com a qual está a interagir."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Ativar Explorar Através do Toque"</string>
@@ -649,6 +657,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Permite que a app modifique a sua coleção de fotos."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"ler as localizações a partir da sua coleção de multimédia"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Permite que a app leia as localizações a partir da sua coleção de multimédia."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Usar a biometria"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Usar a biometria ou o bloqueio de ecrã"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Confirme a sua identidade"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 06b43cb..99c4375 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -354,6 +354,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"acesse dados do sensor sobre seus sinais vitais"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Notificações"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"mostrar notificações"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Acessar conteúdo de uma janela"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Inspeciona o conteúdo de uma janela com a qual você está interagindo."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Ativar Explorar por toque"</string>
@@ -649,6 +657,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Permite que o app modifique sua coleção de fotos."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"ler locais na sua coleção de mídias"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Permite que o app leia os locais na sua coleção de mídias."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Usar biometria"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Usar biometria ou bloqueio de tela"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Confirme que é você"</string>
@@ -1970,7 +2010,7 @@
<string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="8009920446193610996">"Recolher"</string>
<string name="zen_mode_feature_name" msgid="3785547207263754500">"Não perturbe"</string>
- <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Tempo de inatividade"</string>
+ <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Intervalo"</string>
<string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Durante a semana à noite"</string>
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Fim de semana"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Evento"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 73f532a..28728b5 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -354,6 +354,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"să acceseze datele de la senzori despre semnele vitale"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Notificări"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"să afișeze notificări"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"să preia conținutul ferestrei"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Inspectează conținutul unei ferestre cu care interacționezi."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"să activeze funcția Explorează prin atingere"</string>
@@ -649,6 +657,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Permite aplicației să-ți modifice colecția de fotografii."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"să citească locațiile din colecția media"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Permite aplicației să citească locațiile din colecția ta media."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Folosește sistemele biometrice"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Folosește sistemele biometrice sau blocarea ecranului"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Confirmă-ți identitatea"</string>
@@ -2248,14 +2288,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"Dpad centru"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"Panoul de setări pentru clicul automat"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"Clic stânga"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"Clic dreapta"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"Dublu clic"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"Trage"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Derulează"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Întrerupe"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Poziție"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> a fost adăugat la grupul RESTRICȚIONATE"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index e0e0807..f587a73 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -355,6 +355,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"доступ к данным датчиков о состоянии организма"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Уведомления"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"показ уведомлений"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Получать содержимое окна"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Анализировать содержимое активного окна."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Включать Изучение касанием"</string>
@@ -650,6 +658,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Приложение сможет вносить изменения в вашу фотоколлекцию."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"Доступ к геоданным в медиаколлекции"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Приложение получит доступ к геоданным в вашей медиаколлекции."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Использовать биометрию"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Использовать биометрию или блокировку экрана"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Подтвердите, что это вы"</string>
@@ -1014,7 +1054,7 @@
<string name="lockscreen_password_wrong" msgid="8605355913868947490">"Повторите попытку"</string>
<string name="lockscreen_storage_locked" msgid="634993789186443380">"Разблок. для доступа ко всем функциям и данным"</string>
<string name="faceunlock_multiple_failures" msgid="681991538434031708">"Все попытки войти с помощью фейсконтроля использованы"</string>
- <string name="lockscreen_missing_sim_message_short" msgid="1229301273156907613">"SIM-карта отсутствует"</string>
+ <string name="lockscreen_missing_sim_message_short" msgid="1229301273156907613">"Нет SIM-карты"</string>
<string name="lockscreen_missing_sim_message" product="tablet" msgid="3986843848305639161">"В планшете отсутствует SIM-карта."</string>
<string name="lockscreen_missing_sim_message" product="tv" msgid="3903140876952198273">"В устройстве Android TV отсутствует SIM-карта."</string>
<string name="lockscreen_missing_sim_message" product="default" msgid="6184187634180854181">"В телефоне отсутствует SIM-карта."</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index 45dd5df..f30a483 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"ඔබේ ජෛව ලක්ෂණ පිළිබඳ සංවේදක දත්ත වෙත පිවිසෙන්න"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"දැනුම්දීම්"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"දැනුම්දීම් පෙන්වන්න"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"කවුළු අන්න්තර්ගතය ලබාගන්න"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"ඔබ අන්තර්ක්රියාකාරී වන කවුළුවේ අන්තර්ගතය පරීක්ෂා කරන්න."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"ස්පර්ශයෙන් ගවේෂණය සක්රිය කරන්න"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"ඔබගේ ඡායාරූප එකතුව වෙනස් කිරීමට යෙදුමට ඉඩ දෙයි."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"ඔබගේ මාධ්ය එකතුවෙන් ස්ථාන කියවන්න"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"ඔබගේ මාධ්ය එකතුවෙන් ස්ථාන කියවීමට යෙදුමට ඉඩ දෙයි."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"ජෛවමිතික භාවිත කරන්න"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"ජෛවමිතික හෝ තිර අගුල භාවිත කරන්න"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"එය ඔබ බව තහවුරු කරන්න"</string>
@@ -2088,12 +2128,9 @@
<string name="unpin_target" msgid="3963318576590204447">"ගලවන්න"</string>
<string name="unpin_specific_target" msgid="3859828252160908146">"<xliff:g id="LABEL">%1$s</xliff:g> ඇමුණුම ඉවත් කරන්න"</string>
<string name="app_info" msgid="6113278084877079851">"යෙදුම් තොරතුරු"</string>
- <!-- no translation found for shortcut_group_a11y_title (2992150163811583865) -->
- <skip />
- <!-- no translation found for suggested_apps_group_a11y_title (2804876567839501831) -->
- <skip />
- <!-- no translation found for all_apps_group_a11y_title (7020352520224108745) -->
- <skip />
+ <string name="shortcut_group_a11y_title" msgid="2992150163811583865">"සෘජු බෙදා ගැනීමේ ඉලක්ක"</string>
+ <string name="suggested_apps_group_a11y_title" msgid="2804876567839501831">"යෙදුම් යෝජනා"</string>
+ <string name="all_apps_group_a11y_title" msgid="7020352520224108745">"යෙදුම් ලැයිස්තුව"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"ආදර්ශනය ආරම්භ කරමින්..."</string>
<string name="demo_restarting_message" msgid="1160053183701746766">"උපාංගය යළි සකසමින්..."</string>
@@ -2250,14 +2287,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"Dpad මැද"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"ස්වයං ක්ලික් ආකාර සැකසීම් පැනලය"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"වම්පස ක්ලිකය"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"දකුණු ක්ලිකය"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"දෙවරක් ක්ලික් කරන්න"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"අදින්න"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"අනුචලනය කරන්න"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"විරාම කරන්න"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"ස්ථානය"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> අවහිර කළ බාල්දියට දමා ඇත"</string>
@@ -2534,12 +2567,8 @@
<string name="keyboard_shortcut_group_applications_maps" msgid="7950000659522589471">"සිතියම්"</string>
<string name="keyboard_shortcut_group_applications" msgid="3010389163951364798">"යෙදුම්"</string>
<string name="fingerprint_loe_notification_msg" msgid="3927447270148854546">"ඔබේ ඇඟිලි සලකුණු තවදුරටත් හඳුනාගත නොහැක. ඇඟිලි සලකුණු අගුළු හැරීම නැවත පිහිටුවන්න."</string>
- <!-- no translation found for usb_apm_usb_plugged_in_when_locked_notification_title (468577168569874967) -->
- <skip />
- <!-- no translation found for usb_apm_usb_plugged_in_when_locked_notification_text (6695268246267993166) -->
- <skip />
- <!-- no translation found for usb_apm_usb_suspicious_activity_notification_title (3461195995882871461) -->
- <skip />
- <!-- no translation found for usb_apm_usb_suspicious_activity_notification_text (6537085605929303187) -->
- <skip />
+ <string name="usb_apm_usb_plugged_in_when_locked_notification_title" msgid="468577168569874967">"අගුළු දමා ඇති විට USB උපාංගය පේනුගත කර ඇත"</string>
+ <string name="usb_apm_usb_plugged_in_when_locked_notification_text" msgid="6695268246267993166">"Android අගුළු දමා ඇති විට USB උපාංගය පේනුගත කර ඇත. උපාංගය භාවිතා කිරීමට, පළමුව Android අගුළු හැර, පසුව එය භාවිතා කිරීමට USB උපාංගය නැවත ඇතුළු කරන්න."</string>
+ <string name="usb_apm_usb_suspicious_activity_notification_title" msgid="3461195995882871461">"සැක සහිත USB ක්රියාකාරකම"</string>
+ <string name="usb_apm_usb_suspicious_activity_notification_text" msgid="6537085605929303187">"USB දත්ත සංඥාව අබල කර ඇත."</string>
</resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index d675978..49600ce 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -355,6 +355,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"prístup k dátam senzorov vašich životných funkcií"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Upozornenia"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"zobrazovať upozornenia"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Načítať obsah okna"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Môžete preskúmať obsah okna, s ktorým pracujete."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Zapnúť funkciu Preskúmanie dotykom"</string>
@@ -650,6 +658,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Umožňuje aplikácii upravovať zbierku fotiek."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"čítať polohy zo zbierky médií"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Umožňuje aplikácii čítať polohy zo zbierky médií."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Použiť biometrické údaje"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Použiť biometrické údaje alebo zámku obrazovky"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Potvrďte, že ste to vy"</string>
@@ -1433,8 +1473,8 @@
<string name="usb_power_notification_message" msgid="7284765627437897702">"Pripojené zariadenie sa nabíja. Ďalšie možností získate klepnutím."</string>
<string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"Bolo zistené analógové zvukové príslušenstvo"</string>
<string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"Pripojené zariadenie nie je kompatibilné s týmto telefónom. Ďalšie informácie zobrazíte klepnutím."</string>
- <string name="adb_active_notification_title" msgid="408390247354560331">"Ladenie cez USB je pripojené"</string>
- <string name="adb_active_notification_message" msgid="5617264033476778211">"Klepnutím vypnite ladenie cez USB"</string>
+ <string name="adb_active_notification_title" msgid="408390247354560331">"Ladenie cez USB je zapnuté"</string>
+ <string name="adb_active_notification_message" msgid="5617264033476778211">"Klepnutím vypnete"</string>
<string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"Vyberte, ak chcete zakázať ladenie cez USB."</string>
<string name="adbwifi_active_notification_title" msgid="6147343659168302473">"Bezdrôtové ladenie je pripojené"</string>
<string name="adbwifi_active_notification_message" msgid="930987922852867972">"Klepnutím vypnete bezdrôtové ladenie"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 0136f5f8..c8dc4ee 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -355,6 +355,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"dostop do podatkov tipala o vaših vitalnih znakih"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Obvestila"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"prikaz obvestil"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Pridobiti vsebino okna"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Preverjanje vsebine okna, ki ga uporabljate."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Vklopiti raziskovanje z dotikom"</string>
@@ -650,6 +658,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Aplikaciji omogoča spreminjanje zbirke fotografij."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"branje lokacij v predstavnostni zbirki"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Aplikaciji omogoča branje lokacij v predstavnostni zbirki."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Uporaba biometrike"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Uporaba biometrike ali odklepanja s poverilnico"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Potrdite, da ste res vi"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 37aa8bf..fa3eeae 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"qasu tek të dhënat e sensorëve rreth shenjave të tua jetësore"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Njoftimet"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"shfaq njoftimet"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Të nxjerrë përmbajtjen e dritares"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Inspekton përmbajtjen e dritares me të cilën po ndërvepron."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Të aktivizojë veçorinë \"Eksploro me prekje\""</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Lejon aplikacionin të modifikojë koleksionin tënd të fotografive."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"lexo vendndodhjet nga koleksioni yt i medias"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Lejon aplikacionin të lexojë vendndodhjet nga koleksioni yt i medias."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Përdor sistemet biometrike"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Përdor sistemet biometrike ose kyçjen e ekranit"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Verifiko që je ti"</string>
@@ -2247,14 +2287,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"Qendra e bllokut të drejtimit"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"Paneli i cilësimeve për llojin e klikimit automatik"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"Klikimi majtas"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"Kliko djathtas"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"Kliko dy herë"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"Zvarrit"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Lëviz"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Vendos në pauzë"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Pozicioni"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> është vendosur në grupin E KUFIZUAR"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index a4f0e55..5481023 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -354,6 +354,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"приступа подацима сензора о виталним функцијама"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Обавештења"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"приказивање обавештења"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"да преузима садржај прозора"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Проверава садржај прозора са којим остварујете интеракцију."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"да укључи Истраживања додиром"</string>
@@ -649,6 +657,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Дозвољава апликацији да мења колекцију слика."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"читање локација из медијске колекције"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Дозвољава апликацији да чита локације из медијске колекције."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Користите биометрију"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Користите биометрију или откључавање екрана"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Потврдите идентитет"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index e56097f..38634d5 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"få åtkomst till sensordata om dina vitalparametrar"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Aviseringar"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"visa aviseringar"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Hämta fönsterinnehåll"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Granska innehållet i ett fönster som du interagerar med."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Aktivera Explore by touch"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Tillåter att appen gör ändringar i din fotosamling."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"läsa av platser i din mediesamling"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Tillåter att appen läser av platser i din mediesamling."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Använd biometri"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Använd biometrisk data eller skärmlåset"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Verifiera din identitet"</string>
@@ -2247,14 +2287,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"Styrkors, mitten"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"Inställningspanel för typ av automatiskt klick"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"Vänsterklick"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"Högerklicka"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"Dubbelklicka"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"Trycka och dra"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Scrolla"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pausa"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Position"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> har placerats i hinken RESTRICTED"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 03a581a..b6eab89 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"fikia data ya kitambuzi kuhusu alama zako muhimu"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Arifa"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"kuonyesha arifa"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Kufikia maudhui ya dirisha"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Kuchunguza maudhui ya dirisha unalotumia."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Kuwasha \'Chunguza kwa Kugusa\'"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Inaruhusu programu kubadilisha mkusanyiko wa picha zako."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"kusoma maeneo kwenye mkusanyiko wa vipengee vyako"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Inaruhusu programu kusoma maeneo kwenye mkusanyiko wa vipengee vyako."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Tumia bayometriki"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Tumia bayometriki au mbinu ya kufunga skrini"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Thibitisha kuwa ni wewe"</string>
@@ -1409,7 +1449,7 @@
<string name="carrier_app_notification_title" msgid="5815477368072060250">"SIM mpya imewekwa"</string>
<string name="carrier_app_notification_text" msgid="6567057546341958637">"Gusa ili uiweke"</string>
<string name="time_zone_change_notification_title" msgid="5232503069219193218">"Saa za eneo lako zimebadilika"</string>
- <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Sasa unatumia saa za eneo za <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string>
+ <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Sasa unatumia <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string>
<string name="time_picker_dialog_title" msgid="9053376764985220821">"Weka saa"</string>
<string name="date_picker_dialog_title" msgid="5030520449243071926">"Weka tarehe"</string>
<string name="date_time_set" msgid="4603445265164486816">"Weka"</string>
@@ -2247,14 +2287,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"Kitufe cha katikati cha Dpad"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"Kidirisha cha mipangilio ya aina ya kubofya kiotomatiki"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"Bofya kushoto"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"Bofya kulia"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"Bofya mara mbili"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"Buruta"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Sogeza"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Sitisha"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Nafasi"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> kimewekwa katika kikundi KILICHODHIBITIWA"</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 16c021e..d48f4a2 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"உங்கள் உடல் இயக்கம் பற்றி உணர்விகள் கூறும் தகவலைப் பார்க்கலாம்"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"அறிவிப்புகள்"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"அறிவிப்புகளைக் காட்டும்"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"சாளர உள்ளடக்கத்தைப் பெறும்"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"நீங்கள் பணியாற்றிக் கொண்டிருக்கும் சாளரத்தின் உள்ளடக்கத்தைப் பார்க்கலாம்."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"தொடுவதன் மூலம் அறிவதை இயக்கும்"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"உங்களின் படத் தொகுப்பை மாற்ற ஆப்ஸை அனுமதிக்கும்."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"மீடியா தொகுப்பிலிருந்து இடங்களை அறிதல்"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"உங்களின் மீடியா தொகுப்பிலிருந்து இடங்களை அறிந்துகொள்ள ஆப்ஸை அனுமதிக்கும்."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"பயோமெட்ரிக்ஸைப் பயன்படுத்து"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"பயோமெட்ரிக்ஸையோ திரைப் பூட்டையோ பயன்படுத்து"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"நீங்கள்தான் என உறுதிசெய்க"</string>
@@ -2247,14 +2287,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"மையப் பகுதியைக் காட்டும் பட்டன்"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"ஆட்டோ கிளிக் வகை அமைப்புகள் பேனல்"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"இடது கிளிக்"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"வலது கிளிக் செய்யும்"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"இரு கிளிக் செய்யும்"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"இழுக்கும்"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"நகர்த்தும்"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"இடைநிறுத்து"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"நிலை"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> என்பதை வரம்பிடப்பட்ட பக்கெட்திற்குள் சேர்க்கப்பட்டது"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index c565618..84e56d2 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"మీ అత్యంత కీలకమైన గుర్తుల గురించి సెన్సార్ డేటాను యాక్సెస్ చేస్తుంది"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"నోటిఫికేషన్లు"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"నోటిఫికేషన్లను చూపండి"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"విండో కంటెంట్ను తిరిగి పొందుతుంది"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"మీరు పరస్పర చర్య చేస్తున్న విండో కంటెంట్ను పరిశీలిస్తుంది."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"తాకడం ద్వారా విశ్లేషణను ఆన్ చేయండి"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"మీ ఫోటో సేకరణను ఎడిట్ చేయడానికి యాప్ను అనుమతిస్తుంది."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"మీ మీడియా సేకరణ నుండి లొకేషన్లను చదవండి"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"మీ మీడియా సేకరణ నుండి లొకేషన్లను చదవడానికి యాప్ను అనుమతిస్తుంది."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"బయోమెట్రిక్స్ను ఉపయోగించండి"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"బయోమెట్రిక్స్ను లేదా స్క్రీన్ లాక్ను ఉపయోగించండి"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"ఈ చర్య చేస్తోంది మీరేనని వెరిఫై చేయండి"</string>
@@ -887,7 +927,7 @@
<item msgid="6216981255272016212">"అనుకూలం"</item>
</string-array>
<string-array name="emailAddressTypes">
- <item msgid="7786349763648997741">"ఇల్లు"</item>
+ <item msgid="7786349763648997741">"హోమ్"</item>
<item msgid="435564470865989199">"కార్యాలయం"</item>
<item msgid="4199433197875490373">"ఇతరం"</item>
<item msgid="3233938986670468328">"అనుకూలం"</item>
@@ -1153,7 +1193,7 @@
<string name="year" msgid="5182610307741238982">"సంవత్సరం"</string>
<string name="years" msgid="5797714729103773425">"సంవత్సరాలు"</string>
<string name="now_string_shortest" msgid="3684914126941650330">"ఇప్పుడు"</string>
- <string name="duration_minutes_shortest" msgid="5744379079540806690">"<xliff:g id="COUNT">%d</xliff:g>నిమిషం"</string>
+ <string name="duration_minutes_shortest" msgid="5744379079540806690">"<xliff:g id="COUNT">%d</xliff:g>ని"</string>
<string name="duration_hours_shortest" msgid="1477752094141971675">"<xliff:g id="COUNT">%d</xliff:g>గంట"</string>
<string name="duration_days_shortest" msgid="4083124701676227233">"<xliff:g id="COUNT">%d</xliff:g>రోజు"</string>
<string name="duration_years_shortest" msgid="483982719231145618">"<xliff:g id="COUNT">%d</xliff:g>సం"</string>
@@ -2020,7 +2060,7 @@
<string name="call_notification_screening_text" msgid="8396931408268940208">"ఇన్కమింగ్ కాల్ను స్క్రీన్ చేయండి"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"వర్గీకరించబడలేదు"</string>
<string name="promotional_notification_channel_label" msgid="7414844730492860233">"ప్రమోషన్లు"</string>
- <string name="social_notification_channel_label" msgid="106520267132019945">"సామాజికం"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"సోషల్ మీడియా"</string>
<string name="news_notification_channel_label" msgid="4299937455247883311">"వార్తలు"</string>
<string name="recs_notification_channel_label" msgid="4945985121418684297">"సిఫార్సులు"</string>
<string name="importance_from_user" msgid="2782756722448800447">"మీరు ఈ నోటిఫికేషన్ల ప్రాముఖ్యతను సెట్ చేశారు."</string>
@@ -2247,14 +2287,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"DPad మధ్యన"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"ఆటో-క్లిక్ టైప్ సెట్టింగ్ల ప్యానెల్"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"ఎడమ క్లిక్"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"రైట్-క్లిక్"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"డబుల్ క్లిక్"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"లాగండి"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"స్క్రోల్ చేయండి"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"పాజ్ చేయండి"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"స్థానం"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> పరిమితం చేయబడిన బకెట్లో ఉంచబడింది"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index f4a3651..e16a28a 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"เข้าถึงข้อมูลเซ็นเซอร์เกี่ยวกับสัญญาณชีพของคุณ"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"การแจ้งเตือน"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"แสดงการแจ้งเตือน"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"เรียกข้อมูลเนื้อหาของหน้าต่าง"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"ตรวจสอบเนื้อหาของหน้าต่างที่คุณกำลังโต้ตอบอยู่"</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"เปิด \"แตะเพื่อสำรวจ\""</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"อนุญาตให้แอปแก้ไขคอลเล็กชันรูปภาพของคุณ"</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"อ่านตำแหน่งจากคอลเล็กชันสื่อของคุณ"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"อนุญาตให้แอปอ่านตำแหน่งจากคอลเล็กชันสื่อของคุณ"</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"ใช้ข้อมูลไบโอเมตริก"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"ใช้ข้อมูลไบโอเมตริกหรือการล็อกหน้าจอ"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"ยืนยันว่าเป็นตัวคุณ"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 8782970..98de106 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"i-access ang data ng sensor tungkol sa iyong vital signs"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Mga Notification"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"magpakita ng mga notification"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Kunin ang content ng window"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Siyasatin ang nilalaman ng isang window kung saan ka nakikipag-ugnayan."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"I-on ang Explore by Touch"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Pinapayagan ang app na baguhin ang iyong koleksyon ng larawan."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"basahin ang mga lokasyon mula sa iyong koleksyon ng media"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Pinapayagan ang app na basahin ang mga lokasyon mula sa iyong koleksyon ng media."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Gumamit ng biometrics"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Gumamit ng biometrics o lock ng screen"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"I-verify na ikaw ito"</string>
@@ -2247,14 +2287,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"Dpad Center"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"Panel ng mga setting ng uri ng autoclick"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"Mag-left click"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"Mag-right click"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"Mag-double click"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"I-drag"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Mag-scroll"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"I-pause"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Posisyon"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Inilagay ang <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> sa PINAGHIHIGPITANG bucket"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 7048a83..2ec15ca 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"hayati belirtilerinizle ilgili sensör verilerine erişme"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Bildirimler"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"bildirimleri göster"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Pencere içeriğini alma"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Etkileşim kurduğunuz pencerenin içeriğini inceler."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Dokunarak Keşfet\'i açma"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Uygulamanın fotoğraf koleksiyonunuzu değiştirmesine izin verir."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"medya koleksiyonunuzdaki konumları okuma"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Uygulamanın medya koleksiyonunuzdaki konumları okumasına izin verir."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Biyometri kullan"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Biyometri veya ekran kilidi kullan"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Kimliğinizi doğrulayın"</string>
@@ -1409,7 +1449,7 @@
<string name="carrier_app_notification_title" msgid="5815477368072060250">"Yeni SIM kart takıldı"</string>
<string name="carrier_app_notification_text" msgid="6567057546341958637">"Kurmak için dokunun"</string>
<string name="time_zone_change_notification_title" msgid="5232503069219193218">"Saat diliminiz değişti"</string>
- <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Artık <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>) saat dilimindesiniz"</string>
+ <string name="time_zone_change_notification_body" msgid="6135793674904665585">"<xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>) saat dilimindesiniz"</string>
<string name="time_picker_dialog_title" msgid="9053376764985220821">"Saati ayarlayın"</string>
<string name="date_picker_dialog_title" msgid="5030520449243071926">"Tarihi ayarlayın"</string>
<string name="date_time_set" msgid="4603445265164486816">"Ayarla"</string>
@@ -2247,14 +2287,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"Dpad Orta"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"Otomatik tıklama türü ayarları paneli"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"Sol tıklama"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"Sağ tıklama"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"Çift tıklama"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"Sürükleme"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Kaydırma"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Duraklatma"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Konum"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> KISITLANMIŞ gruba yerleştirildi"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index a366990..9aeee9c 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -355,6 +355,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"отримувати доступ до інформації датчиків про ваші життєві показники"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Сповіщення"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"показувати сповіщення"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Отримувати вміст вікна"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Перевіряти вміст вікна, з яким ви взаємодієте."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Увімкнути функцію дослідження дотиком"</string>
@@ -650,6 +658,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Додаток зможе змінювати вашу колекцію фотографій."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"розпізнавати геодані з колекції медіа-вмісту"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Додаток зможе розпізнавати геодані з вашої колекції медіа-вмісту."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Доступ через біометрію"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Використовувати біометрію або дані для розблокування екрана"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Підтвердьте, що це ви"</string>
@@ -2090,12 +2130,9 @@
<string name="unpin_target" msgid="3963318576590204447">"Відкріпити"</string>
<string name="unpin_specific_target" msgid="3859828252160908146">"Відкріпити додаток <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="app_info" msgid="6113278084877079851">"Про додатки"</string>
- <!-- no translation found for shortcut_group_a11y_title (2992150163811583865) -->
- <skip />
- <!-- no translation found for suggested_apps_group_a11y_title (2804876567839501831) -->
- <skip />
- <!-- no translation found for all_apps_group_a11y_title (7020352520224108745) -->
- <skip />
+ <string name="shortcut_group_a11y_title" msgid="2992150163811583865">"Цілі прямого надання доступу"</string>
+ <string name="suggested_apps_group_a11y_title" msgid="2804876567839501831">"Рекомендовані додатки"</string>
+ <string name="all_apps_group_a11y_title" msgid="7020352520224108745">"Список додатків"</string>
<string name="negative_duration" msgid="1938335096972945232">"-<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Запуск демонстрації…"</string>
<string name="demo_restarting_message" msgid="1160053183701746766">"Скидання налаштувань пристрою…"</string>
@@ -2252,14 +2289,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"Центральна кнопка панелі керування"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"Панель налаштувань типу автоматичного натискання"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"Натиснути лівою кнопкою миші"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"Натиснути правою кнопкою миші"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"Двічі натиснути"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"Перетягнути"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Прокрутити"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Призупинити"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Змінити позицію"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Пакет \"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>\" додано в сегмент з обмеженнями"</string>
@@ -2536,12 +2569,8 @@
<string name="keyboard_shortcut_group_applications_maps" msgid="7950000659522589471">"Карти"</string>
<string name="keyboard_shortcut_group_applications" msgid="3010389163951364798">"Додатки"</string>
<string name="fingerprint_loe_notification_msg" msgid="3927447270148854546">"Ваші відбитки пальців більше не розпізнаються. Налаштуйте розблокування відбитком пальця повторно."</string>
- <!-- no translation found for usb_apm_usb_plugged_in_when_locked_notification_title (468577168569874967) -->
- <skip />
- <!-- no translation found for usb_apm_usb_plugged_in_when_locked_notification_text (6695268246267993166) -->
- <skip />
- <!-- no translation found for usb_apm_usb_suspicious_activity_notification_title (3461195995882871461) -->
- <skip />
- <!-- no translation found for usb_apm_usb_suspicious_activity_notification_text (6537085605929303187) -->
- <skip />
+ <string name="usb_apm_usb_plugged_in_when_locked_notification_title" msgid="468577168569874967">"USB-пристрій підключено до заблокованого пристрою"</string>
+ <string name="usb_apm_usb_plugged_in_when_locked_notification_text" msgid="6695268246267993166">"USB-пристрій підключено, коли пристрій Android заблоковано. Щоб використовувати USB-пристрій, вийміть і знову вставте його після того, як розблокуєте пристрій Android."</string>
+ <string name="usb_apm_usb_suspicious_activity_notification_title" msgid="3461195995882871461">"Підозрілі дії з USB-пристроєм"</string>
+ <string name="usb_apm_usb_suspicious_activity_notification_text" msgid="6537085605929303187">"Передавання даних через USB вимкнено."</string>
</resources>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index b725a12..f934b87 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"اپنی علامات حیات کے متعلق سنسر ڈیٹا تک رسائی حاصل کریں"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"اطلاعات"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"اطلاعات دکھائیں"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"ونڈو مواد بازیافت کرنے کی"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"کسی ایسی ونڈو کے مواد کا معائنہ کریں جس کے ساتھ آپ تعامل کر رہے ہیں۔"</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"ٹچ کے ذریعے دریافت کریں کو آن کرنے کی"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"ایپ کو آپ کی تصویر کے مجموعے میں ترمیم کی اجازت دیتا ہے۔"</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"اپنی میڈيا کے مجموعے سے مقامات پڑھیں"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"ایپ کو آپ کی میڈيا کے مجموعے سے مقامات پڑھنے کی اجازت دیتا ہے۔"</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"بایو میٹرکس استعمال کریں"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"بایو میٹرکس یا اسکرین لاک استعمال کریں"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"توثیق کریں کہ یہ آپ ہیں"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index a834669..942be79 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"organizm holati haqidagi sezgich ma’lumotlariga kirish"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Bildirishnomalar"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"bildirishnomalarni chiqarish"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Oynadagi kontentni o‘qiydi"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Joriy oynadagi kontent mazmunini aniqlaydi."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Teginib o‘rganish xizmatini yoqadi"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Ilovaga suratlar to‘plamingizni o‘zgartirishga ruxsat beradi."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"multimedia to‘plamidan joylashuv axborotini o‘qish"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Ilovaga multimedia to‘plamingizdan joylashuv axborotini o‘qishga ruxsat beradi."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Biometrik tasdiqlash"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Biometrika yoki ekran qulfi"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Oʻzingizni taniting"</string>
@@ -1431,11 +1471,11 @@
<string name="usb_power_notification_message" msgid="7284765627437897702">"Ulangan qurilma quvvatlanmoqda. Boshqa parametrlar uchun bosing."</string>
<string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"Analogli audio uskuna aniqlandi"</string>
<string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"Biriktirilgan qurilma mazkur telefon bilan mos emas. Batafsil axborot olish uchun bu yerga bosing."</string>
- <string name="adb_active_notification_title" msgid="408390247354560331">"USB debagging ulandi"</string>
- <string name="adb_active_notification_message" msgid="5617264033476778211">"USB debaggingni uzish uchun bosing"</string>
+ <string name="adb_active_notification_title" msgid="408390247354560331">"USB debaging ulandi"</string>
+ <string name="adb_active_notification_message" msgid="5617264033476778211">"Uzish uchun bosing"</string>
<string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"USB orqali nosozliklarni tuzatishni o‘chirib qo‘yish uchun bosing."</string>
- <string name="adbwifi_active_notification_title" msgid="6147343659168302473">"Wi-Fi orqali debagging yoqildi"</string>
- <string name="adbwifi_active_notification_message" msgid="930987922852867972">"Wi-Fi orqali debagging uzilishi uchun bosing"</string>
+ <string name="adbwifi_active_notification_title" msgid="6147343659168302473">"Wi-Fi orqali debaging yoqildi"</string>
+ <string name="adbwifi_active_notification_message" msgid="930987922852867972">"Wi-Fi orqali debaging uzilishi uchun bosing"</string>
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Uni faolsizlantirish uchun bosing."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Xavfsizlik sinovi rejimi yoqildi"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Xavfsizlik sinovi rejimini faolsizlantirish uchun zavod sozlamalariga qaytaring."</string>
@@ -2247,14 +2287,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"Dpad – markazga"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"Avtomatik klik turi sozlamalari paneli"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"Chap klik"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"Oʻng klik"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"Ikki marta bosish"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"Tortish"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Aylantirish"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pauza"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Joylashuvi"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> cheklangan turkumga joylandi"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index c07ff1d..947a9b4 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"truy cập dữ liệu cảm biến về dấu hiệu sinh tồn của bạn"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Thông báo"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"hiển thị thông báo"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Truy xuất nội dung cửa sổ"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Kiểm tra nội dung của cửa sổ bạn đang tương tác."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Bật tính năng Khám phá bằng cách chạm"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Cho phép ứng dụng này sửa đổi bộ sưu tập ảnh của bạn."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"đọc vị trí từ bộ sưu tập phương tiện"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Cho phép ứng dụng này đọc vị trí từ bộ sưu tập phương tiện của bạn."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Dùng dữ liệu sinh trắc học"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Dùng dữ liệu sinh trắc học hoặc phương thức khóa màn hình"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Xác minh danh tính của bạn"</string>
@@ -2247,14 +2287,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"Căn giữa bằng bàn phím di chuyển"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"Bảng cài đặt loại tự động nhấp"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"Nhấp chuột trái"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"Nhấp chuột phải"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"Nhấp đúp"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"Kéo"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Cuộn"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Tạm dừng"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Vị trí"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Đã đưa <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> vào bộ chứa BỊ HẠN CHẾ"</string>
diff --git a/core/res/res/values-w192dp/dimens_watch.xml b/core/res/res/values-w192dp/dimens_watch.xml
new file mode 100644
index 0000000..c6bf767
--- /dev/null
+++ b/core/res/res/values-w192dp/dimens_watch.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2025 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.
+ -->
+<resources>
+ <!-- 16.7% of display size -->
+ <dimen name="base_error_dialog_top_padding">32dp</dimen>
+ <!-- 5.2% of display size -->
+ <dimen name="base_error_dialog_padding">10dp</dimen>
+ <!-- 20.83% of display size -->
+ <dimen name="base_error_dialog_bottom_padding">40dp</dimen>
+
+ <!-- watch's indeterminate progress bar dimens based on the current screen size -->
+ <dimen name="loader_horizontal_min_width_watch">67dp</dimen>
+ <dimen name="loader_horizontal_min_height_watch">15dp</dimen>
+</resources>
diff --git a/core/res/res/values-w204dp-round-watch/dimens_watch.xml b/core/res/res/values-w204dp-round-watch/dimens_watch.xml
new file mode 100644
index 0000000..3509474
--- /dev/null
+++ b/core/res/res/values-w204dp-round-watch/dimens_watch.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2025 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.
+ -->
+<resources>
+ <!-- watch's indeterminate progress bar dimens based on the current screen size -->
+ <dimen name="loader_horizontal_min_width_watch">70dp</dimen>
+ <dimen name="loader_horizontal_min_height_watch">15dp</dimen>
+</resources>
diff --git a/core/res/res/values-w216dp/dimens_watch.xml b/core/res/res/values-w216dp/dimens_watch.xml
new file mode 100644
index 0000000..e14ce5e
--- /dev/null
+++ b/core/res/res/values-w216dp/dimens_watch.xml
@@ -0,0 +1,21 @@
+<!--
+ ~ Copyright (C) 2025 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.
+ -->
+
+<resources>
+ <!-- watch's indeterminate progress bar dimens based on the current screen size -->
+ <dimen name="loader_horizontal_min_width_watch">72dp</dimen>
+ <dimen name="loader_horizontal_min_height_watch">16dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/core/res/res/values-w228dp/dimens_watch.xml b/core/res/res/values-w228dp/dimens_watch.xml
new file mode 100644
index 0000000..3c62656
--- /dev/null
+++ b/core/res/res/values-w228dp/dimens_watch.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2025 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.
+ -->
+<resources>
+ <!-- watch's indeterminate progress bar dimens based on the current screen size -->
+ <dimen name="loader_horizontal_min_width">76dp</dimen>
+ <dimen name="loader_horizontal_min_height">14dp</dimen>
+</resources>
diff --git a/core/res/res/values-w240dp/dimens_material.xml b/core/res/res/values-w240dp/dimens_material.xml
index bd26c8b..e30aea4 100644
--- a/core/res/res/values-w240dp/dimens_material.xml
+++ b/core/res/res/values-w240dp/dimens_material.xml
@@ -21,4 +21,8 @@
<dimen name="screen_percentage_12">28.8dp</dimen>
<dimen name="screen_percentage_15">36dp</dimen>
<dimen name="screen_percentage_3646">87.5dp</dimen>
+
+ <!-- watch's indeterminate progress bar dimens based on the current screen size -->
+ <dimen name="progress_indeterminate_horizontal_min_width_watch">80dp</dimen>
+ <dimen name="progress_indeterminate_horizontal_min_height_watch">17dp</dimen>
</resources>
diff --git a/core/res/res/values-watch/styles_device_defaults.xml b/core/res/res/values-watch/styles_device_defaults.xml
index fb7dbb0..eeb66e7 100644
--- a/core/res/res/values-watch/styles_device_defaults.xml
+++ b/core/res/res/values-watch/styles_device_defaults.xml
@@ -42,5 +42,8 @@
<item name="indeterminateOnly">false</item>
<!-- Use Wear Material3 ring shape as default determinate drawable -->
<item name="progressDrawable">@drawable/progress_ring_watch</item>
+ <item name="indeterminateDrawable">@drawable/loader_horizontal_watch</item>
+ <item name="android:minWidth">@dimen/loader_horizontal_min_width_watch</item>
+ <item name="android:minHeight">@dimen/loader_horizontal_min_height_watch</item>
</style>
</resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index c746d3c..46c53eb 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"访问与您的生命体征相关的传感器数据"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"通知"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"显示通知"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"检索窗口内容"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"检测您与之互动的窗口的内容。"</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"启用触摸浏览"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"允许该应用修改您的照片收藏。"</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"从您的媒体收藏中读取位置信息"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"允许该应用从您的媒体收藏中读取位置信息。"</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"使用生物识别"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"使用生物识别或屏幕锁定凭据"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"验证是您本人在操作"</string>
@@ -2247,14 +2287,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"方向键中心"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"自动点击类型设置面板"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"点击鼠标左键"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"右键点击"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"双击"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"拖动"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"滚动"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"暂停"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"位置"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> 已被放入受限存储分区"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index c6b952c..d013a47 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"存取與你生命體徵相關的感應器資料"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"通知"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"顯示通知"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"擷取視窗內容"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"檢查你使用中的視窗內容。"</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"開啟「輕觸探索」功能"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"允許應用程式修改你的相片集。"</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"讀取媒體集的位置"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"允許應用程式讀取媒體集的位置。"</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"使用生物識別"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"使用生物識別或螢幕鎖定"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"驗證是你本人"</string>
@@ -1409,7 +1449,7 @@
<string name="carrier_app_notification_title" msgid="5815477368072060250">"已插入新的 SIM 卡"</string>
<string name="carrier_app_notification_text" msgid="6567057546341958637">"輕按即可設定"</string>
<string name="time_zone_change_notification_title" msgid="5232503069219193218">"你的時區已變更"</string>
- <string name="time_zone_change_notification_body" msgid="6135793674904665585">"你現在處於 <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string>
+ <string name="time_zone_change_notification_body" msgid="6135793674904665585">"目前所在時區為<xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</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>
@@ -2247,14 +2287,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"十字鍵中心鍵"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"自動點擊類型設定面板"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"按一下左鍵"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"按一下右鍵"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"連按兩下"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"拖曳"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"捲動"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"暫停"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"位置"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> 已納入受限制的儲存區"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index ca0402a..f1c9dcd 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"存取與你生命徵象相關的感應器資料"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"通知"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"顯示通知"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"擷取視窗內容"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"檢查你存取的視窗內容。"</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"啟用輕觸探索功能"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"允許應用程式修改你的相片收藏。"</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"讀取你的媒體收藏的位置資訊"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"允許應用程式讀取你的媒體收藏的位置資訊。"</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"使用生物辨識功能"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"使用生物辨識或螢幕鎖定功能"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"驗證你的身分"</string>
@@ -2247,14 +2287,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"Dpad 置中"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"自動點選類型設定面板"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"按滑鼠左鍵"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"按一下滑鼠右鍵"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"按兩下"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"拖曳"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"捲動"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"暫停"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"位置"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"已將「<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>」移入受限制的值區"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 96d6b57..5732cec 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -353,6 +353,14 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"finyelela idatha yesizweli mayelana nezimpawu zakho ezibalulekile"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Izaziso"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"bonisa izaziso"</string>
+ <!-- no translation found for permgrouplab_xr_tracking (7418994009794287471) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking (6777198859446500821) -->
+ <skip />
+ <!-- no translation found for permgrouplab_xr_tracking_sensitive (1194833982988144536) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_xr_tracking_sensitive (9178027369004805829) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Thola okuqukethwe kwewindi"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Hlola okuqukethwe kwewindi ohlanganyela nalo."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Vula ukuhlola ngokuthinta"</string>
@@ -648,6 +656,38 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Ivumela uhlelo lwakho lokusebenza ukuthi lilungise iqoqo lakho lesithombe."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"funda izindawo kusukela kuqoqo lakho lemidiya"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Ivumela uhlelo lokusebenza ukuthi lifunde izindawo kusukela kuqoqo lakho lemidiya."</string>
+ <!-- no translation found for permlab_eye_tracking_coarse (7989596289790269059) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_coarse (870510233930553355) -->
+ <skip />
+ <!-- no translation found for permlab_eye_tracking_fine (6914457357027049512) -->
+ <skip />
+ <!-- no translation found for permdesc_eye_tracking_fine (5788889152304524730) -->
+ <skip />
+ <!-- no translation found for permlab_face_tracking (2272048395128283324) -->
+ <skip />
+ <!-- no translation found for permdesc_face_tracking (2622783922311211866) -->
+ <skip />
+ <!-- no translation found for permlab_hand_tracking (6478233866595566940) -->
+ <skip />
+ <!-- no translation found for permdesc_hand_tracking (8639715900104966456) -->
+ <skip />
+ <!-- no translation found for permlab_head_tracking (1309731456372087270) -->
+ <skip />
+ <!-- no translation found for permdesc_head_tracking (231597390513699188) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_coarse (6518646430502858641) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_coarse (4508880777646198656) -->
+ <skip />
+ <!-- no translation found for permlab_scene_understanding_fine (409126403264393251) -->
+ <skip />
+ <!-- no translation found for permdesc_scene_understanding_fine (6223368011593524179) -->
+ <skip />
+ <!-- no translation found for permlab_xr_tracking_in_background (7117098718465619023) -->
+ <skip />
+ <!-- no translation found for permdesc_xr_tracking_in_background (939504041387836853) -->
+ <skip />
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Sebenzisa i-biometrics"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Sebenzisa i-biometrics noma ukukhiya isikrini"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Qinisekisa ukuthi nguwe"</string>
@@ -2247,14 +2287,10 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"Isikhungo se-Dpad"</string>
<string name="accessibility_autoclick_type_settings_panel_title" msgid="7354373370578758696">"Iphaneli yamasethingi ohlobo lokuchofoza ngokuzenzekelayo"</string>
<string name="accessibility_autoclick_left_click" msgid="2301793352260551080">"Chofoza kwesokunxele"</string>
- <!-- no translation found for accessibility_autoclick_right_click (4353495816526181293) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_double_click (2103826849116176478) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_drag (1499559489796843224) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll (3499385943728726933) -->
- <skip />
+ <string name="accessibility_autoclick_right_click" msgid="4353495816526181293">"Chofoza ngakwesokudla"</string>
+ <string name="accessibility_autoclick_double_click" msgid="2103826849116176478">"Chofoza kabili"</string>
+ <string name="accessibility_autoclick_drag" msgid="1499559489796843224">"Hudula"</string>
+ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Skrola"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Misa"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Indawo"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"I-<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ifakwe kubhakede LOKUKHAWULELWE"</string>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 1a311d57..2188469 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2643,6 +2643,15 @@
<!-- MMS user agent prolfile url -->
<string name="config_mms_user_agent_profile_url" translatable="false"></string>
+ <!-- The default list of possible CMF Names|Style|ColorSource. This array can be
+ overridden device-specific resources. A wildcard (fallback) must be supplied.
+ Name - Read from `ro.boot.hardware.color` sysprop. Fallback (*) required.
+ Styles - frameworks/libs/systemui/monet/src/com/android/systemui/monet/Style.java
+ Color - `home_wallpaper` (for color extraction) or a hexadecimal int (#FFcc99) -->
+ <string-array name="theming_defaults">
+ <item>*|TONAL_SPOT|home_wallpaper</item>
+ </string-array>
+
<!-- National Language Identifier codes for the following two config items.
(from 3GPP TS 23.038 V9.1.1 Table 6.2.1.2.4.1):
0 - reserved
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index e9d87e4..9acb242 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -580,9 +580,6 @@
<dimen name="notification_text_size">14sp</dimen>
<!-- Size of notification text titles (see TextAppearance.StatusBar.EventContent.Title) -->
<dimen name="notification_title_text_size">14sp</dimen>
- <!-- Size of notification text titles, 2025 redesign version (see TextAppearance.StatusBar.EventContent.Title) -->
- <!-- TODO: b/378660052 - When inlining the redesign flag, this should be updated directly in TextAppearance.DeviceDefault.Notification.Title -->
- <dimen name="notification_2025_title_text_size">16sp</dimen>
<!-- Size of big notification text titles (see TextAppearance.StatusBar.EventContent.BigTitle) -->
<dimen name="notification_big_title_text_size">16sp</dimen>
<!-- Size of smaller notification text (see TextAppearance.StatusBar.EventContent.Line2, Info, Time) -->
diff --git a/core/res/res/values/dimens_watch.xml b/core/res/res/values/dimens_watch.xml
index 2aae987..1984591 100644
--- a/core/res/res/values/dimens_watch.xml
+++ b/core/res/res/values/dimens_watch.xml
@@ -61,4 +61,8 @@
<dimen name="disabled_alpha_wear_material3">0.12</dimen>
<!-- Alpha transparency applied to elements which are considered primary (e.g. primary text) -->
<dimen name="primary_content_alpha_wear_material3">0.38</dimen>
+
+ <!-- watch's indeterminate progress bar dimens -->
+ <dimen name="loader_horizontal_min_width">68dp</dimen>
+ <dimen name="loader_horizontal_min_height">13dp</dimen>
</resources>
diff --git a/core/res/res/values/public-staging.xml b/core/res/res/values/public-staging.xml
index e3137e2..ac1e841 100644
--- a/core/res/res/values/public-staging.xml
+++ b/core/res/res/values/public-staging.xml
@@ -116,14 +116,14 @@
<public name="alternateLauncherIcons"/>
<!-- @FlaggedApi(android.content.pm.Flags.FLAG_CHANGE_LAUNCHER_BADGING) -->
<public name="alternateLauncherLabels"/>
- <!-- @hide Only for device overlay to use this. -->
- <public name="pointerIconVectorFill"/>
- <!-- @hide Only for device overlay to use this. -->
- <public name="pointerIconVectorFillInverse"/>
- <!-- @hide Only for device overlay to use this. -->
- <public name="pointerIconVectorStroke"/>
- <!-- @hide Only for device overlay to use this. -->
- <public name="pointerIconVectorStrokeInverse"/>
+ <!-- @hide Wrongly added here. -->
+ <public name="removed_pointerIconVectorFill"/>
+ <!-- @hide Wrongly added here. -->
+ <public name="removed_pointerIconVectorFillInverse"/>
+ <!-- @hide Wrongly added here. -->
+ <public name="removed_pointerIconVectorStroke"/>
+ <!-- @hide Wrongly added here. -->
+ <public name="removed_pointerIconVectorStrokeInverse"/>
</staging-public-group>
<staging-public-group type="id" first-id="0x01b20000">
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index c62732d..26f0ab3 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -575,7 +575,6 @@
<java-symbol type="dimen" name="notification_text_size" />
<java-symbol type="dimen" name="notification_title_text_size" />
<java-symbol type="dimen" name="notification_subtext_size" />
- <java-symbol type="dimen" name="notification_2025_title_text_size" />
<java-symbol type="dimen" name="notification_top_pad" />
<java-symbol type="dimen" name="notification_top_pad_narrow" />
<java-symbol type="dimen" name="notification_top_pad_large_text" />
@@ -1727,10 +1726,12 @@
<java-symbol type="style" name="PointerIconVectorStyleFillBlue" />
<java-symbol type="style" name="PointerIconVectorStyleFillPurple" />
<java-symbol type="attr" name="pointerIconVectorFill" />
+ <java-symbol type="attr" name="pointerIconVectorFillInverse" />
<java-symbol type="style" name="PointerIconVectorStyleStrokeWhite" />
<java-symbol type="style" name="PointerIconVectorStyleStrokeBlack" />
<java-symbol type="style" name="PointerIconVectorStyleStrokeNone" />
<java-symbol type="attr" name="pointerIconVectorStroke" />
+ <java-symbol type="attr" name="pointerIconVectorStrokeInverse" />
<java-symbol type="style" name="TextAppearance.DeviceDefault.Notification.Title" />
<java-symbol type="style" name="TextAppearance.DeviceDefault.Notification.Info" />
@@ -1742,7 +1743,6 @@
<java-symbol type="id" name="media_route_list" />
<java-symbol type="id" name="media_route_volume_layout" />
<java-symbol type="id" name="media_route_volume_slider" />
- <java-symbol type="id" name="media_route_control_frame" />
<java-symbol type="id" name="media_route_extended_settings_button" />
<java-symbol type="id" name="media_route_progress_bar" />
<java-symbol type="string" name="media_route_chooser_title" />
@@ -5648,6 +5648,8 @@
<java-symbol type="id" name="accessibility_autoclick_pause_button" />
<java-symbol type="id" name="accessibility_autoclick_position_layout" />
<java-symbol type="id" name="accessibility_autoclick_position_button" />
+ <java-symbol type="drawable" name="accessibility_autoclick_pause" />
+ <java-symbol type="drawable" name="accessibility_autoclick_resume" />
<!-- For HapticFeedbackConstants configurability defined at HapticFeedbackCustomization -->
<java-symbol type="string" name="config_hapticFeedbackCustomizationFile" />
@@ -5904,6 +5906,9 @@
<java-symbol type="drawable" name="ic_notification_summarization" />
<java-symbol type="dimen" name="notification_collapsed_height_with_summarization" />
+ <!-- Device CMF Theming Settings -->
+ <java-symbol type="array" name="theming_defaults" />
+
<!-- Advanced Protection Service USB feature -->
<java-symbol type="string" name="usb_apm_usb_plugged_in_when_locked_notification_title" />
<java-symbol type="string" name="usb_apm_usb_plugged_in_when_locked_notification_text" />
diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp
index c06ad64..4c49ff8 100644
--- a/core/tests/coretests/Android.bp
+++ b/core/tests/coretests/Android.bp
@@ -10,8 +10,8 @@
filegroup {
name: "FrameworksCoreTests-aidl",
srcs: [
- "src/**/I*.aidl",
"aidl/**/I*.aidl",
+ "src/**/I*.aidl",
],
visibility: ["//visibility:private"],
}
@@ -19,13 +19,13 @@
filegroup {
name: "FrameworksCoreTests-helpers",
srcs: [
- "DisabledTestApp/src/**/*.java",
- "EnabledTestApp/src/**/*.java",
+ "AppThatCallsBinderMethods/src/**/*.kt",
+ "BinderDeathRecipientHelperApp/src/**/*.java",
"BinderFrozenStateChangeCallbackTestApp/src/**/*.java",
"BinderProxyCountingTestApp/src/**/*.java",
"BinderProxyCountingTestService/src/**/*.java",
- "BinderDeathRecipientHelperApp/src/**/*.java",
- "AppThatCallsBinderMethods/src/**/*.kt",
+ "DisabledTestApp/src/**/*.java",
+ "EnabledTestApp/src/**/*.java",
],
visibility: ["//visibility:private"],
}
@@ -45,11 +45,11 @@
defaults: ["FrameworksCoreTests-resources"],
srcs: [
- "src/**/*.java",
- "src/**/*.kt",
+ ":FrameworksCoreTestDoubles-sources",
":FrameworksCoreTests-aidl",
":FrameworksCoreTests-helpers",
- ":FrameworksCoreTestDoubles-sources",
+ "src/**/*.java",
+ "src/**/*.kt",
],
aidl: {
@@ -65,74 +65,74 @@
"-c fa",
],
static_libs: [
- "collector-device-lib-platform",
- "frameworks-base-testutils",
- "core-test-rules", // for libcore.dalvik.system.CloseGuardSupport
- "core-tests-support",
- "cts-input-lib",
+ "TestParameterInjector",
"android-common",
- "frameworks-core-util-lib",
- "mockwebserver",
- "guava",
- "guava-android-testlib",
"android.app.usage.flags-aconfig-java",
+ "android.content.res.flags-aconfig-java",
+ "android.security.flags-aconfig-java",
"android.view.accessibility.flags-aconfig-java",
"androidx.core_core",
"androidx.core_core-ktx",
"androidx.test.core",
"androidx.test.espresso.core",
"androidx.test.ext.junit",
- "androidx.test.runner",
"androidx.test.rules",
- "flag-junit",
- "junit-params",
- "kotlin-test",
- "mockito-target-minus-junit4",
+ "androidx.test.runner",
"androidx.test.uiautomator_uiautomator",
- "platform-parametric-runner-lib",
- "platform-test-annotations",
- "platform-compat-test-rules",
- "truth",
- "print-test-util-lib",
- "testng",
- "servicestests-utils",
- "device-time-shell-utils",
- "testables",
+ "collector-device-lib-platform",
"com.android.text.flags-aconfig-java",
+ "core-test-rules", // for libcore.dalvik.system.CloseGuardSupport
+ "core-tests-support",
+ "cts-input-lib",
+ "device-time-shell-utils",
"flag-junit",
- "ravenwood-junit",
- "perfetto_trace_java_protos",
+ "flag-junit",
"flickerlib-parsers",
"flickerlib-trace_processor_shell",
- "mockito-target-extended-minus-junit4",
- "TestParameterInjector",
- "android.content.res.flags-aconfig-java",
- "android.security.flags-aconfig-java",
+ "frameworks-base-testutils",
+ "frameworks-core-util-lib",
+ "guava",
+ "guava-android-testlib",
+ "junit-params",
+ "kotlin-test",
"mockito-kotlin2",
+ "mockito-target-extended-minus-junit4",
+ "mockito-target-minus-junit4",
+ "mockwebserver",
+ "perfetto_trace_java_protos",
+ "platform-compat-test-rules",
+ "platform-parametric-runner-lib",
+ "platform-test-annotations",
+ "print-test-util-lib",
+ "ravenwood-junit",
+ "servicestests-utils",
+ "testables",
+ "testng",
+ "truth",
],
libs: [
- "android.test.runner.stubs",
- "org.apache.http.legacy.stubs",
"android.test.base.stubs",
"android.test.mock.stubs",
- "framework",
- "ext",
- "framework-res",
+ "android.test.runner.stubs",
"android.view.flags-aconfig-java",
+ "ext",
+ "framework",
+ "framework-res",
+ "org.apache.http.legacy.stubs",
],
jni_libs: [
+ "libAppOpsTest_jni",
"libpowermanagertest_jni",
"libviewRootImplTest_jni",
"libworksourceparceltest_jni",
- "libAppOpsTest_jni",
],
sdk_version: "core_platform",
test_suites: [
- "device-tests",
- "device-platinum-tests",
"automotive-tests",
+ "device-platinum-tests",
+ "device-tests",
],
certificate: "platform",
@@ -141,21 +141,21 @@
java_resources: [":FrameworksCoreTests_unit_test_cert_der"],
data: [
+ ":AppThatCallsBinderMethods",
+ ":AppThatUsesAppOps",
":BinderDeathRecipientHelperApp1",
":BinderDeathRecipientHelperApp2",
- ":com.android.cts.helpers.aosp",
":BinderFrozenStateChangeCallbackTestApp",
":BinderProxyCountingTestApp",
":BinderProxyCountingTestService",
- ":AppThatUsesAppOps",
- ":AppThatCallsBinderMethods",
- ":HelloWorldSdk1",
- ":HelloWorldUsingSdk1AndSdk1",
- ":HelloWorldUsingSdk1And2",
- ":HelloWorldUsingSdkMalformedNegativeVersion",
":CtsStaticSharedLibConsumerApp1",
":CtsStaticSharedLibConsumerApp3",
":CtsStaticSharedLibProviderApp1",
+ ":HelloWorldSdk1",
+ ":HelloWorldUsingSdk1And2",
+ ":HelloWorldUsingSdk1AndSdk1",
+ ":HelloWorldUsingSdkMalformedNegativeVersion",
+ ":com.android.cts.helpers.aosp",
],
}
@@ -170,8 +170,8 @@
// FrameworksCoreTestsRavenwood references the .aapt.srcjar
use_resource_processor: false,
libs: [
- "framework-res",
"android.test.runner.stubs",
+ "framework-res",
"org.apache.http.legacy.stubs",
],
uses_libs: [
@@ -231,16 +231,16 @@
static_libs: [
"androidx.test.espresso.core",
"androidx.test.ext.junit",
- "androidx.test.runner",
"androidx.test.rules",
+ "androidx.test.runner",
"mockito-target-minus-junit4",
"truth",
],
libs: [
- "android.test.runner.stubs.system",
"android.test.base.stubs.system",
"android.test.mock.stubs.system",
+ "android.test.runner.stubs.system",
"framework",
"framework-res",
],
@@ -249,43 +249,43 @@
android_ravenwood_test {
name: "FrameworksCoreTestsRavenwood",
libs: [
- "android.test.runner.stubs.system",
"android.test.base.stubs.system",
+ "android.test.runner.stubs.system",
],
static_libs: [
- "core-test-rules", // for libcore.dalvik.system.CloseGuardSupport
+ "androidx.annotation_annotation",
"androidx.core_core",
"androidx.core_core-ktx",
- "androidx.annotation_annotation",
- "androidx.test.rules",
"androidx.test.ext.junit",
+ "androidx.test.rules",
"androidx.test.uiautomator_uiautomator",
"compatibility-device-util-axt-ravenwood",
+ "core-test-rules", // for libcore.dalvik.system.CloseGuardSupport
"flag-junit",
- "platform-test-annotations",
+ "flag-junit",
"perfetto_trace_java_protos",
- "flag-junit",
+ "platform-test-annotations",
"testng",
],
srcs: [
"src/android/app/ActivityManagerTest.java",
+ "src/android/app/PropertyInvalidatedCacheTests.java",
"src/android/colormodel/CamTest.java",
"src/android/content/ContextTest.java",
+ "src/android/content/TestComponentCallbacks2.java",
"src/android/content/pm/PackageManagerTest.java",
"src/android/content/pm/UserInfoTest.java",
- "src/android/app/PropertyInvalidatedCacheTests.java",
- "src/android/database/CursorWindowTest.java",
- "src/android/os/**/*.java",
"src/android/content/res/*.java",
"src/android/content/res/*.kt",
+ "src/android/database/CursorWindowTest.java",
+ "src/android/os/**/*.java",
"src/android/telephony/PinResultTest.java",
"src/android/util/**/*.java",
"src/android/view/DisplayAdjustmentsTests.java",
- "src/android/view/DisplayTest.java",
"src/android/view/DisplayInfoTest.java",
+ "src/android/view/DisplayTest.java",
"src/com/android/internal/logging/**/*.java",
"src/com/android/internal/os/**/*.java",
- "src/com/android/internal/util/**/*.java",
"src/com/android/internal/power/EnergyConsumerStatsTest.java",
"src/com/android/internal/ravenwood/**/*.java",
@@ -293,10 +293,12 @@
// to avoid having a dependency to FrameworksCoreTests.
// This way, when updating source files and running this test, we don't need to
// rebuild the entire FrameworksCoreTests, which would be slow.
- ":FrameworksCoreTests-resonly{.aapt.srcjar}",
+ "src/com/android/internal/util/**/*.java",
+
+ ":FrameworksCoreTestDoubles-sources",
":FrameworksCoreTests-aidl",
":FrameworksCoreTests-helpers",
- ":FrameworksCoreTestDoubles-sources",
+ ":FrameworksCoreTests-resonly{.aapt.srcjar}",
],
exclude_srcs: [
"src/android/content/res/FontScaleConverterActivityTest.java",
@@ -320,8 +322,8 @@
base: "FrameworksCoreTests",
test_suites: [
"automotive-tests",
- "device-tests",
"device-platinum-tests",
+ "device-tests",
],
include_annotations: ["android.platform.test.annotations.Presubmit"],
}
@@ -331,12 +333,12 @@
base: "FrameworksCoreTests",
test_suites: [
"automotive-tests",
- "device-tests",
"device-platinum-tests",
+ "device-tests",
],
include_filters: [
- "com.android.internal.inputmethod",
"android.view.inputmethod",
+ "com.android.internal.inputmethod",
],
exclude_annotations: ["androidx.test.filters.FlakyTest"],
}
@@ -346,8 +348,8 @@
base: "FrameworksCoreTests",
test_suites: [
"automotive-tests",
- "device-tests",
"device-platinum-tests",
+ "device-tests",
],
include_filters: ["android.content.ContextTest"],
}
@@ -357,8 +359,8 @@
base: "FrameworksCoreTests",
test_suites: [
"automotive-tests",
- "device-tests",
"device-platinum-tests",
+ "device-tests",
],
include_filters: ["android.app.KeyguardManagerTest"],
}
@@ -368,8 +370,8 @@
base: "FrameworksCoreTests",
test_suites: [
"automotive-tests",
- "device-tests",
"device-platinum-tests",
+ "device-tests",
],
include_filters: ["android.app.PropertyInvalidatedCacheTests"],
}
@@ -379,12 +381,12 @@
base: "FrameworksCoreTests",
test_suites: [
"automotive-tests",
- "device-tests",
"device-platinum-tests",
+ "device-tests",
],
include_filters: [
- "android.content.ContextTest",
"android.content.ComponentCallbacksControllerTest",
+ "android.content.ContextTest",
"android.content.ContextWrapperTest",
],
}
@@ -394,8 +396,8 @@
base: "FrameworksCoreTests",
test_suites: [
"automotive-tests",
- "device-tests",
"device-platinum-tests",
+ "device-tests",
],
include_filters: ["android.database.sqlite.SQLiteRawStatementTest"],
}
@@ -405,8 +407,8 @@
base: "FrameworksCoreTests",
test_suites: [
"automotive-tests",
- "device-tests",
"device-platinum-tests",
+ "device-tests",
],
include_filters: ["android.net"],
include_annotations: ["android.platform.test.annotations.Presubmit"],
@@ -417,8 +419,8 @@
base: "FrameworksCoreTests",
test_suites: [
"automotive-tests",
- "device-tests",
"device-platinum-tests",
+ "device-tests",
],
include_filters: ["com.android.internal.os.BatteryStatsTests"],
exclude_annotations: ["com.android.internal.os.SkipPresubmit"],
@@ -429,8 +431,8 @@
base: "FrameworksCoreTests",
test_suites: [
"automotive-tests",
- "device-tests",
"device-platinum-tests",
+ "device-tests",
],
include_filters: ["android.os.EnvironmentTest"],
}
@@ -440,12 +442,12 @@
base: "FrameworksCoreTests",
test_suites: [
"automotive-tests",
- "device-tests",
"device-platinum-tests",
+ "device-tests",
],
include_filters: [
- "com.android.internal.util.FastDataTest",
"android.util.CharsetUtilsTest",
+ "com.android.internal.util.FastDataTest",
],
}
@@ -454,12 +456,12 @@
base: "FrameworksCoreTests",
test_suites: [
"automotive-tests",
- "device-tests",
"device-platinum-tests",
+ "device-tests",
],
include_filters: [
- "android.util.XmlTest",
"android.util.BinaryXmlTest",
+ "android.util.XmlTest",
],
}
@@ -468,8 +470,8 @@
base: "FrameworksCoreTests",
test_suites: [
"automotive-tests",
- "device-tests",
"device-platinum-tests",
+ "device-tests",
],
include_filters: ["android.util.apk.SourceStampVerifierTest"],
}
@@ -479,8 +481,8 @@
base: "FrameworksCoreTests",
test_suites: [
"automotive-tests",
- "device-tests",
"device-platinum-tests",
+ "device-tests",
],
include_filters: ["android.view.textclassifier"],
exclude_annotations: ["androidx.test.filters.FlakyTest"],
@@ -491,13 +493,13 @@
base: "FrameworksCoreTests",
test_suites: [
"automotive-tests",
- "device-tests",
"device-platinum-tests",
+ "device-tests",
],
include_filters: ["com.android.internal.app."],
exclude_filters: [
- "com.android.internal.app.WindowDecorActionBarTest",
"com.android.internal.app.IntentForwarderActivityTest",
+ "com.android.internal.app.WindowDecorActionBarTest",
],
}
@@ -506,8 +508,8 @@
base: "FrameworksCoreTests",
test_suites: [
"automotive-tests",
- "device-tests",
"device-platinum-tests",
+ "device-tests",
],
include_filters: ["com.android.internal.content."],
}
@@ -517,8 +519,8 @@
base: "FrameworksCoreTests",
test_suites: [
"automotive-tests",
- "device-tests",
"device-platinum-tests",
+ "device-tests",
],
include_filters: ["com.android.internal.infra."],
}
@@ -528,8 +530,8 @@
base: "FrameworksCoreTests",
test_suites: [
"automotive-tests",
- "device-tests",
"device-platinum-tests",
+ "device-tests",
],
include_filters: ["com.android.internal.jank"],
}
@@ -539,16 +541,16 @@
base: "FrameworksCoreTests",
test_suites: [
"automotive-tests",
- "device-tests",
"device-platinum-tests",
+ "device-tests",
],
include_filters: [
- "android.os.BinderProxyTest",
"android.os.BinderDeathRecipientTest",
"android.os.BinderFrozenStateChangeNotificationTest",
"android.os.BinderProxyCountingTest",
- "android.os.BinderUncaughtExceptionHandlerTest",
+ "android.os.BinderProxyTest",
"android.os.BinderThreadPriorityTest",
+ "android.os.BinderUncaughtExceptionHandlerTest",
"android.os.BinderWorkSourceTest",
"android.os.ParcelNullabilityTest",
"android.os.ParcelTest",
@@ -562,13 +564,13 @@
base: "FrameworksCoreTests",
test_suites: [
"automotive-tests",
- "device-tests",
"device-platinum-tests",
+ "device-tests",
],
include_filters: [
- "com.android.internal.os.KernelCpuUidClusterTimeReaderTest",
- "com.android.internal.os.KernelCpuUidBpfMapReaderTest",
"com.android.internal.os.KernelCpuUidActiveTimeReaderTest",
+ "com.android.internal.os.KernelCpuUidBpfMapReaderTest",
+ "com.android.internal.os.KernelCpuUidClusterTimeReaderTest",
"com.android.internal.os.KernelCpuUidFreqTimeReaderTest",
"com.android.internal.os.KernelSingleUidTimeReaderTest",
],
@@ -579,8 +581,8 @@
base: "FrameworksCoreTests",
test_suites: [
"automotive-tests",
- "device-tests",
"device-platinum-tests",
+ "device-tests",
],
include_filters: ["com.android.server.power.stats.BstatsCpuTimesValidationTest"],
}
@@ -590,8 +592,8 @@
base: "FrameworksCoreTests",
test_suites: [
"automotive-tests",
- "device-tests",
"device-platinum-tests",
+ "device-tests",
],
include_filters: ["com.android.internal.security."],
include_annotations: ["android.platform.test.annotations.Presubmit"],
@@ -602,8 +604,8 @@
base: "FrameworksCoreTests",
test_suites: [
"automotive-tests",
- "device-tests",
"device-platinum-tests",
+ "device-tests",
],
include_filters: ["com.android.internal.util.LatencyTrackerTest"],
}
@@ -613,8 +615,8 @@
base: "FrameworksCoreTests",
test_suites: [
"automotive-tests",
- "device-tests",
"device-platinum-tests",
+ "device-tests",
],
include_filters: ["android.content.ContentCaptureOptionsTest"],
}
@@ -624,8 +626,8 @@
base: "FrameworksCoreTests",
test_suites: [
"automotive-tests",
- "device-tests",
"device-platinum-tests",
+ "device-tests",
],
include_filters: ["android.content.integrity."],
}
@@ -635,8 +637,8 @@
base: "FrameworksCoreTests",
test_suites: [
"automotive-tests",
- "device-tests",
"device-platinum-tests",
+ "device-tests",
],
include_filters: ["android.content.pm."],
include_annotations: ["android.platform.test.annotations.Presubmit"],
@@ -647,8 +649,8 @@
base: "FrameworksCoreTests",
test_suites: [
"automotive-tests",
- "device-tests",
"device-platinum-tests",
+ "device-tests",
],
include_filters: ["android.content.pm."],
include_annotations: ["android.platform.test.annotations.Postsubmit"],
@@ -659,14 +661,14 @@
base: "FrameworksCoreTests",
test_suites: [
"automotive-tests",
- "device-tests",
"device-platinum-tests",
+ "device-tests",
],
include_filters: ["android.content.res."],
include_annotations: ["android.platform.test.annotations.Presubmit"],
exclude_annotations: [
- "androidx.test.filters.FlakyTest",
"android.platform.test.annotations.Postsubmit",
+ "androidx.test.filters.FlakyTest",
"org.junit.Ignore",
],
}
@@ -676,8 +678,8 @@
base: "FrameworksCoreTests",
test_suites: [
"automotive-tests",
- "device-tests",
"device-platinum-tests",
+ "device-tests",
],
include_filters: ["android.content.res."],
include_annotations: ["android.platform.test.annotations.Postsubmit"],
@@ -688,17 +690,17 @@
base: "FrameworksCoreTests",
test_suites: [
"automotive-tests",
- "device-tests",
"device-platinum-tests",
+ "device-tests",
],
include_filters: [
+ "android.service.controls",
+ "android.service.controls.actions",
+ "android.service.controls.templates",
"android.service.euicc",
"android.service.notification",
"android.service.quicksettings",
"android.service.settings.suggestions",
- "android.service.controls.templates",
- "android.service.controls.actions",
- "android.service.controls",
],
exclude_annotations: ["org.junit.Ignore"],
}
@@ -708,8 +710,8 @@
base: "FrameworksCoreTests",
test_suites: [
"automotive-tests",
- "device-tests",
"device-platinum-tests",
+ "device-tests",
],
include_filters: ["android.view.contentcapture"],
}
@@ -719,8 +721,8 @@
base: "FrameworksCoreTests",
test_suites: [
"automotive-tests",
- "device-tests",
"device-platinum-tests",
+ "device-tests",
],
include_filters: ["android.view.contentprotection"],
}
@@ -730,8 +732,8 @@
base: "FrameworksCoreTests",
test_suites: [
"automotive-tests",
- "device-tests",
"device-platinum-tests",
+ "device-tests",
],
include_filters: ["com.android.internal.content."],
include_annotations: ["android.platform.test.annotations.Presubmit"],
@@ -742,8 +744,8 @@
base: "FrameworksCoreTests",
test_suites: [
"automotive-tests",
- "device-tests",
"device-platinum-tests",
+ "device-tests",
],
include_filters: ["android.graphics.drawable.IconTest"],
}
@@ -753,13 +755,13 @@
base: "FrameworksCoreTests",
test_suites: [
"automotive-tests",
- "device-tests",
"device-platinum-tests",
+ "device-tests",
],
include_filters: [
- "com.android.internal.accessibility",
"android.accessibilityservice",
"android.view.accessibility",
+ "com.android.internal.accessibility",
],
}
@@ -768,8 +770,8 @@
base: "FrameworksCoreTests",
test_suites: [
"automotive-tests",
- "device-tests",
"device-platinum-tests",
+ "device-tests",
],
include_filters: ["android.app.usage"],
}
@@ -779,8 +781,8 @@
base: "FrameworksCoreTests",
test_suites: [
"automotive-tests",
- "device-tests",
"device-platinum-tests",
+ "device-tests",
],
include_filters: ["com.android.internal.util.FastDataTest"],
}
@@ -790,8 +792,8 @@
base: "FrameworksCoreTests",
test_suites: [
"automotive-tests",
- "device-tests",
"device-platinum-tests",
+ "device-tests",
],
include_filters: ["android.hardware.input"],
}
@@ -801,12 +803,12 @@
base: "FrameworksCoreTests",
test_suites: [
"automotive-tests",
- "device-tests",
"device-platinum-tests",
+ "device-tests",
],
include_filters: [
- "android.view.VerifiedMotionEventTest",
"android.view.VerifiedKeyEventTest",
+ "android.view.VerifiedMotionEventTest",
],
}
@@ -839,8 +841,8 @@
base: "FrameworksCoreTests",
test_suites: [
"automotive-tests",
- "device-tests",
"device-platinum-tests",
+ "device-tests",
],
include_filters: [
"com.android.internal.jank.FrameTrackerTest",
@@ -854,8 +856,8 @@
base: "FrameworksCoreTests",
test_suites: [
"automotive-tests",
- "device-tests",
"device-platinum-tests",
+ "device-tests",
],
include_annotations: ["android.platform.test.annotations.PlatinumTest"],
}
diff --git a/core/tests/coretests/src/android/app/backup/BackupRestoreEventLoggerTest.java b/core/tests/coretests/src/android/app/backup/BackupRestoreEventLoggerTest.java
index 7b41217..ab2e77e 100644
--- a/core/tests/coretests/src/android/app/backup/BackupRestoreEventLoggerTest.java
+++ b/core/tests/coretests/src/android/app/backup/BackupRestoreEventLoggerTest.java
@@ -23,6 +23,8 @@
import static junit.framework.Assert.fail;
+import static org.junit.Assert.assertThrows;
+
import android.app.backup.BackupRestoreEventLogger.DataTypeResult;
import android.os.Parcel;
import android.platform.test.annotations.Presubmit;
@@ -32,6 +34,8 @@
import com.android.server.backup.Flags;
+import com.google.common.truth.Expect;
+
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -42,6 +46,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Map;
import java.util.Optional;
@Presubmit
@@ -64,6 +69,9 @@
@Rule
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+ @Rule
+ public final Expect expect = Expect.create();
+
@Before
public void setUp() throws Exception {
mHashDigest = MessageDigest.getInstance("SHA-256");
@@ -366,6 +374,32 @@
assertThat(mLogger.getLoggingResults()).isEmpty();
}
+ @Test
+ public void testDataTypeResultToString_nullArgs() {
+ assertThrows(NullPointerException.class, () -> BackupRestoreEventLogger.toString(null));
+ }
+
+ @Test
+ public void testDataTypeResultToString_typeOnly() {
+ DataTypeResult result = new DataTypeResult("The Type is Bond, James Bond!");
+
+ expect.withMessage("toString()")
+ .that(BackupRestoreEventLogger.toString(result)).isEqualTo(
+ "type=The Type is Bond, James Bond!, successCount=0, failCount=0");
+ }
+
+ @Test
+ public void testDataTypeResultToString_allFields() {
+ DataTypeResult result = DataTypeResultTest.createDataTypeResult(
+ "The Type is Bond, James Bond!", /* successCount= */ 42, /* failCount= */ 108,
+ Map.of("D'OH!", 666, "", 0), new byte[] { 4, 8, 15, 16, 23, 42 });
+
+ expect.withMessage("toString()")
+ .that(BackupRestoreEventLogger.toString(result)).isEqualTo(
+ "type=The Type is Bond, James Bond!, successCount=42, failCount=108, "
+ + "errors={=0, D'OH!=666}, metadataHash=[4, 8, 15, 16, 23, 42]");
+ }
+
private static DataTypeResult getResultForDataType(
BackupRestoreEventLogger logger, String dataType) {
Optional<DataTypeResult> result = getResultForDataTypeIfPresent(logger, dataType);
diff --git a/core/tests/coretests/src/android/app/backup/DataTypeResultTest.java b/core/tests/coretests/src/android/app/backup/DataTypeResultTest.java
new file mode 100644
index 0000000..cf9e9c6
--- /dev/null
+++ b/core/tests/coretests/src/android/app/backup/DataTypeResultTest.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2025 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.backup;
+
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import android.app.backup.BackupRestoreEventLogger.DataTypeResult;
+import android.os.Bundle;
+import android.os.Parcel;
+
+import com.google.common.truth.Expect;
+
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.util.Map;
+
+public final class DataTypeResultTest {
+
+ @Rule
+ public final Expect expect = Expect.create();
+
+ @Test
+ public void testGetters_defaultConstructorFields() {
+ var result = new DataTypeResult("The Type is Bond, James Bond!");
+
+ expect.withMessage("getDataType()").that(result.getDataType())
+ .isEqualTo("The Type is Bond, James Bond!");
+ expect.withMessage("getSuccessCount()").that(result.getSuccessCount()).isEqualTo(0);
+ expect.withMessage("getFailCount()").that(result.getFailCount()).isEqualTo(0);
+ expect.withMessage("getErrorsCount()").that(result.getErrors()).isEmpty();
+ expect.withMessage("getMetadataHash()").that(result.getMetadataHash()).isNull();
+ expect.withMessage("describeContents()").that(result.describeContents()).isEqualTo(0);
+ }
+
+ @Test
+ public void testGetters_allFields() {
+ DataTypeResult result = createDataTypeResult("The Type is Bond, James Bond!",
+ /* successCount= */ 42, /* failCount= */ 108, Map.of("D'OH!", 666),
+ new byte[] { 4, 8, 15, 16, 23, 42 });
+
+ expect.withMessage("getDataType()").that(result.getDataType())
+ .isEqualTo("The Type is Bond, James Bond!");
+ expect.withMessage("getSuccessCount()").that(result.getSuccessCount()).isEqualTo(42);
+ expect.withMessage("getFailCount()").that(result.getFailCount()).isEqualTo(108);
+ expect.withMessage("getErrorsCount()").that(result.getErrors()).containsExactly("D'OH!",
+ 666);
+ expect.withMessage("getMetadataHash()").that(result.getMetadataHash()).asList()
+ .containsExactly((byte) 4, (byte) 8, (byte) 15, (byte) 16, (byte) 23, (byte) 42)
+ .inOrder();
+ expect.withMessage("describeContents()").that(result.describeContents()).isEqualTo(0);
+ }
+
+ @Test
+ public void testParcelMethods() {
+ DataTypeResult original = createDataTypeResult("The Type is Bond, James Bond!",
+ /* successCount= */ 42, /* failCount= */ 108, Map.of("D'OH!", 666),
+ new byte[] { 4, 8, 15, 16, 23, 42 });
+ Parcel parcel = Parcel.obtain();
+ try {
+ original.writeToParcel(parcel, /* flags= */ 0);
+
+ parcel.setDataPosition(0);
+ var clone = DataTypeResult.CREATOR.createFromParcel(parcel);
+ assertWithMessage("createFromParcel()").that(clone).isNotNull();
+
+ expect.withMessage("getDataType()").that(clone.getDataType())
+ .isEqualTo(original.getDataType());
+ expect.withMessage("getSuccessCount()").that(clone.getSuccessCount())
+ .isEqualTo(original.getSuccessCount());
+ expect.withMessage("getFailCount()").that(clone.getFailCount())
+ .isEqualTo(original.getFailCount());
+ expect.withMessage("getErrorsCount()").that(clone.getErrors())
+ .containsExactlyEntriesIn(original.getErrors()).inOrder();
+ expect.withMessage("getMetadataHash()").that(clone.getMetadataHash())
+ .isEqualTo(original.getMetadataHash());
+ expect.withMessage("describeContents()").that(clone.describeContents()).isEqualTo(0);
+ } finally {
+ parcel.recycle();
+ }
+ }
+
+ static DataTypeResult createDataTypeResult(String dataType, int successCount, int failCount,
+ Map<String, Integer> errors, byte... metadataHash) {
+ Parcel parcel = Parcel.obtain();
+ try {
+ parcel.writeString(dataType);
+ parcel.writeInt(successCount);
+ parcel.writeInt(failCount);
+ Bundle errorsBundle = new Bundle();
+ errors.entrySet()
+ .forEach(entry -> errorsBundle.putInt(entry.getKey(), entry.getValue()));
+ parcel.writeBundle(errorsBundle);
+ parcel.writeByteArray(metadataHash);
+
+ parcel.setDataPosition(0);
+ var result = DataTypeResult.CREATOR.createFromParcel(parcel);
+ assertWithMessage("createFromParcel()").that(result).isNotNull();
+ return result;
+ } finally {
+ parcel.recycle();
+ }
+ }
+}
diff --git a/core/tests/coretests/src/android/content/ContextTest.java b/core/tests/coretests/src/android/content/ContextTest.java
index a02af78..2505500 100644
--- a/core/tests/coretests/src/android/content/ContextTest.java
+++ b/core/tests/coretests/src/android/content/ContextTest.java
@@ -23,6 +23,7 @@
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -35,17 +36,24 @@
import android.hardware.display.DisplayManager;
import android.hardware.display.VirtualDisplay;
import android.media.ImageReader;
+import android.os.Looper;
import android.os.UserHandle;
+import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.DisabledOnRavenwood;
+import android.platform.test.annotations.EnableFlags;
import android.platform.test.annotations.Presubmit;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.platform.test.ravenwood.RavenwoodRule;
import android.view.Display;
+import android.window.WindowTokenClient;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import androidx.test.platform.app.InstrumentationRegistry;
+import com.android.window.flags.Flags;
+
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -61,6 +69,9 @@
@Rule
public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder().build();
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
@Test
public void testInstrumentationContext() {
// Confirm that we have a valid Context
@@ -280,4 +291,44 @@
return appContext.createDisplayContext(display)
.createWindowContext(TYPE_APPLICATION_OVERLAY, null /* options */);
}
+
+ @Test
+ @DisabledOnRavenwood(blockedBy = Context.class)
+ @DisableFlags(Flags.FLAG_TRACK_SYSTEM_UI_CONTEXT_BEFORE_WMS)
+ public void testSysUiContextRegisterComponentCallbacks_disableFlag() {
+ Looper.prepare();
+
+ // Use createSystemActivityThreadForTesting to initialize
+ // systemUiContext#getApplicationContext.
+ final Context systemUiContext = ActivityThread.createSystemActivityThreadForTesting()
+ .getSystemUiContext();
+ final TestComponentCallbacks2 callbacks = new TestComponentCallbacks2();
+ systemUiContext.registerComponentCallbacks(callbacks);
+
+ final WindowTokenClient windowTokenClient =
+ (WindowTokenClient) systemUiContext.getWindowContextToken();
+ windowTokenClient.onConfigurationChanged(Configuration.EMPTY, DEFAULT_DISPLAY);
+
+ assertWithMessage("ComponentCallbacks should delegate to the app Context "
+ + "if the flag is disabled.").that(callbacks.mConfiguration).isNull();
+ }
+
+ @Test
+ @DisabledOnRavenwood(blockedBy = Context.class)
+ @EnableFlags(Flags.FLAG_TRACK_SYSTEM_UI_CONTEXT_BEFORE_WMS)
+ public void testSysUiContextRegisterComponentCallbacks_enableFlag() {
+ final Context systemUiContext = ActivityThread.currentActivityThread()
+ .createSystemUiContextForTesting(DEFAULT_DISPLAY);
+ final TestComponentCallbacks2 callbacks = new TestComponentCallbacks2();
+ final Configuration config = Configuration.EMPTY;
+
+ systemUiContext.registerComponentCallbacks(callbacks);
+
+ final WindowTokenClient windowTokenClient =
+ (WindowTokenClient) systemUiContext.getWindowContextToken();
+ windowTokenClient.onConfigurationChanged(config, DEFAULT_DISPLAY);
+
+ assertWithMessage("ComponentCallbacks should delegate to SystemUiContext "
+ + "if the flag is enabled.").that(callbacks.mConfiguration).isEqualTo(config);
+ }
}
diff --git a/core/tests/coretests/src/android/content/pm/SystemFeaturesCacheTest.java b/core/tests/coretests/src/android/content/pm/SystemFeaturesCacheTest.java
index ce4aa42..8b513cb 100644
--- a/core/tests/coretests/src/android/content/pm/SystemFeaturesCacheTest.java
+++ b/core/tests/coretests/src/android/content/pm/SystemFeaturesCacheTest.java
@@ -21,12 +21,16 @@
import static com.google.common.truth.Truth.assertThat;
-import android.os.Parcel;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assume.assumeTrue;
+
import android.util.ArrayMap;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
+import org.junit.After;
+import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -36,6 +40,19 @@
private SystemFeaturesCache mCache;
+ private SystemFeaturesCache mOriginalSingletonCache;
+
+ @Before
+ public void setUp() {
+ mOriginalSingletonCache = SystemFeaturesCache.getInstance();
+ }
+
+ @After
+ public void tearDown() {
+ SystemFeaturesCache.clearInstance();
+ SystemFeaturesCache.setInstance(mOriginalSingletonCache);
+ }
+
@Test
public void testNoFeatures() throws Exception {
SystemFeaturesCache cache = new SystemFeaturesCache(new ArrayMap<String, FeatureInfo>());
@@ -84,29 +101,57 @@
}
@Test
- public void testParcel() throws Exception {
+ public void testGetAndSetFeatureVersions() throws Exception {
ArrayMap<String, FeatureInfo> features = new ArrayMap<>();
features.put(FEATURE_WATCH, createFeature(FEATURE_WATCH, 0));
SystemFeaturesCache cache = new SystemFeaturesCache(features);
- Parcel parcel = Parcel.obtain();
- SystemFeaturesCache parceledCache;
- try {
- parcel.writeParcelable(cache, 0);
- parcel.setDataPosition(0);
- parceledCache = parcel.readParcelable(getClass().getClassLoader());
- } finally {
- parcel.recycle();
- }
+ assertThat(cache.getSdkFeatureVersions().length)
+ .isEqualTo(PackageManager.SDK_FEATURE_COUNT);
- assertThat(parceledCache.maybeHasFeature(FEATURE_WATCH, 0))
+ SystemFeaturesCache clonedCache = new SystemFeaturesCache(cache.getSdkFeatureVersions());
+ assertThat(cache.getSdkFeatureVersions()).isEqualTo(clonedCache.getSdkFeatureVersions());
+
+ assertThat(clonedCache.maybeHasFeature(FEATURE_WATCH, 0))
.isEqualTo(cache.maybeHasFeature(FEATURE_WATCH, 0));
- assertThat(parceledCache.maybeHasFeature(FEATURE_PICTURE_IN_PICTURE, 0))
+ assertThat(clonedCache.maybeHasFeature(FEATURE_PICTURE_IN_PICTURE, 0))
.isEqualTo(cache.maybeHasFeature(FEATURE_PICTURE_IN_PICTURE, 0));
- assertThat(parceledCache.maybeHasFeature("custom.feature", 0))
+ assertThat(clonedCache.maybeHasFeature("custom.feature", 0))
.isEqualTo(cache.maybeHasFeature("custom.feature", 0));
}
+ @Test
+ public void testInvalidFeatureVersions() throws Exception {
+ // Raw feature version arrays must match the predefined SDK feature count.
+ int[] invalidFeatureVersions = new int[PackageManager.SDK_FEATURE_COUNT - 1];
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> new SystemFeaturesCache(invalidFeatureVersions));
+ }
+
+ @Test
+ public void testSingleton() throws Exception {
+ ArrayMap<String, FeatureInfo> features = new ArrayMap<>();
+ features.put(FEATURE_WATCH, createFeature(FEATURE_WATCH, 0));
+ SystemFeaturesCache cache = new SystemFeaturesCache(features);
+
+ SystemFeaturesCache.clearInstance();
+ assertThrows(IllegalStateException.class, () -> SystemFeaturesCache.getInstance());
+
+ SystemFeaturesCache.setInstance(cache);
+ assertThat(SystemFeaturesCache.getInstance()).isEqualTo(cache);
+
+ assertThrows(
+ IllegalStateException.class,
+ () -> SystemFeaturesCache.setInstance(new SystemFeaturesCache(features)));
+ }
+
+ @Test
+ public void testSingletonAutomaticallySetWithFeatureEnabled() {
+ assumeTrue(android.content.pm.Flags.cacheSdkSystemFeatures());
+ assertThat(SystemFeaturesCache.getInstance()).isNotNull();
+ }
+
private static FeatureInfo createFeature(String name, int version) {
FeatureInfo fi = new FeatureInfo();
fi.name = name;
diff --git a/data/keyboards/Vendor_0957_Product_0001.kl b/data/keyboards/Vendor_0957_Product_0001.kl
index 87cb942..0241f36 100644
--- a/data/keyboards/Vendor_0957_Product_0001.kl
+++ b/data/keyboards/Vendor_0957_Product_0001.kl
@@ -72,6 +72,8 @@
key usage 0x000c008D GUIDE
key usage 0x000c0089 TV
+key usage 0x000c0187 FEATURED_APP_1 WAKE #FreeTv
+
key usage 0x000c009C CHANNEL_UP
key usage 0x000c009D CHANNEL_DOWN
diff --git a/graphics/java/android/graphics/FrameInfo.java b/graphics/java/android/graphics/FrameInfo.java
index 7d236d2..3b8f466 100644
--- a/graphics/java/android/graphics/FrameInfo.java
+++ b/graphics/java/android/graphics/FrameInfo.java
@@ -93,10 +93,12 @@
// Interval between two consecutive frames
public static final int FRAME_INTERVAL = 11;
+ // Workload target deadline for a frame
+ public static final int WORKLOAD_TARGET = 12;
+
// Must be the last one
// This value must be in sync with `UI_THREAD_FRAME_INFO_SIZE` in FrameInfo.h
- // In calculating size, + 1 for Flags, and + 1 for WorkloadTarget from FrameInfo.h
- private static final int FRAME_INFO_SIZE = FRAME_INTERVAL + 2;
+ private static final int FRAME_INFO_SIZE = WORKLOAD_TARGET + 1;
/** checkstyle */
public void setVsync(long intendedVsync, long usedVsync, long frameTimelineVsyncId,
@@ -108,6 +110,7 @@
frameInfo[FRAME_DEADLINE] = frameDeadline;
frameInfo[FRAME_START_TIME] = frameStartTime;
frameInfo[FRAME_INTERVAL] = frameInterval;
+ frameInfo[WORKLOAD_TARGET] = frameDeadline - intendedVsync;
}
/** checkstyle */
diff --git a/graphics/java/android/graphics/RuntimeShader.java b/graphics/java/android/graphics/RuntimeShader.java
index 9016724..db2376e 100644
--- a/graphics/java/android/graphics/RuntimeShader.java
+++ b/graphics/java/android/graphics/RuntimeShader.java
@@ -622,6 +622,7 @@
private static native long nativeGetFinalizer();
private static native long nativeCreateBuilder(String agsl);
+ private static native long nativeCreateShader(long shaderBuilder, long matrix);
private static native long nativeCreateShader(long shaderBuilder, long matrix,
long colorSpacePtr);
private static native void nativeUpdateUniforms(
diff --git a/keystore/java/android/security/GateKeeper.java b/keystore/java/android/security/GateKeeper.java
index 464714f..c2792e1f 100644
--- a/keystore/java/android/security/GateKeeper.java
+++ b/keystore/java/android/security/GateKeeper.java
@@ -28,7 +28,7 @@
*
* @hide
*/
-public abstract class GateKeeper {
+public final class GateKeeper {
public static final long INVALID_SECURE_USER_ID = 0;
diff --git a/keystore/java/android/security/keystore/ArrayUtils.java b/keystore/java/android/security/keystore/ArrayUtils.java
index f22b604..6472ca9 100644
--- a/keystore/java/android/security/keystore/ArrayUtils.java
+++ b/keystore/java/android/security/keystore/ArrayUtils.java
@@ -23,7 +23,7 @@
/**
* @hide
*/
-public abstract class ArrayUtils {
+public final class ArrayUtils {
private ArrayUtils() {}
public static String[] nullToEmpty(String[] array) {
diff --git a/keystore/java/android/security/keystore/Utils.java b/keystore/java/android/security/keystore/Utils.java
index e58b1cc..c38ce8e 100644
--- a/keystore/java/android/security/keystore/Utils.java
+++ b/keystore/java/android/security/keystore/Utils.java
@@ -23,7 +23,7 @@
*
* @hide
*/
-abstract class Utils {
+public final class Utils {
private Utils() {}
static Date cloneIfNotNull(Date value) {
diff --git a/keystore/java/android/security/keystore2/KeyStore2ParameterUtils.java b/keystore/java/android/security/keystore2/KeyStore2ParameterUtils.java
index 1394bd4..9d306ce 100644
--- a/keystore/java/android/security/keystore2/KeyStore2ParameterUtils.java
+++ b/keystore/java/android/security/keystore2/KeyStore2ParameterUtils.java
@@ -38,7 +38,9 @@
/**
* @hide
*/
-public abstract class KeyStore2ParameterUtils {
+public final class KeyStore2ParameterUtils {
+
+ private KeyStore2ParameterUtils() {}
/**
* This function constructs a {@link KeyParameter} expressing a boolean value.
diff --git a/keystore/java/android/security/keystore2/KeymasterUtils.java b/keystore/java/android/security/keystore2/KeymasterUtils.java
index 614e368..02f3f57 100644
--- a/keystore/java/android/security/keystore2/KeymasterUtils.java
+++ b/keystore/java/android/security/keystore2/KeymasterUtils.java
@@ -16,13 +16,10 @@
package android.security.keystore2;
-import android.security.keymaster.KeymasterArguments;
import android.security.keymaster.KeymasterDefs;
-import android.security.keystore.KeyProperties;
import java.security.AlgorithmParameters;
import java.security.NoSuchAlgorithmException;
-import java.security.ProviderException;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.ECParameterSpec;
import java.security.spec.InvalidParameterSpecException;
@@ -30,7 +27,7 @@
/**
* @hide
*/
-public abstract class KeymasterUtils {
+public final class KeymasterUtils {
private KeymasterUtils() {}
@@ -86,47 +83,6 @@
}
}
- /**
- * Adds {@code KM_TAG_MIN_MAC_LENGTH} tag, if necessary, to the keymaster arguments for
- * generating or importing a key. This tag may only be needed for symmetric keys (e.g., HMAC,
- * AES-GCM).
- */
- public static void addMinMacLengthAuthorizationIfNecessary(KeymasterArguments args,
- int keymasterAlgorithm,
- int[] keymasterBlockModes,
- int[] keymasterDigests) {
- switch (keymasterAlgorithm) {
- case KeymasterDefs.KM_ALGORITHM_AES:
- if (com.android.internal.util.ArrayUtils.contains(
- keymasterBlockModes, KeymasterDefs.KM_MODE_GCM)) {
- // AES GCM key needs the minimum length of AEAD tag specified.
- args.addUnsignedInt(KeymasterDefs.KM_TAG_MIN_MAC_LENGTH,
- AndroidKeyStoreAuthenticatedAESCipherSpi.GCM
- .MIN_SUPPORTED_TAG_LENGTH_BITS);
- }
- break;
- case KeymasterDefs.KM_ALGORITHM_HMAC:
- // HMAC key needs the minimum length of MAC set to the output size of the associated
- // digest. This is because we do not offer a way to generate shorter MACs and
- // don't offer a way to verify MACs (other than by generating them).
- if (keymasterDigests.length != 1) {
- throw new ProviderException(
- "Unsupported number of authorized digests for HMAC key: "
- + keymasterDigests.length
- + ". Exactly one digest must be authorized");
- }
- int keymasterDigest = keymasterDigests[0];
- int digestOutputSizeBits = getDigestOutputSizeBits(keymasterDigest);
- if (digestOutputSizeBits == -1) {
- throw new ProviderException(
- "HMAC key authorized for unsupported digest: "
- + KeyProperties.Digest.fromKeymaster(keymasterDigest));
- }
- args.addUnsignedInt(KeymasterDefs.KM_TAG_MIN_MAC_LENGTH, digestOutputSizeBits);
- break;
- }
- }
-
static String getEcCurveFromKeymaster(int ecCurve) {
switch (ecCurve) {
case android.hardware.security.keymint.EcCurve.P_224:
diff --git a/libs/WindowManager/Shell/OWNERS b/libs/WindowManager/Shell/OWNERS
index ab2f3ef..68970e6 100644
--- a/libs/WindowManager/Shell/OWNERS
+++ b/libs/WindowManager/Shell/OWNERS
@@ -3,5 +3,5 @@
pragyabajoria@google.com
# Give submodule owners in shell resource approval
-per-file res*/*/*.xml = atsjenk@google.com, hwwang@google.com, lbill@google.com, madym@google.com, vaniadesmonda@google.com, pbdr@google.com, mpodolian@google.com, liranb@google.com, pragyabajoria@google.com, uysalorhan@google.com, gsennton@google.com, mattsziklay@google.com, mdehaini@google.com
+per-file res*/*/*.xml = atsjenk@google.com, hwwang@google.com, lbill@google.com, madym@google.com, vaniadesmonda@google.com, pbdr@google.com, mpodolian@google.com, liranb@google.com, pragyabajoria@google.com, uysalorhan@google.com, gsennton@google.com, mattsziklay@google.com, mdehaini@google.com, peanutbutter@google.com, jeremysim@google.com
per-file res*/*/tv_*.xml = bronger@google.com
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/foldable_inner/light_landscape_dragZones_bubble.png b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/foldable_inner/light_landscape_dragZones_bubble.png
new file mode 100644
index 0000000..1519874
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/foldable_inner/light_landscape_dragZones_bubble.png
Binary files differ
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/foldable_inner/light_landscape_dragZones_bubbleBar.png b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/foldable_inner/light_landscape_dragZones_bubbleBar.png
new file mode 100644
index 0000000..99673f6
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/foldable_inner/light_landscape_dragZones_bubbleBar.png
Binary files differ
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/foldable_inner/light_landscape_dragZones_bubble_split_10_90.png b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/foldable_inner/light_landscape_dragZones_bubble_split_10_90.png
new file mode 100644
index 0000000..ba4ebab7
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/foldable_inner/light_landscape_dragZones_bubble_split_10_90.png
Binary files differ
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/foldable_inner/light_landscape_dragZones_bubble_split_90_10.png b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/foldable_inner/light_landscape_dragZones_bubble_split_90_10.png
new file mode 100644
index 0000000..b3ff644
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/foldable_inner/light_landscape_dragZones_bubble_split_90_10.png
Binary files differ
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/foldable_inner/light_landscape_dragZones_expandedView.png b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/foldable_inner/light_landscape_dragZones_expandedView.png
new file mode 100644
index 0000000..534e320
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/foldable_inner/light_landscape_dragZones_expandedView.png
Binary files differ
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/foldable_inner/light_landscape_dragZones_expandedView_split_10_90.png b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/foldable_inner/light_landscape_dragZones_expandedView_split_10_90.png
new file mode 100644
index 0000000..67c9f49
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/foldable_inner/light_landscape_dragZones_expandedView_split_10_90.png
Binary files differ
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/foldable_inner/light_landscape_dragZones_expandedView_split_90_10.png b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/foldable_inner/light_landscape_dragZones_expandedView_split_90_10.png
new file mode 100644
index 0000000..a0fb490
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/foldable_inner/light_landscape_dragZones_expandedView_split_90_10.png
Binary files differ
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/foldable_inner/light_portrait_dragZones_bubble.png b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/foldable_inner/light_portrait_dragZones_bubble.png
new file mode 100644
index 0000000..27b35d4
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/foldable_inner/light_portrait_dragZones_bubble.png
Binary files differ
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/foldable_inner/light_portrait_dragZones_bubbleBar.png b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/foldable_inner/light_portrait_dragZones_bubbleBar.png
new file mode 100644
index 0000000..11528a0
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/foldable_inner/light_portrait_dragZones_bubbleBar.png
Binary files differ
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/foldable_inner/light_portrait_dragZones_bubble_split_10_90.png b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/foldable_inner/light_portrait_dragZones_bubble_split_10_90.png
new file mode 100644
index 0000000..ef99377
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/foldable_inner/light_portrait_dragZones_bubble_split_10_90.png
Binary files differ
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/foldable_inner/light_portrait_dragZones_bubble_split_90_10.png b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/foldable_inner/light_portrait_dragZones_bubble_split_90_10.png
new file mode 100644
index 0000000..f0cf08b
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/foldable_inner/light_portrait_dragZones_bubble_split_90_10.png
Binary files differ
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/foldable_inner/light_portrait_dragZones_expandedView.png b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/foldable_inner/light_portrait_dragZones_expandedView.png
new file mode 100644
index 0000000..bbaafb3
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/foldable_inner/light_portrait_dragZones_expandedView.png
Binary files differ
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/tablet/light_landscape_dragZones_bubble.png b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/tablet/light_landscape_dragZones_bubble.png
new file mode 100644
index 0000000..38ebf3f
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/tablet/light_landscape_dragZones_bubble.png
Binary files differ
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/tablet/light_landscape_dragZones_bubbleBar.png b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/tablet/light_landscape_dragZones_bubbleBar.png
new file mode 100644
index 0000000..2e4fd51
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/tablet/light_landscape_dragZones_bubbleBar.png
Binary files differ
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/tablet/light_landscape_dragZones_expandedView.png b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/tablet/light_landscape_dragZones_expandedView.png
new file mode 100644
index 0000000..a1ba9fb
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/tablet/light_landscape_dragZones_expandedView.png
Binary files differ
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/tablet/light_portrait_dragZones_bubble.png b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/tablet/light_portrait_dragZones_bubble.png
new file mode 100644
index 0000000..51bb15e
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/tablet/light_portrait_dragZones_bubble.png
Binary files differ
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/tablet/light_portrait_dragZones_bubbleBar.png b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/tablet/light_portrait_dragZones_bubbleBar.png
new file mode 100644
index 0000000..b643e2a
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/tablet/light_portrait_dragZones_bubbleBar.png
Binary files differ
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/tablet/light_portrait_dragZones_expandedView.png b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/tablet/light_portrait_dragZones_expandedView.png
new file mode 100644
index 0000000..e6eeab7
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/tablet/light_portrait_dragZones_expandedView.png
Binary files differ
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/src/com/android/wm/shell/shared/bubbles/DragZoneFactoryScreenshotTest.kt b/libs/WindowManager/Shell/multivalentScreenshotTests/src/com/android/wm/shell/shared/bubbles/DragZoneFactoryScreenshotTest.kt
new file mode 100644
index 0000000..24f43d3
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/src/com/android/wm/shell/shared/bubbles/DragZoneFactoryScreenshotTest.kt
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2025 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.shared.bubbles
+
+import android.content.Context
+import android.graphics.Color
+import android.graphics.drawable.Drawable
+import android.graphics.drawable.GradientDrawable
+import android.view.View
+import android.view.WindowManager
+import android.widget.FrameLayout
+import androidx.annotation.ColorInt
+import androidx.core.graphics.blue
+import androidx.core.graphics.green
+import androidx.core.graphics.red
+import androidx.core.graphics.toColorInt
+import androidx.test.core.app.ApplicationProvider.getApplicationContext
+import com.android.wm.shell.shared.bubbles.DragZoneFactory.DesktopWindowModeChecker
+import com.android.wm.shell.shared.bubbles.DragZoneFactory.SplitScreenModeChecker
+import com.android.wm.shell.shared.bubbles.DragZoneFactory.SplitScreenModeChecker.SplitScreenMode
+import com.android.wm.shell.testing.goldenpathmanager.WMShellGoldenPathManager
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
+import platform.test.screenshot.DeviceEmulationSpec
+import platform.test.screenshot.Displays
+import platform.test.screenshot.ViewScreenshotTestRule
+import platform.test.screenshot.ViewScreenshotTestRule.Mode
+import platform.test.screenshot.getEmulatedDevicePathConfig
+
+@RunWith(ParameterizedAndroidJunit4::class)
+class DragZoneFactoryScreenshotTest(private val param: Param) {
+ companion object {
+ @Parameters(name = "{0}")
+ @JvmStatic
+ fun getTestSpecs(): List<Param> {
+ val params = mutableListOf<Param>()
+ val draggedObjects =
+ listOf(
+ DraggedObject.Bubble(BubbleBarLocation.LEFT),
+ DraggedObject.BubbleBar(BubbleBarLocation.LEFT),
+ DraggedObject.ExpandedView(BubbleBarLocation.LEFT),
+ )
+ DeviceEmulationSpec.forDisplays(Displays.Tablet, isDarkTheme = false).forEach { tablet
+ ->
+ draggedObjects.forEach { draggedObject ->
+ params.add(Param(tablet, draggedObject, SplitScreenMode.NONE))
+ }
+ }
+ DeviceEmulationSpec.forDisplays(Displays.FoldableInner, isDarkTheme = false).forEach {
+ foldable ->
+ draggedObjects.forEach { draggedObject ->
+ params.add(Param(foldable, draggedObject, SplitScreenMode.NONE))
+ val isBubble = draggedObject is DraggedObject.Bubble
+ val isExpandedView = draggedObject is DraggedObject.ExpandedView
+ val addMoreSplitModes = isBubble || (isExpandedView && foldable.isLandscape)
+ if (addMoreSplitModes) {
+ params.add(Param(foldable, draggedObject, SplitScreenMode.SPLIT_10_90))
+ params.add(Param(foldable, draggedObject, SplitScreenMode.SPLIT_90_10))
+ }
+ }
+ }
+ return params
+ }
+ }
+
+ class Param(
+ val emulationSpec: DeviceEmulationSpec,
+ val draggedObject: DraggedObject,
+ val splitScreenMode: SplitScreenMode
+ ) {
+ private val draggedObjectName =
+ when (draggedObject) {
+ is DraggedObject.Bubble -> "bubble"
+ is DraggedObject.BubbleBar -> "bubbleBar"
+ is DraggedObject.ExpandedView -> "expandedView"
+ }
+
+ private val splitScreenModeName =
+ when (splitScreenMode) {
+ SplitScreenMode.NONE -> ""
+ SplitScreenMode.SPLIT_50_50 -> "_split_50_50"
+ SplitScreenMode.SPLIT_10_90 -> "_split_10_90"
+ SplitScreenMode.SPLIT_90_10 -> "_split_90_10"
+ }
+
+ val testName = "$draggedObjectName$splitScreenModeName"
+
+ override fun toString() = "${emulationSpec}_$testName"
+ }
+
+ @get:Rule
+ val screenshotRule =
+ ViewScreenshotTestRule(
+ param.emulationSpec,
+ WMShellGoldenPathManager(getEmulatedDevicePathConfig(param.emulationSpec))
+ )
+
+ private val context = getApplicationContext<Context>()
+
+ @Test
+ fun dragZones() {
+ screenshotRule.screenshotTest("dragZones_${param.testName}", mode = Mode.MatchSize) {
+ activity ->
+ activity.actionBar?.hide()
+ val dragZoneFactory = createDragZoneFactory()
+ val dragZones = dragZoneFactory.createSortedDragZones(param.draggedObject)
+ val container = FrameLayout(context)
+ dragZones.forEach { zone -> container.addZoneView(zone) }
+ container
+ }
+ }
+
+ private fun createDragZoneFactory(): DragZoneFactory {
+ val deviceConfig =
+ DeviceConfig.create(context, context.getSystemService(WindowManager::class.java)!!)
+ val splitScreenModeChecker = SplitScreenModeChecker { param.splitScreenMode }
+ val desktopWindowModeChecker = DesktopWindowModeChecker { true }
+ return DragZoneFactory(
+ context,
+ deviceConfig,
+ splitScreenModeChecker,
+ desktopWindowModeChecker
+ )
+ }
+
+ private fun FrameLayout.addZoneView(zone: DragZone) {
+ val view = View(context)
+ this.addView(view, 0)
+ view.layoutParams = FrameLayout.LayoutParams(zone.bounds.width(), zone.bounds.height())
+ view.background = createZoneDrawable(zone.color)
+ view.x = zone.bounds.left.toFloat()
+ view.y = zone.bounds.top.toFloat()
+ }
+
+ private fun createZoneDrawable(@ColorInt color: Int): Drawable {
+ val shape = GradientDrawable()
+ shape.shape = GradientDrawable.RECTANGLE
+ shape.setColor(Color.argb(128, color.red, color.green, color.blue))
+ shape.setStroke(2, color)
+ return shape
+ }
+
+ private val DragZone.color: Int
+ @ColorInt
+ get() =
+ when (this) {
+ is DragZone.Bubble -> "#3F5C8B".toColorInt()
+ is DragZone.Dismiss -> "#8B3F3F".toColorInt()
+ is DragZone.Split -> "#89B675".toColorInt()
+ is DragZone.FullScreen -> "#4ED075".toColorInt()
+ is DragZone.DesktopWindow -> "#EC928E".toColorInt()
+ }
+}
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 8d7e5fd..d50a14c 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
@@ -18,23 +18,28 @@
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:id="@+id/maximize_menu"
android:layout_width="wrap_content"
- android:layout_height="@dimen/desktop_mode_maximize_menu_height"
+ android:layout_height="wrap_content"
android:background="@drawable/desktop_mode_maximize_menu_background"
android:elevation="1dp">
<LinearLayout
android:id="@+id/container"
android:layout_width="wrap_content"
- android:layout_height="@dimen/desktop_mode_maximize_menu_height"
+ android:layout_height="wrap_content"
android:orientation="horizontal"
- android:padding="16dp"
+ android:paddingHorizontal="12dp"
+ android:paddingVertical="16dp"
+ android:measureWithLargestChild="true"
android:gravity="center">
<LinearLayout
android:id="@+id/maximize_menu_immersive_toggle_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:orientation="vertical">
+ android:layout_weight="1"
+ android:orientation="vertical"
+ android:layout_marginStart="4dp"
+ android:layout_marginEnd="4dp">
<Button
android:layout_width="94dp"
@@ -44,21 +49,22 @@
android:stateListAnimator="@null"
android:importantForAccessibility="yes"
android:contentDescription="@string/desktop_mode_maximize_menu_immersive_button_text"
- android:layout_marginEnd="8dp"
android:layout_marginBottom="4dp"
android:alpha="0"/>
<TextView
android:id="@+id/maximize_menu_immersive_toggle_button_text"
- android:layout_width="94dp"
- android:layout_height="18dp"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
android:textSize="11sp"
- android:layout_marginBottom="76dp"
+ android:lineHeight="16sp"
android:gravity="center"
android:fontFamily="google-sans-text"
+ android:textFontWeight="500"
android:importantForAccessibility="no"
android:text="@string/desktop_mode_maximize_menu_immersive_button_text"
android:textColor="@androidprv:color/materialColorOnSurface"
+ android:singleLine="true"
android:alpha="0"/>
</LinearLayout>
@@ -66,7 +72,11 @@
android:id="@+id/maximize_menu_size_toggle_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:orientation="vertical">
+ android:layout_weight="1"
+ android:orientation="vertical"
+ android:gravity="center_horizontal"
+ android:layout_marginStart="4dp"
+ android:layout_marginEnd="4dp">
<Button
android:layout_width="94dp"
@@ -81,15 +91,17 @@
<TextView
android:id="@+id/maximize_menu_size_toggle_button_text"
- android:layout_width="94dp"
- android:layout_height="18dp"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
android:textSize="11sp"
- android:layout_marginBottom="76dp"
+ android:lineHeight="16sp"
android:gravity="center"
android:fontFamily="google-sans-text"
+ android:textFontWeight="500"
android:importantForAccessibility="no"
android:text="@string/desktop_mode_maximize_menu_maximize_text"
android:textColor="@androidprv:color/materialColorOnSurface"
+ android:singleLine="true"
android:alpha="0"/>
</LinearLayout>
@@ -97,7 +109,11 @@
android:id="@+id/maximize_menu_snap_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:orientation="vertical">
+ android:layout_weight="1"
+ android:orientation="vertical"
+ android:gravity="center_horizontal"
+ android:layout_marginStart="4dp"
+ android:layout_marginEnd="4dp">
<LinearLayout
android:id="@+id/maximize_menu_snap_menu_layout"
android:layout_width="wrap_content"
@@ -106,7 +122,6 @@
android:padding="4dp"
android:background="@drawable/desktop_mode_maximize_menu_layout_background"
android:layout_marginBottom="4dp"
- android:layout_marginStart="8dp"
android:alpha="0">
<Button
android:id="@+id/maximize_menu_snap_left_button"
@@ -131,16 +146,17 @@
</LinearLayout>
<TextView
android:id="@+id/maximize_menu_snap_window_text"
- android:layout_width="94dp"
- android:layout_height="18dp"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
android:textSize="11sp"
- android:layout_marginBottom="76dp"
- android:layout_gravity="center"
+ android:lineHeight="16sp"
android:gravity="center"
android:importantForAccessibility="no"
android:fontFamily="google-sans-text"
+ android:textFontWeight="500"
android:text="@string/desktop_mode_maximize_menu_snap_text"
android:textColor="@androidprv:color/materialColorOnSurface"
+ android:singleLine="true"
android:alpha="0"/>
</LinearLayout>
</LinearLayout>
@@ -150,6 +166,6 @@
<View
android:id="@+id/maximize_menu_overlay"
android:layout_width="match_parent"
- android:layout_height="@dimen/desktop_mode_maximize_menu_height"/>
+ android:layout_height="match_parent"/>
</FrameLayout>
diff --git a/libs/WindowManager/Shell/res/values-af/strings.xml b/libs/WindowManager/Shell/res/values-af/strings.xml
index 5444c26..b4d594f 100644
--- a/libs/WindowManager/Shell/res/values-af/strings.xml
+++ b/libs/WindowManager/Shell/res/values-af/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"Apphandvatsel"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Appikoon"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Volskerm"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Rekenaarmodus"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"Verdeelde skerm"</string>
<string name="more_button_text" msgid="3655388105592893530">"Meer"</string>
<string name="float_button_text" msgid="9221657008391364581">"Sweef"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Verander aspekverhouding"</string>
<string name="close_text" msgid="4986518933445178928">"Maak toe"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Maak kieslys toe"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Maak kieslys oop"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimeer skerm"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Verander grootte"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"App kan nie hierheen geskuif word nie"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Verander grootte van linkerkantse venster"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Verander grootte van regterkantse venster"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Maksimeer of stel venstergrootte terug"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Gaan na deelskermmodus"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Gaan na werkskermvenstermodus"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Verander grootte van linkerkantse venster"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Verander grootte van regterkantse venster"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maksimeer of stel venstergrootte terug"</string>
diff --git a/libs/WindowManager/Shell/res/values-am/strings.xml b/libs/WindowManager/Shell/res/values-am/strings.xml
index f3bc29d..9ec8001 100644
--- a/libs/WindowManager/Shell/res/values-am/strings.xml
+++ b/libs/WindowManager/Shell/res/values-am/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"የመተግበሪያ መያዣ"</string>
<string name="app_icon_text" msgid="2823268023931811747">"የመተግበሪያ አዶ"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"ሙሉ ማያ"</string>
- <string name="desktop_text" msgid="1077633567027630454">"የዴስክቶፕ ሁነታ"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"የተከፈለ ማያ ገፅ"</string>
<string name="more_button_text" msgid="3655388105592893530">"ተጨማሪ"</string>
<string name="float_button_text" msgid="9221657008391364581">"ተንሳፋፊ"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"ምጥጥነ ገፅታ ለውጥ"</string>
<string name="close_text" msgid="4986518933445178928">"ዝጋ"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"ምናሌ ዝጋ"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"ምናሌን ክፈት"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"የማያ ገጹ መጠን አሳድግ"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"መጠን ቀይር"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"መተግበሪያ ወደዚህ መንቀሳቀስ አይችልም"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"የመተግበሪያ መስኮትን ወደ ግራ መጠን ቀይር"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"የመተግበሪያ መስኮትን ወደ ቀኝ መጠን ቀይር"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"የመስኮት መጠንን አሳድግ ወይም ወደነበረበት መልስ"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"ወደ የተከፈለ ማያ ገፅ ሁነታ ግባ"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"ወደ የዴስክቶፕ መስኮት ሁነታ ግባ"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"መስኮትን ወደ ግራ መጠን ቀይር"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"መስኮትን ወደ ቀኝ መጠን ቀይር"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"የመስኮት መጠንን አሳድግ ወይም ወደነበረበት መልስ"</string>
diff --git a/libs/WindowManager/Shell/res/values-ar/strings.xml b/libs/WindowManager/Shell/res/values-ar/strings.xml
index 60f27cf..1680922 100644
--- a/libs/WindowManager/Shell/res/values-ar/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ar/strings.xml
@@ -119,7 +119,7 @@
<string name="handle_text" msgid="4419667835599523257">"مقبض التطبيق"</string>
<string name="app_icon_text" msgid="2823268023931811747">"رمز التطبيق"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"ملء الشاشة"</string>
- <string name="desktop_text" msgid="1077633567027630454">"وضع سطح المكتب"</string>
+ <string name="desktop_text" msgid="1582173066857454541">"العرض المخصّص للكمبيوتر المكتبي"</string>
<string name="split_screen_text" msgid="1396336058129570886">"تقسيم الشاشة"</string>
<string name="more_button_text" msgid="3655388105592893530">"المزيد"</string>
<string name="float_button_text" msgid="9221657008391364581">"نافذة عائمة"</string>
@@ -132,7 +132,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"تغيير نسبة العرض إلى الارتفاع"</string>
<string name="close_text" msgid="4986518933445178928">"إغلاق"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"إغلاق القائمة"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"فتح القائمة"</string>
+ <string name="desktop_mode_app_header_chip_text" msgid="8300164817452574565">"<xliff:g id="APP_NAME">%1$s</xliff:g> (العرض المخصّص للكمبيوتر المكتبي)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"تكبير الشاشة إلى أقصى حدّ"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"تغيير الحجم"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"لا يمكن نقل التطبيق إلى هنا"</string>
@@ -145,8 +145,8 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"تغيير حجم نافذة التطبيق بمحاذاتها إلى اليمين"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"تغيير حجم نافذة التطبيق بمحاذاتها إلى اليسار"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"تكبير حجم النافذة أو استعادته"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"تفعيل \"وضع تقسيم الشاشة\""</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"تفعيل وضع عرض المحتوى في النافذة الحالية على سطح المكتب"</string>
+ <string name="app_handle_chip_accessibility_announce" msgid="499881698947450536">"فتح القائمة"</string>
+ <string name="app_handle_menu_accessibility_announce" msgid="7928858564852785398">"تفعيل \"<xliff:g id="WINDOWING_MODE">%1$s</xliff:g>\""</string>
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"تغيير حجم النافذة بمحاذاتها إلى اليمين"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"تغيير حجم النافذة بمحاذاتها إلى اليسار"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"تكبير حجم النافذة أو استعادته"</string>
diff --git a/libs/WindowManager/Shell/res/values-as/strings.xml b/libs/WindowManager/Shell/res/values-as/strings.xml
index 0f43347..05860c2 100644
--- a/libs/WindowManager/Shell/res/values-as/strings.xml
+++ b/libs/WindowManager/Shell/res/values-as/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"এপৰ হেণ্ডেল"</string>
<string name="app_icon_text" msgid="2823268023931811747">"এপৰ চিহ্ন"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"সম্পূৰ্ণ স্ক্ৰীন"</string>
- <string name="desktop_text" msgid="1077633567027630454">"ডেস্কটপ ম’ড"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"বিভাজিত স্ক্ৰীন"</string>
<string name="more_button_text" msgid="3655388105592893530">"অধিক"</string>
<string name="float_button_text" msgid="9221657008391364581">"ওপঙা"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"আকাৰৰ অনুপাত সলনি কৰক"</string>
<string name="close_text" msgid="4986518933445178928">"বন্ধ কৰক"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"মেনু বন্ধ কৰক"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"মেনু খোলক"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"স্ক্ৰীন মেক্সিমাইজ কৰক"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"আকাৰ সলনি কৰক"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ইয়ালৈ এপ্টো আনিব নোৱাৰি"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"বাওঁফালে এপ্ ৱিণ্ড’ৰ আকাৰ সলনি কৰক"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"সোঁফালে এপ্ ৱিণ্ড’ৰ আকাৰ সলনি কৰক"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"ৱিণ্ড’ৰ আকাৰ মেক্সিমাইজ বা পুনঃস্থাপন কৰক"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"বিভাজিত-স্ক্ৰীন ম’ড দিয়ক"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"ডেস্কটপ ৱিণ্ড’ইং ম’ড দিয়ক"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"সোঁফাললৈ ৱিণ্ড’ৰ আকাৰ সলনি কৰক"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"বাওঁফাললৈ ৱিণ্ড’ৰ আকাৰ সলনি কৰক"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"ৱিণ্ড’ৰ আকাৰ মেক্সিমাইজ বা পুনঃস্থাপন কৰক"</string>
diff --git a/libs/WindowManager/Shell/res/values-az/strings.xml b/libs/WindowManager/Shell/res/values-az/strings.xml
index aced354..ea64749 100644
--- a/libs/WindowManager/Shell/res/values-az/strings.xml
+++ b/libs/WindowManager/Shell/res/values-az/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"Tətbiq ləqəbi"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Tətbiq ikonası"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Tam Ekran"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Masaüstü Rejimi"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"Bölünmüş Ekran"</string>
<string name="more_button_text" msgid="3655388105592893530">"Ardı"</string>
<string name="float_button_text" msgid="9221657008391364581">"Üzən pəncərə"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Tərəflər nisbətini dəyişin"</string>
<string name="close_text" msgid="4986518933445178928">"Bağlayın"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Menyunu bağlayın"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Menyunu açın"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Ekranı maksimum böyüdün"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Ölçüsünü dəyişin"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Tətbiqi bura köçürmək mümkün deyil"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Tətbiq pəncərəsinin ölçüsünü sola dəyişin"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Tətbiq pəncərəsinin ölçüsünü sağa dəyişin"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Pəncərə ölçüsünü artırın və ya bərpa edin"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Bölünmüş ekran rejiminə daxil olun"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Masaüstü pəncərə rejiminə daxil olun"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Pəncərə ölçüsünü sola dəyişin"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Pəncərə ölçüsünü sağa dəyişin"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Pəncərə ölçüsünü artırın və ya bərpa edin"</string>
diff --git a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
index b07c612..deec04f 100644
--- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
@@ -119,7 +119,7 @@
<string name="handle_text" msgid="4419667835599523257">"Identifikator aplikacije"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ikona aplikacije"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Preko celog ekrana"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Režim za računare"</string>
+ <string name="desktop_text" msgid="1582173066857454541">"Prikaz za računare"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Podeljeni ekran"</string>
<string name="more_button_text" msgid="3655388105592893530">"Još"</string>
<string name="float_button_text" msgid="9221657008391364581">"Plutajuće"</string>
@@ -132,7 +132,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Promeni razmeru"</string>
<string name="close_text" msgid="4986518933445178928">"Zatvorite"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Zatvorite meni"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Otvorite meni"</string>
+ <string name="desktop_mode_app_header_chip_text" msgid="8300164817452574565">"<xliff:g id="APP_NAME">%1$s</xliff:g> (prikaz za računare)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Povećaj ekran"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Promeni veličinu"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikacija ne može da se premesti ovde"</string>
@@ -145,8 +145,8 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Promenite veličinu prozora aplikacije nalevo"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Promenite veličinu prozora aplikacije nadesno"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Uvećajte ili vratite veličinu prozora"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Uđite u režim podeljenog ekrana"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Uđite u režim prozora na računaru"</string>
+ <string name="app_handle_chip_accessibility_announce" msgid="499881698947450536">"Otvorite Meni"</string>
+ <string name="app_handle_menu_accessibility_announce" msgid="7928858564852785398">"Unesite <xliff:g id="WINDOWING_MODE">%1$s</xliff:g>"</string>
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Promenite veličinu prozora nalevo"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Promenite veličinu prozora nadesno"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Uvećajte ili vratite veličinu prozora"</string>
diff --git a/libs/WindowManager/Shell/res/values-be/strings.xml b/libs/WindowManager/Shell/res/values-be/strings.xml
index 4c2950b..d26c37b 100644
--- a/libs/WindowManager/Shell/res/values-be/strings.xml
+++ b/libs/WindowManager/Shell/res/values-be/strings.xml
@@ -119,7 +119,7 @@
<string name="handle_text" msgid="4419667835599523257">"Маркер праграмы"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Значок праграмы"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"На ўвесь экран"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Рэжым працоўнага стала"</string>
+ <string name="desktop_text" msgid="1582173066857454541">"Версія для камп’ютараў"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Падзяліць экран"</string>
<string name="more_button_text" msgid="3655388105592893530">"Яшчэ"</string>
<string name="float_button_text" msgid="9221657008391364581">"Зрабіць рухомым акном"</string>
@@ -132,7 +132,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Змяніць суадносіны бакоў"</string>
<string name="close_text" msgid="4986518933445178928">"Закрыць"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Закрыць меню"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Адкрыць меню"</string>
+ <string name="desktop_mode_app_header_chip_text" msgid="8300164817452574565">"<xliff:g id="APP_NAME">%1$s</xliff:g> (версія для камп’ютараў)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Разгарнуць на ўвесь экран"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Змяніць памер"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Нельга перамясціць сюды праграму"</string>
@@ -145,8 +145,8 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Змяніць памер акна (злева)"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Змяніць памер акна (справа)"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Разгарнуць акно ці аднавіць яго памер"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Уключыць рэжым падзеленага экрана"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Уключыць рэжым вокнаў працоўнага стала"</string>
+ <string name="app_handle_chip_accessibility_announce" msgid="499881698947450536">"Адкрыць меню"</string>
+ <string name="app_handle_menu_accessibility_announce" msgid="7928858564852785398">"Увесці \"<xliff:g id="WINDOWING_MODE">%1$s</xliff:g>\""</string>
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Змяніць памер акна і перамясціць да левага краю"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Змяніць памер акна і перамясціць да правага краю"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Разгарнуць акно ці аднавіць яго памер"</string>
diff --git a/libs/WindowManager/Shell/res/values-bg/strings.xml b/libs/WindowManager/Shell/res/values-bg/strings.xml
index fcc4d83..0bb5960 100644
--- a/libs/WindowManager/Shell/res/values-bg/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bg/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"Манипулатор за приложението"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Икона на приложението"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Цял екран"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Режим за настолни компютри"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"Разделяне на екрана"</string>
<string name="more_button_text" msgid="3655388105592893530">"Още"</string>
<string name="float_button_text" msgid="9221657008391364581">"Плаващо"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Промяна на съотношението"</string>
<string name="close_text" msgid="4986518933445178928">"Затваряне"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Затваряне на менюто"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Отваряне на менюто"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Увеличаване на екрана"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Преоразмеряване"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Приложението не може да бъде преместено тук"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Преоразмеряване на прозореца на приложението наляво"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Преоразмеряване на прозореца на приложението надясно"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Увеличаване или възстановяване на размера на прозореца"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Активиране на режима за разделен екран"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Активиране на режима за настолни компютри"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Преоразмеряване на прозореца наляво"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Преоразмеряване на прозореца надясно"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Увеличаване или възстановяване на размера на прозореца"</string>
diff --git a/libs/WindowManager/Shell/res/values-bn/strings.xml b/libs/WindowManager/Shell/res/values-bn/strings.xml
index b2c435e..ae63e04 100644
--- a/libs/WindowManager/Shell/res/values-bn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bn/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"অ্যাপের হ্যান্ডেল"</string>
<string name="app_icon_text" msgid="2823268023931811747">"অ্যাপ আইকন"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"ফুলস্ক্রিন"</string>
- <string name="desktop_text" msgid="1077633567027630454">"ডেস্কটপ মোড"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"স্প্লিট স্ক্রিন"</string>
<string name="more_button_text" msgid="3655388105592893530">"আরও"</string>
<string name="float_button_text" msgid="9221657008391364581">"ফ্লোট"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"অ্যাস্পেক্ট রেশিও পরিবর্তন করুন"</string>
<string name="close_text" msgid="4986518933445178928">"বন্ধ করুন"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"\'মেনু\' বন্ধ করুন"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"মেনু খুলুন"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"স্ক্রিন বড় করুন"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"ছোট বড় করুন"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"অ্যাপটি এখানে সরানো যাবে না"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"বাঁদিকে অ্যাপ উইন্ডো রিসাইজ করুন"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"ডানদিকে অ্যাপ উইন্ডো রিসাইজ করুন"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"উইন্ডো সাইজ বড় বা রিস্টোর করুন"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"স্প্লিট স্ক্রিন মোডে প্রবেশ করুন"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"ডেস্কটপ উইন্ডোইং মোডে প্রবেশ করুন"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"বাঁদিকে উইন্ডো রিসাইজ করুন"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"ডানদিকে উইন্ডো রিসাইজ করুন"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"উইন্ডো সাইজ বড় বা রিস্টোর করুন"</string>
diff --git a/libs/WindowManager/Shell/res/values-bs/strings.xml b/libs/WindowManager/Shell/res/values-bs/strings.xml
index 8c1619c..b7c76b5 100644
--- a/libs/WindowManager/Shell/res/values-bs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bs/strings.xml
@@ -119,7 +119,7 @@
<string name="handle_text" msgid="4419667835599523257">"Ručica aplikacije"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ikona aplikacije"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Cijeli ekran"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Način rada radne površine"</string>
+ <string name="desktop_text" msgid="1582173066857454541">"Prikaz na računalu"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Podijeljeni ekran"</string>
<string name="more_button_text" msgid="3655388105592893530">"Više"</string>
<string name="float_button_text" msgid="9221657008391364581">"Lebdeći"</string>
@@ -132,7 +132,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Promjena formata slike"</string>
<string name="close_text" msgid="4986518933445178928">"Zatvaranje"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Zatvaranje menija"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Otvaranje menija"</string>
+ <string name="desktop_mode_app_header_chip_text" msgid="8300164817452574565">"<xliff:g id="APP_NAME">%1$s</xliff:g> (prikaz na računalu)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimiziraj ekran"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Promijeni veličinu"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Ne možete premjestiti aplikaciju ovdje"</string>
@@ -145,8 +145,8 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Promjena veličine prozora aplikacije lijevo"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Promjena veličine prozora aplikacije desno"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Maksimiziranje ili vraćanje veličine prozora"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Pokretanje načina rada podijeljenog ekrana"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Pokretanje načina rada s prozorima na radnoj površini"</string>
+ <string name="app_handle_chip_accessibility_announce" msgid="499881698947450536">"Otvorite izbornik"</string>
+ <string name="app_handle_menu_accessibility_announce" msgid="7928858564852785398">"Unesite <xliff:g id="WINDOWING_MODE">%1$s</xliff:g>"</string>
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Promjena veličine prozora i poravnanje lijevo"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Promjena veličine prozora i poravnanje desno"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maksimiziranje ili vraćanje veličine prozora"</string>
diff --git a/libs/WindowManager/Shell/res/values-ca/strings.xml b/libs/WindowManager/Shell/res/values-ca/strings.xml
index 37802f4..80dd380 100644
--- a/libs/WindowManager/Shell/res/values-ca/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ca/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"Identificador de l\'aplicació"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Icona de l\'aplicació"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Pantalla completa"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Mode d\'escriptori"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"Pantalla dividida"</string>
<string name="more_button_text" msgid="3655388105592893530">"Més"</string>
<string name="float_button_text" msgid="9221657008391364581">"Flotant"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Canvia la relació d\'aspecte"</string>
<string name="close_text" msgid="4986518933445178928">"Tanca"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Tanca el menú"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Obre el menú"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximitza la pantalla"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Canvia la mida"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"L\'aplicació no es pot moure aquí"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Canvia la mida de la finestra de l\'aplicació a l\'esquerra"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Canvia la mida de la finestra de l\'aplicació a la dreta"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Maximitza o restaura la mida de la finestra"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Entra al mode de pantalla dividida"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Entra al mode d\'enfinestrament a l\'escriptori"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Canvia la mida de la finestra a l\'esquerra"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Canvia la mida de la finestra a la dreta"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maximitza o restaura la mida de la finestra"</string>
diff --git a/libs/WindowManager/Shell/res/values-cs/strings.xml b/libs/WindowManager/Shell/res/values-cs/strings.xml
index c4514eb..e47d1f6 100644
--- a/libs/WindowManager/Shell/res/values-cs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-cs/strings.xml
@@ -119,7 +119,7 @@
<string name="handle_text" msgid="4419667835599523257">"Popisovač aplikace"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ikona aplikace"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Celá obrazovka"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Režim počítače"</string>
+ <string name="desktop_text" msgid="1582173066857454541">"Zobrazení na počítači"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Rozdělená obrazovka"</string>
<string name="more_button_text" msgid="3655388105592893530">"Více"</string>
<string name="float_button_text" msgid="9221657008391364581">"Plovoucí"</string>
@@ -132,7 +132,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Změnit poměr stran"</string>
<string name="close_text" msgid="4986518933445178928">"Zavřít"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Zavřít nabídku"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Otevřít nabídku"</string>
+ <string name="desktop_mode_app_header_chip_text" msgid="8300164817452574565">"<xliff:g id="APP_NAME">%1$s</xliff:g> (zobrazení na počítači)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximalizovat obrazovku"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Změnit velikost"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikaci sem nelze přesunout"</string>
@@ -145,8 +145,8 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Změnit velikost okna aplikace vlevo"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Změnit velikost okna aplikace vpravo"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Maximalizovat nebo obnovit velikost okna"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Přechod do režimu rozdělené obrazovky"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Přejít do režimu okenního systému pro počítače"</string>
+ <string name="app_handle_chip_accessibility_announce" msgid="499881698947450536">"Otevřít nabídku"</string>
+ <string name="app_handle_menu_accessibility_announce" msgid="7928858564852785398">"Přejít do režimu <xliff:g id="WINDOWING_MODE">%1$s</xliff:g>"</string>
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Přichytit okno vlevo"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Přichytit okno vpravo"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maximalizovat nebo obnovit velikost okna"</string>
diff --git a/libs/WindowManager/Shell/res/values-da/strings.xml b/libs/WindowManager/Shell/res/values-da/strings.xml
index e662a16..c465ce3 100644
--- a/libs/WindowManager/Shell/res/values-da/strings.xml
+++ b/libs/WindowManager/Shell/res/values-da/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"Apphåndtag"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Appikon"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Fuld skærm"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Computertilstand"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"Opdelt skærm"</string>
<string name="more_button_text" msgid="3655388105592893530">"Mere"</string>
<string name="float_button_text" msgid="9221657008391364581">"Svævende"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Skift billedformat"</string>
<string name="close_text" msgid="4986518933445178928">"Luk"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Luk menu"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Åbn menu"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimér skærm"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Tilpas størrelse"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Apps kan ikke flyttes hertil"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Juster størrelsen på appvinduet til venstre"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Juster størrelsen på appvinduet til højre"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Maksimer eller gendan vinduesstørrelse"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Åbn opdelt skærm"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Åbn tilstanden for vinduer på computeren"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Juster størrelsen på vinduet til venstre"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Juster størrelsen på vinduet til højre"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maksimer eller gendan vinduesstørrelse"</string>
diff --git a/libs/WindowManager/Shell/res/values-de/strings.xml b/libs/WindowManager/Shell/res/values-de/strings.xml
index 7b21719..567dd7a 100644
--- a/libs/WindowManager/Shell/res/values-de/strings.xml
+++ b/libs/WindowManager/Shell/res/values-de/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"App-Ziehpunkt"</string>
<string name="app_icon_text" msgid="2823268023931811747">"App-Symbol"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Vollbild"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Desktopmodus"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"Splitscreen"</string>
<string name="more_button_text" msgid="3655388105592893530">"Mehr"</string>
<string name="float_button_text" msgid="9221657008391364581">"Frei schwebend"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Seitenverhältnis ändern"</string>
<string name="close_text" msgid="4986518933445178928">"Schließen"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Menü schließen"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Menü öffnen"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Bildschirm maximieren"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Größe ändern"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Die App kann nicht hierher verschoben werden"</string>
@@ -142,13 +144,15 @@
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Wiederherstellen"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Links andocken"</string>
<string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Rechts andocken"</string>
- <string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Größe des linken App-Fensters anpassen"</string>
- <string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Größe des rechten App-Fensters anpassen"</string>
+ <string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Größe des App-Fensters links anpassen"</string>
+ <string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Größe des App-Fensters rechts anpassen"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Fenstergröße maximieren oder wiederherstellen"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Splitscreen-Modus aktivieren"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Desktop-Fenstermodus aktivieren"</string>
- <string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Fenstergröße links anpassen"</string>
- <string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Fenstergröße rechts anpassen"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
+ <string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Fenstergröße nach links anpassen"</string>
+ <string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Fenstergröße nach rechts anpassen"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Fenstergröße maximieren oder wiederherstellen"</string>
<string name="maximize_button_talkback_action_maximize_restore_text" msgid="4122441323153198455">"Fenstergröße maximieren oder wiederherstellen"</string>
<string name="minimize_button_talkback_action_maximize_restore_text" msgid="8890767445425625935">"App-Fenster minimieren"</string>
diff --git a/libs/WindowManager/Shell/res/values-el/strings.xml b/libs/WindowManager/Shell/res/values-el/strings.xml
index eb45a31..489a4ce 100644
--- a/libs/WindowManager/Shell/res/values-el/strings.xml
+++ b/libs/WindowManager/Shell/res/values-el/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"Λαβή εφαρμογής"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Εικονίδιο εφαρμογής"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Πλήρης οθόνη"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Λειτουργία επιφάνειας εργασίας"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"Διαχωρισμός οθόνης"</string>
<string name="more_button_text" msgid="3655388105592893530">"Περισσότερα"</string>
<string name="float_button_text" msgid="9221657008391364581">"Κινούμενο"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Αλλαγή λόγου διαστάσεων"</string>
<string name="close_text" msgid="4986518933445178928">"Κλείσιμο"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Κλείσιμο μενού"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Άνοιγμα μενού"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Μεγιστοποίηση οθόνης"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Αλλαγή μεγέθους"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Δεν είναι δυνατή η μετακίνηση της εφαρμογής εδώ"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Αλλαγή μεγέθους παραθύρου εφαρμογής αριστερά"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Αλλαγή μεγέθους παραθύρου εφαρμογής δεξιά"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Μεγιστοποίηση ή επαναφορά μεγέθους παραθύρου"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Είσοδος στη λειτουργία διαχωρισμού οθόνης"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Είσοδος στη λειτουργία προσαρμογής σε παράθυρο υπολογιστή"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Αλλαγή μεγέθους παραθύρου προς τα αριστερά"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Αλλαγή μεγέθους παραθύρου προς τα δεξιά"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Μεγιστοποίηση ή επαναφορά μεγέθους παραθύρου"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
index 8dc27da..1a3d422 100644
--- a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"App handle"</string>
<string name="app_icon_text" msgid="2823268023931811747">"App icon"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Full screen"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Desktop mode"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"Split screen"</string>
<string name="more_button_text" msgid="3655388105592893530">"More"</string>
<string name="float_button_text" msgid="9221657008391364581">"Float"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Change aspect ratio"</string>
<string name="close_text" msgid="4986518933445178928">"Close"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Close menu"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Open menu"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximise screen"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Resize"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"App can\'t be moved here"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Resize app window left"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Resize app window right"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Maximise or restore window size"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Enter split-screen mode"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Enter desktop windowing mode"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Resize window to left"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Resize window to right"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maximise or restore window size"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
index 20d141e..e552f95 100644
--- a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
@@ -119,7 +119,7 @@
<string name="handle_text" msgid="4419667835599523257">"App handle"</string>
<string name="app_icon_text" msgid="2823268023931811747">"App Icon"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Fullscreen"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Desktop Mode"</string>
+ <string name="desktop_text" msgid="1582173066857454541">"Desktop View"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Split Screen"</string>
<string name="more_button_text" msgid="3655388105592893530">"More"</string>
<string name="float_button_text" msgid="9221657008391364581">"Float"</string>
@@ -132,7 +132,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Change aspect ratio"</string>
<string name="close_text" msgid="4986518933445178928">"Close"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Close Menu"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Open Menu"</string>
+ <string name="desktop_mode_app_header_chip_text" msgid="8300164817452574565">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Desktop View)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximize Screen"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Resize"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"App can\'t be moved here"</string>
@@ -145,8 +145,8 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Resize app window left"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Resize app window right"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Maximize or restore window size"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Enter split screen mode"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Enter desktop windowing mode"</string>
+ <string name="app_handle_chip_accessibility_announce" msgid="499881698947450536">"Open Menu"</string>
+ <string name="app_handle_menu_accessibility_announce" msgid="7928858564852785398">"Enter <xliff:g id="WINDOWING_MODE">%1$s</xliff:g>"</string>
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Resize window to left"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Resize window to right"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maximize or restore window size"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
index 8dc27da..1a3d422 100644
--- a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"App handle"</string>
<string name="app_icon_text" msgid="2823268023931811747">"App icon"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Full screen"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Desktop mode"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"Split screen"</string>
<string name="more_button_text" msgid="3655388105592893530">"More"</string>
<string name="float_button_text" msgid="9221657008391364581">"Float"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Change aspect ratio"</string>
<string name="close_text" msgid="4986518933445178928">"Close"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Close menu"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Open menu"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximise screen"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Resize"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"App can\'t be moved here"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Resize app window left"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Resize app window right"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Maximise or restore window size"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Enter split-screen mode"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Enter desktop windowing mode"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Resize window to left"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Resize window to right"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maximise or restore window size"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
index 8dc27da..1a3d422 100644
--- a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"App handle"</string>
<string name="app_icon_text" msgid="2823268023931811747">"App icon"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Full screen"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Desktop mode"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"Split screen"</string>
<string name="more_button_text" msgid="3655388105592893530">"More"</string>
<string name="float_button_text" msgid="9221657008391364581">"Float"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Change aspect ratio"</string>
<string name="close_text" msgid="4986518933445178928">"Close"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Close menu"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Open menu"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximise screen"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Resize"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"App can\'t be moved here"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Resize app window left"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Resize app window right"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Maximise or restore window size"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Enter split-screen mode"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Enter desktop windowing mode"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Resize window to left"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Resize window to right"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maximise or restore window size"</string>
diff --git a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
index 24c2bed..93aa1b6 100644
--- a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"Controlador de la app"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ícono de la app"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Pantalla completa"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Modo de escritorio"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"Pantalla dividida"</string>
<string name="more_button_text" msgid="3655388105592893530">"Más"</string>
<string name="float_button_text" msgid="9221657008391364581">"Flotante"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Cambiar relación de aspecto"</string>
<string name="close_text" msgid="4986518933445178928">"Cerrar"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Cerrar menú"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Abrir el menú"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximizar pantalla"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Cambiar el tamaño"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"No se puede mover la app aquí"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Ajustar el tamaño de la ventana de la app hacia la izquierda"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Ajustar el tamaño de la ventana de la app hacia la derecha"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Maximizar o restablecer el tamaño de la ventana"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Activar el modo de pantalla dividida"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Ingresar al modo ventana de computadora"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Ajustar el tamaño de la ventana hacia la izquierda"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Ajustar el tamaño de la ventana hacia la derecha"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maximizar o restablecer el tamaño de la ventana"</string>
diff --git a/libs/WindowManager/Shell/res/values-es/strings.xml b/libs/WindowManager/Shell/res/values-es/strings.xml
index dd9635d..27c5b80 100644
--- a/libs/WindowManager/Shell/res/values-es/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"Controlador de la aplicación"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Icono de la aplicación"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Pantalla completa"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Modo Escritorio"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"Pantalla dividida"</string>
<string name="more_button_text" msgid="3655388105592893530">"Más"</string>
<string name="float_button_text" msgid="9221657008391364581">"Flotante"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Cambiar relación de aspecto"</string>
<string name="close_text" msgid="4986518933445178928">"Cerrar"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Cerrar menú"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Abrir menú"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximizar pantalla"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Cambiar tamaño"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"La aplicación no se puede mover aquí"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Cambiar tamaño de la ventana de la aplicación izquierda"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Cambiar tamaño de la ventana de la aplicación derecha"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Maximizar o restaurar tamaño de la ventana"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Activar modo Pantalla dividida"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Activar modo Escritorio basado en ventanas"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Cambiar tamaño de la ventana a la izquierda"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Cambiar tamaño de la ventana a la derecha"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maximizar o restaurar tamaño de la ventana"</string>
diff --git a/libs/WindowManager/Shell/res/values-et/strings.xml b/libs/WindowManager/Shell/res/values-et/strings.xml
index 56b5f0b..c8ab83e 100644
--- a/libs/WindowManager/Shell/res/values-et/strings.xml
+++ b/libs/WindowManager/Shell/res/values-et/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"Rakenduse element"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Rakenduse ikoon"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Täisekraan"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Lauaarvuti režiim"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"Jagatud ekraanikuva"</string>
<string name="more_button_text" msgid="3655388105592893530">"Rohkem"</string>
<string name="float_button_text" msgid="9221657008391364581">"Hõljuv"</string>
@@ -132,11 +133,12 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Kuvasuhte muutmine"</string>
<string name="close_text" msgid="4986518933445178928">"Sule"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Sule menüü"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Ava menüü"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Kuva täisekraanil"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Suuruse muutmine"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Rakendust ei saa siia teisaldada"</string>
- <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Kaasahaarav"</string>
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Mahuta"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Taasta"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maksimeeri"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Taasta"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Rakenduse akna suuruse muutmine vasakul"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Rakenduse akna suuruse muutmine paremal"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Akna suuruse maksimeerimine või taastamine"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Poolitatud ekraani režiimi sisenemine"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Töölaua akende kuvamise režiimi sisenemine"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Akna suuruse muutmine, vasakule"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Akna suuruse muutmine, paremale"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Akna suuruse maksimeerimine või taastamine"</string>
diff --git a/libs/WindowManager/Shell/res/values-eu/strings.xml b/libs/WindowManager/Shell/res/values-eu/strings.xml
index 9898af0..abd92ab 100644
--- a/libs/WindowManager/Shell/res/values-eu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-eu/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"Aplikazioaren kontrol-puntua"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Aplikazioaren ikonoa"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Pantaila osoa"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Ordenagailuetarako modua"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"Pantaila zatitzea"</string>
<string name="more_button_text" msgid="3655388105592893530">"Gehiago"</string>
<string name="float_button_text" msgid="9221657008391364581">"Leiho gainerakorra"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Aldatu aspektu-erlazioa"</string>
<string name="close_text" msgid="4986518933445178928">"Itxi"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Itxi menua"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Ireki menua"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Handitu pantaila"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Aldatu tamaina"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikazioa ezin da hona ekarri"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Aldatu aplikazioaren leihoaren tamaina eta eraman ezkerrera"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Aldatu aplikazioaren leihoaren tamaina eta eraman eskuinera"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Maximizatu edo leheneratu leihoaren tamaina"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Sartu pantaila zatituaren moduan"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Sartu ordenagailuan leihoak erabiltzeko moduan"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Aldatu leihoaren tamaina eta eraman ezkerrera"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Aldatu leihoaren tamaina eta eraman eskuinera"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maximizatu edo leheneratu leihoaren tamaina"</string>
diff --git a/libs/WindowManager/Shell/res/values-fa/strings.xml b/libs/WindowManager/Shell/res/values-fa/strings.xml
index 22ef61f..651635a 100644
--- a/libs/WindowManager/Shell/res/values-fa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fa/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"دستگیره برنامه"</string>
<string name="app_icon_text" msgid="2823268023931811747">"نماد برنامه"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"تمامصفحه"</string>
- <string name="desktop_text" msgid="1077633567027630454">"حالت رایانه"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"صفحهٔ دونیمه"</string>
<string name="more_button_text" msgid="3655388105592893530">"بیشتر"</string>
<string name="float_button_text" msgid="9221657008391364581">"شناور"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"تغییر نسبت ابعادی"</string>
<string name="close_text" msgid="4986518933445178928">"بستن"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"بستن منو"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"باز کردن منو"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"بزرگ کردن صفحه"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"تغییر اندازه"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"برنامه را نمیتوان به اینجا منتقل کرد"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"تغییر اندازه پنجره برنامه در چپ"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"تغییر اندازه پنجره برنامه در راست"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"بیشینهسازی یا بازیابی اندازه پنجره"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"ورود به حالت صفحه تقسیمشده"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"رفتن به حالت پردازش پنجرهای میز کار"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"تغییر اندازه پنجره به چپ"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"تغییر اندازه پنجره به راست"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"بیشینهسازی یا بازیابی اندازه پنجره"</string>
diff --git a/libs/WindowManager/Shell/res/values-fi/strings.xml b/libs/WindowManager/Shell/res/values-fi/strings.xml
index b23c833..47e9ea3 100644
--- a/libs/WindowManager/Shell/res/values-fi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fi/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"Sovelluksen tunnus"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Sovelluskuvake"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Koko näyttö"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Työpöytätila"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"Jaettu näyttö"</string>
<string name="more_button_text" msgid="3655388105592893530">"Lisää"</string>
<string name="float_button_text" msgid="9221657008391364581">"Kelluva ikkuna"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Vaihda kuvasuhdetta"</string>
<string name="close_text" msgid="4986518933445178928">"Sulje"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Sulje valikko"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Avaa valikko"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Suurenna näyttö"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Muuta kokoa"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Sovellusta ei voi siirtää tänne"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Muuta vasemmanpuoleisen sovellusikkunan kokoa"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Muuta oikeanpuoleisen sovellusikkunan kokoa"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Suurenna ikkuna tai palauta ikkunan koko"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Avaa kahtia jaettu näyttö"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Siirry työpöydän ikkunointitilaan"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Muuta vasemmanpuoleisen ikkunan kokoa"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Muuta vasemmanpuoleisen ikkunan kokoa"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Suurenna ikkuna tai palauta ikkunan koko"</string>
diff --git a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
index 34b5b0a..dc2025f 100644
--- a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
@@ -119,7 +119,7 @@
<string name="handle_text" msgid="4419667835599523257">"Poignée de l\'appli"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Icône de l\'appli"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Plein écran"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Mode Bureau"</string>
+ <string name="desktop_text" msgid="1582173066857454541">"Affichage sur un ordinateur de bureau"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Écran divisé"</string>
<string name="more_button_text" msgid="3655388105592893530">"Plus"</string>
<string name="float_button_text" msgid="9221657008391364581">"Flottant"</string>
@@ -132,7 +132,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Modifier les proportions"</string>
<string name="close_text" msgid="4986518933445178928">"Fermer"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Fermer le menu"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Ouvrir le menu"</string>
+ <string name="desktop_mode_app_header_chip_text" msgid="8300164817452574565">"<xliff:g id="APP_NAME">%1$s</xliff:g> (affichage sur un ordinateur de bureau)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Agrandir l\'écran"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Redimensionner"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Impossible de déplacer l\'appli ici"</string>
@@ -145,8 +145,8 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Redimensionner la fenêtre de l\'appli à gauche"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Redimensionner la fenêtre de l\'appli à droite"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Agrandir ou restaurer la taille de la fenêtre"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Entrer en mode Écran divisé"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Entrer en mode Fenêtrage bureau"</string>
+ <string name="app_handle_chip_accessibility_announce" msgid="499881698947450536">"Ouvrir le menu"</string>
+ <string name="app_handle_menu_accessibility_announce" msgid="7928858564852785398">"Entrez <xliff:g id="WINDOWING_MODE">%1$s</xliff:g>"</string>
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Redimensionner la fenêtre vers la gauche"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Redimensionner la fenêtre vers la droite"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Agrandir ou restaurer la taille de la fenêtre"</string>
diff --git a/libs/WindowManager/Shell/res/values-fr/strings.xml b/libs/WindowManager/Shell/res/values-fr/strings.xml
index be41bba..038a90d 100644
--- a/libs/WindowManager/Shell/res/values-fr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"Poignée de l\'appli"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Icône d\'application"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Plein écran"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Mode ordinateur"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"Écran partagé"</string>
<string name="more_button_text" msgid="3655388105592893530">"Plus"</string>
<string name="float_button_text" msgid="9221657008391364581">"Flottante"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Modifier le format"</string>
<string name="close_text" msgid="4986518933445178928">"Fermer"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Fermer le menu"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Ouvrir le menu"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Mettre en plein écran"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Redimensionner"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Impossible de déplacer l\'appli ici"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Redimensionner la fenêtre de l\'appli vers la gauche"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Redimensionner la fenêtre de l\'appli vers la droite"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Agrandir ou restaurer la taille de la fenêtre"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Passer en mode Écran partagé"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Activer le mode fenêtrage du bureau"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Redimensionner la fenêtre vers la gauche"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Redimensionner la fenêtre vers la droite"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Agrandir ou restaurer la taille de la fenêtre"</string>
diff --git a/libs/WindowManager/Shell/res/values-gl/strings.xml b/libs/WindowManager/Shell/res/values-gl/strings.xml
index aa2f639..a2a6b3e 100644
--- a/libs/WindowManager/Shell/res/values-gl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gl/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"Controlador da aplicación"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Icona de aplicación"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Pantalla completa"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Modo de escritorio"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"Pantalla dividida"</string>
<string name="more_button_text" msgid="3655388105592893530">"Máis"</string>
<string name="float_button_text" msgid="9221657008391364581">"Flotante"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Cambiar a proporción"</string>
<string name="close_text" msgid="4986518933445178928">"Pechar"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Pechar o menú"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Abrir o menú"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximizar pantalla"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Cambiar tamaño"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Non se pode mover aquí a aplicación"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Axustar o tamaño da ventá da aplicación á esquerda"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Axustar o tamaño da ventá da aplicación á dereita"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Maximizar ou restaurar o tamaño da ventá"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Entrar no modo de pantalla dividida"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Entrar no modo de ventás do ordenador"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Axustar o tamaño da ventá á esquerda"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Axustar o tamaño da ventá á dereita"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maximizar ou restaurar o tamaño da ventá"</string>
diff --git a/libs/WindowManager/Shell/res/values-gu/strings.xml b/libs/WindowManager/Shell/res/values-gu/strings.xml
index dcd5738..196784b 100644
--- a/libs/WindowManager/Shell/res/values-gu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gu/strings.xml
@@ -119,7 +119,7 @@
<string name="handle_text" msgid="4419667835599523257">"ઍપનું હૅન્ડલ"</string>
<string name="app_icon_text" msgid="2823268023931811747">"ઍપનું આઇકન"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"પૂર્ણસ્ક્રીન"</string>
- <string name="desktop_text" msgid="1077633567027630454">"ડેસ્કટૉપ મોડ"</string>
+ <string name="desktop_text" msgid="1582173066857454541">"ડેસ્કટૉપ વ્યૂ"</string>
<string name="split_screen_text" msgid="1396336058129570886">"સ્ક્રીનને વિભાજિત કરો"</string>
<string name="more_button_text" msgid="3655388105592893530">"વધુ"</string>
<string name="float_button_text" msgid="9221657008391364581">"ફ્લોટિંગ વિન્ડો"</string>
@@ -132,7 +132,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"સાપેક્ષ ગુણોત્તર બદલો"</string>
<string name="close_text" msgid="4986518933445178928">"બંધ કરો"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"મેનૂ બંધ કરો"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"મેનૂ ખોલો"</string>
+ <string name="desktop_mode_app_header_chip_text" msgid="8300164817452574565">"<xliff:g id="APP_NAME">%1$s</xliff:g> (ડેસ્કટૉપ વ્યૂ)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"સ્ક્રીન કરો મોટી કરો"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"કદ બદલો"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ઍપ અહીં ખસેડી શકાતી નથી"</string>
@@ -145,8 +145,8 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"ડાબી બાજુથી ઍપની વિન્ડોનું કદ બદલો"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"જમણી બાજુથી ઍપની વિન્ડોનું કદ બદલો"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"વિન્ડોનું કદ મહત્તમ કરો અથવા રિસ્ટોર કરો"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"સ્ક્રીન-વિભાજન મોડ દાખલ કરો"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"ડેસ્કટૉપ વિન્ડો મોડ દાખલ કરો"</string>
+ <string name="app_handle_chip_accessibility_announce" msgid="499881698947450536">"મેનૂ ખોલો"</string>
+ <string name="app_handle_menu_accessibility_announce" msgid="7928858564852785398">"<xliff:g id="WINDOWING_MODE">%1$s</xliff:g> દાખલ કરો"</string>
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"ડાબી બાજુ વિન્ડોનું કદ બદલો"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"જમણી બાજુ વિન્ડોનું કદ બદલો"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"વિન્ડોનું કદ મહત્તમ કરો અથવા રિસ્ટોર કરો"</string>
diff --git a/libs/WindowManager/Shell/res/values-hi/strings.xml b/libs/WindowManager/Shell/res/values-hi/strings.xml
index 4bf2d92..f1f2a0a 100644
--- a/libs/WindowManager/Shell/res/values-hi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hi/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"ऐप्लिकेशन का हैंडल"</string>
<string name="app_icon_text" msgid="2823268023931811747">"ऐप्लिकेशन आइकॉन"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"फ़ुलस्क्रीन"</string>
- <string name="desktop_text" msgid="1077633567027630454">"डेस्कटॉप मोड"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"स्प्लिट स्क्रीन मोड"</string>
<string name="more_button_text" msgid="3655388105592893530">"ज़्यादा देखें"</string>
<string name="float_button_text" msgid="9221657008391364581">"फ़्लोट"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"आसपेक्ट रेशियो (लंबाई-चौड़ाई का अनुपात) बदलें"</string>
<string name="close_text" msgid="4986518933445178928">"बंद करें"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"मेन्यू बंद करें"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"मेन्यू खोलें"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"स्क्रीन को बड़ा करें"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"साइज़ बदलें"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ऐप्लिकेशन को यहां मूव नहीं किया जा सकता"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"ऐप्लिकेशन विंडो का साइज़ बाईं ओर से बदलें"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"ऐप्लिकेशन विंडो का साइज़ दाईं ओर से बदलें"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"विंडो को बड़ा करें या उसका साइज़ पहले जैसा करें"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"स्प्लिट स्क्रीन मोड में चालू करें"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"डेस्कटॉप विंडो मोड में जाएं"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"विंडो का साइज़ बाईं ओर से बदलें"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"विंडो का साइज़ दाईं ओर से बढ़ाएं"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"विंडो को बड़ा करें या उसका साइज़ पहले जैसा करें"</string>
diff --git a/libs/WindowManager/Shell/res/values-hr/strings.xml b/libs/WindowManager/Shell/res/values-hr/strings.xml
index 157822c..b1187dc 100644
--- a/libs/WindowManager/Shell/res/values-hr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hr/strings.xml
@@ -119,7 +119,7 @@
<string name="handle_text" msgid="4419667835599523257">"Pokazivač aplikacije"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ikona aplikacije"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Puni zaslon"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Stolni način rada"</string>
+ <string name="desktop_text" msgid="1582173066857454541">"Prikaz na računalu"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Razdvojeni zaslon"</string>
<string name="more_button_text" msgid="3655388105592893530">"Više"</string>
<string name="float_button_text" msgid="9221657008391364581">"Plutajući"</string>
@@ -132,7 +132,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Promijeni omjer slike"</string>
<string name="close_text" msgid="4986518933445178928">"Zatvorite"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Zatvorite izbornik"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Otvaranje izbornika"</string>
+ <string name="desktop_mode_app_header_chip_text" msgid="8300164817452574565">"<xliff:g id="APP_NAME">%1$s</xliff:g> (prikaz na računalu)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimalno povećaj zaslon"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Promijeni veličinu"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikacija se ne može premjestiti ovdje"</string>
@@ -145,8 +145,8 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Promijeni veličinu prozora aplikacije ulijevo"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Promijeni veličinu prozora aplikacije udesno"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Maksimiziraj ili vrati veličinu prozora"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Pokreni način podijeljenog zaslona"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Pokreni način prikaza u prozorima na računalu"</string>
+ <string name="app_handle_chip_accessibility_announce" msgid="499881698947450536">"Otvorite izbornik"</string>
+ <string name="app_handle_menu_accessibility_announce" msgid="7928858564852785398">"Unesite <xliff:g id="WINDOWING_MODE">%1$s</xliff:g>"</string>
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Promijeni veličinu prozora ulijevo"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Promijeni veličinu prozora udesno"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maksimiziraj ili vrati veličinu prozora"</string>
diff --git a/libs/WindowManager/Shell/res/values-hu/strings.xml b/libs/WindowManager/Shell/res/values-hu/strings.xml
index 546a465..5d52c48 100644
--- a/libs/WindowManager/Shell/res/values-hu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hu/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"App fogópontja"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Alkalmazásikon"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Teljes képernyő"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Asztali üzemmód"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"Osztott képernyő"</string>
<string name="more_button_text" msgid="3655388105592893530">"Továbbiak"</string>
<string name="float_button_text" msgid="9221657008391364581">"Lebegő"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Méretarány módosítása"</string>
<string name="close_text" msgid="4986518933445178928">"Bezárás"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Menü bezárása"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Menü megnyitása"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Képernyő méretének maximalizálása"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Átméretezés"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Az alkalmazás nem helyezhető át ide"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Alkalmazásablak átméretezése balra"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Alkalmazásablak átméretezése jobbra"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Ablak teljes méretre állítása vagy visszaállítása"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Belépés osztott képernyős módba"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Asztali ablakkezelési mód indítása"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Ablak átméretezése balra"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Ablak átméretezése jobbra"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Ablak teljes méretre állítása vagy visszaállítása"</string>
diff --git a/libs/WindowManager/Shell/res/values-hy/strings.xml b/libs/WindowManager/Shell/res/values-hy/strings.xml
index 39a395f..b7b4422 100644
--- a/libs/WindowManager/Shell/res/values-hy/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hy/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"Հավելվածի կեղծանուն"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Հավելվածի պատկերակ"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Լիաէկրան"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Համակարգչի ռեժիմ"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"Տրոհված էկրան"</string>
<string name="more_button_text" msgid="3655388105592893530">"Ավելին"</string>
<string name="float_button_text" msgid="9221657008391364581">"Լողացող պատուհան"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Փոխել կողմերի հարաբերակցությունը"</string>
<string name="close_text" msgid="4986518933445178928">"Փակել"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Փակել ընտրացանկը"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Բացել ընտրացանկը"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Ծավալել էկրանը"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Փոխել չափը"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Հավելվածը հնարավոր չէ տեղափոխել այստեղ"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Ձգել հավելվածի պատուհանը դեպի ձախ"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Ձգել հավելվածի պատուհանը դեպի աջ"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Ծավալել կամ վերականգնել պատուհանի չափսը"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Մտնել էկրանի տրոհման ռեժիմ"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Մտնել համակարգչի ռեժիմ"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Ձգել պատուհանը դեպի ձախ"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Ձգել պատուհանը դեպի աջ"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Ծավալել կամ վերականգնել պատուհանի չափսը"</string>
diff --git a/libs/WindowManager/Shell/res/values-in/strings.xml b/libs/WindowManager/Shell/res/values-in/strings.xml
index 09ce525..a3ed7c3 100644
--- a/libs/WindowManager/Shell/res/values-in/strings.xml
+++ b/libs/WindowManager/Shell/res/values-in/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"Penanganan aplikasi"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ikon Aplikasi"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Layar Penuh"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Mode Desktop"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"Layar Terpisah"</string>
<string name="more_button_text" msgid="3655388105592893530">"Lainnya"</string>
<string name="float_button_text" msgid="9221657008391364581">"Mengambang"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Ubah rasio aspek"</string>
<string name="close_text" msgid="4986518933445178928">"Tutup"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Tutup Menu"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Buka Menu"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Perbesar Layar"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Ubah ukuran"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikasi tidak dapat dipindahkan ke sini"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Ubah ukuran jendela aplikasi ke kiri"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Ubah ukuran jendela aplikasi ke kanan"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Maksimalkan atau pulihkan ukuran jendela"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Masuk ke mode layar terpisah"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Masuk ke mode windowing desktop"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Ubah ukuran jendela ke kiri"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Ubah ukuran jendela ke kanan"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maksimalkan atau pulihkan ukuran jendela"</string>
diff --git a/libs/WindowManager/Shell/res/values-is/strings.xml b/libs/WindowManager/Shell/res/values-is/strings.xml
index 61c1d0e..e8ecad1 100644
--- a/libs/WindowManager/Shell/res/values-is/strings.xml
+++ b/libs/WindowManager/Shell/res/values-is/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"Handfang forrits"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Tákn forrits"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Allur skjárinn"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Skjáborðsstilling"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"Skjáskipting"</string>
<string name="more_button_text" msgid="3655388105592893530">"Meira"</string>
<string name="float_button_text" msgid="9221657008391364581">"Reikult"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Breyta myndhlutfalli"</string>
<string name="close_text" msgid="4986518933445178928">"Loka"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Loka valmynd"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Opna valmynd"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Stækka skjá"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Breyta stærð"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Ekki er hægt að færa forritið hingað"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Breyta stærð forritsglugga til vinstri"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Breyta stærð forritsglugga til hægri"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Hámarka eða endurheimta stærð glugga"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Skipta skjánum"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Opna gluggastillingu í tölvu"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Breyta stærð glugga til vinstri"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Breyta stærð glugga til hægri"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Hámarka eða endurheimta stærð glugga"</string>
diff --git a/libs/WindowManager/Shell/res/values-it/strings.xml b/libs/WindowManager/Shell/res/values-it/strings.xml
index fab259e..630e9ee 100644
--- a/libs/WindowManager/Shell/res/values-it/strings.xml
+++ b/libs/WindowManager/Shell/res/values-it/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"Punto di manipolazione app"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Icona dell\'app"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Schermo intero"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Modalità desktop"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"Schermo diviso"</string>
<string name="more_button_text" msgid="3655388105592893530">"Altro"</string>
<string name="float_button_text" msgid="9221657008391364581">"Mobile"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Cambia proporzioni"</string>
<string name="close_text" msgid="4986518933445178928">"Chiudi"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Chiudi il menu"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Apri il menu"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Massimizza schermo"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Ridimensiona"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Impossibile spostare l\'app qui"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Ridimensiona la finestra dell\'app a sinistra"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Ridimensiona la finestra dell\'app a destra"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Ingrandisci o ripristina le dimensioni della finestra"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Attiva la modalità schermo diviso"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Attiva la modalità finestre del desktop"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Ridimensiona la finestra a sinistra"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Ridimensiona la finestra a destra"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Ingrandisci o ripristina le dimensioni della finestra"</string>
diff --git a/libs/WindowManager/Shell/res/values-iw/strings.xml b/libs/WindowManager/Shell/res/values-iw/strings.xml
index b164b11..102d646 100644
--- a/libs/WindowManager/Shell/res/values-iw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-iw/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"נקודת אחיזה לאפליקציה"</string>
<string name="app_icon_text" msgid="2823268023931811747">"סמל האפליקציה"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"מסך מלא"</string>
- <string name="desktop_text" msgid="1077633567027630454">"ממשק המחשב"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"מסך מפוצל"</string>
<string name="more_button_text" msgid="3655388105592893530">"עוד"</string>
<string name="float_button_text" msgid="9221657008391364581">"בלונים"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"שינוי יחס הגובה-רוחב"</string>
<string name="close_text" msgid="4986518933445178928">"סגירה"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"סגירת התפריט"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"פתיחת התפריט"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"הגדלת המסך"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"שינוי הגודל"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"לא ניתן להעביר את האפליקציה לכאן"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"שינוי הגודל של חלון האפליקציה שמשמאל"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"שינוי הגודל של חלון האפליקציה שמימין"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"שחזור של גודל החלון או הגדלת החלון"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"כניסה למצב מסך מפוצל"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"כניסה למצב שינוי הגודל של החלונות בממשק המחשב"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"שינוי גודל החלון שמשמאל"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"שינוי גודל החלון שמימין"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"שחזור של גודל החלון או הגדלת החלון"</string>
diff --git a/libs/WindowManager/Shell/res/values-ja/strings.xml b/libs/WindowManager/Shell/res/values-ja/strings.xml
index 3fe2a51..ac0df9c 100644
--- a/libs/WindowManager/Shell/res/values-ja/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ja/strings.xml
@@ -119,7 +119,7 @@
<string name="handle_text" msgid="4419667835599523257">"アプリハンドル"</string>
<string name="app_icon_text" msgid="2823268023931811747">"アプリのアイコン"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"全画面表示"</string>
- <string name="desktop_text" msgid="1077633567027630454">"デスクトップ モード"</string>
+ <string name="desktop_text" msgid="1582173066857454541">"デスクトップ ビュー"</string>
<string name="split_screen_text" msgid="1396336058129570886">"分割画面"</string>
<string name="more_button_text" msgid="3655388105592893530">"その他"</string>
<string name="float_button_text" msgid="9221657008391364581">"フローティング"</string>
@@ -132,7 +132,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"アスペクト比を変更"</string>
<string name="close_text" msgid="4986518933445178928">"閉じる"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"メニューを閉じる"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"メニューを開く"</string>
+ <string name="desktop_mode_app_header_chip_text" msgid="8300164817452574565">"<xliff:g id="APP_NAME">%1$s</xliff:g>(デスクトップ ビュー)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"画面の最大化"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"サイズ変更"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"アプリはここに移動できません"</string>
@@ -145,8 +145,8 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"アプリ ウィンドウを左側にサイズ変更する"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"アプリ ウィンドウを右側にサイズ変更する"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"ウィンドウを最大化する、またはウィンドウを元のサイズに戻す"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"分割画面モードに切り替える"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"デスクトップ ウィンドウ モードに切り替える"</string>
+ <string name="app_handle_chip_accessibility_announce" msgid="499881698947450536">"メニューを開く"</string>
+ <string name="app_handle_menu_accessibility_announce" msgid="7928858564852785398">"<xliff:g id="WINDOWING_MODE">%1$s</xliff:g>に切り替え"</string>
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"ウィンドウを左側にサイズ変更する"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"ウィンドウを右側にサイズ変更する"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"ウィンドウを最大化する、またはウィンドウを元のサイズに戻す"</string>
diff --git a/libs/WindowManager/Shell/res/values-ka/strings.xml b/libs/WindowManager/Shell/res/values-ka/strings.xml
index 1be19af..84fab6f 100644
--- a/libs/WindowManager/Shell/res/values-ka/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ka/strings.xml
@@ -119,7 +119,7 @@
<string name="handle_text" msgid="4419667835599523257">"აპის იდენტიფიკატორი"</string>
<string name="app_icon_text" msgid="2823268023931811747">"აპის ხატულა"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"სრულ ეკრანზე"</string>
- <string name="desktop_text" msgid="1077633567027630454">"დესკტოპის რეჟიმი"</string>
+ <string name="desktop_text" msgid="1582173066857454541">"დესკტოპის ხედი"</string>
<string name="split_screen_text" msgid="1396336058129570886">"ეკრანის გაყოფა"</string>
<string name="more_button_text" msgid="3655388105592893530">"სხვა"</string>
<string name="float_button_text" msgid="9221657008391364581">"ფარფატი"</string>
@@ -132,7 +132,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"თანაფარდობის შეცვლა"</string>
<string name="close_text" msgid="4986518933445178928">"დახურვა"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"მენიუს დახურვა"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"მენიუს გახსნა"</string>
+ <string name="desktop_mode_app_header_chip_text" msgid="8300164817452574565">"<xliff:g id="APP_NAME">%1$s</xliff:g> (დესკტოპის ხედი)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"აპლიკაციის გაშლა სრულ ეკრანზე"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"ზომის შეცვლა"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"აპის აქ გადატანა შეუძლებელია"</string>
@@ -145,8 +145,8 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"აპის მარცხენა ფანჯრის ზომის შეცვლა"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"აპის მარჯვენა ფანჯრის ზომის შეცვლა"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"ფანჯრის მაქსიმალურ ზომამდე გაზრდა ან აღდგენა"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"გაყოფილი ეკრანის რეჟიმში შესვლა"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"დესკტოპის ფანჯრის რეჟიმში შესვლა"</string>
+ <string name="app_handle_chip_accessibility_announce" msgid="499881698947450536">"მენიუს გახსნა"</string>
+ <string name="app_handle_menu_accessibility_announce" msgid="7928858564852785398">"შეიყვანეთ <xliff:g id="WINDOWING_MODE">%1$s</xliff:g>"</string>
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"ფანჯრის ზომის შეცვლა მარცხნივ"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"ფანჯრის ზომის შეცვლა მარჯვნივ"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"ფანჯრის მაქსიმალურ ზომამდე გაზრდა ან აღდგენა"</string>
diff --git a/libs/WindowManager/Shell/res/values-kk/strings.xml b/libs/WindowManager/Shell/res/values-kk/strings.xml
index 5bd8519..31a0153 100644
--- a/libs/WindowManager/Shell/res/values-kk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kk/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"Қолданба идентификаторы"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Қолданба белгішесі"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Толық экран"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Компьютер режимі"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"Экранды бөлу"</string>
<string name="more_button_text" msgid="3655388105592893530">"Қосымша"</string>
<string name="float_button_text" msgid="9221657008391364581">"Қалқыма"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Арақатынасты өзгерту"</string>
<string name="close_text" msgid="4986518933445178928">"Жабу"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Мәзірді жабу"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Мәзірді ашу"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Экранды ұлғайту"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Өлшемін өзгерту"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Қолданба бұл жерге қойылмайды."</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Қолданба терезесінің өлшемін сол жақтан өзгерту"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Қолданба терезесінің өлшемін оң жақтан өзгерту"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Терезе өлшемін ұлғайту не қалпына келтіру"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Экранды бөлу режиміне өту"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Жұмыс үстелінің терезе режиміне өту"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Терезе өлшемін сол жаққа өзгерту"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Терезе өлшемін оң жаққа өзгерту"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Терезе өлшемін ұлғайту не қалпына келтіру"</string>
diff --git a/libs/WindowManager/Shell/res/values-km/strings.xml b/libs/WindowManager/Shell/res/values-km/strings.xml
index f511897..9a7db67 100644
--- a/libs/WindowManager/Shell/res/values-km/strings.xml
+++ b/libs/WindowManager/Shell/res/values-km/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"ឈ្មោះអ្នកប្រើប្រាស់កម្មវិធី"</string>
<string name="app_icon_text" msgid="2823268023931811747">"រូបកម្មវិធី"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"អេក្រង់ពេញ"</string>
- <string name="desktop_text" msgid="1077633567027630454">"មុខងារកុំព្យូទ័រ"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"មុខងារបំបែកអេក្រង់"</string>
<string name="more_button_text" msgid="3655388105592893530">"ច្រើនទៀត"</string>
<string name="float_button_text" msgid="9221657008391364581">"អណ្ដែត"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"ប្ដូរសមាមាត្រ"</string>
<string name="close_text" msgid="4986518933445178928">"បិទ"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"បិទម៉ឺនុយ"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"បើកម៉ឺនុយ"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"ពង្រីកអេក្រង់"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"ប្ដូរទំហំ"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"មិនអាចផ្លាស់ទីកម្មវិធីមកទីនេះបានទេ"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"ប្ដូរទំហំវិនដូកម្មវិធីទៅឆ្វេង"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"ប្ដូរទំហំវិនដូកម្មវិធីទៅស្ដាំ"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"ស្ដារ ឬបង្កើនទំហំវិនដូជាអតិបរមា"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"ចូលទៅមុខងារបំបែកអេក្រង់"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"ចូលទៅមុខងារវិនដូកុំព្យូទ័រ"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"ប្ដូរទំហំវិនដូទៅឆ្វេង"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"ប្ដូរទំហំវិនដូទៅស្ដាំ"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"ស្ដារ ឬបង្កើនទំហំវិនដូជាអតិបរមា"</string>
diff --git a/libs/WindowManager/Shell/res/values-kn/strings.xml b/libs/WindowManager/Shell/res/values-kn/strings.xml
index 3bd5527..e9fa2cf 100644
--- a/libs/WindowManager/Shell/res/values-kn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kn/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"ಆ್ಯಪ್ ಹ್ಯಾಂಡಲ್"</string>
<string name="app_icon_text" msgid="2823268023931811747">"ಆ್ಯಪ್ ಐಕಾನ್"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"ಫುಲ್ಸ್ಕ್ರೀನ್"</string>
- <string name="desktop_text" msgid="1077633567027630454">"ಡೆಸ್ಕ್ಟಾಪ್ ಮೋಡ್"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"ಸ್ಪ್ಲಿಟ್ ಸ್ಕ್ರೀನ್"</string>
<string name="more_button_text" msgid="3655388105592893530">"ಇನ್ನಷ್ಟು"</string>
<string name="float_button_text" msgid="9221657008391364581">"ಫ್ಲೋಟ್"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"ದೃಶ್ಯಾನುಪಾತವನ್ನು ಬದಲಾಯಿಸಿ"</string>
<string name="close_text" msgid="4986518933445178928">"ಮುಚ್ಚಿ"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"ಮೆನು ಮುಚ್ಚಿ"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"ಮೆನು ತೆರೆಯಿರಿ"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"ಸ್ಕ್ರೀನ್ ಅನ್ನು ಮ್ಯಾಕ್ಸಿಮೈಸ್ ಮಾಡಿ"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"ಮರುಗಾತ್ರಗೊಳಿಸಿ"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ಆ್ಯಪ್ ಅನ್ನು ಇಲ್ಲಿಗೆ ಸರಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"ಮರುಗಾತ್ರಗೊಳಿಸಿ ಆ್ಯಪ್ ವಿಂಡೋ ಎಡ"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"ಮರುಗಾತ್ರಗೊಳಿಸಿ ಆ್ಯಪ್ ವಿಂಡೋ ಬಲ"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"ವಿಂಡೋ ಗಾತ್ರವನ್ನು ಗರಿಷ್ಠಗೊಳಿಸಿ ಅಥವಾ ಮರುಸ್ಥಾಪಿಸಿ"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"ಸ್ಪ್ಲಿಟ್ ಸ್ಕ್ರೀನ್ ಮೋಡ್ಗೆ ಪ್ರವೇಶಿಸಿ"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"ಡೆಸ್ಕ್ಟಾಪ್ ವಿಂಡೋಯಿಂಗ್ ಮೋಡ್ಗೆ ಪ್ರವೇಶಿಸಿ"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"ಮರುಗಾತ್ರಗೊಳಿಸಿ ವಿಂಡೋವನ್ನು ಎಡಕ್ಕೆ ಸರಿಸಿ"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"ಮರುಗಾತ್ರಗೊಳಿಸಿ ವಿಂಡೋವನ್ನು ಬಲಕ್ಕೆ ಸರಿಸಿ"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"ವಿಂಡೋ ಗಾತ್ರವನ್ನು ಗರಿಷ್ಠಗೊಳಿಸಿ ಅಥವಾ ಮರುಸ್ಥಾಪಿಸಿ"</string>
diff --git a/libs/WindowManager/Shell/res/values-ko/strings.xml b/libs/WindowManager/Shell/res/values-ko/strings.xml
index 65add57..dcdbaba 100644
--- a/libs/WindowManager/Shell/res/values-ko/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ko/strings.xml
@@ -119,7 +119,7 @@
<string name="handle_text" msgid="4419667835599523257">"앱 핸들"</string>
<string name="app_icon_text" msgid="2823268023931811747">"앱 아이콘"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"전체 화면"</string>
- <string name="desktop_text" msgid="1077633567027630454">"데스크톱 모드"</string>
+ <string name="desktop_text" msgid="1582173066857454541">"데스크톱 뷰"</string>
<string name="split_screen_text" msgid="1396336058129570886">"화면 분할"</string>
<string name="more_button_text" msgid="3655388105592893530">"더보기"</string>
<string name="float_button_text" msgid="9221657008391364581">"플로팅"</string>
@@ -132,7 +132,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"가로세로 비율 변경"</string>
<string name="close_text" msgid="4986518933445178928">"닫기"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"메뉴 닫기"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"메뉴 열기"</string>
+ <string name="desktop_mode_app_header_chip_text" msgid="8300164817452574565">"<xliff:g id="APP_NAME">%1$s</xliff:g>(데스크톱 뷰)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"화면 최대화"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"크기 조절"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"앱을 여기로 이동할 수 없음"</string>
@@ -145,8 +145,8 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"앱 창 크기 왼쪽으로 조절"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"앱 창 크기 오른쪽으로 조절"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"창 최대화 또는 크기 복원"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"화면 분할 모드 시작"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"데스크톱 창 모드 시작"</string>
+ <string name="app_handle_chip_accessibility_announce" msgid="499881698947450536">"메뉴 열기"</string>
+ <string name="app_handle_menu_accessibility_announce" msgid="7928858564852785398">"<xliff:g id="WINDOWING_MODE">%1$s</xliff:g> 입력"</string>
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"창 크기 왼쪽으로 조절"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"창 크기 오른쪽으로 조절"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"창 최대화 또는 크기 복원"</string>
diff --git a/libs/WindowManager/Shell/res/values-ky/strings.xml b/libs/WindowManager/Shell/res/values-ky/strings.xml
index 96c2226..3716741 100644
--- a/libs/WindowManager/Shell/res/values-ky/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ky/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"Колдонмонун маркери"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Колдонмонун сүрөтчөсү"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Толук экран"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Компьютер режими"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"Экранды бөлүү"</string>
<string name="more_button_text" msgid="3655388105592893530">"Дагы"</string>
<string name="float_button_text" msgid="9221657008391364581">"Калкыма"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Тараптардын катнашын өзгөртүү"</string>
<string name="close_text" msgid="4986518933445178928">"Жабуу"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Менюну жабуу"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Менюну ачуу"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Экранды чоңойтуу"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Өлчөмүн өзгөртүү"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Колдонмону бул жерге жылдырууга болбойт"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Колдонмонун терезесинин өлчөмүн солго өзгөртүү"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Колдонмонун терезесинин өлчөмүн оңго өзгөртүү"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Терезенин өлчөмүн чоңойтуу же калыбына келтирүү"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Экранды бөлүү режимине өтүү"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Иш тактанын терезелери режимине өтүү"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Терезенин өлчөмүн солго өзгөртүү"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Терезенин өлчөмүн оңго өзгөртүү"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Терезенин өлчөмүн чоңойтуу же калыбына келтирүү"</string>
diff --git a/libs/WindowManager/Shell/res/values-lo/strings.xml b/libs/WindowManager/Shell/res/values-lo/strings.xml
index 9337efc..a1d9d29 100644
--- a/libs/WindowManager/Shell/res/values-lo/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lo/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"ຊື່ຜູ້ໃຊ້ແອັບ"</string>
<string name="app_icon_text" msgid="2823268023931811747">"ໄອຄອນແອັບ"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"ເຕັມຈໍ"</string>
- <string name="desktop_text" msgid="1077633567027630454">"ໂໝດເດັສທັອບ"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"ແບ່ງໜ້າຈໍ"</string>
<string name="more_button_text" msgid="3655388105592893530">"ເພີ່ມເຕີມ"</string>
<string name="float_button_text" msgid="9221657008391364581">"ລອຍ"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"ປ່ຽນອັດຕາສ່ວນຮູບ"</string>
<string name="close_text" msgid="4986518933445178928">"ປິດ"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"ປິດເມນູ"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"ເປີດເມນູ"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"ປັບຈໍໃຫຍ່ສຸດ"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"ປັບຂະໜາດ"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ບໍ່ສາມາດຍ້າຍແອັບມາບ່ອນນີ້ໄດ້"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"ປັບຂະໜາດໜ້າຈໍແອັບໄປທາງຊ້າຍ"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"ປັບຂະໜາດໜ້າຈໍແອັບໄປທາງຂວາ"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"ຂະຫຍາຍ ຫຼື ຄືນຄ່າຂະໜາດໜ້າຈໍ"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"ເຂົ້າສູ່ໂໝດແບ່ງໜ້າຈໍ"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"ເຂົ້າສູ່ໂໝດໜ້າຈໍເດັສທັອບ"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"ປັບຂະໜາດໜ້າຈໍໄປທາງຊ້າຍ"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"ປັບຂະໜາດໜ້າຈໍໄປທາງຂວາ"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"ຂະຫຍາຍ ຫຼື ຄືນຄ່າຂະໜາດໜ້າຈໍ"</string>
diff --git a/libs/WindowManager/Shell/res/values-lt/strings.xml b/libs/WindowManager/Shell/res/values-lt/strings.xml
index ede2564..7ebd43d 100644
--- a/libs/WindowManager/Shell/res/values-lt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lt/strings.xml
@@ -119,7 +119,7 @@
<string name="handle_text" msgid="4419667835599523257">"Programos kreipinys"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Programos piktograma"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Visas ekranas"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Stalinio kompiuterio režimas"</string>
+ <string name="desktop_text" msgid="1582173066857454541">"Rodinio versija staliniams kompiuteriams"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Išskaidyto ekrano režimas"</string>
<string name="more_button_text" msgid="3655388105592893530">"Daugiau"</string>
<string name="float_button_text" msgid="9221657008391364581">"Slankusis langas"</string>
@@ -132,7 +132,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Keisti kraštinių santykį"</string>
<string name="close_text" msgid="4986518933445178928">"Uždaryti"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Uždaryti meniu"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Atidaryti meniu"</string>
+ <string name="desktop_mode_app_header_chip_text" msgid="8300164817452574565">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ (rodinio versija staliniams kompiuteriams)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Išskleisti ekraną"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Pakeisti dydį"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Programos negalima perkelti čia"</string>
@@ -145,8 +145,8 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Pakeisti programos lango dydį kairėje"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Pakeisti programos lango dydį dešinėje"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Padidinti arba atkurti lango dydį"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Išskaidyto ekrano režimo įjungimas"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Įjungti darbalaukio pateikimo lange režimą"</string>
+ <string name="app_handle_chip_accessibility_announce" msgid="499881698947450536">"Atidaryti meniu"</string>
+ <string name="app_handle_menu_accessibility_announce" msgid="7928858564852785398">"Eiti į „<xliff:g id="WINDOWING_MODE">%1$s</xliff:g>“"</string>
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Pakeisti lango dydį kairėje"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Pakeisti lango dydį dešinėje"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Padidinti arba atkurti lango dydį"</string>
diff --git a/libs/WindowManager/Shell/res/values-lv/strings.xml b/libs/WindowManager/Shell/res/values-lv/strings.xml
index 24a969b..3fcbbe2 100644
--- a/libs/WindowManager/Shell/res/values-lv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lv/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"Lietotnes turis"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Lietotnes ikona"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Pilnekrāna režīms"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Darbvirsmas režīms"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"Sadalīt ekrānu"</string>
<string name="more_button_text" msgid="3655388105592893530">"Vairāk"</string>
<string name="float_button_text" msgid="9221657008391364581">"Peldošs"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Mainīt malu attiecību"</string>
<string name="close_text" msgid="4986518933445178928">"Aizvērt"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Aizvērt izvēlni"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Atvērt izvēlni"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimizēt ekrānu"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Mainīt lielumu"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Lietotni nevar pārvietot šeit."</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Mainīt lietotnes loga lielumu uz kreiso pusi"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Mainīt lietotnes loga lielumu uz labo pusi"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Maksimizēt vai atjaunot loga lielumu"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Ieslēgt ekrāna sadalīšanas režīmu"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Ieslēgt darbvirsmas logu režīmu"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Mainīt loga lielumu uz kreiso pusi"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Mainīt loga lielumu uz labo pusi"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maksimizēt vai atjaunot loga lielumu"</string>
diff --git a/libs/WindowManager/Shell/res/values-mk/strings.xml b/libs/WindowManager/Shell/res/values-mk/strings.xml
index f7177ac..76b62ec1 100644
--- a/libs/WindowManager/Shell/res/values-mk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mk/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"Прекар на апликацијата"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Икона на апликацијата"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Цел екран"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Режим за компјутер"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"Поделен екран"</string>
<string name="more_button_text" msgid="3655388105592893530">"Повеќе"</string>
<string name="float_button_text" msgid="9221657008391364581">"Лебдечко"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Промени го соодносот"</string>
<string name="close_text" msgid="4986518933445178928">"Затворете"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Затворете го менито"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Отвори го менито"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Максимизирај го екранот"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Промени ја гол."</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Апликацијата не може да се премести овде"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Променете ја големината на прозорецот на апликацијата одлево"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Променете ја големината на прозорецот на апликацијата оддесно"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Максимизирајте или вратете ја големината на прозорецот"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Влезете во „Режим на поделен екран“"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Влезете во „Режим со прозорци на работната површина“"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Променете ја големината на прозорецот налево"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Променете ја големината на прозорецот надесно"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Максимизирајте или вратете ја големината на прозорецот"</string>
diff --git a/libs/WindowManager/Shell/res/values-ml/strings.xml b/libs/WindowManager/Shell/res/values-ml/strings.xml
index 89215b6..d9d0cf9 100644
--- a/libs/WindowManager/Shell/res/values-ml/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ml/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"ആപ്പ് ഹാൻഡിൽ"</string>
<string name="app_icon_text" msgid="2823268023931811747">"ആപ്പ് ഐക്കൺ"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"പൂർണ്ണസ്ക്രീൻ"</string>
- <string name="desktop_text" msgid="1077633567027630454">"ഡെസ്ക്ടോപ്പ് മോഡ്"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"സ്ക്രീൻ വിഭജനം"</string>
<string name="more_button_text" msgid="3655388105592893530">"കൂടുതൽ"</string>
<string name="float_button_text" msgid="9221657008391364581">"ഫ്ലോട്ട്"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"വീക്ഷണ അനുപാതം മാറ്റുക"</string>
<string name="close_text" msgid="4986518933445178928">"അടയ്ക്കുക"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"മെനു അടയ്ക്കുക"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"മെനു തുറക്കുക"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"സ്ക്രീൻ വലുതാക്കുക"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"വലുപ്പം മാറ്റുക"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ആപ്പ് ഇവിടേക്ക് നീക്കാനാകില്ല"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"ഇടത് ആപ്പ് വിൻഡോ വലുപ്പം മാറ്റുക"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"വലത് ആപ്പ് വിൻഡോ വലുപ്പം മാറ്റുക"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"വിന്ഡോ വലുപ്പം വലുതാക്കുക അല്ലെങ്കിൽ പഴയത് പുനഃസ്ഥാപിക്കുക"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"സ്പ്ലിറ്റ് സ്ക്രീൻ മോഡിൽ പ്രവേശിക്കുക"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"ഡെസ്ക്ടോപ്പ് വിൻഡോയിംഗ് മോഡിൽ പ്രവേശിക്കുക"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"ഇടത്തേക്ക് ആപ്പ് വിൻഡോ വലുപ്പം മാറ്റുക"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"വലത്തേക്ക് ആപ്പ് വിൻഡോ വലുപ്പം മാറ്റുക"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"വിന്ഡോ വലുപ്പം വലുതാക്കുക അല്ലെങ്കിൽ പഴയത് പുനഃസ്ഥാപിക്കുക"</string>
diff --git a/libs/WindowManager/Shell/res/values-mn/strings.xml b/libs/WindowManager/Shell/res/values-mn/strings.xml
index b38026c..875ecea 100644
--- a/libs/WindowManager/Shell/res/values-mn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mn/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"Аппын бариул"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Aппын дүрс тэмдэг"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Бүтэн дэлгэц"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Дэлгэцийн горим"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"Дэлгэцийг хуваах"</string>
<string name="more_button_text" msgid="3655388105592893530">"Бусад"</string>
<string name="float_button_text" msgid="9221657008391364581">"Хөвөгч"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Аспектын харьцааг өөрчлөх"</string>
<string name="close_text" msgid="4986518933445178928">"Хаах"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Цэсийг хаах"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Цэсийг нээх"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Дэлгэцийг томруулах"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Хэмжээг өөрчлөх"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Аппыг ийш зөөх боломжгүй"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Аппын цонхны хэмжээг зүүн тал руу өөрчлөх"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Аппын цонхны хэмжээг баруун тал руу өөрчлөх"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Цонхны хэмжээг томруулах эсвэл сэргээх"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Дэлгэц хуваах горимд орох"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Дэлгэцийн цонхны горимд орох"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Цонхны хэмжээг зүүн тал руу өөрчлөх"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Цонхны хэмжээг баруун тал руу өөрчлөх"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Цонхны хэмжээг томруулах эсвэл сэргээх"</string>
diff --git a/libs/WindowManager/Shell/res/values-mr/strings.xml b/libs/WindowManager/Shell/res/values-mr/strings.xml
index d9c1d1f..73c16e6 100644
--- a/libs/WindowManager/Shell/res/values-mr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mr/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"अॅपचे हँडल"</string>
<string name="app_icon_text" msgid="2823268023931811747">"अॅप आयकन"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"फुलस्क्रीन"</string>
- <string name="desktop_text" msgid="1077633567027630454">"डेस्कटॉप मोड"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"स्प्लिट स्क्रीन"</string>
<string name="more_button_text" msgid="3655388105592893530">"आणखी"</string>
<string name="float_button_text" msgid="9221657008391364581">"फ्लोट"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"आस्पेक्ट रेशो बदला"</string>
<string name="close_text" msgid="4986518933445178928">"बंद करा"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"मेनू बंद करा"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"मेनू उघडा"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"स्क्रीन मोठी करा"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"आकार बदला"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"अॅप इथे हलवू शकत नाही"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"अॅप विंडोचा डावीकडून आकार बदला"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"अॅप विंडोचा उजवीकडून आकार बदला"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"विंडोचा आकार मोठा करा किंवा रिस्टोअर करा"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"स्प्लिट स्क्रीन मोड एंटर करा"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"डेस्कटॉप विंडोइंग मोड एंटर करा"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"अॅप विंडोचा डावीकडे आकार बदला"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"अॅप विंडोचा उजवीकडे आकार बदला"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"विंडोचा आकार मोठा करा किंवा रिस्टोअर करा"</string>
diff --git a/libs/WindowManager/Shell/res/values-ms/strings.xml b/libs/WindowManager/Shell/res/values-ms/strings.xml
index a54ef14..81e00c5 100644
--- a/libs/WindowManager/Shell/res/values-ms/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ms/strings.xml
@@ -119,7 +119,7 @@
<string name="handle_text" msgid="4419667835599523257">"Pengendalian apl"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ikon Apl"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Skrin penuh"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Mod Desktop"</string>
+ <string name="desktop_text" msgid="1582173066857454541">"Paparan Desktop"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Skrin Pisah"</string>
<string name="more_button_text" msgid="3655388105592893530">"Lagi"</string>
<string name="float_button_text" msgid="9221657008391364581">"Terapung"</string>
@@ -132,7 +132,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Tukar nisbah bidang"</string>
<string name="close_text" msgid="4986518933445178928">"Tutup"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Tutup Menu"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Buka Menu"</string>
+ <string name="desktop_mode_app_header_chip_text" msgid="8300164817452574565">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Paparan Desktop)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimumkan Skrin"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Ubah saiz"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Apl tidak boleh dialihkan ke sini"</string>
@@ -145,8 +145,8 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Butang kiri ubah saiz tetingkap apl"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Butang kanan ubah saiz tetingkap apl"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Maksimumkan atau pulihkan saiz tetingkap"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Masuki mod skrin pisah"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Masuki mod tetingkap desktop"</string>
+ <string name="app_handle_chip_accessibility_announce" msgid="499881698947450536">"Buka Menu"</string>
+ <string name="app_handle_menu_accessibility_announce" msgid="7928858564852785398">"Masukkan <xliff:g id="WINDOWING_MODE">%1$s</xliff:g>"</string>
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Ubah saiz tetingkap ke sebelah kiri"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Ubah saiz tetingkap ke sebelah kanan"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maksimumkan atau pulihkan saiz tetingkap"</string>
diff --git a/libs/WindowManager/Shell/res/values-my/strings.xml b/libs/WindowManager/Shell/res/values-my/strings.xml
index 1f4db6d..be7cca5 100644
--- a/libs/WindowManager/Shell/res/values-my/strings.xml
+++ b/libs/WindowManager/Shell/res/values-my/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"အက်ပ်သုံးသူအမည်"</string>
<string name="app_icon_text" msgid="2823268023931811747">"အက်ပ်သင်္ကေတ"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"ဖန်သားပြင်အပြည့်"</string>
- <string name="desktop_text" msgid="1077633567027630454">"ဒက်စ်တော့မုဒ်"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"မျက်နှာပြင် ခွဲ၍ပြသရန်"</string>
<string name="more_button_text" msgid="3655388105592893530">"ပိုပြပါ"</string>
<string name="float_button_text" msgid="9221657008391364581">"မျှောရန်"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"အချိုးအစား ပြောင်းရန်"</string>
<string name="close_text" msgid="4986518933445178928">"ပိတ်ရန်"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"မီနူး ပိတ်ရန်"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"မီနူး ဖွင့်ရန်"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"စခရင်ကို ချဲ့မည်"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"အရွယ်ပြင်ရန်"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"အက်ပ်ကို ဤနေရာသို့ ရွှေ့၍မရပါ"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"အက်ပ်ဝင်းဒိုး ဘယ်ဘက်ကို အရွယ်ပြင်ရန်"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"အက်ပ်ဝင်းဒိုး ညာဘက်ကို အရွယ်ပြင်ရန်"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"ဝင်းဒိုးအရွယ်အစားကို ချဲ့ရန် (သို့) ပြန်ပြောင်းရန်"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"မျက်နှာပြင်ခွဲပြခြင်းမုဒ်သို့ ဝင်ရန်"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"ဒက်စ်တော့ ဝင်းဒိုးမုဒ်သို့ ဝင်ရန်"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"ဝင်းဒိုးကို ဘယ်ဘက်သို့ အရွယ်ပြင်ရန်"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"ဝင်းဒိုးကို ညာဘက်သို့ အရွယ်ပြင်ရန်"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"ဝင်းဒိုးအရွယ်အစားကို ချဲ့ရန် (သို့) ပြန်ပြောင်းရန်"</string>
diff --git a/libs/WindowManager/Shell/res/values-nb/strings.xml b/libs/WindowManager/Shell/res/values-nb/strings.xml
index 586a50f..c213b7b 100644
--- a/libs/WindowManager/Shell/res/values-nb/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nb/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"Apphåndtak"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Appikon"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Fullskjerm"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Skrivebordmodus"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"Delt skjerm"</string>
<string name="more_button_text" msgid="3655388105592893530">"Mer"</string>
<string name="float_button_text" msgid="9221657008391364581">"Svevende"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Endre høyde/bredde-forholdet"</string>
<string name="close_text" msgid="4986518933445178928">"Lukk"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Lukk menyen"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Åpne menyen"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimer skjermen"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Endre størrelse"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Appen kan ikke flyttes hit"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Endre størrelsen på appvinduet til venstre"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Endre størrelsen på appvinduet til høyre"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Maksimer eller gjenopprett størrelsen på vinduet"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Start modusen for delt skjerm"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Start vindusmodus for skrivebordet"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Endre størrelsen på vinduet til venstre"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Endre størrelsen på vinduet til høyre"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maksimer eller gjenopprett størrelsen på vinduet"</string>
diff --git a/libs/WindowManager/Shell/res/values-ne/strings.xml b/libs/WindowManager/Shell/res/values-ne/strings.xml
index f66fb1d..e5f4cbe 100644
--- a/libs/WindowManager/Shell/res/values-ne/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ne/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"एपको ह्यान्डल"</string>
<string name="app_icon_text" msgid="2823268023931811747">"एपको आइकन"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"फुल स्क्रिन"</string>
- <string name="desktop_text" msgid="1077633567027630454">"डेस्कटप मोड"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"स्प्लिट स्क्रिन"</string>
<string name="more_button_text" msgid="3655388105592893530">"थप"</string>
<string name="float_button_text" msgid="9221657008391364581">"फ्लोट"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"एस्पेक्ट रेसियो परिवर्तन गर्नुहोस्"</string>
<string name="close_text" msgid="4986518933445178928">"बन्द गर्नुहोस्"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"मेनु बन्द गर्नुहोस्"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"मेनु खोल्नुहोस्"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"स्क्रिन ठुलो बनाउनुहोस्"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"आकार बदल्नुहोस्"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"एप सारेर यहाँ ल्याउन सकिएन"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"एपको विन्डोको आकार बदलेर बायाँतिर लैजानुहोस्"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"एपको विन्डोको आकार बदलेर दायाँतिर लैजानुहोस्"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"विन्डोको आकार म्याक्सिमाइज गर्नुहोस् वा रिस्टोर गर्नुहोस्"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"स्प्लिट स्क्रिन मोड प्रयोग गर्नुहोस्"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"डेस्कटप विन्डोइङ मोड प्रयोग गर्नुहोस्"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"विन्डोको आकार बदलेर बायाँतिर लैजानुहोस्"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"विन्डोको आकार बदलेर दायाँतिर लैजानुहोस्"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"विन्डोको आकार म्याक्सिमाइज गर्नुहोस् वा रिस्टोर गर्नुहोस्"</string>
diff --git a/libs/WindowManager/Shell/res/values-nl/strings.xml b/libs/WindowManager/Shell/res/values-nl/strings.xml
index 20bc65a..8396b3e 100644
--- a/libs/WindowManager/Shell/res/values-nl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nl/strings.xml
@@ -119,7 +119,7 @@
<string name="handle_text" msgid="4419667835599523257">"App-handgreep"</string>
<string name="app_icon_text" msgid="2823268023931811747">"App-icoon"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Volledig scherm"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Desktopmodus"</string>
+ <string name="desktop_text" msgid="1582173066857454541">"Desktopweergave"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Gesplitst scherm"</string>
<string name="more_button_text" msgid="3655388105592893530">"Meer"</string>
<string name="float_button_text" msgid="9221657008391364581">"Zwevend"</string>
@@ -132,7 +132,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Beeldverhouding wijzigen"</string>
<string name="close_text" msgid="4986518933445178928">"Sluiten"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Menu sluiten"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Menu openen"</string>
+ <string name="desktop_mode_app_header_chip_text" msgid="8300164817452574565">"<xliff:g id="APP_NAME">%1$s</xliff:g> (desktopweergave)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Scherm maximaliseren"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Formaat aanpassen"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Kan de app niet hierheen verplaatsen"</string>
@@ -145,8 +145,8 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Formaat van app-venster naar links aanpassen"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Formaat van app-venster naar rechts aanpassen"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Formaat van venster maximaliseren of herstellen"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Modus voor gesplitst scherm openen"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Modus voor desktopvensterfuncties openen"</string>
+ <string name="app_handle_chip_accessibility_announce" msgid="499881698947450536">"Menu openen"</string>
+ <string name="app_handle_menu_accessibility_announce" msgid="7928858564852785398">"<xliff:g id="WINDOWING_MODE">%1$s</xliff:g> openen"</string>
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Formaat van venster naar links aanpassen"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Formaat van venster naar rechts aanpassen"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Formaat van venster maximaliseren of herstellen"</string>
diff --git a/libs/WindowManager/Shell/res/values-or/strings.xml b/libs/WindowManager/Shell/res/values-or/strings.xml
index edb5208..182ea46d8 100644
--- a/libs/WindowManager/Shell/res/values-or/strings.xml
+++ b/libs/WindowManager/Shell/res/values-or/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"ଆପର ହେଣ୍ଡେଲ"</string>
<string name="app_icon_text" msgid="2823268023931811747">"ଆପ ଆଇକନ"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"ପୂର୍ଣ୍ଣସ୍କ୍ରିନ"</string>
- <string name="desktop_text" msgid="1077633567027630454">"ଡେସ୍କଟପ ମୋଡ"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନ"</string>
<string name="more_button_text" msgid="3655388105592893530">"ଅଧିକ"</string>
<string name="float_button_text" msgid="9221657008391364581">"ଫ୍ଲୋଟ"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"ଚଉଡ଼ା ଓ ଉଚ୍ଚତାର ଅନୁପାତ ପରିବର୍ତ୍ତନ କରନ୍ତୁ"</string>
<string name="close_text" msgid="4986518933445178928">"ବନ୍ଦ କରନ୍ତୁ"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"ମେନୁ ବନ୍ଦ କରନ୍ତୁ"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"ମେନୁ ଖୋଲନ୍ତୁ"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"ସ୍କ୍ରିନକୁ ବଡ଼ କରନ୍ତୁ"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"ରିସାଇଜ କରନ୍ତୁ"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ଆପକୁ ଏଠାକୁ ମୁଭ କରାଯାଇପାରିବ ନାହିଁ"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"ଆପ ୱିଣ୍ଡୋ ରିସାଇଜ କରିବା ପାଇଁ ବାମ ବଟନ"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"ଆପ ୱିଣ୍ଡୋ ରିସାଇଜ କରିବା ପାଇଁ ଡାହାଣ ବଟନ"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"ୱିଣ୍ଡୋ ସାଇଜକୁ ମେକ୍ସିମାଇଜ କିମ୍ବା ରିଷ୍ଟୋର କରନ୍ତୁ"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନ ମୋଡରେ ପ୍ରବେଶ କରନ୍ତୁ"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"ଡେସ୍କଟପ ୱିଣ୍ଡୋଇଂ ମୋଡରେ ପ୍ରବେଶ କରନ୍ତୁ"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"ବାମପଟକୁ ୱିଣ୍ଡୋ ରିସାଇଜ କରନ୍ତୁ"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"ଡାହାଣପଟକୁ ୱିଣ୍ଡୋ ରିସାଇଜ କରନ୍ତୁ"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"ୱିଣ୍ଡୋ ସାଇଜକୁ ମେକ୍ସିମାଇଜ କିମ୍ବା ରିଷ୍ଟୋର କରନ୍ତୁ"</string>
diff --git a/libs/WindowManager/Shell/res/values-pa/strings.xml b/libs/WindowManager/Shell/res/values-pa/strings.xml
index 29de4c4..3bc730b 100644
--- a/libs/WindowManager/Shell/res/values-pa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pa/strings.xml
@@ -119,7 +119,7 @@
<string name="handle_text" msgid="4419667835599523257">"ਐਪ ਹੈਂਡਲ"</string>
<string name="app_icon_text" msgid="2823268023931811747">"ਐਪ ਪ੍ਰਤੀਕ"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"ਪੂਰੀ-ਸਕ੍ਰੀਨ"</string>
- <string name="desktop_text" msgid="1077633567027630454">"ਡੈਸਕਟਾਪ ਮੋਡ"</string>
+ <string name="desktop_text" msgid="1582173066857454541">"ਡੈਸਕਟਾਪ ਦ੍ਰਿਸ਼"</string>
<string name="split_screen_text" msgid="1396336058129570886">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ"</string>
<string name="more_button_text" msgid="3655388105592893530">"ਹੋਰ"</string>
<string name="float_button_text" msgid="9221657008391364581">"ਫ਼ਲੋਟ"</string>
@@ -132,7 +132,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"ਆਕਾਰ ਅਨੁਪਾਤ ਬਦਲੋ"</string>
<string name="close_text" msgid="4986518933445178928">"ਬੰਦ ਕਰੋ"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"ਮੀਨੂ ਬੰਦ ਕਰੋ"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"ਮੀਨੂ ਖੋਲ੍ਹੋ"</string>
+ <string name="desktop_mode_app_header_chip_text" msgid="8300164817452574565">"<xliff:g id="APP_NAME">%1$s</xliff:g> (ਡੈਸਕਟਾਪ ਦ੍ਰਿਸ਼)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"ਸਕ੍ਰੀਨ ਦਾ ਆਕਾਰ ਵਧਾਓ"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"ਆਕਾਰ ਬਦਲੋ"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ਐਪ ਨੂੰ ਇੱਥੇ ਨਹੀਂ ਲਿਜਾਇਆ ਜਾ ਸਕਦਾ"</string>
@@ -145,8 +145,8 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"ਐਪ ਵਿੰਡੋ ਦਾ ਆਕਾਰ ਬਦਲ ਕੇ ਖੱਬੇ ਪਾਸੇ ਕਰੋ"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"ਐਪ ਵਿੰਡੋ ਦਾ ਆਕਾਰ ਬਦਲ ਕੇ ਸੱਜੇ ਪਾਸੇ ਕਰੋ"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"ਵਿੰਡੋ ਦਾ ਆਕਾਰ ਵਧਾਓ ਜਾਂ ਮੁੜ-ਬਹਾਲ ਕਰੋ"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਮੋਡ ਵਿੱਚ ਦਾਖਲ ਹੋਵੋ"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"ਡੈਸਕਟਾਪ ਵਿੰਡੋ ਮੋਡ ਵਿੱਚ ਦਾਖਲ ਹੋਵੋ"</string>
+ <string name="app_handle_chip_accessibility_announce" msgid="499881698947450536">"ਮੀਨੂ ਖੋਲ੍ਹੋ"</string>
+ <string name="app_handle_menu_accessibility_announce" msgid="7928858564852785398">"Enter <xliff:g id="WINDOWING_MODE">%1$s</xliff:g>"</string>
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"ਵਿੰਡੋ ਦਾ ਆਕਾਰ ਬਦਲ ਕੇ ਖੱਬੇ ਪਾਸੇ ਕਰੋ"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"ਵਿੰਡੋ ਦਾ ਆਕਾਰ ਬਦਲ ਕੇ ਸੱਜੇ ਪਾਸੇ ਕਰੋ"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"ਵਿੰਡੋ ਦਾ ਆਕਾਰ ਵਧਾਓ ਜਾਂ ਮੁੜ-ਬਹਾਲ ਕਰੋ"</string>
diff --git a/libs/WindowManager/Shell/res/values-pl/strings.xml b/libs/WindowManager/Shell/res/values-pl/strings.xml
index 47ee80e..9a1bf33 100644
--- a/libs/WindowManager/Shell/res/values-pl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pl/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"Uchwyt aplikacji"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ikona aplikacji"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Pełny ekran"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Tryb pulpitu"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"Podzielony ekran"</string>
<string name="more_button_text" msgid="3655388105592893530">"Więcej"</string>
<string name="float_button_text" msgid="9221657008391364581">"Pływające"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Zmień format obrazu"</string>
<string name="close_text" msgid="4986518933445178928">"Zamknij"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Zamknij menu"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Otwórz menu"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksymalizuj ekran"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Zmień rozmiar"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Nie można przenieść aplikacji tutaj"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Zmień rozmiar okna aplikacji po lewej"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Zmień rozmiar okna aplikacji po prawej"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Zmaksymalizuj lub przywróć rozmiar okna"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Włącz tryb podzielonego ekranu"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Włącz tryb okien na pulpicie"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Zmień rozmiar okna do lewej"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Zmień rozmiar okna do prawej"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Zmaksymalizuj lub przywróć rozmiar okna"</string>
diff --git a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
index 0a3ea70..3e019ec 100644
--- a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
@@ -119,7 +119,7 @@
<string name="handle_text" msgid="4419667835599523257">"Identificador do app"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ícone do app"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Tela cheia"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Modo área de trabalho"</string>
+ <string name="desktop_text" msgid="1582173066857454541">"Versão para computadores"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Tela dividida"</string>
<string name="more_button_text" msgid="3655388105592893530">"Mais"</string>
<string name="float_button_text" msgid="9221657008391364581">"Ponto flutuante"</string>
@@ -132,7 +132,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Mudar a proporção"</string>
<string name="close_text" msgid="4986518933445178928">"Fechar"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Fechar menu"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Abrir o menu"</string>
+ <string name="desktop_mode_app_header_chip_text" msgid="8300164817452574565">"<xliff:g id="APP_NAME">%1$s</xliff:g> (versão para computadores)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Ampliar tela"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Redimensionar"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Não é possível mover o app para cá"</string>
@@ -145,8 +145,8 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Redimensionar janela do app para a esquerda"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Redimensionar janela do app para a direita"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Maximizar ou restaurar o tamanho da janela"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Entrar no modo de tela dividida"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Entrar no modo de janela do computador"</string>
+ <string name="app_handle_chip_accessibility_announce" msgid="499881698947450536">"Abrir o menu"</string>
+ <string name="app_handle_menu_accessibility_announce" msgid="7928858564852785398">"Entrar no <xliff:g id="WINDOWING_MODE">%1$s</xliff:g>"</string>
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Redimensionar janela para a esquerda"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Redimensionar janela para a direita"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maximizar ou restaurar o tamanho da janela"</string>
diff --git a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
index c9d196b..0ca0e8e 100644
--- a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
@@ -119,7 +119,7 @@
<string name="handle_text" msgid="4419667835599523257">"Indicador da app"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ícone da app"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Ecrã inteiro"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Modo de ambiente de trabalho"</string>
+ <string name="desktop_text" msgid="1582173066857454541">"Vista de computador"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Ecrã dividido"</string>
<string name="more_button_text" msgid="3655388105592893530">"Mais"</string>
<string name="float_button_text" msgid="9221657008391364581">"Flutuar"</string>
@@ -132,7 +132,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Alterar formato"</string>
<string name="close_text" msgid="4986518933445178928">"Fechar"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Fechar menu"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Abrir menu"</string>
+ <string name="desktop_mode_app_header_chip_text" msgid="8300164817452574565">"<xliff:g id="APP_NAME">%1$s</xliff:g> (vista de computador)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximizar ecrã"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Redimensionar"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Não é possível mover a app para aqui"</string>
@@ -145,8 +145,8 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Redimensionar janela da app para a esquerda"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Redimensionar janela da app para a direita"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Maximizar ou restaurar tamanho da janela"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Aceder ao modo de ecrã dividido"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Aceder ao modo de janelas de computador"</string>
+ <string name="app_handle_chip_accessibility_announce" msgid="499881698947450536">"Abrir menu"</string>
+ <string name="app_handle_menu_accessibility_announce" msgid="7928858564852785398">"Entrar no modo <xliff:g id="WINDOWING_MODE">%1$s</xliff:g>"</string>
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Redimensionar janela para a esquerda"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Redimensionar janela para a direita"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maximizar ou restaurar tamanho da janela"</string>
diff --git a/libs/WindowManager/Shell/res/values-pt/strings.xml b/libs/WindowManager/Shell/res/values-pt/strings.xml
index 0a3ea70..3e019ec 100644
--- a/libs/WindowManager/Shell/res/values-pt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt/strings.xml
@@ -119,7 +119,7 @@
<string name="handle_text" msgid="4419667835599523257">"Identificador do app"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ícone do app"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Tela cheia"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Modo área de trabalho"</string>
+ <string name="desktop_text" msgid="1582173066857454541">"Versão para computadores"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Tela dividida"</string>
<string name="more_button_text" msgid="3655388105592893530">"Mais"</string>
<string name="float_button_text" msgid="9221657008391364581">"Ponto flutuante"</string>
@@ -132,7 +132,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Mudar a proporção"</string>
<string name="close_text" msgid="4986518933445178928">"Fechar"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Fechar menu"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Abrir o menu"</string>
+ <string name="desktop_mode_app_header_chip_text" msgid="8300164817452574565">"<xliff:g id="APP_NAME">%1$s</xliff:g> (versão para computadores)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Ampliar tela"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Redimensionar"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Não é possível mover o app para cá"</string>
@@ -145,8 +145,8 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Redimensionar janela do app para a esquerda"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Redimensionar janela do app para a direita"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Maximizar ou restaurar o tamanho da janela"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Entrar no modo de tela dividida"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Entrar no modo de janela do computador"</string>
+ <string name="app_handle_chip_accessibility_announce" msgid="499881698947450536">"Abrir o menu"</string>
+ <string name="app_handle_menu_accessibility_announce" msgid="7928858564852785398">"Entrar no <xliff:g id="WINDOWING_MODE">%1$s</xliff:g>"</string>
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Redimensionar janela para a esquerda"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Redimensionar janela para a direita"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maximizar ou restaurar o tamanho da janela"</string>
diff --git a/libs/WindowManager/Shell/res/values-ro/strings.xml b/libs/WindowManager/Shell/res/values-ro/strings.xml
index a3313b6..f71d93b 100644
--- a/libs/WindowManager/Shell/res/values-ro/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ro/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"Handle de aplicație"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Pictograma aplicației"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Ecran complet"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Modul desktop"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"Ecran împărțit"</string>
<string name="more_button_text" msgid="3655388105592893530">"Mai multe"</string>
<string name="float_button_text" msgid="9221657008391364581">"Flotantă"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Schimbă raportul de dimensiuni"</string>
<string name="close_text" msgid="4986518933445178928">"Închide"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Închide meniul"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Deschide meniul"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximizează fereastra"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Redimensionează"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplicația nu poate fi mutată aici"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Redimensionează fereastra aplicației la stânga"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Redimensionează fereastra aplicației la dreapta"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Maximizează sau restabilește dimensiunea ferestrei"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Accesează modul ecran împărțit"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Accesează modul de windowing pe desktop"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Redimensionează fereastra la stânga"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Redimensionează fereastra la dreapta"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maximizează sau restabilește dimensiunea ferestrei"</string>
diff --git a/libs/WindowManager/Shell/res/values-ru/strings.xml b/libs/WindowManager/Shell/res/values-ru/strings.xml
index 5b20b2b..adc6f32 100644
--- a/libs/WindowManager/Shell/res/values-ru/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ru/strings.xml
@@ -119,7 +119,7 @@
<string name="handle_text" msgid="4419667835599523257">"Обозначение приложения"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Значок приложения"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Полноэкранный режим"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Режим компьютера"</string>
+ <string name="desktop_text" msgid="1582173066857454541">"Версия для ПК"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Разделить экран"</string>
<string name="more_button_text" msgid="3655388105592893530">"Ещё"</string>
<string name="float_button_text" msgid="9221657008391364581">"Плавающее окно"</string>
@@ -132,7 +132,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Изменить соотношение сторон"</string>
<string name="close_text" msgid="4986518933445178928">"Закрыть"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Закрыть меню"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Открыть меню"</string>
+ <string name="desktop_mode_app_header_chip_text" msgid="8300164817452574565">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" (версия для ПК)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Развернуть на весь экран"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Изменить размер"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Приложение нельзя сюда переместить"</string>
@@ -145,8 +145,8 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Растянуть окно приложения влево"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Растянуть окно приложения вправо"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Развернуть окно или восстановить его размер"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Перейти в режим разделения экрана"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Перейти в режим компьютера"</string>
+ <string name="app_handle_chip_accessibility_announce" msgid="499881698947450536">"Открыть меню"</string>
+ <string name="app_handle_menu_accessibility_announce" msgid="7928858564852785398">"Открыть в режиме \"<xliff:g id="WINDOWING_MODE">%1$s</xliff:g>\""</string>
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Растянуть окно влево"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Растянуть окно вправо"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Развернуть окно или восстановить его размер"</string>
diff --git a/libs/WindowManager/Shell/res/values-si/strings.xml b/libs/WindowManager/Shell/res/values-si/strings.xml
index f0ef1d1..b7b2863 100644
--- a/libs/WindowManager/Shell/res/values-si/strings.xml
+++ b/libs/WindowManager/Shell/res/values-si/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"යෙදුම් හසුරුව"</string>
<string name="app_icon_text" msgid="2823268023931811747">"යෙදුම් නිරූපකය"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"පූර්ණ තිරය"</string>
- <string name="desktop_text" msgid="1077633567027630454">"ඩෙස්ක්ටොප් ප්රකාරය"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"බෙදුම් තිරය"</string>
<string name="more_button_text" msgid="3655388105592893530">"තව"</string>
<string name="float_button_text" msgid="9221657008391364581">"පාවෙන"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"දර්ශන අනුපාතය වෙනස් කරන්න"</string>
<string name="close_text" msgid="4986518933445178928">"වසන්න"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"මෙනුව වසන්න"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"මෙනුව විවෘත කරන්න"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"තිරය උපරිම කරන්න"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"ප්රතිප්රමාණය කරන්න"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"යෙදුම මෙතැනට ගෙන යා නොහැක"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"යෙදුම් කවුළුව වමට ප්රතිප්රමාණ කරන්න"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"යෙදුම් කවුළුව දකුණට ප්රතිප්රමාණ කරන්න"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"කවුළු ප්රමාණය උපරිම කරන්න හෝ ප්රතිසාධනය කරන්න"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"බෙදුම් තිර මාදිලියට ඇතුළු වන්න"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"ඩෙස්ක්ටොප කවුළුකරණ මාදිලියට ඇතුළු වන්න"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"කවුළුව වමට ප්රතිප්රමාණ කරන්න"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"කවුළුව දකුණට ප්රතිප්රමාණ කරන්න"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"කවුළු ප්රමාණය උපරිම කරන්න හෝ ප්රතිසාධනය කරන්න"</string>
diff --git a/libs/WindowManager/Shell/res/values-sk/strings.xml b/libs/WindowManager/Shell/res/values-sk/strings.xml
index 688c217..ede0cdd 100644
--- a/libs/WindowManager/Shell/res/values-sk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sk/strings.xml
@@ -119,7 +119,7 @@
<string name="handle_text" msgid="4419667835599523257">"Rukoväť aplikácie"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ikona aplikácie"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Celá obrazovka"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Režim počítača"</string>
+ <string name="desktop_text" msgid="1582173066857454541">"Zobrazenie v počítači"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Rozdelená obrazovka"</string>
<string name="more_button_text" msgid="3655388105592893530">"Viac"</string>
<string name="float_button_text" msgid="9221657008391364581">"Plávajúce"</string>
@@ -132,7 +132,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Zmeniť pomer strán"</string>
<string name="close_text" msgid="4986518933445178928">"Zavrieť"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Zavrieť ponuku"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Otvoriť ponuku"</string>
+ <string name="desktop_mode_app_header_chip_text" msgid="8300164817452574565">"<xliff:g id="APP_NAME">%1$s</xliff:g> (zobrazenie v počítači)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximalizovať obrazovku"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Zmeniť veľkosť"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikácia sa sem nedá presunúť"</string>
@@ -145,8 +145,8 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Zmeniť veľkosť okna aplikácie vľavo"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Zmeniť veľkosť okna aplikácie vpravo"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Maximalizovať alebo obnoviť veľkosť okna"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Spustiť režim rozdelenej obrazovky"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Prejsť na režim okien na pracovnej ploche"</string>
+ <string name="app_handle_chip_accessibility_announce" msgid="499881698947450536">"Otvoriť ponuku"</string>
+ <string name="app_handle_menu_accessibility_announce" msgid="7928858564852785398">"Zadať <xliff:g id="WINDOWING_MODE">%1$s</xliff:g>"</string>
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Zmeniť veľkosť okna vľavo"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Zmeniť veľkosť okna vpravo"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maximalizovať alebo obnoviť veľkosť okna"</string>
diff --git a/libs/WindowManager/Shell/res/values-sl/strings.xml b/libs/WindowManager/Shell/res/values-sl/strings.xml
index 69eb3e3..5f1f6ef 100644
--- a/libs/WindowManager/Shell/res/values-sl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sl/strings.xml
@@ -119,7 +119,7 @@
<string name="handle_text" msgid="4419667835599523257">"Identifikator aplikacije"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ikona aplikacije"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Celozaslonsko"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Namizni način"</string>
+ <string name="desktop_text" msgid="1582173066857454541">"Pogled za namizni računalnik"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Razdeljen zaslon"</string>
<string name="more_button_text" msgid="3655388105592893530">"Več"</string>
<string name="float_button_text" msgid="9221657008391364581">"Lebdeče"</string>
@@ -132,7 +132,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Sprememba razmerja stranic"</string>
<string name="close_text" msgid="4986518933445178928">"Zapri"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Zapri meni"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Odpri meni"</string>
+ <string name="desktop_mode_app_header_chip_text" msgid="8300164817452574565">"<xliff:g id="APP_NAME">%1$s</xliff:g> (pogled za namizni računalnik)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimiraj zaslon"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Spremeni velikost"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikacije ni mogoče premakniti sem"</string>
@@ -145,8 +145,8 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Sprememba velikosti okna aplikacije na levi"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Sprememba velikosti okna aplikacije na desni"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Povečava ali obnovitev velikosti okna"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Vklop načina razdeljenega zaslona"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Vklop načina prikaza v oknu na namizju"</string>
+ <string name="app_handle_chip_accessibility_announce" msgid="499881698947450536">"Odpiranje menija"</string>
+ <string name="app_handle_menu_accessibility_announce" msgid="7928858564852785398">"Odpiranje pogleda <xliff:g id="WINDOWING_MODE">%1$s</xliff:g>"</string>
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Sprememba velikosti okna na levi"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Sprememba velikosti okna na desni"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Povečava ali obnovitev velikosti okna"</string>
diff --git a/libs/WindowManager/Shell/res/values-sq/strings.xml b/libs/WindowManager/Shell/res/values-sq/strings.xml
index fcb0aa6..ea26bc6 100644
--- a/libs/WindowManager/Shell/res/values-sq/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sq/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"Emërtimi i aplikacionit"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ikona e aplikacionit"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Ekrani i plotë"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Modaliteti i desktopit"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"Ekrani i ndarë"</string>
<string name="more_button_text" msgid="3655388105592893530">"Më shumë"</string>
<string name="float_button_text" msgid="9221657008391364581">"Pluskuese"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Ndrysho raportin e pamjes"</string>
<string name="close_text" msgid="4986518933445178928">"Mbyll"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Mbyll menynë"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Hap menynë"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimizo ekranin"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Ndrysho përmasat"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikacioni nuk mund të zhvendoset këtu"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Ndrysho përmasat e dritares së aplikacionit majtas"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Ndrysho përmasat e dritares së aplikacionit djathtas"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Maksimizo ose restauro madhësinë e dritares"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Hyr në modalitetin e ekranit të ndarë"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Hyr në modalitetin e dritareve në desktop"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Ndrysho përmasat e dritares në të majtë"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Ndrysho përmasat e dritares në të djathtë"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maksimizo ose restauro madhësinë e dritares"</string>
diff --git a/libs/WindowManager/Shell/res/values-sr/strings.xml b/libs/WindowManager/Shell/res/values-sr/strings.xml
index 6a2ffcd..ea7a1bb 100644
--- a/libs/WindowManager/Shell/res/values-sr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sr/strings.xml
@@ -119,7 +119,7 @@
<string name="handle_text" msgid="4419667835599523257">"Идентификатор апликације"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Икона апликације"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Преко целог екрана"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Режим за рачунаре"</string>
+ <string name="desktop_text" msgid="1582173066857454541">"Приказ за рачунаре"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Подељени екран"</string>
<string name="more_button_text" msgid="3655388105592893530">"Још"</string>
<string name="float_button_text" msgid="9221657008391364581">"Плутајуће"</string>
@@ -132,7 +132,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Промени размеру"</string>
<string name="close_text" msgid="4986518933445178928">"Затворите"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Затворите мени"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Отворите мени"</string>
+ <string name="desktop_mode_app_header_chip_text" msgid="8300164817452574565">"<xliff:g id="APP_NAME">%1$s</xliff:g> (приказ за рачунаре)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Повећај екран"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Промени величину"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Апликација не може да се премести овде"</string>
@@ -145,8 +145,8 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Промените величину прозора апликације налево"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Промените величину прозора апликације надесно"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Увећајте или вратите величину прозора"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Уђите у режим подељеног екрана"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Уђите у режим прозора на рачунару"</string>
+ <string name="app_handle_chip_accessibility_announce" msgid="499881698947450536">"Отворите Мени"</string>
+ <string name="app_handle_menu_accessibility_announce" msgid="7928858564852785398">"Унесите <xliff:g id="WINDOWING_MODE">%1$s</xliff:g>"</string>
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Промените величину прозора налево"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Промените величину прозора надесно"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Увећајте или вратите величину прозора"</string>
diff --git a/libs/WindowManager/Shell/res/values-sv/strings.xml b/libs/WindowManager/Shell/res/values-sv/strings.xml
index a9df476..f3e53d0e 100644
--- a/libs/WindowManager/Shell/res/values-sv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sv/strings.xml
@@ -119,7 +119,7 @@
<string name="handle_text" msgid="4419667835599523257">"Apphandtag"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Appikon"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Helskärm"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Datorläge"</string>
+ <string name="desktop_text" msgid="1582173066857454541">"Datorvy"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Delad skärm"</string>
<string name="more_button_text" msgid="3655388105592893530">"Mer"</string>
<string name="float_button_text" msgid="9221657008391364581">"Svävande"</string>
@@ -132,7 +132,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Ändra bildformat"</string>
<string name="close_text" msgid="4986518933445178928">"Stäng"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Stäng menyn"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Öppna menyn"</string>
+ <string name="desktop_mode_app_header_chip_text" msgid="8300164817452574565">"<xliff:g id="APP_NAME">%1$s</xliff:g> (datorvy)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximera skärmen"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Ändra storlek"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Det går inte att flytta appen hit"</string>
@@ -145,8 +145,8 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Ändra storlek på appfönstret åt vänster"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Ändra storlek på appfönstret åt höger"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Maximera eller återställ fönsterstorleken"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Starta läget för delad skärm"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Starta datorläget"</string>
+ <string name="app_handle_chip_accessibility_announce" msgid="499881698947450536">"Öppna menyn"</string>
+ <string name="app_handle_menu_accessibility_announce" msgid="7928858564852785398">"Ange <xliff:g id="WINDOWING_MODE">%1$s</xliff:g>"</string>
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Ändra storlek på fönstret åt vänster"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Ändra storlek på fönstret åt höger"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maximera eller återställ fönsterstorleken"</string>
diff --git a/libs/WindowManager/Shell/res/values-sw/strings.xml b/libs/WindowManager/Shell/res/values-sw/strings.xml
index a3c9a0d..51aacac 100644
--- a/libs/WindowManager/Shell/res/values-sw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sw/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"Utambulisho wa programu"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Aikoni ya Programu"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Skrini nzima"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Hali ya Kompyuta ya mezani"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"Gawa Skrini"</string>
<string name="more_button_text" msgid="3655388105592893530">"Zaidi"</string>
<string name="float_button_text" msgid="9221657008391364581">"Inayoelea"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Badilisha uwiano"</string>
<string name="close_text" msgid="4986518933445178928">"Funga"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Funga Menyu"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Fungua Menyu"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Panua Dirisha kwenye Skrini"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Badilisha ukubwa"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Imeshindwa kuhamishia programu hapa"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Badilisha ukubwa wa dirisha la programu kushoto"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Badilisha ukubwa wa dirisha la programu kulia"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Panua au urejeshe ukubwa wa dirisha"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Ingia katika hali ya skrini iliyogawanywa"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Ingia katika hali ya madirisha ya kompyuta ya mezani"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Badilisha ukubwa wa dirisha kushoto"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Badilisha ukubwa wa dirisha kulia"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Panua au urejeshe ukubwa wa dirisha"</string>
diff --git a/libs/WindowManager/Shell/res/values-ta/strings.xml b/libs/WindowManager/Shell/res/values-ta/strings.xml
index b1b8c7f..0c7206c 100644
--- a/libs/WindowManager/Shell/res/values-ta/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ta/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"ஆப்ஸ் ஹேண்டில்"</string>
<string name="app_icon_text" msgid="2823268023931811747">"ஆப்ஸ் ஐகான்"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"முழுத்திரை"</string>
- <string name="desktop_text" msgid="1077633567027630454">"டெஸ்க்டாப் பயன்முறை"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"திரையைப் பிரிக்கும்"</string>
<string name="more_button_text" msgid="3655388105592893530">"கூடுதல் விருப்பத்தேர்வுகள்"</string>
<string name="float_button_text" msgid="9221657008391364581">"மிதக்கும் சாளரம்"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"தோற்ற விகிதத்தை மாற்று"</string>
<string name="close_text" msgid="4986518933445178928">"மூடும்"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"மெனுவை மூடும்"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"மெனுவைத் திறக்கும்"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"திரையைப் பெரிதாக்கு"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"அளவை மாற்று"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ஆப்ஸை இங்கே நகர்த்த முடியாது"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"ஆப்ஸ் சாளரத்தின் இடதுபுறத்தில் அளவை மாற்றும்"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"ஆப்ஸ் சாளரத்தின் வலதுபுறத்தில் அளவை மாற்றும்"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"சாளரத்தின் அளவைப் பெரிதாக்கும்/மீட்டெடுக்கும்"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"திரைப் பிரிப்புப் பயன்முறையில் உள்நுழையும்"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"டெஸ்க்டாப் சாளரப் பயன்முறையில் உள்நுழையும்"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"சாளரத்தை இடதுபுறமாக அளவு மாற்றும்"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"சாளரத்தை வலதுபுறமாக அளவு மாற்றும்"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"சாளரத்தின் அளவைப் பெரிதாக்கும்/மீட்டெடுக்கும்"</string>
diff --git a/libs/WindowManager/Shell/res/values-te/strings.xml b/libs/WindowManager/Shell/res/values-te/strings.xml
index 932f831..f7cf43e 100644
--- a/libs/WindowManager/Shell/res/values-te/strings.xml
+++ b/libs/WindowManager/Shell/res/values-te/strings.xml
@@ -119,7 +119,7 @@
<string name="handle_text" msgid="4419667835599523257">"యాప్ హ్యాండిల్"</string>
<string name="app_icon_text" msgid="2823268023931811747">"యాప్ చిహ్నం"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"ఫుల్-స్క్రీన్"</string>
- <string name="desktop_text" msgid="1077633567027630454">"డెస్క్టాప్ మోడ్"</string>
+ <string name="desktop_text" msgid="1582173066857454541">"డెస్క్టాప్ వీక్షణ"</string>
<string name="split_screen_text" msgid="1396336058129570886">"స్ప్లిట్ స్క్రీన్"</string>
<string name="more_button_text" msgid="3655388105592893530">"మరిన్ని"</string>
<string name="float_button_text" msgid="9221657008391364581">"ఫ్లోట్"</string>
@@ -132,7 +132,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"ఆకార నిష్పత్తిని మార్చండి"</string>
<string name="close_text" msgid="4986518933445178928">"మూసివేయండి"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"మెనూను మూసివేయండి"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"మెనూను తెరవండి"</string>
+ <string name="desktop_mode_app_header_chip_text" msgid="8300164817452574565">"<xliff:g id="APP_NAME">%1$s</xliff:g> (డెస్క్టాప్ వీక్షణ)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"స్క్రీన్ సైజ్ను పెంచండి"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"సైజ్ మార్చండి"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"యాప్ను ఇక్కడకి తరలించడం సాధ్యం కాదు"</string>
@@ -145,8 +145,8 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"యాప్ విండో ఎడమ వైపు సైజ్ మార్చండి"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"యాప్ విండో కుడి వైపు సైజ్ మార్చండి"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"విండో సైజ్ను మ్యాగ్జిమైజ్ చేయండి లేదా రీస్టోర్ చేయండి"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"స్ప్లిట్ స్క్రీన్ మోడ్ను ఉపయోగించండి"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"డెస్క్టాప్ విండోయింగ్ మోడ్ను ఎంటర్ చేయండి"</string>
+ <string name="app_handle_chip_accessibility_announce" msgid="499881698947450536">"మెనూను తెరవండి"</string>
+ <string name="app_handle_menu_accessibility_announce" msgid="7928858564852785398">"<xliff:g id="WINDOWING_MODE">%1$s</xliff:g>ను ఎంటర్ చేయండి"</string>
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"విండో ఎడమ వైపునకు సైజ్ను మార్చండి"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"విండో కుడి వైపునకు సైజ్ను మార్చండి"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"విండో సైజ్ను మ్యాగ్జిమైజ్ చేయండి లేదా రీస్టోర్ చేయండి"</string>
diff --git a/libs/WindowManager/Shell/res/values-th/strings.xml b/libs/WindowManager/Shell/res/values-th/strings.xml
index e157474..77cd2e2 100644
--- a/libs/WindowManager/Shell/res/values-th/strings.xml
+++ b/libs/WindowManager/Shell/res/values-th/strings.xml
@@ -119,7 +119,7 @@
<string name="handle_text" msgid="4419667835599523257">"แฮนเดิลแอป"</string>
<string name="app_icon_text" msgid="2823268023931811747">"ไอคอนแอป"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"เต็มหน้าจอ"</string>
- <string name="desktop_text" msgid="1077633567027630454">"โหมดเดสก์ท็อป"</string>
+ <string name="desktop_text" msgid="1582173066857454541">"มุมมองบนเดสก์ท็อป"</string>
<string name="split_screen_text" msgid="1396336058129570886">"แยกหน้าจอ"</string>
<string name="more_button_text" msgid="3655388105592893530">"เพิ่มเติม"</string>
<string name="float_button_text" msgid="9221657008391364581">"ล่องลอย"</string>
@@ -132,7 +132,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"เปลี่ยนสัดส่วนการแสดงผล"</string>
<string name="close_text" msgid="4986518933445178928">"ปิด"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"ปิดเมนู"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"เปิดเมนู"</string>
+ <string name="desktop_mode_app_header_chip_text" msgid="8300164817452574565">"<xliff:g id="APP_NAME">%1$s</xliff:g> (มุมมองบนเดสก์ท็อป)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"ขยายหน้าจอให้ใหญ่สุด"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"ปรับขนาด"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ย้ายแอปมาที่นี่ไม่ได้"</string>
@@ -145,8 +145,8 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"ปรับขนาดหน้าต่างแอปไปทางซ้าย"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"ปรับขนาดหน้าต่างแอปไปทางขวา"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"ขยายหรือคืนค่าขนาดหน้าต่าง"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"เข้าสู่โหมดแยกหน้าจอ"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"เข้าสู่โหมดหน้าต่างเดสก์ท็อป"</string>
+ <string name="app_handle_chip_accessibility_announce" msgid="499881698947450536">"เปิดเมนู"</string>
+ <string name="app_handle_menu_accessibility_announce" msgid="7928858564852785398">"เข้าสู่ <xliff:g id="WINDOWING_MODE">%1$s</xliff:g>"</string>
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"ปรับขนาดหน้าต่างไปทางซ้าย"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"ปรับขนาดหน้าต่างไปทางขวา"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"ขยายหรือคืนค่าขนาดหน้าต่าง"</string>
diff --git a/libs/WindowManager/Shell/res/values-tl/strings.xml b/libs/WindowManager/Shell/res/values-tl/strings.xml
index 7f29704..5787e10 100644
--- a/libs/WindowManager/Shell/res/values-tl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tl/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"Handle ng app"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Icon ng App"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Fullscreen"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Desktop Mode"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"Split Screen"</string>
<string name="more_button_text" msgid="3655388105592893530">"Higit pa"</string>
<string name="float_button_text" msgid="9221657008391364581">"Float"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Baguhin ang aspect ratio"</string>
<string name="close_text" msgid="4986518933445178928">"Isara"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Isara ang Menu"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Buksan ang Menu"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"I-maximize ang Screen"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"I-resize"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Hindi mailipat dito ang app"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"I-resize pakaliwa ang window ng app"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"I-resize pakanan ang window ng app"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"I-maximize o i-restore ang laki ng window"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Pumunta sa split screen mode"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Pumunta sa desktop windowing mode"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"I-resize pakaliwa ang window"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"I-resize pakanan ang window"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"I-maximize o i-restore ang laki ng window"</string>
diff --git a/libs/WindowManager/Shell/res/values-tr/strings.xml b/libs/WindowManager/Shell/res/values-tr/strings.xml
index 6a5d1ab..28b2a7d 100644
--- a/libs/WindowManager/Shell/res/values-tr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tr/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"Uygulama tanıtıcısı"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Uygulama Simgesi"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Tam Ekran"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Masaüstü Modu"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"Bölünmüş Ekran"</string>
<string name="more_button_text" msgid="3655388105592893530">"Daha Fazla"</string>
<string name="float_button_text" msgid="9221657008391364581">"Havada Süzülen"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"En boy oranını değiştir"</string>
<string name="close_text" msgid="4986518933445178928">"Kapat"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Menüyü kapat"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Menüyü aç"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Ekranı Büyüt"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Yeniden boyutlandır"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Uygulama buraya taşınamıyor"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Uygulama penceresini sola yeniden boyutlandır"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Uygulama penceresini sağa yeniden boyutlandır"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Pencereyi ekranı kaplayacak şekilde büyüt veya önceki boyutuna döndür"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Bölünmüş ekran moduna gir"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Masaüstü pencereleme moduna gir"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Pencereyi sola yeniden boyutlandır"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Pencereyi sağa yeniden boyutlandır"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Pencereyi ekranı kaplayacak şekilde büyüt veya önceki boyutuna döndür"</string>
diff --git a/libs/WindowManager/Shell/res/values-uk/strings.xml b/libs/WindowManager/Shell/res/values-uk/strings.xml
index 7f4e91d..f5693ca 100644
--- a/libs/WindowManager/Shell/res/values-uk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uk/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"Дескриптор додатка"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Значок додатка"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"На весь екран"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Режим комп’ютера"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"Розділити екран"</string>
<string name="more_button_text" msgid="3655388105592893530">"Більше"</string>
<string name="float_button_text" msgid="9221657008391364581">"Плаваюче вікно"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Змінити формат"</string>
<string name="close_text" msgid="4986518933445178928">"Закрити"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Закрити меню"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Відкрити меню"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Розгорнути екран"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Змінити розмір"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Сюди не можна перемістити додаток"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Змінити розмір вікна додатка ліворуч"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Змінити розмір вікна додатка праворуч"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Розгорнути вікно або відновити його розмір"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Увімкнути режим розділення екрана"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Увімкнути режим вікон для комп’ютера"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Змінити розмір вікна ліворуч"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Змінити розмір вікна праворуч"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Розгорнути вікно або відновити його розмір"</string>
diff --git a/libs/WindowManager/Shell/res/values-ur/strings.xml b/libs/WindowManager/Shell/res/values-ur/strings.xml
index f461d40..a801b5e 100644
--- a/libs/WindowManager/Shell/res/values-ur/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ur/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"ایپ ہینڈل"</string>
<string name="app_icon_text" msgid="2823268023931811747">"ایپ کا آئیکن"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"مکمل اسکرین"</string>
- <string name="desktop_text" msgid="1077633567027630454">"ڈیسک ٹاپ موڈ"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"اسپلٹ اسکرین"</string>
<string name="more_button_text" msgid="3655388105592893530">"مزید"</string>
<string name="float_button_text" msgid="9221657008391364581">"فلوٹ"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"تناسبی شرح کو تبدیل کریں"</string>
<string name="close_text" msgid="4986518933445178928">"بند کریں"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"مینیو بند کریں"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"مینو کھولیں"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"اسکرین کو بڑا کریں"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"سائز تبدیل کریں"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ایپ کو یہاں منتقل نہیں کیا جا سکتا"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"دائیں طرف ایپ ونڈو کا سائز تبدیل کریں"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"ایپ ونڈو کا سائز بائیں طرف تبدیل کریں"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"ونڈو کا سائز زیادہ سے زیادہ یا بحال کریں"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"سپلٹ اسکرین موڈ میں داخل ہوں"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"ڈیسک ٹاپ ونڈو وضع میں داخل ہوں"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"دائیں طرف ونڈو کا سائز تبدیل کریں"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"ونڈو کا سائز بائیں طرف تبدیل کریں"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"ونڈو کا سائز زیادہ سے زیادہ یا بحال کریں"</string>
diff --git a/libs/WindowManager/Shell/res/values-uz/strings.xml b/libs/WindowManager/Shell/res/values-uz/strings.xml
index 7c6a2a2..9fbbdc8 100644
--- a/libs/WindowManager/Shell/res/values-uz/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uz/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"Ilova identifikatori"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ilova belgisi"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Butun ekran"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Desktop rejimi"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"Ekranni ikkiga ajratish"</string>
<string name="more_button_text" msgid="3655388105592893530">"Yana"</string>
<string name="float_button_text" msgid="9221657008391364581">"Pufakli"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Tomonlar nisbatini oʻzgartirish"</string>
<string name="close_text" msgid="4986518933445178928">"Yopish"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Menyuni yopish"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Menyuni ochish"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Ekranni yoyish"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Oʻlchamini oʻzgartirish"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Ilova bu yerga surilmaydi"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Ilova chap oynasi oʻlchamini oʻzgartirish"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Ilova oʻng oynasi oʻlchamini oʻzgartirish"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Oyna oʻlchamini kengaytirish yoki asliga qaytarish"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Ajratilgan ekran rejimiga kirish"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Kompyuter rejimiga kirish"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Oyna oʻlchamini chapga oʻzgartirish"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Oyna oʻlchamini oʻngga oʻzgartirish"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Oyna oʻlchamini kengaytirish yoki asliga qaytarish"</string>
diff --git a/libs/WindowManager/Shell/res/values-vi/strings.xml b/libs/WindowManager/Shell/res/values-vi/strings.xml
index e7cacc3..b40a4e6 100644
--- a/libs/WindowManager/Shell/res/values-vi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-vi/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"Ô điều khiển ứng dụng"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Biểu tượng ứng dụng"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Toàn màn hình"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Chế độ máy tính"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"Chia đôi màn hình"</string>
<string name="more_button_text" msgid="3655388105592893530">"Tuỳ chọn khác"</string>
<string name="float_button_text" msgid="9221657008391364581">"Nổi"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Thay đổi tỷ lệ khung hình"</string>
<string name="close_text" msgid="4986518933445178928">"Đóng"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Đóng trình đơn"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Mở Trình đơn"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Mở rộng màn hình"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Đổi kích thước"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Không di chuyển được ứng dụng đến đây"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Đổi kích thước và chuyển cửa sổ ứng dụng sang trái"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Đổi kích thước và chuyển cửa sổ ứng dụng sang phải"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Phóng to hoặc khôi phục kích thước cửa sổ"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Mở chế độ chia đôi màn hình"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Mở chế độ cửa sổ trên máy tính"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Đổi kích thước và chuyển cửa sổ sang trái"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Đổi kích thước và chuyển cửa sổ sang phải"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Phóng to hoặc khôi phục kích thước cửa sổ"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
index 562a0ee0..45cd25b 100644
--- a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"应用手柄"</string>
<string name="app_icon_text" msgid="2823268023931811747">"应用图标"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"全屏"</string>
- <string name="desktop_text" msgid="1077633567027630454">"桌面模式"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"分屏"</string>
<string name="more_button_text" msgid="3655388105592893530">"更多"</string>
<string name="float_button_text" msgid="9221657008391364581">"悬浮"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"更改宽高比"</string>
<string name="close_text" msgid="4986518933445178928">"关闭"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"关闭菜单"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"打开菜单"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"最大化屏幕"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"调整大小"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"无法将应用移至此处"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"调整应用窗口大小并贴靠左侧"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"调整应用窗口大小并贴靠右侧"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"将窗口最大化或恢复大小"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"进入分屏模式"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"进入桌面设备窗口化模式"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"调整窗口大小并贴靠左侧"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"调整窗口大小并贴靠右侧"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"将窗口最大化或恢复大小"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
index eecd9f2..d2c22da 100644
--- a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"應用程式控點"</string>
<string name="app_icon_text" msgid="2823268023931811747">"應用程式圖示"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"全螢幕"</string>
- <string name="desktop_text" msgid="1077633567027630454">"桌面模式"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"分割螢幕"</string>
<string name="more_button_text" msgid="3655388105592893530">"更多"</string>
<string name="float_button_text" msgid="9221657008391364581">"浮動"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"變更長寬比"</string>
<string name="close_text" msgid="4986518933445178928">"關閉"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"關閉選單"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"打開選單"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"畫面最大化"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"調整大小"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"應用程式無法移至這裡"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"調整左邊應用程式視窗大小"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"調整右邊應用程式視窗大小"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"將視窗放到最大或者還原視窗大小"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"進入分割螢幕模式"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"進入桌面視窗模式"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"將視窗移去左邊調整大小"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"將視窗移去右邊調整大小"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"將視窗放到最大或者還原視窗大小"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
index c157c193..0984fad 100644
--- a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"應用程式控制代碼"</string>
<string name="app_icon_text" msgid="2823268023931811747">"應用程式圖示"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"全螢幕"</string>
- <string name="desktop_text" msgid="1077633567027630454">"電腦模式"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"分割畫面"</string>
<string name="more_button_text" msgid="3655388105592893530">"更多"</string>
<string name="float_button_text" msgid="9221657008391364581">"浮動"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"變更顯示比例"</string>
<string name="close_text" msgid="4986518933445178928">"關閉"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"關閉選單"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"開啟選單"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"畫面最大化"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"調整大小"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"應用程式無法移至此處"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"調整應用程式視窗大小並向左貼齊"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"調整應用程式視窗大小並向右貼齊"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"將視窗最大化或還原大小"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"進入分割畫面模式"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"進入電腦視窗化模式"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"調整應用程式視窗大小並向左貼齊"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"調整應用程式視窗大小並向右貼齊"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"將視窗最大化或還原大小"</string>
diff --git a/libs/WindowManager/Shell/res/values-zu/strings.xml b/libs/WindowManager/Shell/res/values-zu/strings.xml
index a7ba6d2..13f8ed1 100644
--- a/libs/WindowManager/Shell/res/values-zu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zu/strings.xml
@@ -119,7 +119,8 @@
<string name="handle_text" msgid="4419667835599523257">"Inkomba ye-App"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Isithonjana Se-app"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Isikrini esigcwele"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Imodi Yedeskithophu"</string>
+ <!-- no translation found for desktop_text (1582173066857454541) -->
+ <skip />
<string name="split_screen_text" msgid="1396336058129570886">"Hlukanisa isikrini"</string>
<string name="more_button_text" msgid="3655388105592893530">"Okwengeziwe"</string>
<string name="float_button_text" msgid="9221657008391364581">"Iflowuthi"</string>
@@ -132,7 +133,8 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Shintsha ukubukeka kwesilinganiselo"</string>
<string name="close_text" msgid="4986518933445178928">"Vala"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Vala Imenyu"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Vula Imenyu"</string>
+ <!-- no translation found for desktop_mode_app_header_chip_text (8300164817452574565) -->
+ <skip />
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Khulisa Isikrini Sifike Ekugcineni"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Shintsha usayizi"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"I-app ayikwazi ukuhanjiswa lapha"</string>
@@ -145,8 +147,10 @@
<string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Shintsha usayizi we-app yewindi ngakwesokunxele"</string>
<string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Shintsha usayizi we-app yewindi ngakwesokudla"</string>
<string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Khulisa noma buyisela usayizi wewindi"</string>
- <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Faka imodi yokuhlukanisa isikrini"</string>
- <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Faka imodi yokwenza iwindi yedeskithophu"</string>
+ <!-- no translation found for app_handle_chip_accessibility_announce (499881698947450536) -->
+ <skip />
+ <!-- no translation found for app_handle_menu_accessibility_announce (7928858564852785398) -->
+ <skip />
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Shintsha usayizi wewindi ngakwesokunxele"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Shintsha usayizi wewindi ngakwesokudla"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Khulisa noma buyisela usayizi wewindi"</string>
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index e395341..f5f3f0f 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -498,14 +498,6 @@
<!-- The default minimum allowed window height when resizing a window in desktop mode. -->
<dimen name="desktop_mode_minimum_window_height">352dp</dimen>
- <!-- The width of the maximize menu in desktop mode, depending on the number of options -->
- <dimen name="desktop_mode_maximize_menu_width_one_options">126dp</dimen>
- <dimen name="desktop_mode_maximize_menu_width_two_options">228dp</dimen>
- <dimen name="desktop_mode_maximize_menu_width_three_options">330dp</dimen>
-
- <!-- The height of the maximize menu in desktop mode. -->
- <dimen name="desktop_mode_maximize_menu_height">114dp</dimen>
-
<!-- The padding of the maximize menu in desktop mode. -->
<dimen name="desktop_mode_menu_padding">16dp</dimen>
diff --git a/libs/WindowManager/Shell/shared/res/values/dimen.xml b/libs/WindowManager/Shell/shared/res/values/dimen.xml
index 5f013c5..11a6f32 100644
--- a/libs/WindowManager/Shell/shared/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/shared/res/values/dimen.xml
@@ -38,6 +38,7 @@
<dimen name="drag_zone_v_split_from_expanded_view_height_fold_short">100dp</dimen>
<!-- Bubble drop target dimensions -->
+ <dimen name="drop_target_elevation">1dp</dimen>
<dimen name="drop_target_full_screen_padding">20dp</dimen>
<dimen name="drop_target_desktop_window_padding_small">100dp</dimen>
<dimen name="drop_target_desktop_window_padding_large">130dp</dimen>
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/TransitionUtil.java b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/TransitionUtil.java
index 4d00c741..8519872 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/TransitionUtil.java
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/TransitionUtil.java
@@ -21,6 +21,7 @@
import static android.view.RemoteAnimationTarget.MODE_CLOSING;
import static android.view.RemoteAnimationTarget.MODE_OPENING;
import static android.view.WindowManager.LayoutParams.INVALID_WINDOW_TYPE;
+import static android.view.WindowManager.LayoutParams.LAST_SYSTEM_WINDOW;
import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_CLOSE;
@@ -55,9 +56,15 @@
public class TransitionUtil {
/** Flag applied to a transition change to identify it as a divider bar for animation. */
public static final int FLAG_IS_DIVIDER_BAR = FLAG_FIRST_CUSTOM;
+ public static final int FLAG_IS_DIM_LAYER = FLAG_FIRST_CUSTOM << 1;
/** Flag applied to a transition change to identify it as a desktop wallpaper activity. */
- public static final int FLAG_IS_DESKTOP_WALLPAPER_ACTIVITY = FLAG_FIRST_CUSTOM << 1;
+ public static final int FLAG_IS_DESKTOP_WALLPAPER_ACTIVITY = FLAG_FIRST_CUSTOM << 2;
+
+ /**
+ * Applied to a {@link RemoteAnimationTarget} to identify dim layers for animation in Launcher.
+ */
+ public static final int TYPE_SPLIT_SCREEN_DIM_LAYER = LAST_SYSTEM_WINDOW + 1;
/** @return true if the transition was triggered by opening something vs closing something */
public static boolean isOpeningType(@WindowManager.TransitionType int type) {
@@ -117,6 +124,11 @@
return isNonApp(change) && change.hasFlags(FLAG_IS_DIVIDER_BAR);
}
+ /** Returns `true` if `change` is an app's dim layer. */
+ public static boolean isDimLayer(TransitionInfo.Change change) {
+ return isNonApp(change) && change.hasFlags(FLAG_IS_DIM_LAYER);
+ }
+
/** Returns `true` if `change` is only re-ordering. */
public static boolean isOrderOnly(TransitionInfo.Change change) {
return change.getMode() == TRANSIT_CHANGE
@@ -231,6 +243,14 @@
t.setLayer(leash, Integer.MAX_VALUE);
return;
}
+ if (isDimLayer(change)) {
+ // When a dim layer gets reparented onto the transition root, we need to zero out its
+ // position so that it's in line with everything else on the transition root. Also,
+ // we need to set a crop because we don't want it applying MATCH_PARENT on the whole
+ // root surface.
+ t.setPosition(leash, 0, 0);
+ t.setCrop(leash, change.getEndAbsBounds());
+ }
// Put all the OPEN/SHOW on top
if ((change.getFlags() & FLAG_IS_WALLPAPER) != 0) {
@@ -284,14 +304,19 @@
// Copied Transitions setup code (which expects bottom-to-top order, so we swap here)
setupLeash(leashSurface, change, info.getChanges().size() - order, info, t);
t.reparent(change.getLeash(), leashSurface);
- t.setAlpha(change.getLeash(), 1.0f);
- t.show(change.getLeash());
+ if (!isDimLayer(change)) {
+ // Most leashes going onto the transition root should have their alpha set here to make
+ // them visible. But dim layers should be left untouched (their alpha value is their
+ // actual dim value).
+ t.setAlpha(change.getLeash(), 1.0f);
+ }
if (!isDividerBar(change)) {
// For divider, don't modify its inner leash position when creating the outer leash
// for the transition. In case the position being wrong after the transition finished.
t.setPosition(change.getLeash(), 0, 0);
}
t.setLayer(change.getLeash(), 0);
+ t.show(change.getLeash());
return leashSurface;
}
@@ -333,6 +358,9 @@
if (isDividerBar(change)) {
return getDividerTarget(change, leash);
}
+ if (isDimLayer(change)) {
+ return getDimLayerTarget(change, leash);
+ }
int taskId;
boolean isNotInRecents;
@@ -439,6 +467,17 @@
TYPE_DOCK_DIVIDER);
}
+ private static RemoteAnimationTarget getDimLayerTarget(TransitionInfo.Change change,
+ SurfaceControl leash) {
+ return new RemoteAnimationTarget(-1 /* taskId */, newModeToLegacyMode(change.getMode()),
+ leash, false /* isTranslucent */, null /* clipRect */,
+ null /* contentInsets */, Integer.MAX_VALUE /* prefixOrderIndex */,
+ new android.graphics.Point(0, 0) /* position */, change.getStartAbsBounds(),
+ change.getStartAbsBounds(), new WindowConfiguration(), true, null /* startLeash */,
+ null /* startBounds */, null /* taskInfo */, false /* allowEnterPip */,
+ TYPE_SPLIT_SCREEN_DIM_LAYER);
+ }
+
/**
* Finds the "correct" root idx for a change. The change's end display is prioritized, then
* the start display. If there is no display, it will fallback on the 0th root in the
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/animation/Interpolators.java b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/animation/Interpolators.java
index f45dc3a..e92c1eb 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/animation/Interpolators.java
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/animation/Interpolators.java
@@ -93,10 +93,21 @@
public static final PathInterpolator SLOWDOWN_INTERPOLATOR =
new PathInterpolator(0.5f, 1f, 0.5f, 1f);
+ /**
+ * An interpolator used for dimming a task as it travels offscreen, or towards a distant dismiss
+ * point. A sharp rise, followed by a steady middle, and ending with another sharp rise.
+ */
public static final PathInterpolator DIM_INTERPOLATOR =
new PathInterpolator(.23f, .87f, .52f, -0.11f);
/**
+ * An interpolator used for dimming a task very quickly. Roughly approximates one of the "sharp
+ * rises" of {@link #DIM_INTERPOLATOR}.
+ */
+ public static final PathInterpolator FAST_DIM_INTERPOLATOR =
+ new PathInterpolator(0.23f, 0.87f, 0.83f, 0.83f);
+
+ /**
* Use this interpolator for animating progress values coming from the back callback to get
* the predictive-back-typical decelerate motion.
*
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DragZone.kt b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DragZone.kt
index 5d346c0..6eff75c 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DragZone.kt
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DragZone.kt
@@ -31,29 +31,41 @@
/** The bounds of this drag zone. */
val bounds: Rect
+ /** The bounds of the drop target associated with this drag zone. */
+ val dropTarget: Rect?
fun contains(x: Int, y: Int) = bounds.contains(x, y)
/** Represents the bubble drag area on the screen. */
- sealed class Bubble(override val bounds: Rect) : DragZone {
- data class Left(override val bounds: Rect, val dropTarget: Rect) : Bubble(bounds)
- data class Right(override val bounds: Rect, val dropTarget: Rect) : Bubble(bounds)
+ sealed class Bubble(override val bounds: Rect, override val dropTarget: Rect) : DragZone {
+ data class Left(override val bounds: Rect, override val dropTarget: Rect) :
+ Bubble(bounds, dropTarget)
+
+ data class Right(override val bounds: Rect, override val dropTarget: Rect) :
+ Bubble(bounds, dropTarget)
}
/** Represents dragging to Desktop Window. */
- data class DesktopWindow(override val bounds: Rect, val dropTarget: Rect) : DragZone
+ data class DesktopWindow(override val bounds: Rect, override val dropTarget: Rect) : DragZone
/** Represents dragging to Full Screen. */
- data class FullScreen(override val bounds: Rect, val dropTarget: Rect) : DragZone
+ data class FullScreen(override val bounds: Rect, override val dropTarget: Rect) : DragZone
/** Represents dragging to dismiss. */
- data class Dismiss(override val bounds: Rect) : DragZone
+ data class Dismiss(override val bounds: Rect) : DragZone {
+ override val dropTarget: Rect? = null
+ }
/** Represents dragging to enter Split or replace a Split app. */
sealed class Split(override val bounds: Rect) : DragZone {
+ override val dropTarget: Rect? = null
+
data class Left(override val bounds: Rect) : Split(bounds)
+
data class Right(override val bounds: Rect) : Split(bounds)
+
data class Top(override val bounds: Rect) : Split(bounds)
+
data class Bottom(override val bounds: Rect) : Split(bounds)
}
}
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DropTargetManager.kt b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DropTargetManager.kt
index 29ce8d9..2dc183f 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DropTargetManager.kt
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DropTargetManager.kt
@@ -16,22 +16,54 @@
package com.android.wm.shell.shared.bubbles
+import android.content.Context
+import android.graphics.Rect
+import android.view.View
+import android.widget.FrameLayout
+import androidx.core.animation.Animator
+import androidx.core.animation.AnimatorListenerAdapter
+import androidx.core.animation.ValueAnimator
+
/**
* Manages animating drop targets in response to dragging bubble icons or bubble expanded views
* across different drag zones.
*/
class DropTargetManager(
+ context: Context,
+ private val container: FrameLayout,
private val isLayoutRtl: Boolean,
- private val dragZoneChangedListener: DragZoneChangedListener
+ private val dragZoneChangedListener: DragZoneChangedListener,
) {
private var state: DragState? = null
+ private val dropTargetView = View(context)
+ private var animator: ValueAnimator? = null
+
+ private companion object {
+ const val ANIMATION_DURATION_MS = 250L
+ }
/** Must be called when a drag gesture is starting. */
fun onDragStarted(draggedObject: DraggedObject, dragZones: List<DragZone>) {
val state = DragState(dragZones, draggedObject)
dragZoneChangedListener.onInitialDragZoneSet(state.initialDragZone)
this.state = state
+ animator?.cancel()
+ setupDropTarget()
+ }
+
+ private fun setupDropTarget() {
+ if (dropTargetView.parent != null) container.removeView(dropTargetView)
+ container.addView(dropTargetView, 0)
+ // TODO b/393173014: set elevation and background
+ dropTargetView.alpha = 0f
+ dropTargetView.scaleX = 1f
+ dropTargetView.scaleY = 1f
+ dropTargetView.translationX = 0f
+ dropTargetView.translationY = 0f
+ // the drop target is added with a width and height of 1 pixel. when it gets resized, we use
+ // set its scale to the width and height of the bounds it should have to avoid layout passes
+ dropTargetView.layoutParams = FrameLayout.LayoutParams(/* width= */ 1, /* height= */ 1)
}
/** Called when the user drags to a new location. */
@@ -42,14 +74,67 @@
state.currentDragZone = newDragZone
if (oldDragZone != newDragZone) {
dragZoneChangedListener.onDragZoneChanged(from = oldDragZone, to = newDragZone)
+ updateDropTarget()
}
}
/** Called when the drag ended. */
fun onDragEnded() {
+ startFadeAnimation(from = dropTargetView.alpha, to = 0f) {
+ container.removeView(dropTargetView)
+ }
state = null
}
+ private fun updateDropTarget() {
+ val currentDragZone = state?.currentDragZone ?: return
+ val dropTargetBounds = currentDragZone.dropTarget
+ when {
+ dropTargetBounds == null -> startFadeAnimation(from = dropTargetView.alpha, to = 0f)
+ dropTargetView.alpha == 0f -> {
+ dropTargetView.translationX = dropTargetBounds.exactCenterX()
+ dropTargetView.translationY = dropTargetBounds.exactCenterY()
+ dropTargetView.scaleX = dropTargetBounds.width().toFloat()
+ dropTargetView.scaleY = dropTargetBounds.height().toFloat()
+ startFadeAnimation(from = 0f, to = 1f)
+ }
+ else -> startMorphAnimation(dropTargetBounds)
+ }
+ }
+
+ private fun startFadeAnimation(from: Float, to: Float, onEnd: (() -> Unit)? = null) {
+ animator?.cancel()
+ val animator = ValueAnimator.ofFloat(from, to).setDuration(ANIMATION_DURATION_MS)
+ animator.addUpdateListener { _ -> dropTargetView.alpha = animator.animatedValue as Float }
+ if (onEnd != null) {
+ animator.doOnEnd(onEnd)
+ }
+ this.animator = animator
+ animator.start()
+ }
+
+ private fun startMorphAnimation(bounds: Rect) {
+ animator?.cancel()
+ val startAlpha = dropTargetView.alpha
+ val startTx = dropTargetView.translationX
+ val startTy = dropTargetView.translationY
+ val startScaleX = dropTargetView.scaleX
+ val startScaleY = dropTargetView.scaleY
+ val animator = ValueAnimator.ofFloat(0f, 1f).setDuration(ANIMATION_DURATION_MS)
+ animator.addUpdateListener { _ ->
+ val fraction = animator.animatedValue as Float
+ dropTargetView.alpha = startAlpha + (1 - startAlpha) * fraction
+ dropTargetView.translationX = startTx + (bounds.exactCenterX() - startTx) * fraction
+ dropTargetView.translationY = startTy + (bounds.exactCenterY() - startTy) * fraction
+ dropTargetView.scaleX =
+ startScaleX + (bounds.width().toFloat() - startScaleX) * fraction
+ dropTargetView.scaleY =
+ startScaleY + (bounds.height().toFloat() - startScaleY) * fraction
+ }
+ this.animator = animator
+ animator.start()
+ }
+
/** Stores the current drag state. */
private inner class DragState(
private val dragZones: List<DragZone>,
@@ -72,7 +157,18 @@
interface DragZoneChangedListener {
/** An initial drag zone was set. Called when a drag starts. */
fun onInitialDragZoneSet(dragZone: DragZone)
+
/** Called when the object was dragged to a different drag zone. */
fun onDragZoneChanged(from: DragZone, to: DragZone)
}
+
+ private fun Animator.doOnEnd(onEnd: () -> Unit) {
+ addListener(
+ object : AnimatorListenerAdapter() {
+ override fun onAnimationEnd(animation: Animator) {
+ onEnd()
+ }
+ }
+ )
+ }
}
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeCompatPolicy.kt b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeCompatPolicy.kt
index 126ab3d..14338a4 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeCompatPolicy.kt
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeCompatPolicy.kt
@@ -24,7 +24,6 @@
import android.content.pm.ActivityInfo.OVERRIDE_EXCLUDE_CAPTION_INSETS_FROM_APP_BOUNDS
import android.window.DesktopModeFlags
import com.android.internal.R
-import com.android.window.flags.Flags
/**
* Class to decide whether to apply app compat policies in desktop mode.
@@ -64,7 +63,7 @@
* is enabled.
*/
fun shouldExcludeCaptionFromAppBounds(taskInfo: TaskInfo): Boolean =
- Flags.excludeCaptionFromAppBounds()
+ DesktopModeFlags.EXCLUDE_CAPTION_FROM_APP_BOUNDS.isTrue
&& isAnyForceConsumptionFlagsEnabled()
&& taskInfo.topActivityInfo?.let {
isInsetsCoupledWithConfiguration(it) && (!taskInfo.isResizeable || it.isChangeEnabled(
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 00901a4..00c446c 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
@@ -27,6 +27,7 @@
import android.os.SystemProperties;
import android.view.Display;
import android.view.WindowManager;
+import android.window.DesktopExperienceFlags;
import android.window.DesktopModeFlags;
import com.android.internal.R;
@@ -271,7 +272,7 @@
* frontend implementations).
*/
public static boolean enableMultipleDesktops(@NonNull Context context) {
- return Flags.enableMultipleDesktopsBackend()
+ return DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue()
&& Flags.enableMultipleDesktopsFrontend()
&& canEnterDesktopMode(context);
}
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/split/SplitScreenConstants.java b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/split/SplitScreenConstants.java
index b48296f5..759e711 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/split/SplitScreenConstants.java
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/split/SplitScreenConstants.java
@@ -262,6 +262,7 @@
/** Flag applied to a transition change to identify it as a divider bar for animation. */
public static final int FLAG_IS_DIVIDER_BAR = TransitionUtil.FLAG_IS_DIVIDER_BAR;
+ public static final int FLAG_IS_DIM_LAYER = TransitionUtil.FLAG_IS_DIM_LAYER;
public static final String splitPositionToString(@SplitPosition int pos) {
switch (pos) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
index 58b46d2..f6a2c8d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
@@ -595,7 +595,10 @@
* <p>If bubble bar is supported, bubble views will be updated to switch to bar mode.
*/
public void registerBubbleStateListener(Bubbles.BubbleStateListener listener) {
- if (Flags.enableBubbleBar() && mBubblePositioner.isLargeScreen() && listener != null) {
+ final boolean bubbleBarAllowed = Flags.enableBubbleBar()
+ && (mBubblePositioner.isLargeScreen() || Flags.enableBubbleBarOnPhones())
+ && listener != null;
+ if (bubbleBarAllowed) {
// Only set the listener if we can show the bubble bar.
mBubbleStateListener = listener;
setUpBubbleViewsForMode();
@@ -772,7 +775,7 @@
/** Whether bubbles would be shown with the bubble bar UI. */
public boolean isShowingAsBubbleBar() {
return Flags.enableBubbleBar()
- && mBubblePositioner.isLargeScreen()
+ && (mBubblePositioner.isLargeScreen() || Flags.enableBubbleBarOnPhones())
&& mBubbleStateListener != null;
}
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 5273a7c..221c933 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
@@ -32,6 +32,7 @@
import com.android.internal.protolog.ProtoLog;
import com.android.launcher3.icons.IconNormalizer;
+import com.android.wm.shell.Flags;
import com.android.wm.shell.R;
import com.android.wm.shell.shared.bubbles.BubbleBarLocation;
import com.android.wm.shell.shared.bubbles.BubbleDropTargetBoundsProvider;
@@ -906,7 +907,7 @@
if (isOverflow) {
return mOverflowHeight;
} else {
- return getBubbleBarExpandedViewHeightForLandscape();
+ return getBubbleBarExpandedViewHeight();
}
}
@@ -927,18 +928,23 @@
* | bottom inset ↕ | ↓
* |----------------------| --- mScreenRect.bottom
*/
- private int getBubbleBarExpandedViewHeightForLandscape() {
+ private int getBubbleBarExpandedViewHeight() {
int heightOfBubbleBarContainer =
mScreenRect.height() - getExpandedViewBottomForBubbleBar();
- // getting landscape height from screen rect
- int expandedViewHeight = Math.min(mScreenRect.width(), mScreenRect.height());
+ int expandedViewHeight;
+ if (Flags.enableBubbleBarOnPhones() && !mDeviceConfig.isLargeScreen()) {
+ // we're on a phone, use the max / height
+ expandedViewHeight = Math.max(mScreenRect.width(), mScreenRect.height());
+ } else {
+ // getting landscape height from screen rect
+ expandedViewHeight = Math.min(mScreenRect.width(), mScreenRect.height());
+ }
expandedViewHeight -= heightOfBubbleBarContainer; /* removing bubble container height */
expandedViewHeight -= mInsets.top; /* removing top inset */
expandedViewHeight -= mExpandedViewPadding; /* removing spacing */
return expandedViewHeight;
}
-
/** The bottom position of the expanded view when showing above the bubble bar. */
public int getExpandedViewBottomForBubbleBar() {
return mBubbleBarTopOnScreen - mExpandedViewPadding;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java
index 4c3bde9..97184c8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java
@@ -67,6 +67,7 @@
private final SparseArray<DisplayRecord> mDisplays = new SparseArray<>();
private final ArrayList<OnDisplaysChangedListener> mDisplayChangedListeners = new ArrayList<>();
private final Map<Integer, RectF> mUnpopulatedDisplayBounds = new HashMap<>();
+ private DisplayTopology mDisplayTopology;
public DisplayController(Context context, IWindowManager wmService, ShellInit shellInit,
ShellExecutor mainExecutor, DisplayManager displayManager) {
@@ -157,6 +158,7 @@
for (int i = 0; i < mDisplays.size(); ++i) {
listener.onDisplayAdded(mDisplays.keyAt(i));
}
+ listener.onTopologyChanged(mDisplayTopology);
}
}
@@ -245,6 +247,7 @@
if (topology == null) {
return;
}
+ mDisplayTopology = topology;
SparseArray<RectF> absoluteBounds = topology.getAbsoluteBounds();
mUnpopulatedDisplayBounds.clear();
for (int i = 0; i < absoluteBounds.size(); ++i) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/WindowContainerTransactionSupplier.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/common/WindowContainerTransactionSupplier.kt
new file mode 100644
index 0000000..a1d700a
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/WindowContainerTransactionSupplier.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2025 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.window.WindowContainerTransaction
+import com.android.wm.shell.dagger.WMSingleton
+import java.util.function.Supplier
+import javax.inject.Inject
+
+/**
+ * An Injectable [Supplier<WindowContainerTransaction>]. This can be used in place of kotlin default
+ * parameters values [builder = ::WindowContainerTransaction] which requires the
+ * [@JvmOverloads] annotation to make this available in Java.
+ * This can be used every time a component needs the dependency to the default [Supplier] for
+ * [WindowContainerTransaction]s.
+ */
+@WMSingleton
+class WindowContainerTransactionSupplier @Inject constructor(
+) : Supplier<WindowContainerTransaction> {
+ override fun get(): WindowContainerTransaction = WindowContainerTransaction()
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/CenterParallaxSpec.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/CenterParallaxSpec.java
new file mode 100644
index 0000000..fb2a324
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/CenterParallaxSpec.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2025 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.split;
+
+import android.graphics.Point;
+import android.graphics.Rect;
+
+/**
+ * Calculation class, used when
+ * {@link com.android.wm.shell.common.split.SplitLayout#PARALLAX_ALIGN_CENTER} is the desired
+ * parallax effect.
+ */
+public class CenterParallaxSpec implements ParallaxSpec {
+ @Override
+ public void getParallax(Point retreatingOut, Point advancingOut, int position,
+ DividerSnapAlgorithm snapAlgorithm, boolean isLeftRightSplit, Rect displayBounds,
+ Rect retreatingSurface, Rect retreatingContent, Rect advancingSurface,
+ Rect advancingContent, int dimmingSide, boolean topLeftShrink) {
+ if (isLeftRightSplit) {
+ retreatingOut.x = (retreatingSurface.width() - retreatingContent.width()) / 2;
+ } else {
+ retreatingOut.y = (retreatingSurface.height() - retreatingContent.height()) / 2;
+ }
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DismissingParallaxSpec.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DismissingParallaxSpec.java
new file mode 100644
index 0000000..39ecbb3
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DismissingParallaxSpec.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2025 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.split;
+
+import static android.view.WindowManager.DOCKED_INVALID;
+
+import static com.android.wm.shell.shared.animation.Interpolators.SLOWDOWN_INTERPOLATOR;
+
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.view.WindowManager;
+
+/**
+ * Calculation class, used when
+ * {@link com.android.wm.shell.common.split.SplitLayout#PARALLAX_DISMISSING} is the desired parallax
+ * effect.
+ */
+public class DismissingParallaxSpec implements ParallaxSpec {
+ @Override
+ public void getParallax(Point retreatingOut, Point advancingOut, int position,
+ DividerSnapAlgorithm snapAlgorithm, boolean isLeftRightSplit, Rect displayBounds,
+ Rect retreatingSurface, Rect retreatingContent, Rect advancingSurface,
+ Rect advancingContent, int dimmingSide, boolean topLeftShrink) {
+ if (dimmingSide == DOCKED_INVALID) {
+ return;
+ }
+
+ float progressTowardScreenEdge =
+ Math.max(0, Math.min(snapAlgorithm.calculateDismissingFraction(position), 1f));
+ int totalDismissingDistance = 0;
+ if (position < snapAlgorithm.getFirstSplitTarget().getPosition()) {
+ totalDismissingDistance = snapAlgorithm.getDismissStartTarget().getPosition()
+ - snapAlgorithm.getFirstSplitTarget().getPosition();
+ } else if (position > snapAlgorithm.getLastSplitTarget().getPosition()) {
+ totalDismissingDistance = snapAlgorithm.getLastSplitTarget().getPosition()
+ - snapAlgorithm.getDismissEndTarget().getPosition();
+ }
+
+ float parallaxFraction =
+ calculateParallaxDismissingFraction(progressTowardScreenEdge, dimmingSide);
+ if (isLeftRightSplit) {
+ retreatingOut.x = (int) (parallaxFraction * totalDismissingDistance);
+ } else {
+ retreatingOut.y = (int) (parallaxFraction * totalDismissingDistance);
+ }
+ }
+
+ /**
+ * @return for a specified {@code fraction}, this returns an adjusted value that simulates a
+ * slowing down parallax effect
+ */
+ private float calculateParallaxDismissingFraction(float fraction, int dockSide) {
+ float result = SLOWDOWN_INTERPOLATOR.getInterpolation(fraction) / 3.5f;
+
+ // Less parallax at the top, just because.
+ if (dockSide == WindowManager.DOCKED_TOP) {
+ result /= 2f;
+ }
+ return result;
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerSnapAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerSnapAlgorithm.java
index 2f5afca..5b2dd97 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerSnapAlgorithm.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerSnapAlgorithm.java
@@ -465,5 +465,9 @@
this.snapPosition = snapPosition;
this.distanceMultiplier = distanceMultiplier;
}
+
+ public int getPosition() {
+ return position;
+ }
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/FlexParallaxSpec.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/FlexParallaxSpec.java
new file mode 100644
index 0000000..9fa1621
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/FlexParallaxSpec.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2025 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.split;
+
+import static android.view.WindowManager.DOCKED_BOTTOM;
+import static android.view.WindowManager.DOCKED_INVALID;
+import static android.view.WindowManager.DOCKED_LEFT;
+import static android.view.WindowManager.DOCKED_RIGHT;
+import static android.view.WindowManager.DOCKED_TOP;
+
+import static com.android.wm.shell.common.split.ResizingEffectPolicy.DEFAULT_OFFSCREEN_DIM;
+import static com.android.wm.shell.shared.animation.Interpolators.DIM_INTERPOLATOR;
+import static com.android.wm.shell.shared.animation.Interpolators.FAST_DIM_INTERPOLATOR;
+
+import android.graphics.Point;
+import android.graphics.Rect;
+
+/**
+ * Calculation class, used when {@link com.android.wm.shell.common.split.SplitLayout#PARALLAX_FLEX}
+ * is the desired parallax effect.
+ */
+public class FlexParallaxSpec implements ParallaxSpec {
+ final Rect mTempRect = new Rect();
+
+ @Override
+ public int getDimmingSide(int position, DividerSnapAlgorithm snapAlgorithm,
+ boolean isLeftRightSplit) {
+ if (position < snapAlgorithm.getMiddleTarget().getPosition()) {
+ return isLeftRightSplit ? DOCKED_LEFT : DOCKED_TOP;
+ } else if (position > snapAlgorithm.getMiddleTarget().getPosition()) {
+ return isLeftRightSplit ? DOCKED_RIGHT : DOCKED_BOTTOM;
+ }
+ return DOCKED_INVALID;
+ }
+
+ /**
+ * Calculates the amount of dim to apply to a task surface moving offscreen in flexible split.
+ * In flexible split, there are two dimming "behaviors".
+ * 1) "slow dim": when moving the divider from the middle of the screen to a target at 10% or
+ * 90%, we dim the app slightly as it moves partially offscreen.
+ * 2) "fast dim": when moving the divider from a side snap target further toward the screen
+ * edge, we dim the app rapidly as it approaches the dismiss point.
+ * @return 0f = no dim applied. 1f = full black.
+ */
+ public float getDimValue(int position, DividerSnapAlgorithm snapAlgorithm) {
+ int startDismissPos = snapAlgorithm.getDismissStartTarget().getPosition();
+ int firstTargetPos = snapAlgorithm.getFirstSplitTarget().getPosition();
+ int middleTargetPos = snapAlgorithm.getMiddleTarget().getPosition();
+ int lastTargetPos = snapAlgorithm.getLastSplitTarget().getPosition();
+ int endDismissPos = snapAlgorithm.getDismissEndTarget().getPosition();
+ float progress;
+
+ if (startDismissPos <= position && position < firstTargetPos) {
+ // Divider is on the left/top (between 0% and 10% of screen), "fast dim" as it moves
+ // toward the screen edge
+ progress = (float) (firstTargetPos - position) / (firstTargetPos - startDismissPos);
+ return fastDim(progress);
+ } else if (firstTargetPos <= position && position < middleTargetPos) {
+ // Divider is between 10% and 50%, "slow dim" as it moves toward the left/top target
+ progress = (float) (middleTargetPos - position) / (middleTargetPos - firstTargetPos);
+ return slowDim(progress);
+ } else if (middleTargetPos <= position && position < lastTargetPos) {
+ // Divider is between 50% and 90%, "slow dim" as it moves toward the right/bottom target
+ progress = (float) (position - middleTargetPos) / (lastTargetPos - middleTargetPos);
+ return slowDim(progress);
+ } else if (lastTargetPos <= position && position <= endDismissPos) {
+ // Divider is on the right/bottom (between 90% and 100% of screen), "fast dim" as it
+ // moves toward screen edge
+ progress = (float) (position - lastTargetPos) / (endDismissPos - lastTargetPos);
+ return fastDim(progress);
+ }
+ return 0f;
+ }
+
+ /**
+ * Used by {@link #getDimValue} to determine the amount to dim an app. Starts at zero and ramps
+ * up to the default amount of dimming for an offscreen app,
+ * {@link ResizingEffectPolicy#DEFAULT_OFFSCREEN_DIM}.
+ */
+ private float slowDim(float progress) {
+ return DIM_INTERPOLATOR.getInterpolation(progress) * DEFAULT_OFFSCREEN_DIM;
+ }
+
+ /**
+ * Used by {@link #getDimValue} to determine the amount to dim an app. Starts at
+ * {@link ResizingEffectPolicy#DEFAULT_OFFSCREEN_DIM} and ramps up to 100% dim (full black).
+ */
+ private float fastDim(float progress) {
+ return DEFAULT_OFFSCREEN_DIM + (FAST_DIM_INTERPOLATOR.getInterpolation(progress)
+ * (1 - DEFAULT_OFFSCREEN_DIM));
+ }
+
+ @Override
+ public void getParallax(Point retreatingOut, Point advancingOut, int position,
+ DividerSnapAlgorithm snapAlgorithm, boolean isLeftRightSplit, Rect displayBounds,
+ Rect retreatingSurface, Rect retreatingContent, Rect advancingSurface,
+ Rect advancingContent, int dimmingSide, boolean topLeftShrink) {
+ // Whether an app is getting pushed offscreen by the divider.
+ boolean isRetreatingOffscreen = !displayBounds.contains(retreatingSurface);
+ // Whether an app was getting pulled onscreen at the beginning of the drag.
+ boolean advancingSideStartedOffscreen = !displayBounds.contains(advancingContent);
+
+ // The simpler case when an app gets pushed offscreen (e.g. 50:50 -> 90:10)
+ if (isRetreatingOffscreen && !advancingSideStartedOffscreen) {
+ // On the left side, we use parallax to simulate the contents sticking to the
+ // divider. This is because surfaces naturally expand to the bottom and right,
+ // so when a surface's area expands, the contents stick to the left. This is
+ // correct behavior on the right-side surface, but not the left.
+ if (topLeftShrink) {
+ if (isLeftRightSplit) {
+ retreatingOut.x = retreatingSurface.width() - retreatingContent.width();
+ } else {
+ retreatingOut.y = retreatingSurface.height() - retreatingContent.height();
+ }
+ }
+ // All other cases (e.g. 10:90 -> 50:50, 10:90 -> 90:10, 10:90 -> dismiss)
+ } else {
+ mTempRect.set(retreatingSurface);
+ Point rootOffset = new Point();
+ // 10:90 -> 50:50, 10:90, or dismiss right
+ if (advancingSideStartedOffscreen) {
+ // We have to handle a complicated case here to keep the parallax smooth.
+ // When the divider crosses the 50% mark, the retreating-side app surface
+ // will start expanding offscreen. This is expected and unavoidable, but
+ // makes the parallax look disjointed. In order to preserve the illusion,
+ // we add another offset (rootOffset) to simulate the surface staying
+ // onscreen.
+ if (mTempRect.intersect(displayBounds)) {
+ if (retreatingSurface.left < displayBounds.left) {
+ rootOffset.x = displayBounds.left - retreatingSurface.left;
+ }
+ if (retreatingSurface.top < displayBounds.top) {
+ rootOffset.y = displayBounds.top - retreatingSurface.top;
+ }
+ }
+
+ // On the left side, we again have to simulate the contents sticking to the
+ // divider.
+ if (!topLeftShrink) {
+ if (isLeftRightSplit) {
+ advancingOut.x = advancingSurface.width() - advancingContent.width();
+ } else {
+ advancingOut.y = advancingSurface.height() - advancingContent.height();
+ }
+ }
+ }
+
+ // In all these cases, the shrinking app also receives a center parallax.
+ if (isLeftRightSplit) {
+ retreatingOut.x = rootOffset.x
+ + ((mTempRect.width() - retreatingContent.width()) / 2);
+ } else {
+ retreatingOut.y = rootOffset.y
+ + ((mTempRect.height() - retreatingContent.height()) / 2);
+ }
+ }
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/NoParallaxSpec.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/NoParallaxSpec.java
new file mode 100644
index 0000000..043b288
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/NoParallaxSpec.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2025 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.split;
+
+import android.graphics.Point;
+import android.graphics.Rect;
+
+/**
+ * Calculation class, used when {@link com.android.wm.shell.common.split.SplitLayout#PARALLAX_NONE}
+ * is the desired parallax effect.
+ */
+public class NoParallaxSpec implements ParallaxSpec {
+ @Override
+ public void getParallax(Point retreatingOut, Point advancingOut, int position,
+ DividerSnapAlgorithm snapAlgorithm, boolean isLeftRightSplit, Rect displayBounds,
+ Rect retreatingSurface, Rect retreatingContent, Rect advancingSurface,
+ Rect advancingContent, int dimmingSide, boolean topLeftShrink) {
+ // no-op
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/OffscreenTouchZone.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/OffscreenTouchZone.java
index 381f0b0..3211307 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/OffscreenTouchZone.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/OffscreenTouchZone.java
@@ -56,6 +56,7 @@
/** The function that will be run when this zone is tapped. */
private final Runnable mOnClickRunnable;
private SurfaceControlViewHost mViewHost;
+ private SurfaceControl mLeash;
/**
* @param isTopLeft Whether the desired touch zone will be on the top/left or the bottom/right
@@ -96,6 +97,7 @@
.setCallsite("OffscreenTouchZone::init");
builder.setParent(stageRoot);
SurfaceControl leash = builder.build();
+ mLeash = leash;
// Create a ViewHost that will hold our view.
WindowlessWindowManager wwm = new WindowlessWindowManager(config, leash, null);
@@ -117,10 +119,14 @@
}
/** Releases the touch zone when it's no longer needed. */
- void release() {
+ void release(SurfaceControl.Transaction t) {
if (mViewHost != null) {
mViewHost.release();
}
+ if (mLeash != null) {
+ t.remove(mLeash);
+ mLeash = null;
+ }
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/ParallaxSpec.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/ParallaxSpec.java
new file mode 100644
index 0000000..84d849b
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/ParallaxSpec.java
@@ -0,0 +1,62 @@
+/*
+ * 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.split;
+
+import static android.view.WindowManager.DOCKED_BOTTOM;
+import static android.view.WindowManager.DOCKED_INVALID;
+import static android.view.WindowManager.DOCKED_LEFT;
+import static android.view.WindowManager.DOCKED_RIGHT;
+import static android.view.WindowManager.DOCKED_TOP;
+
+import static com.android.wm.shell.shared.animation.Interpolators.DIM_INTERPOLATOR;
+
+import android.graphics.Point;
+import android.graphics.Rect;
+
+/**
+ * Default interface for a set of calculation classes, used for calculating various parallax and
+ * dimming effects in split screen.
+ */
+public interface ParallaxSpec {
+ /** Returns an int indicating which side of the screen is being dimmed (if any). */
+ default int getDimmingSide(int position, DividerSnapAlgorithm snapAlgorithm,
+ boolean isLeftRightSplit) {
+ if (position < snapAlgorithm.getFirstSplitTarget().getPosition()) {
+ return isLeftRightSplit ? DOCKED_LEFT : DOCKED_TOP;
+ } else if (position > snapAlgorithm.getLastSplitTarget().getPosition()) {
+ return isLeftRightSplit ? DOCKED_RIGHT : DOCKED_BOTTOM;
+ }
+ return DOCKED_INVALID;
+ }
+
+ /** Returns the dim amount that we'll apply to the app surface. 0f = no dim, 1f = full black */
+ default float getDimValue(int position, DividerSnapAlgorithm snapAlgorithm) {
+ float progressTowardScreenEdge =
+ Math.max(0, Math.min(snapAlgorithm.calculateDismissingFraction(position), 1f));
+ return DIM_INTERPOLATOR.getInterpolation(progressTowardScreenEdge);
+ }
+
+ /**
+ * Calculates the amount to offset app surfaces to create nice parallax effects. Writes to
+ * {@link ResizingEffectPolicy#mRetreatingSideParallax} and
+ * {@link ResizingEffectPolicy#mAdvancingSideParallax}.
+ */
+ void getParallax(Point retreatingOut, Point advancingOut, int position,
+ DividerSnapAlgorithm snapAlgorithm, boolean isLeftRightSplit, Rect displayBounds,
+ Rect retreatingSurface, Rect retreatingContent, Rect advancingSurface,
+ Rect advancingContent, int dimmingSide, boolean topLeftShrink);
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/ResizingEffectPolicy.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/ResizingEffectPolicy.java
index 3f76fd0..e2e1f96 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/ResizingEffectPolicy.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/ResizingEffectPolicy.java
@@ -26,27 +26,32 @@
import static com.android.wm.shell.common.split.SplitLayout.PARALLAX_DISMISSING;
import static com.android.wm.shell.common.split.SplitLayout.PARALLAX_FLEX;
import static com.android.wm.shell.common.split.SplitLayout.PARALLAX_NONE;
-import static com.android.wm.shell.shared.animation.Interpolators.DIM_INTERPOLATOR;
-import static com.android.wm.shell.shared.animation.Interpolators.SLOWDOWN_INTERPOLATOR;
import android.graphics.Point;
import android.graphics.Rect;
import android.view.SurfaceControl;
-import android.view.WindowManager;
/**
* This class governs how and when parallax and dimming effects are applied to task surfaces,
* usually when the divider is being moved around by the user (or during an animation).
*/
class ResizingEffectPolicy {
+ /** The default amount to dim an app that is partially offscreen. */
+ public static float DEFAULT_OFFSCREEN_DIM = 0.32f;
+
private final SplitLayout mSplitLayout;
/** The parallax algorithm we are currently using. */
private final int mParallaxType;
+ /**
+ * A convenience class, corresponding to {@link #mParallaxType}, that performs all the
+ * calculations for parallax and dimming values.
+ */
+ private final ParallaxSpec mParallaxSpec;
int mShrinkSide = DOCKED_INVALID;
// The current dismissing side.
- int mDismissingSide = DOCKED_INVALID;
+ int mDimmingSide = DOCKED_INVALID;
/**
* A {@link Point} that stores a single x and y value, representing the parallax translation
@@ -62,7 +67,7 @@
final Point mAdvancingSideParallax = new Point();
// The dimming value to hint the dismissing side and progress.
- float mDismissingDimValue = 0.0f;
+ float mDimValue = 0.0f;
/**
* Content bounds for the app that the divider is moving toward. This is the content that is
@@ -95,35 +100,38 @@
ResizingEffectPolicy(int parallaxType, SplitLayout splitLayout) {
mParallaxType = parallaxType;
mSplitLayout = splitLayout;
+ switch (mParallaxType) {
+ case PARALLAX_DISMISSING:
+ mParallaxSpec = new DismissingParallaxSpec();
+ break;
+ case PARALLAX_ALIGN_CENTER:
+ mParallaxSpec = new CenterParallaxSpec();
+ break;
+ case PARALLAX_FLEX:
+ mParallaxSpec = new FlexParallaxSpec();
+ break;
+ case PARALLAX_NONE:
+ default:
+ mParallaxSpec = new NoParallaxSpec();
+ break;
+ }
}
/**
- * Calculates the desired parallax values and stores them in {@link #mRetreatingSideParallax}
- * and {@link #mAdvancingSideParallax}. These values will be then be applied in
- * {@link #adjustRootSurface}.
- *
- * @param position The divider's position on the screen (x-coordinate in left-right split,
- * y-coordinate in top-bottom split).
+ * Calculates the desired parallax and dimming values for a task surface and stores them in
+ * {@link #mRetreatingSideParallax}, {@link #mAdvancingSideParallax}, and
+ * {@link #mDimValue} These values will be then be applied in
+ * {@link #adjustRootSurface} and {@link #adjustDimSurface} respectively.
*/
void applyDividerPosition(
int position, boolean isLeftRightSplit, DividerSnapAlgorithm snapAlgorithm) {
- mDismissingSide = DOCKED_INVALID;
+ mDimmingSide = DOCKED_INVALID;
mRetreatingSideParallax.set(0, 0);
mAdvancingSideParallax.set(0, 0);
- mDismissingDimValue = 0;
+ mDimValue = 0;
Rect displayBounds = mSplitLayout.getRootBounds();
- int totalDismissingDistance = 0;
- if (position < snapAlgorithm.getFirstSplitTarget().position) {
- mDismissingSide = isLeftRightSplit ? DOCKED_LEFT : DOCKED_TOP;
- totalDismissingDistance = snapAlgorithm.getDismissStartTarget().position
- - snapAlgorithm.getFirstSplitTarget().position;
- } else if (position > snapAlgorithm.getLastSplitTarget().position) {
- mDismissingSide = isLeftRightSplit ? DOCKED_RIGHT : DOCKED_BOTTOM;
- totalDismissingDistance = snapAlgorithm.getLastSplitTarget().position
- - snapAlgorithm.getDismissEndTarget().position;
- }
-
+ // Figure out which side is shrinking, and assign retreating/advancing bounds
final boolean topLeftShrink = isLeftRightSplit
? position < mSplitLayout.getTopLeftContentBounds().right
: position < mSplitLayout.getTopLeftContentBounds().bottom;
@@ -141,106 +149,20 @@
mAdvancingSurface.set(mSplitLayout.getTopLeftBounds());
}
- if (mDismissingSide != DOCKED_INVALID) {
- float fraction =
- Math.max(0, Math.min(snapAlgorithm.calculateDismissingFraction(position), 1f));
- mDismissingDimValue = DIM_INTERPOLATOR.getInterpolation(fraction);
- if (mParallaxType == PARALLAX_DISMISSING) {
- fraction = calculateParallaxDismissingFraction(fraction, mDismissingSide);
- if (isLeftRightSplit) {
- mRetreatingSideParallax.x = (int) (fraction * totalDismissingDistance);
- } else {
- mRetreatingSideParallax.y = (int) (fraction * totalDismissingDistance);
- }
- }
+ // Figure out if we should be dimming one side
+ mDimmingSide = mParallaxSpec.getDimmingSide(position, snapAlgorithm, isLeftRightSplit);
+
+ // If so, calculate dimming
+ if (mDimmingSide != DOCKED_INVALID) {
+ mDimValue = mParallaxSpec.getDimValue(position, snapAlgorithm);
}
- if (mParallaxType == PARALLAX_ALIGN_CENTER) {
- if (isLeftRightSplit) {
- mRetreatingSideParallax.x =
- (mRetreatingSurface.width() - mRetreatingContent.width()) / 2;
- } else {
- mRetreatingSideParallax.y =
- (mRetreatingSurface.height() - mRetreatingContent.height()) / 2;
- }
- } else if (mParallaxType == PARALLAX_FLEX) {
- // Whether an app is getting pushed offscreen by the divider.
- boolean isRetreatingOffscreen = !displayBounds.contains(mRetreatingSurface);
- // Whether an app was getting pulled onscreen at the beginning of the drag.
- boolean advancingSideStartedOffscreen = !displayBounds.contains(mAdvancingContent);
-
- // The simpler case when an app gets pushed offscreen (e.g. 50:50 -> 90:10)
- if (isRetreatingOffscreen && !advancingSideStartedOffscreen) {
- // On the left side, we use parallax to simulate the contents sticking to the
- // divider. This is because surfaces naturally expand to the bottom and right,
- // so when a surface's area expands, the contents stick to the left. This is
- // correct behavior on the right-side surface, but not the left.
- if (topLeftShrink) {
- if (isLeftRightSplit) {
- mRetreatingSideParallax.x =
- mRetreatingSurface.width() - mRetreatingContent.width();
- } else {
- mRetreatingSideParallax.y =
- mRetreatingSurface.height() - mRetreatingContent.height();
- }
- }
- // All other cases (e.g. 10:90 -> 50:50, 10:90 -> 90:10, 10:90 -> dismiss)
- } else {
- mTempRect.set(mRetreatingSurface);
- Point rootOffset = new Point();
- // 10:90 -> 50:50, 10:90, or dismiss right
- if (advancingSideStartedOffscreen) {
- // We have to handle a complicated case here to keep the parallax smooth.
- // When the divider crosses the 50% mark, the retreating-side app surface
- // will start expanding offscreen. This is expected and unavoidable, but
- // makes the parallax look disjointed. In order to preserve the illusion,
- // we add another offset (rootOffset) to simulate the surface staying
- // onscreen.
- mTempRect.intersect(displayBounds);
- if (mRetreatingSurface.left < displayBounds.left) {
- rootOffset.x = displayBounds.left - mRetreatingSurface.left;
- }
- if (mRetreatingSurface.top < displayBounds.top) {
- rootOffset.y = displayBounds.top - mRetreatingSurface.top;
- }
-
- // On the left side, we again have to simulate the contents sticking to the
- // divider.
- if (!topLeftShrink) {
- if (isLeftRightSplit) {
- mAdvancingSideParallax.x =
- mAdvancingSurface.width() - mAdvancingContent.width();
- } else {
- mAdvancingSideParallax.y =
- mAdvancingSurface.height() - mAdvancingContent.height();
- }
- }
- }
-
- // In all these cases, the shrinking app also receives a center parallax.
- if (isLeftRightSplit) {
- mRetreatingSideParallax.x = rootOffset.x
- + ((mTempRect.width() - mRetreatingContent.width()) / 2);
- } else {
- mRetreatingSideParallax.y = rootOffset.y
- + ((mTempRect.height() - mRetreatingContent.height()) / 2);
- }
- }
- }
- }
-
- /**
- * @return for a specified {@code fraction}, this returns an adjusted value that simulates a
- * slowing down parallax effect
- */
- private float calculateParallaxDismissingFraction(float fraction, int dockSide) {
- float result = SLOWDOWN_INTERPOLATOR.getInterpolation(fraction) / 3.5f;
-
- // Less parallax at the top, just because.
- if (dockSide == WindowManager.DOCKED_TOP) {
- result /= 2f;
- }
- return result;
+ // Calculate parallax and modify mRetreatingSideParallax and mAdvancingSideParallax, for use
+ // in adjustRootSurface().
+ mParallaxSpec.getParallax(mRetreatingSideParallax, mAdvancingSideParallax, position,
+ snapAlgorithm, isLeftRightSplit, displayBounds, mRetreatingSurface,
+ mRetreatingContent, mAdvancingSurface, mAdvancingContent, mDimmingSide,
+ topLeftShrink);
}
/** Applies the calculated parallax and dimming values to task surfaces. */
@@ -250,7 +172,7 @@
SurfaceControl advancingLeash = null;
if (mParallaxType == PARALLAX_DISMISSING) {
- switch (mDismissingSide) {
+ switch (mDimmingSide) {
case DOCKED_TOP:
case DOCKED_LEFT:
retreatingLeash = leash1;
@@ -303,14 +225,17 @@
void adjustDimSurface(SurfaceControl.Transaction t,
SurfaceControl dimLayer1, SurfaceControl dimLayer2) {
SurfaceControl targetDimLayer;
- switch (mDismissingSide) {
+ SurfaceControl oppositeDimLayer;
+ switch (mDimmingSide) {
case DOCKED_TOP:
case DOCKED_LEFT:
targetDimLayer = dimLayer1;
+ oppositeDimLayer = dimLayer2;
break;
case DOCKED_BOTTOM:
case DOCKED_RIGHT:
targetDimLayer = dimLayer2;
+ oppositeDimLayer = dimLayer1;
break;
case DOCKED_INVALID:
default:
@@ -318,7 +243,9 @@
t.setAlpha(dimLayer2, 0).hide(dimLayer2);
return;
}
- t.setAlpha(targetDimLayer, mDismissingDimValue)
- .setVisibility(targetDimLayer, mDismissingDimValue > 0.001f);
+ t.setAlpha(targetDimLayer, mDimValue)
+ .setVisibility(targetDimLayer, mDimValue > 0.001f);
+ t.setAlpha(oppositeDimLayer, 0f)
+ .setVisibility(oppositeDimLayer, false);
}
}
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 bd89f5c..720e8e5 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
@@ -128,6 +128,8 @@
// The touch layer is on a stage root, and is sibling with things like the app activity itself
// and the app veil. We want it to be above all those.
public static final int RESTING_TOUCH_LAYER = Integer.MAX_VALUE;
+ // The dim layer is also on the stage root, and stays under the touch layer.
+ public static final int RESTING_DIM_LAYER = RESTING_TOUCH_LAYER - 1;
// Animation specs for the swap animation
private static final int SWAP_ANIMATION_TOTAL_DURATION = 500;
@@ -459,7 +461,14 @@
return;
}
- mOffscreenTouchZones.forEach(OffscreenTouchZone::release);
+ // TODO (b/349828130): It would be good to reuse a Transaction from StageCoordinator's
+ // mTransactionPool here, but passing it through SplitLayout and specifically
+ // SplitLayout.release() is complicated because that function is purposely called with a
+ // null value sometimes. When that function is refactored, we should also pass the
+ // Transaction in here.
+ SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+ mOffscreenTouchZones.forEach(touchZone -> touchZone.release(t));
+ t.apply();
mOffscreenTouchZones.clear();
}
@@ -973,8 +982,16 @@
final boolean shouldVeil =
insets.left != 0 || insets.top != 0 || insets.right != 0 || insets.bottom != 0;
+ // Find the "left/top"-most position of the app surface -- usually 0, but sometimes negative
+ // if the left/top app is offscreen.
+ int leftTop = 0;
+ if (Flags.enableFlexibleTwoAppSplit()) {
+ leftTop = mIsLeftRightSplit ? getTopLeftBounds().left : getTopLeftBounds().top;
+ }
+
final int dividerPos = mDividerSnapAlgorithm.calculateNonDismissingSnapTarget(
- mIsLeftRightSplit ? getBottomRightBounds().width() : getBottomRightBounds().height()
+ leftTop + (mIsLeftRightSplit
+ ? getBottomRightBounds().width() : getBottomRightBounds().height())
).position;
final Rect endBounds1 = new Rect();
final Rect endBounds2 = new Rect();
@@ -1201,6 +1218,12 @@
// Resets layer of divider bar to make sure it is always on top.
t.setLayer(dividerLeash, RESTING_DIVIDER_LAYER);
}
+ if (dimLayer1 != null) {
+ t.setLayer(dimLayer1, RESTING_DIM_LAYER);
+ }
+ if (dimLayer2 != null) {
+ t.setLayer(dimLayer2, RESTING_DIM_LAYER);
+ }
copyTopLeftRefBounds(mTempRect);
t.setPosition(leash1, mTempRect.left, mTempRect.top)
.setWindowCrop(leash1, mTempRect.width(), mTempRect.height());
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitState.java
index d1d133d..ad0e7fc 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitState.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitState.java
@@ -57,4 +57,9 @@
public List<RectF> getLayout(@SplitScreenState int state) {
return mSplitSpec.getSpec(state);
}
+
+ /** Returns the layout associated with the current split state. */
+ public List<RectF> getCurrentLayout() {
+ return getLayout(mState);
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/events/ReachabilityGestureListener.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/events/ReachabilityGestureListener.kt
new file mode 100644
index 0000000..bdffcf5
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/events/ReachabilityGestureListener.kt
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2025 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.compatui.letterbox.events
+
+import android.graphics.Rect
+import android.view.GestureDetector
+import android.view.MotionEvent
+import android.window.WindowContainerToken
+import com.android.wm.shell.common.WindowContainerTransactionSupplier
+import com.android.wm.shell.transition.Transitions
+import com.android.wm.shell.transition.Transitions.TRANSIT_MOVE_LETTERBOX_REACHABILITY
+
+/**
+ * [GestureDetector.SimpleOnGestureListener] implementation which receives events from the
+ * Letterbox Input surface, understands the type of event and filter them based on the current
+ * letterbox position.
+ */
+class ReachabilityGestureListener(
+ private val taskId: Int,
+ private val token: WindowContainerToken?,
+ private val transitions: Transitions,
+ private val animationHandler: Transitions.TransitionHandler,
+ private val wctSupplier: WindowContainerTransactionSupplier
+) : GestureDetector.SimpleOnGestureListener() {
+
+ // The current letterbox bounds. Double tap events are ignored when happening in these bounds.
+ private val activityBounds = Rect()
+
+ override fun onDoubleTap(e: MotionEvent): Boolean {
+ val x = e.rawX.toInt()
+ val y = e.rawY.toInt()
+ if (!activityBounds.contains(x, y)) {
+ val wct = wctSupplier.get().apply {
+ setReachabilityOffset(token!!, taskId, x, y)
+ }
+ transitions.startTransition(
+ TRANSIT_MOVE_LETTERBOX_REACHABILITY,
+ wct,
+ animationHandler
+ )
+ return true
+ }
+ return false
+ }
+
+ /**
+ * Updates the bounds for the letterboxed activity.
+ */
+ fun updateActivityBounds(newActivityBounds: Rect) {
+ activityBounds.set(newActivityBounds)
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/events/ReachabilityGestureListenerFactory.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/events/ReachabilityGestureListenerFactory.kt
new file mode 100644
index 0000000..5e9fe09
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/events/ReachabilityGestureListenerFactory.kt
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2025 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.compatui.letterbox.events
+
+import android.window.WindowContainerToken
+import com.android.wm.shell.common.WindowContainerTransactionSupplier
+import com.android.wm.shell.dagger.WMSingleton
+import com.android.wm.shell.transition.Transitions
+import javax.inject.Inject
+
+/**
+ * A Factory for [ReachabilityGestureListener].
+ */
+@WMSingleton
+class ReachabilityGestureListenerFactory @Inject constructor(
+ private val transitions: Transitions,
+ private val animationHandler: Transitions.TransitionHandler,
+ private val wctSupplier: WindowContainerTransactionSupplier
+) {
+ /**
+ * @return a [ReachabilityGestureListener] implementation to listen to double tap events and
+ * creating the related [WindowContainerTransaction] to handle the transition.
+ */
+ fun createReachabilityGestureListener(
+ taskId: Int,
+ token: WindowContainerToken?
+ ): ReachabilityGestureListener =
+ ReachabilityGestureListener(taskId, token, transitions, animationHandler, wctSupplier)
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java
index 7d80ee5..f8b18f2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java
@@ -53,6 +53,7 @@
import com.android.wm.shell.pip2.phone.PipTransitionState;
import com.android.wm.shell.pip2.phone.PipUiStateChangeController;
import com.android.wm.shell.shared.annotations.ShellMainThread;
+import com.android.wm.shell.splitscreen.SplitScreenController;
import com.android.wm.shell.sysui.ShellCommandHandler;
import com.android.wm.shell.sysui.ShellController;
import com.android.wm.shell.sysui.ShellInit;
@@ -85,11 +86,13 @@
@NonNull PipDisplayLayoutState pipDisplayLayoutState,
@NonNull PipUiStateChangeController pipUiStateChangeController,
DisplayController displayController,
+ Optional<SplitScreenController> splitScreenControllerOptional,
PipDesktopState pipDesktopState) {
return new PipTransition(context, shellInit, shellTaskOrganizer, transitions,
pipBoundsState, null, pipBoundsAlgorithm, pipTaskListener,
pipScheduler, pipStackListenerController, pipDisplayLayoutState,
- pipUiStateChangeController, displayController, pipDesktopState);
+ pipUiStateChangeController, displayController, splitScreenControllerOptional,
+ pipDesktopState);
}
@WMSingleton
@@ -140,9 +143,10 @@
PipBoundsState pipBoundsState,
@ShellMainThread ShellExecutor mainExecutor,
PipTransitionState pipTransitionState,
+ Optional<SplitScreenController> splitScreenControllerOptional,
PipDesktopState pipDesktopState) {
return new PipScheduler(context, pipBoundsState, mainExecutor, pipTransitionState,
- pipDesktopState);
+ splitScreenControllerOptional, pipDesktopState);
}
@WMSingleton
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopDisplayEventHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopDisplayEventHandler.kt
index 6f455df..c38558d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopDisplayEventHandler.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopDisplayEventHandler.kt
@@ -26,6 +26,7 @@
import android.view.Display.DEFAULT_DISPLAY
import android.view.IWindowManager
import android.view.WindowManager.TRANSIT_CHANGE
+import android.window.DesktopExperienceFlags
import android.window.WindowContainerTransaction
import com.android.internal.protolog.ProtoLog
import com.android.window.flags.Flags
@@ -62,7 +63,7 @@
private fun onInit() {
displayController.addDisplayWindowListener(this)
- if (Flags.enableMultipleDesktopsBackend()) {
+ if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue()) {
desktopTasksController.onDeskRemovedListener = this
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeShellCommandHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeShellCommandHandler.kt
index 03bc42f..0cc8a6a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeShellCommandHandler.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeShellCommandHandler.kt
@@ -16,7 +16,7 @@
package com.android.wm.shell.desktopmode
-import com.android.window.flags.Flags
+import android.window.DesktopExperienceFlags
import com.android.wm.shell.shared.desktopmode.DesktopModeTransitionSource.UNKNOWN
import com.android.wm.shell.sysui.ShellCommandHandler
import java.io.PrintWriter
@@ -56,7 +56,7 @@
pw.println("Error: task id should be an integer")
return false
}
- if (!Flags.enableMultipleDesktopsBackend()) {
+ if (!DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
return controller.moveTaskToDefaultDeskAndActivate(taskId, transitionSource = UNKNOWN)
}
if (args.size < 3) {
@@ -95,7 +95,7 @@
}
private fun runCreateDesk(args: Array<String>, pw: PrintWriter): Boolean {
- if (!Flags.enableMultipleDesktopsBackend()) {
+ if (!DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
pw.println("Not supported.")
return false
}
@@ -116,7 +116,7 @@
}
private fun runActivateDesk(args: Array<String>, pw: PrintWriter): Boolean {
- if (!Flags.enableMultipleDesktopsBackend()) {
+ if (!DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
pw.println("Not supported.")
return false
}
@@ -137,7 +137,7 @@
}
private fun runRemoveDesk(args: Array<String>, pw: PrintWriter): Boolean {
- if (!Flags.enableMultipleDesktopsBackend()) {
+ if (!DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
pw.println("Not supported.")
return false
}
@@ -158,7 +158,7 @@
}
private fun runRemoveAllDesks(args: Array<String>, pw: PrintWriter): Boolean {
- if (!Flags.enableMultipleDesktopsBackend()) {
+ if (!DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
pw.println("Not supported.")
return false
}
@@ -167,7 +167,7 @@
}
private fun runMoveTaskToFront(args: Array<String>, pw: PrintWriter): Boolean {
- if (!Flags.enableMultipleDesktopsBackend()) {
+ if (!DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
pw.println("Not supported.")
return false
}
@@ -188,7 +188,7 @@
}
private fun runMoveTaskOutOfDesk(args: Array<String>, pw: PrintWriter): Boolean {
- if (!Flags.enableMultipleDesktopsBackend()) {
+ if (!DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
pw.println("Not supported.")
return false
}
@@ -204,12 +204,12 @@
pw.println("Error: task id should be an integer")
return false
}
- pw.println("Not implemented.")
- return false
+ controller.moveToFullscreen(taskId, transitionSource = UNKNOWN)
+ return true
}
private fun runCanCreateDesk(args: Array<String>, pw: PrintWriter): Boolean {
- if (!Flags.enableMultipleDesktopsBackend()) {
+ if (!DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
pw.println("Not supported.")
return false
}
@@ -225,7 +225,7 @@
}
private fun runGetActiveDeskId(args: Array<String>, pw: PrintWriter): Boolean {
- if (!Flags.enableMultipleDesktopsBackend()) {
+ if (!DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
pw.println("Not supported.")
return false
}
@@ -246,7 +246,7 @@
}
override fun printShellCommandHelp(pw: PrintWriter, prefix: String) {
- if (!Flags.enableMultipleDesktopsBackend()) {
+ if (!DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
pw.println("$prefix moveTaskToDesk <taskId> ")
pw.println("$prefix Move a task with given id to desktop mode.")
pw.println("$prefix moveToNextDisplay <taskId> ")
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt
index 9b850de6..c5ee313 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt
@@ -33,6 +33,7 @@
import com.android.wm.shell.R
import com.android.wm.shell.common.DisplayController
import com.android.wm.shell.common.DisplayLayout
+import kotlin.math.ceil
val DESKTOP_MODE_INITIAL_BOUNDS_SCALE: Float =
SystemProperties.getInt("persist.wm.debug.desktop_mode_initial_bounds_scale", 75) / 100f
@@ -190,22 +191,22 @@
val finalWidth: Int
// Get orientation either through top activity or task's orientation
if (taskInfo.hasPortraitTopActivity()) {
- val tempWidth = (targetHeight / aspectRatio).toInt()
+ val tempWidth = ceil(targetHeight / aspectRatio).toInt()
if (tempWidth <= targetWidth) {
finalHeight = targetHeight
finalWidth = tempWidth
} else {
finalWidth = targetWidth
- finalHeight = (finalWidth * aspectRatio).toInt()
+ finalHeight = ceil(finalWidth * aspectRatio).toInt()
}
} else {
- val tempWidth = (targetHeight * aspectRatio).toInt()
+ val tempWidth = ceil(targetHeight * aspectRatio).toInt()
if (tempWidth <= targetWidth) {
finalHeight = targetHeight
finalWidth = tempWidth
} else {
finalWidth = targetWidth
- finalHeight = (finalWidth / aspectRatio).toInt()
+ finalHeight = ceil(finalWidth / aspectRatio).toInt()
}
}
return Size(finalWidth, finalHeight + captionInsets)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt
index 4777e7f..eba1be5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt
@@ -22,6 +22,7 @@
import android.util.ArraySet
import android.util.SparseArray
import android.view.Display.INVALID_DISPLAY
+import android.window.DesktopExperienceFlags
import android.window.DesktopModeFlags
import androidx.core.util.forEach
import androidx.core.util.valueIterator
@@ -137,7 +138,7 @@
private var desktopGestureExclusionExecutor: Executor? = null
private val desktopData: DesktopData =
- if (Flags.enableMultipleDesktopsBackend()) {
+ if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
MultiDesktopData()
} else {
SingleDesktopData()
@@ -226,10 +227,19 @@
desktopData.setActiveDesk(displayId = displayId, deskId = deskId)
}
+ /** Sets the given desk as inactive if it was active. */
+ fun setDeskInactive(deskId: Int) {
+ desktopData.setDeskInactive(deskId)
+ }
+
/** Returns the id of the active desk in the given display, if any. */
@VisibleForTesting
fun getActiveDeskId(displayId: Int): Int? = desktopData.getActiveDesk(displayId)?.deskId
+ /** Returns the id of the desk to which this task belongs. */
+ fun getDeskIdForTask(taskId: Int): Int? =
+ desktopData.desksSequence().find { desk -> desk.activeTasks.contains(taskId) }?.deskId
+
/**
* Adds task with [taskId] to the list of freeform tasks on [displayId]'s active desk.
*
@@ -270,20 +280,40 @@
@VisibleForTesting
fun removeActiveTask(taskId: Int, excludedDeskId: Int? = null) {
val affectedDisplays = mutableSetOf<Int>()
- desktopData.forAllDesks { displayId, desk ->
- if (desk.deskId != excludedDeskId && desk.activeTasks.remove(taskId)) {
- logD(
- "Removed active task=%d displayId=%d deskId=%d",
- taskId,
- displayId,
- desk.deskId,
- )
- affectedDisplays.add(displayId)
+ desktopData
+ .desksSequence()
+ .filter { desk -> desk.displayId != excludedDeskId }
+ .forEach { desk ->
+ val removed = removeActiveTaskFromDesk(desk.deskId, taskId, notifyListeners = false)
+ if (removed) {
+ logD(
+ "Removed active task=%d displayId=%d deskId=%d",
+ taskId,
+ desk.displayId,
+ desk.deskId,
+ )
+ affectedDisplays.add(desk.displayId)
+ }
}
- }
affectedDisplays.forEach { displayId -> updateActiveTasksListeners(displayId) }
}
+ private fun removeActiveTaskFromDesk(
+ deskId: Int,
+ taskId: Int,
+ notifyListeners: Boolean = true,
+ ): Boolean {
+ val desk = desktopData.getDesk(deskId) ?: return false
+ if (desk.activeTasks.remove(taskId)) {
+ logD("Removed active task=%d from deskId=%d", taskId, desk.deskId)
+ if (notifyListeners) {
+ updateActiveTasksListeners(desk.displayId)
+ }
+ return true
+ }
+ return false
+ }
+
/**
* Adds given task to the closing task list for [displayId]'s active desk.
*
@@ -322,10 +352,22 @@
fun isActiveTask(taskId: Int) = desksSequence().any { taskId in it.activeTasks }
+ @VisibleForTesting
+ fun isActiveTaskInDesk(taskId: Int, deskId: Int): Boolean {
+ val desk = desktopData.getDesk(deskId) ?: return false
+ return taskId in desk.activeTasks
+ }
+
fun isClosingTask(taskId: Int) = desksSequence().any { taskId in it.closingTasks }
fun isVisibleTask(taskId: Int) = desksSequence().any { taskId in it.visibleTasks }
+ @VisibleForTesting
+ fun isVisibleTaskInDesk(taskId: Int, deskId: Int): Boolean {
+ val desk = desktopData.getDesk(deskId) ?: return false
+ return taskId in desk.visibleTasks
+ }
+
fun isMinimizedTask(taskId: Int) = desksSequence().any { taskId in it.minimizedTasks }
/**
@@ -415,12 +457,19 @@
/** Removes task from visible tasks of all desks except [excludedDeskId]. */
private fun removeVisibleTask(taskId: Int, excludedDeskId: Int? = null) {
desktopData.forAllDesks { displayId, desk ->
- if (desk.deskId != excludedDeskId && desk.visibleTasks.remove(taskId)) {
- notifyVisibleTaskListeners(displayId, desk.visibleTasks.size)
+ if (desk.deskId != excludedDeskId) {
+ removeVisibleTaskFromDesk(deskId = desk.deskId, taskId = taskId)
}
}
}
+ private fun removeVisibleTaskFromDesk(deskId: Int, taskId: Int) {
+ val desk = desktopData.getDesk(deskId) ?: return
+ if (desk.visibleTasks.remove(taskId)) {
+ notifyVisibleTaskListeners(desk.displayId, desk.visibleTasks.size)
+ }
+ }
+
/**
* Updates visibility of a freeform task with [taskId] on [displayId] and notifies listeners.
*
@@ -576,15 +625,26 @@
/**
* Set whether the given task is the full-immersive task in this display's active desk.
*
- * TODO: b/389960283 - add explicit [deskId] argument.
+ * TODO: b/389960283 - consider forcing callers to use [setTaskInFullImmersiveStateInDesk] with
+ * an explicit desk id instead of using this function and defaulting to the active one.
*/
fun setTaskInFullImmersiveState(displayId: Int, taskId: Int, immersive: Boolean) {
- val desktopData = desktopData.getActiveDesk(displayId) ?: return
+ val activeDesk = desktopData.getActiveDesk(displayId) ?: return
+ setTaskInFullImmersiveStateInDesk(
+ deskId = activeDesk.deskId,
+ taskId = taskId,
+ immersive = immersive,
+ )
+ }
+
+ /** Sets whether the given task is the full-immersive task in the given desk. */
+ fun setTaskInFullImmersiveStateInDesk(deskId: Int, taskId: Int, immersive: Boolean) {
+ val desk = desktopData.getDesk(deskId) ?: return
if (immersive) {
- desktopData.fullImmersiveTaskId = taskId
+ desk.fullImmersiveTaskId = taskId
} else {
- if (desktopData.fullImmersiveTaskId == taskId) {
- desktopData.fullImmersiveTaskId = null
+ if (desk.fullImmersiveTaskId == taskId) {
+ desk.fullImmersiveTaskId = null
}
}
}
@@ -674,7 +734,8 @@
/**
* Minimizes the task for [taskId] and [displayId]'s active display.
*
- * TODO: b/389960283 - add explicit [deskId] argument.
+ * TODO: b/389960283 - consider forcing callers to use [minimizeTaskInDesk] with an explicit
+ * desk id instead of using this function and defaulting to the active one.
*/
fun minimizeTask(displayId: Int, taskId: Int) {
if (displayId == INVALID_DISPLAY) {
@@ -683,32 +744,41 @@
getDisplayIdForTask(taskId)?.let { minimizeTask(it, taskId) }
?: logW("Minimize task: No display id found for task: taskId=%d", taskId)
return
- } else {
- logD("Minimize Task: display=%d, task=%d", displayId, taskId)
- desktopData.getActiveDesk(displayId)?.minimizedTasks?.add(taskId)
- ?: logD("Minimize task: No active desk found for task: taskId=%d", taskId)
}
- updateTask(displayId, taskId, isVisible = false)
+ val deskId = desktopData.getActiveDesk(displayId)?.deskId
+ if (deskId == null) {
+ logD("Minimize task: No active desk found for task: taskId=%d", taskId)
+ return
+ }
+ minimizeTaskInDesk(displayId, deskId, taskId)
+ }
+
+ /** Minimizes the task in its desk. */
+ @VisibleForTesting
+ fun minimizeTaskInDesk(displayId: Int, deskId: Int, taskId: Int) {
+ logD("Minimize Task: displayId=%d deskId=%d, task=%d", displayId, deskId, taskId)
+ desktopData.getDesk(deskId)?.minimizedTasks?.add(taskId)
+ ?: logD("Minimize task: No active desk found for task: taskId=%d", taskId)
+ updateTaskInDesk(displayId, deskId, taskId, isVisible = false)
if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue()) {
- updatePersistentRepository(displayId)
+ updatePersistentRepositoryForDesk(deskId)
}
}
/**
* Unminimizes the task for [taskId] and [displayId].
*
- * TODO: b/389960283 - consider adding an explicit [deskId] argument.
+ * TODO: b/389960283 - consider using [unminimizeTaskFromDesk] instead.
*/
fun unminimizeTask(displayId: Int, taskId: Int) {
logD("Unminimize Task: display=%d, task=%d", displayId, taskId)
- var removed = false
- desktopData.forAllDesks(displayId) { desk ->
- if (desk.minimizedTasks.remove(taskId)) {
- removed = true
- }
- }
- if (!removed) {
- logW("Unminimize Task: display=%d, task=%d, no task data", displayId, taskId)
+ desktopData.forAllDesks(displayId) { desk -> unminimizeTaskFromDesk(desk.deskId, taskId) }
+ }
+
+ private fun unminimizeTaskFromDesk(deskId: Int, taskId: Int) {
+ logD("Unminimize Task: deskId=%d, taskId=%d", deskId, taskId)
+ if (desktopData.getDesk(deskId)?.minimizedTasks?.remove(taskId) != true) {
+ logW("Unminimize Task: deskId=%d, taskId=%d, no task data", deskId, taskId)
}
}
@@ -729,7 +799,7 @@
* Removes [taskId] from the respective display. If [INVALID_DISPLAY], the original display id
* will be looked up from the task id.
*
- * TODO: b/389960283 - consider adding an explicit [deskId] argument.
+ * TODO: b/389960283 - consider using [removeTaskFromDesk] instead.
*/
fun removeTask(displayId: Int, taskId: Int) {
logD("Removes freeform task: taskId=%d", taskId)
@@ -745,24 +815,33 @@
private fun removeTaskFromDisplay(displayId: Int, taskId: Int) {
logD("Removes freeform task: taskId=%d, displayId=%d", taskId, displayId)
desktopData.forAllDesks(displayId) { desk ->
- if (desk.freeformTasksInZOrder.remove(taskId)) {
- logD(
- "Remaining freeform tasks in desk: %d, tasks: %s",
- desk.deskId,
- desk.freeformTasksInZOrder.toDumpString(),
- )
- }
+ removeTaskFromDesk(deskId = desk.deskId, taskId = taskId)
}
+ }
+
+ /** Removes the given task from the given desk. */
+ fun removeTaskFromDesk(deskId: Int, taskId: Int) {
+ logD("removeTaskFromDesk: deskId=%d, taskId=%d", deskId, taskId)
+ // TODO: b/362720497 - consider not clearing bounds on any removal, such as when moving
+ // it between desks. It might be better to allow restoring to the previous bounds as long
+ // as they're valid (probably valid if in the same display).
boundsBeforeMaximizeByTaskId.remove(taskId)
boundsBeforeFullImmersiveByTaskId.remove(taskId)
- // Remove task from unminimized task if it is minimized.
- unminimizeTask(displayId, taskId)
+ val desk = desktopData.getDesk(deskId) ?: return
+ if (desk.freeformTasksInZOrder.remove(taskId)) {
+ logD(
+ "Remaining freeform tasks in desk: %d, tasks: %s",
+ desk.deskId,
+ desk.freeformTasksInZOrder.toDumpString(),
+ )
+ }
+ unminimizeTaskFromDesk(deskId, taskId)
// Mark task as not in immersive if it was immersive.
- setTaskInFullImmersiveState(displayId = displayId, taskId = taskId, immersive = false)
- removeActiveTask(taskId)
- removeVisibleTask(taskId)
- if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue()) {
- updatePersistentRepository(displayId)
+ setTaskInFullImmersiveStateInDesk(deskId = deskId, taskId = taskId, immersive = false)
+ removeActiveTaskFromDesk(deskId = deskId, taskId = taskId)
+ removeVisibleTaskFromDesk(deskId = deskId, taskId = taskId)
+ if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue) {
+ updatePersistentRepositoryForDesk(desk.deskId)
}
}
@@ -832,24 +911,29 @@
private fun updatePersistentRepository(displayId: Int) {
val desks = desktopData.desksSequence(displayId).map { desk -> desk.deepCopy() }.toList()
mainCoroutineScope.launch {
- desks.forEach { desk ->
- try {
- persistentRepository.addOrUpdateDesktop(
- // Use display id as desk id for now since only once desk per display
- // is supported.
- userId = userId,
- desktopId = desk.deskId,
- visibleTasks = desk.visibleTasks,
- minimizedTasks = desk.minimizedTasks,
- freeformTasksInZOrder = desk.freeformTasksInZOrder,
- )
- } catch (exception: Exception) {
- logE(
- "An exception occurred while updating the persistent repository \n%s",
- exception.stackTrace,
- )
- }
- }
+ desks.forEach { desk -> updatePersistentRepositoryForDesk(desk) }
+ }
+ }
+
+ private fun updatePersistentRepositoryForDesk(deskId: Int) {
+ val desk = desktopData.getDesk(deskId)?.deepCopy() ?: return
+ mainCoroutineScope.launch { updatePersistentRepositoryForDesk(desk) }
+ }
+
+ private suspend fun updatePersistentRepositoryForDesk(desk: Desk) {
+ try {
+ persistentRepository.addOrUpdateDesktop(
+ userId = userId,
+ desktopId = desk.deskId,
+ visibleTasks = desk.visibleTasks,
+ minimizedTasks = desk.minimizedTasks,
+ freeformTasksInZOrder = desk.freeformTasksInZOrder,
+ )
+ } catch (exception: Exception) {
+ logE(
+ "An exception occurred while updating the persistent repository \n%s",
+ exception.stackTrace,
+ )
}
}
@@ -866,21 +950,27 @@
desktopData
.desksSequence()
.groupBy { it.displayId }
- .forEach { (displayId, desks) ->
+ .map { (displayId, desks) ->
+ Triple(displayId, desktopData.getActiveDesk(displayId)?.deskId, desks)
+ }
+ .forEach { (displayId, activeDeskId, desks) ->
pw.println("${prefix}Display #$displayId:")
+ pw.println("${innerPrefix}activeDesk=$activeDeskId")
+ pw.println("${innerPrefix}desks:")
+ val desksPrefix = "$innerPrefix "
desks.forEach { desk ->
- pw.println("${innerPrefix}Desk #${desk.deskId}:")
- pw.print("$innerPrefix activeTasks=")
+ pw.println("${desksPrefix}Desk #${desk.deskId}:")
+ pw.print("$desksPrefix activeTasks=")
pw.println(desk.activeTasks.toDumpString())
- pw.print("$innerPrefix visibleTasks=")
+ pw.print("$desksPrefix visibleTasks=")
pw.println(desk.visibleTasks.toDumpString())
- pw.print("$innerPrefix freeformTasksInZOrder=")
+ pw.print("$desksPrefix freeformTasksInZOrder=")
pw.println(desk.freeformTasksInZOrder.toDumpString())
- pw.print("$innerPrefix minimizedTasks=")
+ pw.print("$desksPrefix minimizedTasks=")
pw.println(desk.minimizedTasks.toDumpString())
- pw.print("$innerPrefix fullImmersiveTaskId=")
+ pw.print("$desksPrefix fullImmersiveTaskId=")
pw.println(desk.fullImmersiveTaskId)
- pw.print("$innerPrefix topTransparentFullscreenTaskId=")
+ pw.print("$desksPrefix topTransparentFullscreenTaskId=")
pw.println(desk.topTransparentFullscreenTaskId)
}
}
@@ -910,6 +1000,9 @@
/** Sets the given desk as the active desk in the given display. */
fun setActiveDesk(displayId: Int, deskId: Int)
+ /** Sets the desk as inactive if it was active. */
+ fun setDeskInactive(deskId: Int)
+
/**
* Returns the default desk in the given display. Useful when the system wants to activate a
* desk but doesn't care about which one it activates (e.g. when putting a window into a
@@ -990,6 +1083,11 @@
// existence of visible desktop windows, among other factors.
}
+ override fun setDeskInactive(deskId: Int) {
+ // No-op, in single-desk setups, which desktop is "active" is determined by the
+ // existence of visible desktop windows, among other factors.
+ }
+
override fun getDefaultDesk(displayId: Int): Desk = getDesk(deskId = displayId)
override fun getAllActiveDesks(): Set<Desk> =
@@ -1058,6 +1156,14 @@
display.activeDeskId = desk.deskId
}
+ override fun setDeskInactive(deskId: Int) {
+ desktopDisplays.forEach { id, display ->
+ if (display.activeDeskId == deskId) {
+ display.activeDeskId = null
+ }
+ }
+ }
+
override fun getDefaultDesk(displayId: Int): Desk? {
val display = desktopDisplays[displayId] ?: return null
return display.orderedDesks.find { it.deskId == display.activeDeskId }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTaskChangeListener.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTaskChangeListener.kt
index 4d87b21..e831d5e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTaskChangeListener.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTaskChangeListener.kt
@@ -42,6 +42,12 @@
desktopUserRepositories.getProfile(taskInfo.userId)
if (!desktopRepository.isActiveTask(taskInfo.taskId)) return
+ // TODO: b/394281403 - with multiple desks, it's possible to have a non-freeform task
+ // inside a desk, so this should be decoupled from windowing mode.
+ // Also, changes in/out of desks are handled by the [DesksTransitionObserver], which has
+ // more specific information about the desk involved in the transition, which might be
+ // more accurate than assuming it's always the default/active desk in the display, as this
+ // method does.
// Case 1: Freeform task is changed in Desktop Mode.
if (isFreeformTask(taskInfo)) {
if (taskInfo.isVisible) {
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 3f4edeb..93058db 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
@@ -54,6 +54,7 @@
import android.view.WindowManager.TRANSIT_PIP
import android.view.WindowManager.TRANSIT_TO_FRONT
import android.widget.Toast
+import android.window.DesktopExperienceFlags
import android.window.DesktopModeFlags
import android.window.DesktopModeFlags.DISABLE_NON_RESIZABLE_APP_SNAP_RESIZE
import android.window.DesktopModeFlags.ENABLE_DESKTOP_WALLPAPER_ACTIVITY_FOR_SYSTEM_USER
@@ -72,6 +73,7 @@
import com.android.internal.jank.Cuj.CUJ_DESKTOP_MODE_SNAP_RESIZE
import com.android.internal.jank.InteractionJankMonitor
import com.android.internal.protolog.ProtoLog
+import com.android.internal.util.LatencyTracker
import com.android.window.flags.Flags
import com.android.wm.shell.Flags.enableFlexibleSplit
import com.android.wm.shell.R
@@ -152,6 +154,16 @@
import java.util.function.Consumer
import kotlin.jvm.optionals.getOrNull
+/**
+ * A callback to be invoked when a transition is started via |Transitions.startTransition| with the
+ * transition binder token that it produces.
+ *
+ * Useful when multiple components are appending WCT operations to a single transition that is
+ * started outside of their control, and each of them wants to track the transition lifecycle
+ * independently by cross-referencing the transition token with future ready-transitions.
+ */
+typealias RunOnTransitStart = (IBinder) -> Unit
+
/** Handles moving tasks in and out of desktop */
class DesktopTasksController(
private val context: Context,
@@ -429,7 +441,7 @@
/** Creates a new desk in the given display. */
fun createDesk(displayId: Int) {
- if (Flags.enableMultipleDesktopsBackend()) {
+ if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
desksOrganizer.createDesk(displayId) { deskId ->
taskRepository.addDesk(displayId = displayId, deskId = deskId)
}
@@ -456,10 +468,7 @@
}
// TODO(342378842): Instead of using default display, support multiple displays
val displayId = runningTask?.displayId ?: DEFAULT_DISPLAY
- val deskId =
- checkNotNull(taskRepository.getDefaultDeskId(displayId)) {
- "Expected a default desk to exist"
- }
+ val deskId = getDefaultDeskId(displayId)
return moveTaskToDesk(
taskId = taskId,
deskId = deskId,
@@ -480,7 +489,7 @@
): Boolean {
val runningTask = shellTaskOrganizer.getRunningTaskInfo(taskId)
if (runningTask != null) {
- moveRunningTaskToDesk(
+ return moveRunningTaskToDesk(
task = runningTask,
deskId = deskId,
wct = wct,
@@ -562,10 +571,10 @@
transitionSource: DesktopModeTransitionSource,
remoteTransition: RemoteTransition? = null,
callback: IMoveToDesktopCallback? = null,
- ) {
+ ): Boolean {
if (desktopModeCompatPolicy.isTopActivityExemptFromDesktopWindowing(task)) {
logW("Cannot enter desktop for taskId %d, ineligible top activity found", task.taskId)
- return
+ return false
}
val displayId = taskRepository.getDisplayForDesk(deskId)
logV(
@@ -608,7 +617,7 @@
addPendingMinimizeTransition(transition, it, MinimizeReason.TASK_LIMIT)
}
exitResult.asExit()?.runOnTransitionStart?.invoke(transition)
- if (Flags.enableMultipleDesktopsBackend()) {
+ if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
desksTransitionObserver.addPendingTransition(
DeskTransition.ActiveDeskWithTask(
token = transition,
@@ -620,6 +629,7 @@
} else {
taskRepository.setActiveDesk(displayId = displayId, deskId = deskId)
}
+ return true
}
/**
@@ -636,7 +646,7 @@
task: RunningTaskInfo,
): Int? {
val taskIdToMinimize =
- if (Flags.enableMultipleDesktopsBackend()) {
+ if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
// Activate the desk first.
prepareForDeskActivation(displayId, wct)
desksOrganizer.activateDesk(wct, deskId)
@@ -656,7 +666,7 @@
// Bring other apps to front first.
bringDesktopAppsToFrontBeforeShowingNewTask(displayId, wct, task.taskId)
}
- if (Flags.enableMultipleDesktopsBackend()) {
+ if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
prepareMoveTaskToDesk(wct, task, deskId)
} else {
addMoveToDesktopChanges(wct, task)
@@ -703,10 +713,7 @@
* [startDragToDesktop].
*/
private fun finalizeDragToDesktop(taskInfo: RunningTaskInfo) {
- val deskId =
- checkNotNull(taskRepository.getDefaultDeskId(taskInfo.displayId)) {
- "Expected a default desk to exist"
- }
+ val deskId = getDefaultDeskId(taskInfo.displayId)
ProtoLog.v(
WM_SHELL_DESKTOP_MODE,
"DesktopTasksController: finalizeDragToDesktop taskId=%d deskId=%d",
@@ -715,7 +722,7 @@
)
val wct = WindowContainerTransaction()
exitSplitIfApplicable(wct, taskInfo)
- if (!Flags.enableMultipleDesktopsBackend()) {
+ if (!DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
// |moveHomeTask| is also called in |bringDesktopAppsToFrontBeforeShowingNewTask|, so
// this shouldn't be necessary at all.
if (Flags.enablePerDisplayDesktopWallpaperActivity()) {
@@ -742,12 +749,12 @@
desktopModeEnterExitTransitionListener?.onEnterDesktopModeTransitionStarted(
DRAG_TO_DESKTOP_FINISH_ANIM_DURATION_MS.toInt()
)
- transition?.let {
- taskIdToMinimize?.let { taskId ->
- addPendingMinimizeTransition(it, taskId, MinimizeReason.TASK_LIMIT)
+ if (transition != null) {
+ taskIdToMinimize?.let {
+ addPendingMinimizeTransition(transition, it, MinimizeReason.TASK_LIMIT)
}
exitResult.asExit()?.runOnTransitionStart?.invoke(transition)
- if (Flags.enableMultipleDesktopsBackend()) {
+ if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
desksTransitionObserver.addPendingTransition(
DeskTransition.ActiveDeskWithTask(
token = transition,
@@ -759,6 +766,9 @@
} else {
taskRepository.setActiveDesk(displayId = taskInfo.displayId, deskId = deskId)
}
+ } else {
+ LatencyTracker.getInstance(context)
+ .onActionCancel(LatencyTracker.ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG)
}
}
@@ -788,22 +798,44 @@
wct: WindowContainerTransaction,
displayId: Int,
taskInfo: RunningTaskInfo,
- ): ((IBinder) -> Unit)? {
+ ): ((IBinder) -> Unit) {
val taskId = taskInfo.taskId
+ val deskId = taskRepository.getDeskIdForTask(taskInfo.taskId)
snapEventHandler.removeTaskIfTiled(displayId, taskId)
- performDesktopExitCleanupIfNeeded(taskId, displayId, wct, forceToFullscreen = false)
+ val shouldExitDesktop =
+ willExitDesktop(
+ triggerTaskId = taskInfo.taskId,
+ displayId = displayId,
+ forceToFullscreen = false,
+ )
+ taskRepository.setPipShouldKeepDesktopActive(displayId, keepActive = true)
+ val desktopExitRunnable =
+ performDesktopExitCleanUp(
+ wct = wct,
+ deskId = deskId,
+ displayId = displayId,
+ willExitDesktop = shouldExitDesktop,
+ shouldEndUpAtHome = true,
+ )
+
taskRepository.addClosingTask(displayId, taskId)
taskbarDesktopTaskListener?.onTaskbarCornerRoundingUpdate(
doesAnyTaskRequireTaskbarRounding(displayId, taskId)
)
- return desktopImmersiveController
- .exitImmersiveIfApplicable(
- wct = wct,
- taskInfo = taskInfo,
- reason = DesktopImmersiveController.ExitReason.CLOSED,
- )
- .asExit()
- ?.runOnTransitionStart
+
+ val immersiveRunnable =
+ desktopImmersiveController
+ .exitImmersiveIfApplicable(
+ wct = wct,
+ taskInfo = taskInfo,
+ reason = DesktopImmersiveController.ExitReason.CLOSED,
+ )
+ .asExit()
+ ?.runOnTransitionStart
+ return { transitionToken ->
+ immersiveRunnable?.invoke(transitionToken)
+ desktopExitRunnable?.invoke(transitionToken)
+ }
}
fun minimizeTask(taskInfo: RunningTaskInfo, minimizeReason: MinimizeReason) {
@@ -837,10 +869,20 @@
private fun minimizeTaskInner(taskInfo: RunningTaskInfo, minimizeReason: MinimizeReason) {
val taskId = taskInfo.taskId
+ val deskId = taskRepository.getDeskIdForTask(taskInfo.taskId)
val displayId = taskInfo.displayId
val wct = WindowContainerTransaction()
+
snapEventHandler.removeTaskIfTiled(displayId, taskId)
- performDesktopExitCleanupIfNeeded(taskId, displayId, wct, forceToFullscreen = false)
+ taskRepository.setPipShouldKeepDesktopActive(displayId, keepActive = true)
+ val willExitDesktop = willExitDesktop(taskId, displayId, forceToFullscreen = false)
+ val desktopExitRunnable =
+ performDesktopExitCleanUp(
+ wct = wct,
+ deskId = deskId,
+ displayId = displayId,
+ willExitDesktop = willExitDesktop,
+ )
// Notify immersive handler as it might need to exit immersive state.
val exitResult =
desktopImmersiveController.exitImmersiveIfApplicable(
@@ -862,6 +904,7 @@
)
}
exitResult.asExit()?.runOnTransitionStart?.invoke(transition)
+ desktopExitRunnable?.invoke(transition)
}
/** Move a task with given `taskId` to fullscreen */
@@ -909,7 +952,8 @@
) {
logV("moveToFullscreenWithAnimation taskId=%d", task.taskId)
val wct = WindowContainerTransaction()
- addMoveToFullscreenChanges(wct, task)
+ val willExitDesktop = willExitDesktop(task.taskId, task.displayId, forceToFullscreen = true)
+ val deactivationRunnable = addMoveToFullscreenChanges(wct, task, willExitDesktop)
// We are moving a freeform task to fullscreen, put the home task under the fullscreen task.
if (!forceEnterDesktop(task.displayId)) {
@@ -917,12 +961,14 @@
wct.reorder(task.token, /* onTop= */ true)
}
- exitDesktopTaskTransitionHandler.startTransition(
- transitionSource,
- wct,
- position,
- mOnAnimationFinishedCallback,
- )
+ val transition =
+ exitDesktopTaskTransitionHandler.startTransition(
+ transitionSource,
+ wct,
+ position,
+ mOnAnimationFinishedCallback,
+ )
+ deactivationRunnable?.invoke(transition)
// handles case where we are moving to full screen without closing all DW tasks.
if (!taskRepository.isOnlyVisibleNonClosingTask(task.taskId)) {
@@ -1181,6 +1227,8 @@
wct.reorder(task.token, /* onTop= */ true, /* includingParents= */ true)
}
+ // TODO: b/394268248 - desk needs to be deactivated when moving the last task and going
+ // home.
if (Flags.enablePerDisplayDesktopWallpaperActivity()) {
performDesktopExitCleanupIfNeeded(
task.taskId,
@@ -1544,7 +1592,7 @@
private fun prepareForDeskActivation(displayId: Int, wct: WindowContainerTransaction) {
// Move home to front, ensures that we go back home when all desktop windows are closed
val useParamDisplayId =
- Flags.enableMultipleDesktopsBackend() ||
+ DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue ||
Flags.enablePerDisplayDesktopWallpaperActivity()
moveHomeTask(displayId = if (useParamDisplayId) displayId else context.displayId, wct = wct)
// Currently, we only handle the desktop on the default display really.
@@ -1727,33 +1775,59 @@
}
}
- /**
- * Remove wallpaper activity if task provided is last task and wallpaper activity token is not
- * null
- */
- private fun performDesktopExitCleanupIfNeeded(
- taskId: Int,
+ private fun willExitDesktop(
+ triggerTaskId: Int,
displayId: Int,
- wct: WindowContainerTransaction,
forceToFullscreen: Boolean,
- shouldEndUpAtHome: Boolean = true,
- ) {
- taskRepository.setPipShouldKeepDesktopActive(displayId, !forceToFullscreen)
+ ): Boolean {
if (Flags.enablePerDisplayDesktopWallpaperActivity()) {
- if (!taskRepository.isOnlyVisibleNonClosingTask(taskId, displayId)) {
- return
+ if (!taskRepository.isOnlyVisibleNonClosingTask(triggerTaskId, displayId)) {
+ return false
}
} else if (
Flags.enableDesktopWindowingPip() &&
taskRepository.isMinimizedPipPresentInDisplay(displayId) &&
!forceToFullscreen
) {
- return
+ return false
} else {
- if (!taskRepository.isOnlyVisibleNonClosingTask(taskId)) {
- return
+ if (!taskRepository.isOnlyVisibleNonClosingTask(triggerTaskId)) {
+ return false
}
}
+ return true
+ }
+
+ private fun performDesktopExitCleanupIfNeeded(
+ taskId: Int,
+ displayId: Int,
+ wct: WindowContainerTransaction,
+ forceToFullscreen: Boolean,
+ shouldEndUpAtHome: Boolean = true,
+ ): RunOnTransitStart? {
+ taskRepository.setPipShouldKeepDesktopActive(displayId, keepActive = !forceToFullscreen)
+ if (!willExitDesktop(taskId, displayId, forceToFullscreen)) {
+ return null
+ }
+ // TODO: b/394268248 - update remaining callers to pass in a |deskId| and apply the
+ // |RunOnTransitStart| when the transition is started.
+ return performDesktopExitCleanUp(
+ wct = wct,
+ deskId = null,
+ displayId = displayId,
+ willExitDesktop = true,
+ shouldEndUpAtHome = shouldEndUpAtHome,
+ )
+ }
+
+ private fun performDesktopExitCleanUp(
+ wct: WindowContainerTransaction,
+ deskId: Int?,
+ displayId: Int,
+ willExitDesktop: Boolean,
+ shouldEndUpAtHome: Boolean = true,
+ ): RunOnTransitStart? {
+ if (!willExitDesktop) return null
desktopModeEnterExitTransitionListener?.onExitDesktopModeTransitionStarted(
FULLSCREEN_ANIMATION_DURATION
)
@@ -1763,6 +1837,7 @@
// intent.
addLaunchHomePendingIntent(wct, displayId)
}
+ return prepareDeskDeactivationIfNeeded(wct, deskId)
}
fun releaseVisualIndicator() {
@@ -1973,8 +2048,10 @@
unminimizeReason = UnminimizeReason.APP_HANDLE_MENU_BUTTON,
)
} else {
- moveBackgroundTaskToDesktop(
+ val deskId = getDefaultDeskId(callingTask.displayId)
+ moveTaskToDesk(
requestedTaskId,
+ deskId,
WindowContainerTransaction(),
DesktopModeTransitionSource.APP_HANDLE_MENU_BUTTON,
)
@@ -2092,7 +2169,16 @@
): WindowContainerTransaction? {
logV("DesktopTasksController: handleMidRecentsFreeformTaskLaunch")
val wct = WindowContainerTransaction()
- addMoveToFullscreenChanges(wct, task)
+ addMoveToFullscreenChanges(
+ wct = wct,
+ taskInfo = task,
+ willExitDesktop =
+ willExitDesktop(
+ triggerTaskId = task.taskId,
+ displayId = task.displayId,
+ forceToFullscreen = true,
+ ),
+ )
wct.reorder(task.token, true)
return wct
}
@@ -2116,7 +2202,16 @@
// launched. We should make this task go to fullscreen instead of freeform. Note
// that this means any re-launch of a freeform window outside of desktop will be in
// fullscreen as long as default-desktop flag is disabled.
- addMoveToFullscreenChanges(wct, task)
+ addMoveToFullscreenChanges(
+ wct = wct,
+ taskInfo = task,
+ willExitDesktop =
+ willExitDesktop(
+ triggerTaskId = task.taskId,
+ displayId = task.displayId,
+ forceToFullscreen = true,
+ ),
+ )
return wct
}
bringDesktopAppsToFrontBeforeShowingNewTask(task.displayId, wct, task.taskId)
@@ -2212,7 +2307,16 @@
// changes we do for similar transitions. The task not having WINDOWING_MODE_UNDEFINED
// set when needed can interfere with future split / multi-instance transitions.
return WindowContainerTransaction().also { wct ->
- addMoveToFullscreenChanges(wct, task)
+ addMoveToFullscreenChanges(
+ wct = wct,
+ taskInfo = task,
+ willExitDesktop =
+ willExitDesktop(
+ triggerTaskId = task.taskId,
+ displayId = task.displayId,
+ forceToFullscreen = true,
+ ),
+ )
}
}
return null
@@ -2240,10 +2344,25 @@
}
// Already fullscreen, no-op.
if (task.isFullscreen) return null
- return WindowContainerTransaction().also { wct -> addMoveToFullscreenChanges(wct, task) }
+ return WindowContainerTransaction().also { wct ->
+ addMoveToFullscreenChanges(
+ wct = wct,
+ taskInfo = task,
+ willExitDesktop =
+ willExitDesktop(
+ triggerTaskId = task.taskId,
+ displayId = task.displayId,
+ forceToFullscreen = true,
+ ),
+ )
+ }
}
- /** Handle task closing by removing wallpaper activity if it's the last active task */
+ /**
+ * Handle task closing by removing wallpaper activity if it's the last active task.
+ *
+ * TODO: b/394268248 - desk needs to be deactivated.
+ */
private fun handleTaskClosing(
task: RunningTaskInfo,
transition: IBinder,
@@ -2310,7 +2429,7 @@
taskInfo: RunningTaskInfo,
deskId: Int,
) {
- if (!Flags.enableMultipleDesktopsBackend()) return
+ if (!DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) return
val displayId = taskRepository.getDisplayForDesk(deskId)
val displayLayout = displayController.getDisplayLayout(displayId) ?: return
val initialBounds = getInitialBounds(displayLayout, taskInfo, displayId)
@@ -2394,10 +2513,15 @@
return bounds
}
+ /**
+ * Applies the changes needed to enter fullscreen and returns the id of the desk that needs to
+ * be deactivated.
+ */
private fun addMoveToFullscreenChanges(
wct: WindowContainerTransaction,
taskInfo: RunningTaskInfo,
- ) {
+ willExitDesktop: Boolean,
+ ): RunOnTransitStart? {
val tdaInfo = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(taskInfo.displayId)!!
val tdaWindowingMode = tdaInfo.configuration.windowConfiguration.windowingMode
val targetWindowingMode =
@@ -2412,12 +2536,16 @@
if (useDesktopOverrideDensity()) {
wct.setDensityDpi(taskInfo.token, getDefaultDensityDpi())
}
-
- performDesktopExitCleanupIfNeeded(
- taskInfo.taskId,
- taskInfo.displayId,
- wct,
- forceToFullscreen = true,
+ if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
+ wct.reparent(taskInfo.token, tdaInfo.token, /* onTop= */ true)
+ }
+ taskRepository.setPipShouldKeepDesktopActive(taskInfo.displayId, keepActive = false)
+ val deskId = taskRepository.getDeskIdForTask(taskInfo.taskId)
+ return performDesktopExitCleanUp(
+ wct = wct,
+ deskId = deskId,
+ displayId = taskInfo.displayId,
+ willExitDesktop = willExitDesktop,
shouldEndUpAtHome = false,
)
}
@@ -2442,6 +2570,8 @@
/**
* Adds split screen changes to a transaction. Note that bounds are not reset here due to
* animation; see {@link onDesktopSplitSelectAnimComplete}
+ *
+ * TODO: b/394268248 - desk needs to be deactivated.
*/
private fun addMoveToSplitChanges(wct: WindowContainerTransaction, taskInfo: RunningTaskInfo) {
// This windowing mode is to get the transition animation started; once we complete
@@ -2531,10 +2661,7 @@
displayId: Int,
remoteTransition: RemoteTransition? = null,
) {
- val deskId =
- checkNotNull(taskRepository.getDefaultDeskId(displayId)) {
- "Expected a default desk to exist"
- }
+ val deskId = getDefaultDeskId(displayId)
activateDesk(deskId, remoteTransition)
}
@@ -2542,7 +2669,7 @@
fun activateDesk(deskId: Int, remoteTransition: RemoteTransition? = null) {
val displayId = taskRepository.getDisplayForDesk(deskId)
val wct = WindowContainerTransaction()
- if (Flags.enableMultipleDesktopsBackend()) {
+ if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
prepareForDeskActivation(displayId, wct)
desksOrganizer.activateDesk(wct, deskId)
if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue()) {
@@ -2563,7 +2690,7 @@
val transition = transitions.startTransition(transitionType, wct, handler)
handler?.setTransition(transition)
- if (Flags.enableMultipleDesktopsBackend()) {
+ if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
desksTransitionObserver.addPendingTransition(
DeskTransition.ActivateDesk(
token = transition,
@@ -2578,16 +2705,35 @@
)
}
+ /**
+ * TODO: b/393978539 - Deactivation should not happen in desktop-first devices when going home.
+ */
+ private fun prepareDeskDeactivationIfNeeded(
+ wct: WindowContainerTransaction,
+ deskId: Int?,
+ ): RunOnTransitStart? {
+ if (!DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) return null
+ if (deskId == null) return null
+ desksOrganizer.deactivateDesk(wct, deskId)
+ return { transition ->
+ desksTransitionObserver.addPendingTransition(
+ DeskTransition.DeactivateDesk(token = transition, deskId = deskId)
+ )
+ }
+ }
+
/** Removes the default desk in the given display. */
@Deprecated("Deprecated with multi-desks.", ReplaceWith("removeDesk()"))
fun removeDefaultDeskInDisplay(displayId: Int) {
- val deskId =
- checkNotNull(taskRepository.getDefaultDeskId(displayId)) {
- "Expected a default desk to exist"
- }
+ val deskId = getDefaultDeskId(displayId)
removeDesk(displayId = displayId, deskId = deskId)
}
+ private fun getDefaultDeskId(displayId: Int) =
+ checkNotNull(taskRepository.getDefaultDeskId(displayId)) {
+ "Expected a default desk to exist in display: $displayId"
+ }
+
/** Removes the given desk. */
fun removeDesk(deskId: Int) {
val displayId = taskRepository.getDisplayForDesk(deskId)
@@ -2599,7 +2745,7 @@
logV("removeDesk deskId=%d from displayId=%d", deskId, displayId)
val tasksToRemove =
- if (Flags.enableMultipleDesktopsBackend()) {
+ if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
taskRepository.getActiveTaskIdsInDesk(deskId)
} else {
// TODO: 362720497 - make sure minimized windows are also removed in WM
@@ -2608,7 +2754,7 @@
}
val wct = WindowContainerTransaction()
- if (!Flags.enableMultipleDesktopsBackend()) {
+ if (!DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
tasksToRemove.forEach {
val task = shellTaskOrganizer.getRunningTaskInfo(it)
if (task != null) {
@@ -2621,9 +2767,9 @@
// TODO: 362720497 - double check background tasks are also removed.
desksOrganizer.removeDesk(wct, deskId)
}
- if (!Flags.enableMultipleDesktopsBackend() && wct.isEmpty) return
+ if (!DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue && wct.isEmpty) return
val transition = transitions.startTransition(TRANSIT_CLOSE, wct, /* handler= */ null)
- if (Flags.enableMultipleDesktopsBackend()) {
+ if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
desksTransitionObserver.addPendingTransition(
DeskTransition.RemoveDesk(
token = transition,
@@ -2942,6 +3088,8 @@
val indicatorType = indicator.updateIndicatorType(inputCoordinates)
when (indicatorType) {
IndicatorType.TO_DESKTOP_INDICATOR -> {
+ LatencyTracker.getInstance(context)
+ .onActionStart(LatencyTracker.ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG)
// Start a new jank interaction for the drag release to desktop window animation.
interactionJankMonitor.begin(
taskSurface,
@@ -3300,11 +3448,15 @@
}
override fun createDesk(displayId: Int) {
- // TODO: b/362720497 - Implement this API.
+ executeRemoteCallWithTaskPermission(controller, "createDesk") { c ->
+ c.createDesk(displayId)
+ }
}
override fun activateDesk(deskId: Int, remoteTransition: RemoteTransition?) {
- // TODO: b/362720497 - Implement this API.
+ executeRemoteCallWithTaskPermission(controller, "activateDesk") { c ->
+ c.activateDesk(deskId, remoteTransition)
+ }
}
override fun showDesktopApps(displayId: Int, remoteTransition: RemoteTransition?) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserver.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserver.kt
index 3ada988..9a97ae8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserver.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserver.kt
@@ -186,14 +186,16 @@
for (change in info.changes) {
val taskInfo = change.taskInfo
if (taskInfo == null || taskInfo.taskId == -1) continue
- if (change.mode != TRANSIT_CLOSE) continue
- if (minimizingTask == null) {
- minimizingTask = getMinimizingTaskForClosingTransition(taskInfo)
+ if (
+ TransitionUtil.isClosingMode(change.mode) &&
+ DesktopWallpaperActivity.isWallpaperTask(taskInfo)
+ ) {
+ hasWallpaperClosing = true
}
- if (DesktopWallpaperActivity.isWallpaperTask(taskInfo)) {
- hasWallpaperClosing = true
+ if (change.mode == TRANSIT_CLOSE && minimizingTask == null) {
+ minimizingTask = getMinimizingTaskForClosingTransition(taskInfo)
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandler.kt
index aaecf8c..b46051c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandler.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandler.kt
@@ -35,6 +35,7 @@
import com.android.internal.jank.Cuj.CUJ_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG_RELEASE
import com.android.internal.jank.InteractionJankMonitor
import com.android.internal.protolog.ProtoLog
+import com.android.internal.util.LatencyTracker
import com.android.wm.shell.RootTaskDisplayAreaOrganizer
import com.android.wm.shell.animation.FloatProperties
import com.android.wm.shell.bubbles.BubbleController
@@ -251,7 +252,8 @@
(cancelState == CancelState.CANCEL_BUBBLE_LEFT ||
cancelState == CancelState.CANCEL_BUBBLE_RIGHT)
) {
- if (!bubbleController.isPresent) {
+ if (bubbleController.isEmpty || state !is TransitionState.FromFullscreen) {
+ // TODO(b/388853233): add support for dragging split task to bubble
startCancelAnimation()
} else {
// Animation is handled by BubbleController
@@ -497,6 +499,11 @@
state.cancelState == CancelState.CANCEL_BUBBLE_LEFT ||
state.cancelState == CancelState.CANCEL_BUBBLE_RIGHT
) {
+ if (bubbleController.isEmpty || state !is TransitionState.FromFullscreen) {
+ // TODO(b/388853233): add support for dragging split task to bubble
+ startCancelDragToDesktopTransition()
+ return true
+ }
val taskInfo =
state.draggedTaskChange?.taskInfo ?: error("Expected non-null task info.")
val wct = WindowContainerTransaction()
@@ -562,8 +569,12 @@
)
// Call finishCallback to merge animation before startTransitionFinishCb is called
finishCallback.onTransitionFinished(/* wct= */ null)
+ LatencyTracker.getInstance(context)
+ .onActionEnd(LatencyTracker.ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG)
animateEndDragToDesktop(startTransaction = startT, startTransitionFinishCb)
} else if (isCancelTransition) {
+ LatencyTracker.getInstance(context)
+ .onActionCancel(LatencyTracker.ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG)
info.changes.forEach { change ->
startT.show(change.leash)
startTransactionFinishT.show(change.leash)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandler.java
index 5ae1fca..95cc1e6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandler.java
@@ -106,7 +106,7 @@
* @param position Position of the task when transition is started
* @param onAnimationEndCallback to be called after animation
*/
- public void startTransition(@NonNull DesktopModeTransitionSource transitionSource,
+ public IBinder startTransition(@NonNull DesktopModeTransitionSource transitionSource,
@NonNull WindowContainerTransaction wct, Point position,
Function0<Unit> onAnimationEndCallback) {
mPosition = position;
@@ -114,6 +114,7 @@
final IBinder token = mTransitions.startTransition(getExitTransitionType(transitionSource),
wct, this);
mPendingTransitionTokens.add(token);
+ return token;
}
@Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/desktopwallpaperactivity/DesktopWallpaperActivityTokenProvider.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/desktopwallpaperactivity/DesktopWallpaperActivityTokenProvider.kt
index 2a8a347..b5490cb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/desktopwallpaperactivity/DesktopWallpaperActivityTokenProvider.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/desktopwallpaperactivity/DesktopWallpaperActivityTokenProvider.kt
@@ -20,7 +20,7 @@
import android.util.SparseBooleanArray
import android.view.Display.DEFAULT_DISPLAY
import android.window.WindowContainerToken
-import androidx.core.util.forEach
+import androidx.core.util.keyIterator
import com.android.internal.protolog.ProtoLog
import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
@@ -45,11 +45,13 @@
}
fun removeToken(token: WindowContainerToken) {
- wallpaperActivityTokenByDisplayId.forEach { displayId, value ->
- if (value == token) {
- logV("Remove desktop wallpaper activity token for display %s", displayId)
- wallpaperActivityTokenByDisplayId.delete(displayId)
+ val displayId =
+ wallpaperActivityTokenByDisplayId.keyIterator().asSequence().find {
+ wallpaperActivityTokenByDisplayId[it] == token
}
+ if (displayId != null) {
+ logV("Remove desktop wallpaper activity token for display %s", displayId)
+ wallpaperActivityTokenByDisplayId.delete(displayId)
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/DeskTransition.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/DeskTransition.kt
index 8c4fd9d..9dec969 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/DeskTransition.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/DeskTransition.kt
@@ -42,4 +42,7 @@
val deskId: Int,
val enterTaskId: Int,
) : DeskTransition()
+
+ /** A transition to deactivate a desk. */
+ data class DeactivateDesk(override val token: IBinder, val deskId: Int) : DeskTransition()
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/DesksOrganizer.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/DesksOrganizer.kt
index 547890a..0f2f371 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/DesksOrganizer.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/DesksOrganizer.kt
@@ -27,6 +27,9 @@
/** Activates the given desk, making it visible in its display. */
fun activateDesk(wct: WindowContainerTransaction, deskId: Int)
+ /** Deactivates the given desk, removing it as the default launch container for new tasks. */
+ fun deactivateDesk(wct: WindowContainerTransaction, deskId: Int)
+
/** Removes the given desk and its desktop windows. */
fun removeDesk(wct: WindowContainerTransaction, deskId: Int)
@@ -37,6 +40,9 @@
task: ActivityManager.RunningTaskInfo,
)
+ /** Whether the change is for the given desk id. */
+ fun isDeskChange(change: TransitionInfo.Change, deskId: Int): Boolean
+
/**
* Returns the desk id in which the task in the given change is located at the end of a
* transition, if any.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/DesksTransitionObserver.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/DesksTransitionObserver.kt
index 6d88c33..e57b563 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/DesksTransitionObserver.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/DesksTransitionObserver.kt
@@ -17,9 +17,11 @@
import android.os.IBinder
import android.view.WindowManager.TRANSIT_CLOSE
+import android.window.DesktopExperienceFlags
import android.window.TransitionInfo
-import com.android.window.flags.Flags
+import com.android.internal.protolog.ProtoLog
import com.android.wm.shell.desktopmode.DesktopUserRepositories
+import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
/**
* Observer of desk-related transitions, such as adding, removing or activating a whole desk. It
@@ -33,7 +35,7 @@
/** Adds a pending desk transition to be tracked. */
fun addPendingTransition(transition: DeskTransition) {
- if (!Flags.enableMultipleDesktopsBackend()) return
+ if (!DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) return
deskTransitions[transition.token] = transition
}
@@ -42,8 +44,9 @@
* observer.
*/
fun onTransitionReady(transition: IBinder, info: TransitionInfo) {
- if (!Flags.enableMultipleDesktopsBackend()) return
+ if (!DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) return
val deskTransition = deskTransitions.remove(transition) ?: return
+ logD("Desk transition ready: %s", deskTransition)
val desktopRepository = desktopUserRepositories.current
when (deskTransition) {
is DeskTransition.RemoveDesk -> {
@@ -88,6 +91,42 @@
)
}
}
+ is DeskTransition.DeactivateDesk -> {
+ var visibleDeactivation = false
+ for (change in info.changes) {
+ val isDeskChange = desksOrganizer.isDeskChange(change, deskTransition.deskId)
+ if (isDeskChange) {
+ visibleDeactivation = true
+ continue
+ }
+ val taskId = change.taskInfo?.taskId ?: continue
+ val removedFromDesk =
+ desktopRepository.getDeskIdForTask(taskId) == deskTransition.deskId &&
+ desksOrganizer.getDeskAtEnd(change) == null
+ if (removedFromDesk) {
+ desktopRepository.removeTaskFromDesk(
+ deskId = deskTransition.deskId,
+ taskId = taskId,
+ )
+ }
+ }
+ // Always deactivate even if there's no change that confirms the desk was
+ // deactivated. Some interactions, such as the desk deactivating because it's
+ // occluded by a fullscreen task result in a transition change, but others, such
+ // as transitioning from an empty desk to home may not.
+ if (!visibleDeactivation) {
+ logD("Deactivating desk without transition change")
+ }
+ desktopRepository.setDeskInactive(deskId = deskTransition.deskId)
+ }
}
}
+
+ private fun logD(msg: String, vararg arguments: Any?) {
+ ProtoLog.d(WM_SHELL_DESKTOP_MODE, "%s: $msg", TAG, *arguments)
+ }
+
+ private companion object {
+ private const val TAG = "DesksTransitionObserver"
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/RootTaskDesksOrganizer.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/RootTaskDesksOrganizer.kt
index 5cda76e..339932c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/RootTaskDesksOrganizer.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/RootTaskDesksOrganizer.kt
@@ -23,12 +23,12 @@
import android.util.SparseArray
import android.view.SurfaceControl
import android.view.WindowManager.TRANSIT_TO_FRONT
+import android.window.DesktopExperienceFlags
import android.window.TransitionInfo
import android.window.WindowContainerTransaction
import androidx.core.util.forEach
import com.android.internal.annotations.VisibleForTesting
import com.android.internal.protolog.ProtoLog
-import com.android.window.flags.Flags
import com.android.wm.shell.ShellTaskOrganizer
import com.android.wm.shell.desktopmode.multidesks.DesksOrganizer.OnCreateCallback
import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
@@ -47,7 +47,7 @@
@VisibleForTesting val roots = SparseArray<DeskRoot>()
init {
- if (Flags.enableMultipleDesktopsBackend()) {
+ if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
shellInit.addInitCallback(
{ shellCommandHandler.addDumpCallback(this::dump, this) },
this,
@@ -83,6 +83,16 @@
)
}
+ override fun deactivateDesk(wct: WindowContainerTransaction, deskId: Int) {
+ logV("deactivateDesk %d", deskId)
+ val root = checkNotNull(roots[deskId]) { "Root not found for desk: $deskId" }
+ wct.setLaunchRoot(
+ /* container= */ root.taskInfo.token,
+ /* windowingModes= */ null,
+ /* activityTypes= */ null,
+ )
+ }
+
override fun moveTaskToDesk(
wct: WindowContainerTransaction,
deskId: Int,
@@ -93,6 +103,9 @@
wct.reparent(task.token, root.taskInfo.token, /* onTop= */ true)
}
+ override fun isDeskChange(change: TransitionInfo.Change, deskId: Int): Boolean =
+ roots.contains(deskId) && change.taskInfo?.taskId == deskId
+
override fun getDeskAtEnd(change: TransitionInfo.Change): Int? =
change.taskInfo?.parentTaskId?.takeIf { it in roots }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializerImpl.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializerImpl.kt
index 5a89451..0507e59 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializerImpl.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializerImpl.kt
@@ -17,8 +17,8 @@
package com.android.wm.shell.desktopmode.persistence
import android.content.Context
+import android.window.DesktopExperienceFlags
import android.window.DesktopModeFlags
-import com.android.window.flags.Flags
import com.android.wm.shell.desktopmode.DesktopRepository
import com.android.wm.shell.desktopmode.DesktopUserRepositories
import com.android.wm.shell.shared.annotations.ShellMainThread
@@ -58,7 +58,7 @@
repository.addDesk(
displayId = persistentDesktop.displayId,
deskId =
- if (Flags.enableMultipleDesktopsBackend()) {
+ if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
persistentDesktop.desktopId
} else {
// When disabled, desk ids are always the display id.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java
index da31810..cef18f5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java
@@ -145,7 +145,7 @@
/**
* Called when the Shell wants to start an exit-via-expand from Pip transition/animation.
*/
- public void startExpandTransition(WindowContainerTransaction out) {
+ public void startExpandTransition(WindowContainerTransaction out, boolean toSplit) {
// Default implementation does nothing.
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipDismissTargetHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipDismissTargetHandler.java
index 7169759..a837e7d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipDismissTargetHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipDismissTargetHandler.java
@@ -296,6 +296,7 @@
return;
}
+ mMagneticTarget.updateLocationOnScreen();
createOrUpdateDismissTarget();
if (mTargetViewContainer.getVisibility() != View.VISIBLE) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java
index e17587f..df7a25a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java
@@ -35,6 +35,10 @@
import com.android.wm.shell.pip2.PipSurfaceTransactionHelper;
import com.android.wm.shell.pip2.animation.PipAlphaAnimator;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
+import com.android.wm.shell.shared.split.SplitScreenConstants;
+import com.android.wm.shell.splitscreen.SplitScreenController;
+
+import java.util.Optional;
/**
* Scheduler for Shell initiated PiP transitions and animations.
@@ -47,6 +51,7 @@
private final ShellExecutor mMainExecutor;
private final PipTransitionState mPipTransitionState;
private final PipDesktopState mPipDesktopState;
+ private final Optional<SplitScreenController> mSplitScreenControllerOptional;
private PipTransitionController mPipTransitionController;
private PipSurfaceTransactionHelper.SurfaceControlTransactionFactory
mSurfaceControlTransactionFactory;
@@ -59,12 +64,14 @@
PipBoundsState pipBoundsState,
ShellExecutor mainExecutor,
PipTransitionState pipTransitionState,
+ Optional<SplitScreenController> splitScreenControllerOptional,
PipDesktopState pipDesktopState) {
mContext = context;
mPipBoundsState = pipBoundsState;
mMainExecutor = mainExecutor;
mPipTransitionState = pipTransitionState;
mPipDesktopState = pipDesktopState;
+ mSplitScreenControllerOptional = splitScreenControllerOptional;
mSurfaceControlTransactionFactory =
new PipSurfaceTransactionHelper.VsyncSurfaceControlTransactionFactory();
@@ -96,10 +103,23 @@
public void scheduleExitPipViaExpand() {
mMainExecutor.execute(() -> {
if (!mPipTransitionState.isInPip()) return;
- WindowContainerTransaction wct = getExitPipViaExpandTransaction();
- if (wct != null) {
- mPipTransitionController.startExpandTransition(wct);
- }
+
+ final WindowContainerTransaction expandWct = getExitPipViaExpandTransaction();
+ if (expandWct == null) return;
+
+ final WindowContainerTransaction wct = new WindowContainerTransaction();
+ mSplitScreenControllerOptional.ifPresent(splitScreenController -> {
+ int lastParentTaskId = mPipTransitionState.getPipTaskInfo()
+ .lastParentTaskIdBeforePip;
+ if (splitScreenController.isTaskInSplitScreen(lastParentTaskId)) {
+ splitScreenController.prepareEnterSplitScreen(wct,
+ null /* taskInfo */, SplitScreenConstants.SPLIT_POSITION_UNDEFINED);
+ }
+ });
+
+ boolean toSplit = !wct.isEmpty();
+ wct.merge(expandWct, true /* transfer */);
+ mPipTransitionController.startExpandTransition(wct, toSplit);
});
}
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 9adaa36..035c93d 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
@@ -16,7 +16,6 @@
package com.android.wm.shell.pip2.phone;
-import static android.app.WindowConfiguration.ROTATION_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.view.Surface.ROTATION_0;
@@ -29,7 +28,13 @@
import static android.view.WindowManager.TRANSIT_TO_BACK;
import static android.view.WindowManager.TRANSIT_TO_FRONT;
+import static com.android.wm.shell.pip2.phone.transition.PipTransitionUtils.getChangeByToken;
+import static com.android.wm.shell.pip2.phone.transition.PipTransitionUtils.getFixedRotationDelta;
+import static com.android.wm.shell.pip2.phone.transition.PipTransitionUtils.getLeash;
+import static com.android.wm.shell.pip2.phone.transition.PipTransitionUtils.getPipChange;
+import static com.android.wm.shell.pip2.phone.transition.PipTransitionUtils.getPipParams;
import static com.android.wm.shell.transition.Transitions.TRANSIT_EXIT_PIP;
+import static com.android.wm.shell.transition.Transitions.TRANSIT_EXIT_PIP_TO_SPLIT;
import static com.android.wm.shell.transition.Transitions.TRANSIT_REMOVE_PIP;
import static com.android.wm.shell.transition.Transitions.TRANSIT_RESIZE_PIP;
import static com.android.wm.shell.transition.Transitions.transitTypeToString;
@@ -45,7 +50,6 @@
import android.graphics.Rect;
import android.os.Bundle;
import android.os.IBinder;
-import android.view.Surface;
import android.view.SurfaceControl;
import android.view.WindowManager;
import android.window.TransitionInfo;
@@ -70,11 +74,14 @@
import com.android.wm.shell.pip2.PipSurfaceTransactionHelper;
import com.android.wm.shell.pip2.animation.PipAlphaAnimator;
import com.android.wm.shell.pip2.animation.PipEnterAnimator;
-import com.android.wm.shell.pip2.animation.PipExpandAnimator;
+import com.android.wm.shell.pip2.phone.transition.PipExpandHandler;
import com.android.wm.shell.shared.TransitionUtil;
+import com.android.wm.shell.splitscreen.SplitScreenController;
import com.android.wm.shell.sysui.ShellInit;
import com.android.wm.shell.transition.Transitions;
+import java.util.Optional;
+
/**
* Implementation of transitions for PiP on phone.
*/
@@ -130,6 +137,7 @@
//
// Internal state and relevant cached info
//
+ private final PipExpandHandler mExpandHandler;
private Transitions.TransitionFinishCallback mFinishCallback;
@@ -151,6 +159,7 @@
PipDisplayLayoutState pipDisplayLayoutState,
PipUiStateChangeController pipUiStateChangeController,
DisplayController displayController,
+ Optional<SplitScreenController> splitScreenControllerOptional,
PipDesktopState pipDesktopState) {
super(shellInit, shellTaskOrganizer, transitions, pipBoundsState, pipMenuController,
pipBoundsAlgorithm);
@@ -165,6 +174,9 @@
mDisplayController = displayController;
mPipSurfaceTransactionHelper = new PipSurfaceTransactionHelper(mContext);
mPipDesktopState = pipDesktopState;
+
+ mExpandHandler = new PipExpandHandler(mContext, pipBoundsState, pipBoundsAlgorithm,
+ pipTransitionState, pipDisplayLayoutState, splitScreenControllerOptional);
}
@Override
@@ -184,10 +196,11 @@
//
@Override
- public void startExpandTransition(WindowContainerTransaction out) {
+ public void startExpandTransition(WindowContainerTransaction out, boolean toSplit) {
if (out == null) return;
mPipTransitionState.setState(PipTransitionState.EXITING_PIP);
- mExitViaExpandTransition = mTransitions.startTransition(TRANSIT_EXIT_PIP, out, this);
+ mExitViaExpandTransition = mTransitions.startTransition(toSplit ? TRANSIT_EXIT_PIP_TO_SPLIT
+ : TRANSIT_EXIT_PIP, out, this);
}
@Override
@@ -239,10 +252,11 @@
@NonNull SurfaceControl.Transaction finishT,
@NonNull IBinder mergeTarget,
@NonNull Transitions.TransitionFinishCallback finishCallback) {
- // Just jump-cut the current animation if any, but do not merge.
if (info.getType() == TRANSIT_EXIT_PIP) {
end();
}
+ mExpandHandler.mergeAnimation(transition, info, startT, finishT, mergeTarget,
+ finishCallback);
}
@Override
@@ -290,7 +304,8 @@
finishCallback);
} else if (transition == mExitViaExpandTransition) {
mExitViaExpandTransition = null;
- return startExpandAnimation(info, startTransaction, finishTransaction, finishCallback);
+ return mExpandHandler.startAnimation(transition, info, startTransaction,
+ finishTransaction, finishCallback);
} else if (transition == mResizeTransition) {
mResizeTransition = null;
return startResizeAnimation(info, startTransaction, finishTransaction, finishCallback);
@@ -436,7 +451,7 @@
(destinationBounds.height() - overlaySize) / 2f);
}
- final int delta = getFixedRotationDelta(info, pipChange);
+ final int delta = getFixedRotationDelta(info, pipChange, mPipDisplayLayoutState);
if (delta != ROTATION_0) {
// Update transition target changes in place to prepare for fixed rotation.
handleBoundsEnterFixedRotation(info, pipChange, pipActivityChange);
@@ -496,7 +511,7 @@
final Rect adjustedSourceRectHint = getAdjustedSourceRectHint(info, pipChange,
pipActivityChange);
- final int delta = getFixedRotationDelta(info, pipChange);
+ final int delta = getFixedRotationDelta(info, pipChange, mPipDisplayLayoutState);
if (delta != ROTATION_0) {
// Update transition target changes in place to prepare for fixed rotation.
handleBoundsEnterFixedRotation(info, pipChange, pipActivityChange);
@@ -585,27 +600,6 @@
endBounds.top + activityEndOffset.y);
}
- private void handleExpandFixedRotation(TransitionInfo.Change outPipTaskChange, int delta) {
- final Rect endBounds = outPipTaskChange.getEndAbsBounds();
- final int width = endBounds.width();
- final int height = endBounds.height();
- final int left = endBounds.left;
- final int top = endBounds.top;
- int newTop, newLeft;
-
- if (delta == Surface.ROTATION_90) {
- newLeft = top;
- newTop = -(left + width);
- } else {
- newLeft = -(height + top);
- newTop = left;
- }
- // Modify the endBounds, rotating and placing them potentially off-screen, so that
- // as we translate and rotate around the origin, we place them right into the target.
- endBounds.set(newLeft, newTop, newLeft + height, newTop + width);
- }
-
-
private boolean startAlphaTypeEnterAnimation(@NonNull TransitionInfo info,
@NonNull SurfaceControl.Transaction startTransaction,
@NonNull SurfaceControl.Transaction finishTransaction,
@@ -633,83 +627,6 @@
return true;
}
- private boolean startExpandAnimation(@NonNull TransitionInfo info,
- @NonNull SurfaceControl.Transaction startTransaction,
- @NonNull SurfaceControl.Transaction finishTransaction,
- @NonNull Transitions.TransitionFinishCallback finishCallback) {
- WindowContainerToken pipToken = mPipTransitionState.getPipTaskToken();
-
- TransitionInfo.Change pipChange = getChangeByToken(info, pipToken);
- if (pipChange == null) {
- // pipChange is null, check to see if we've reparented the PIP activity for
- // the multi activity case. If so we should use the activity leash instead
- for (TransitionInfo.Change change : info.getChanges()) {
- if (change.getTaskInfo() == null
- && change.getLastParent() != null
- && change.getLastParent().equals(pipToken)) {
- pipChange = change;
- break;
- }
- }
-
- // failsafe
- if (pipChange == null) {
- return false;
- }
- }
- mFinishCallback = finishCallback;
-
- // The parent change if we were in a multi-activity PiP; null if single activity PiP.
- final TransitionInfo.Change parentBeforePip = pipChange.getTaskInfo() == null
- ? getChangeByToken(info, pipChange.getParent()) : null;
- if (parentBeforePip != null) {
- // For multi activity, we need to manually set the leash layer
- startTransaction.setLayer(parentBeforePip.getLeash(), Integer.MAX_VALUE - 1);
- }
-
- final Rect startBounds = pipChange.getStartAbsBounds();
- final Rect endBounds = pipChange.getEndAbsBounds();
- final SurfaceControl pipLeash = getLeash(pipChange);
-
- PictureInPictureParams params = null;
- if (pipChange.getTaskInfo() != null) {
- // single activity
- params = getPipParams(pipChange);
- } else if (parentBeforePip != null && parentBeforePip.getTaskInfo() != null) {
- // multi activity
- params = getPipParams(parentBeforePip);
- }
- final Rect sourceRectHint = PipBoundsAlgorithm.getValidSourceHintRect(params, endBounds,
- startBounds);
-
- // We define delta = startRotation - endRotation, so we need to flip the sign.
- final int delta = -getFixedRotationDelta(info, pipChange);
- if (delta != ROTATION_0) {
- // Update PiP target change in place to prepare for fixed rotation;
- handleExpandFixedRotation(pipChange, delta);
- }
-
- PipExpandAnimator animator = new PipExpandAnimator(mContext, pipLeash,
- startTransaction, finishTransaction, endBounds, startBounds, endBounds,
- sourceRectHint, delta);
- animator.setAnimationEndCallback(() -> {
- if (parentBeforePip != null) {
- // TODO b/377362511: Animate local leash instead to also handle letterbox case.
- // For multi-activity, set the crop to be null
- finishTransaction.setCrop(pipLeash, null);
- }
- finishTransition();
- });
- cacheAndStartTransitionAnimator(animator);
-
- // Save the PiP bounds in case, we re-enter the PiP with the same component.
- float snapFraction = mPipBoundsAlgorithm.getSnapFraction(
- mPipBoundsState.getBounds());
- mPipBoundsState.saveReentryState(snapFraction);
-
- return true;
- }
-
private boolean startRemoveAnimation(@NonNull TransitionInfo info,
@NonNull SurfaceControl.Transaction startTransaction,
@NonNull SurfaceControl.Transaction finishTransaction,
@@ -743,29 +660,6 @@
// Various helpers to resolve transition requests and infos
//
- @Nullable
- private TransitionInfo.Change getPipChange(TransitionInfo info) {
- for (TransitionInfo.Change change : info.getChanges()) {
- if (change.getTaskInfo() != null
- && change.getTaskInfo().getWindowingMode() == WINDOWING_MODE_PINNED) {
- return change;
- }
- }
- return null;
- }
-
- @Nullable
- private TransitionInfo.Change getChangeByToken(TransitionInfo info,
- WindowContainerToken token) {
- for (TransitionInfo.Change change : info.getChanges()) {
- if (change.getTaskInfo() != null
- && change.getTaskInfo().getToken().equals(token)) {
- return change;
- }
- }
- return null;
- }
-
@NonNull
private Rect getAdjustedSourceRectHint(@NonNull TransitionInfo info,
@NonNull TransitionInfo.Change pipTaskChange,
@@ -789,8 +683,8 @@
Rect cutoutInsets = parentBeforePip != null
? parentBeforePip.getTaskInfo().displayCutoutInsets
: pipTaskChange.getTaskInfo().displayCutoutInsets;
- if (cutoutInsets != null
- && getFixedRotationDelta(info, pipTaskChange) == ROTATION_90) {
+ if (cutoutInsets != null && getFixedRotationDelta(info, pipTaskChange,
+ mPipDisplayLayoutState) == ROTATION_90) {
adjustedSourceRectHint.offset(cutoutInsets.left, cutoutInsets.top);
}
if (mPipDesktopState.isDesktopWindowingPipEnabled()) {
@@ -807,25 +701,6 @@
return adjustedSourceRectHint;
}
- @Surface.Rotation
- private int getFixedRotationDelta(@NonNull TransitionInfo info,
- @NonNull TransitionInfo.Change pipChange) {
- TransitionInfo.Change fixedRotationChange = findFixedRotationChange(info);
- int startRotation = pipChange.getStartRotation();
- if (pipChange.getEndRotation() != ROTATION_UNDEFINED
- && startRotation != pipChange.getEndRotation()) {
- // If PiP change was collected along with the display change and the orientation change
- // happened in sync with the PiP change, then do not treat this as fixed-rotation case.
- return ROTATION_0;
- }
-
- int endRotation = fixedRotationChange != null
- ? fixedRotationChange.getEndFixedRotation() : mPipDisplayLayoutState.getRotation();
- int delta = endRotation == ROTATION_UNDEFINED ? ROTATION_0
- : startRotation - endRotation;
- return delta;
- }
-
private void prepareOtherTargetTransforms(TransitionInfo info,
SurfaceControl.Transaction startTransaction,
SurfaceControl.Transaction finishTransaction) {
@@ -853,7 +728,8 @@
// If PiP is enabled on Connected Displays, update PipDisplayLayoutState to have the correct
// display info that PiP is entering in.
- if (mPipDesktopState.isConnectedDisplaysPipEnabled()) {
+ if (mPipDesktopState.isConnectedDisplaysPipEnabled()
+ && pipTask.displayId != mPipDisplayLayoutState.getDisplayId()) {
final DisplayLayout displayLayout = mDisplayController.getDisplayLayout(
pipTask.displayId);
if (displayLayout != null) {
@@ -1012,20 +888,6 @@
mTransitionAnimator.start();
}
- @NonNull
- private static PictureInPictureParams getPipParams(@NonNull TransitionInfo.Change pipChange) {
- return pipChange.getTaskInfo().pictureInPictureParams != null
- ? pipChange.getTaskInfo().pictureInPictureParams
- : new PictureInPictureParams.Builder().build();
- }
-
- @NonNull
- private static SurfaceControl getLeash(TransitionInfo.Change change) {
- SurfaceControl leash = change.getLeash();
- Preconditions.checkNotNull(leash, "Leash is null for change=" + change);
- return leash;
- }
-
//
// Miscellaneous callbacks and listeners
//
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransitionState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransitionState.java
index 8805cbb..18c9a70 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransitionState.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransitionState.java
@@ -314,7 +314,8 @@
mSwipePipToHomeAppBounds.setEmpty();
}
- @Nullable WindowContainerToken getPipTaskToken() {
+ @Nullable
+ public WindowContainerToken getPipTaskToken() {
return mPipTaskInfo != null ? mPipTaskInfo.getToken() : null;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/transition/PipExpandHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/transition/PipExpandHandler.java
new file mode 100644
index 0000000..db4942b
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/transition/PipExpandHandler.java
@@ -0,0 +1,331 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.pip2.phone.transition;
+
+import static android.view.Surface.ROTATION_0;
+
+import static com.android.wm.shell.pip2.phone.transition.PipTransitionUtils.getChangeByToken;
+import static com.android.wm.shell.pip2.phone.transition.PipTransitionUtils.getFixedRotationDelta;
+import static com.android.wm.shell.pip2.phone.transition.PipTransitionUtils.getLeash;
+import static com.android.wm.shell.pip2.phone.transition.PipTransitionUtils.getPipParams;
+import static com.android.wm.shell.transition.Transitions.TRANSIT_EXIT_PIP;
+import static com.android.wm.shell.transition.Transitions.TRANSIT_EXIT_PIP_TO_SPLIT;
+
+import android.animation.ValueAnimator;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.PictureInPictureParams;
+import android.content.Context;
+import android.graphics.Rect;
+import android.os.IBinder;
+import android.view.Surface;
+import android.view.SurfaceControl;
+import android.window.TransitionInfo;
+import android.window.TransitionRequestInfo;
+import android.window.WindowContainerToken;
+import android.window.WindowContainerTransaction;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.protolog.ProtoLog;
+import com.android.wm.shell.common.pip.PipBoundsAlgorithm;
+import com.android.wm.shell.common.pip.PipBoundsState;
+import com.android.wm.shell.common.pip.PipDisplayLayoutState;
+import com.android.wm.shell.pip2.animation.PipExpandAnimator;
+import com.android.wm.shell.pip2.phone.PipTransitionState;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
+import com.android.wm.shell.splitscreen.SplitScreenController;
+import com.android.wm.shell.transition.Transitions;
+
+import java.util.Optional;
+
+public class PipExpandHandler implements Transitions.TransitionHandler {
+ private final Context mContext;
+ private final PipBoundsState mPipBoundsState;
+ private final PipBoundsAlgorithm mPipBoundsAlgorithm;
+ private final PipTransitionState mPipTransitionState;
+ private final PipDisplayLayoutState mPipDisplayLayoutState;
+ private final Optional<SplitScreenController> mSplitScreenControllerOptional;
+
+ @Nullable
+ private Transitions.TransitionFinishCallback mFinishCallback;
+ @Nullable
+ private ValueAnimator mTransitionAnimator;
+
+ private PipExpandAnimatorSupplier mPipExpandAnimatorSupplier;
+
+ public PipExpandHandler(Context context,
+ PipBoundsState pipBoundsState,
+ PipBoundsAlgorithm pipBoundsAlgorithm,
+ PipTransitionState pipTransitionState,
+ PipDisplayLayoutState pipDisplayLayoutState,
+ Optional<SplitScreenController> splitScreenControllerOptional) {
+ mContext = context;
+ mPipBoundsState = pipBoundsState;
+ mPipBoundsAlgorithm = pipBoundsAlgorithm;
+ mPipTransitionState = pipTransitionState;
+ mPipDisplayLayoutState = pipDisplayLayoutState;
+ mSplitScreenControllerOptional = splitScreenControllerOptional;
+
+ mPipExpandAnimatorSupplier = PipExpandAnimator::new;
+ }
+
+ @Override
+ public WindowContainerTransaction handleRequest(@NonNull IBinder transition,
+ @NonNull TransitionRequestInfo request) {
+ // All Exit-via-Expand from PiP transitions are Shell initiated.
+ return null;
+ }
+
+ @Override
+ public boolean startAnimation(@NonNull IBinder transition,
+ @NonNull TransitionInfo info,
+ @NonNull SurfaceControl.Transaction startTransaction,
+ @NonNull SurfaceControl.Transaction finishTransaction,
+ @NonNull Transitions.TransitionFinishCallback finishCallback) {
+ switch (info.getType()) {
+ case TRANSIT_EXIT_PIP:
+ return startExpandAnimation(info, startTransaction, finishTransaction,
+ finishCallback);
+ case TRANSIT_EXIT_PIP_TO_SPLIT:
+ return startExpandToSplitAnimation(info, startTransaction, finishTransaction,
+ finishCallback);
+ }
+ return false;
+ }
+
+ @Override
+ public void mergeAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
+ @NonNull SurfaceControl.Transaction t, @NonNull IBinder mergeTarget,
+ @NonNull Transitions.TransitionFinishCallback finishCallback) {
+ end();
+ }
+
+ /**
+ * Ends the animation if such is running in the context of expanding out of PiP.
+ */
+ public void end() {
+ if (mTransitionAnimator != null && mTransitionAnimator.isRunning()) {
+ mTransitionAnimator.end();
+ mTransitionAnimator = null;
+ }
+ }
+
+ private boolean startExpandAnimation(@NonNull TransitionInfo info,
+ @NonNull SurfaceControl.Transaction startTransaction,
+ @NonNull SurfaceControl.Transaction finishTransaction,
+ @NonNull Transitions.TransitionFinishCallback finishCallback) {
+ WindowContainerToken pipToken = mPipTransitionState.getPipTaskToken();
+
+ TransitionInfo.Change pipChange = getChangeByToken(info, pipToken);
+ if (pipChange == null) {
+ // pipChange is null, check to see if we've reparented the PIP activity for
+ // the multi activity case. If so we should use the activity leash instead
+ for (TransitionInfo.Change change : info.getChanges()) {
+ if (change.getTaskInfo() == null
+ && change.getLastParent() != null
+ && change.getLastParent().equals(pipToken)) {
+ pipChange = change;
+ break;
+ }
+ }
+
+ // failsafe
+ if (pipChange == null) {
+ return false;
+ }
+ }
+ mFinishCallback = finishCallback;
+
+ // The parent change if we were in a multi-activity PiP; null if single activity PiP.
+ final TransitionInfo.Change parentBeforePip = pipChange.getTaskInfo() == null
+ ? getChangeByToken(info, pipChange.getParent()) : null;
+ if (parentBeforePip != null) {
+ // For multi activity, we need to manually set the leash layer
+ startTransaction.setLayer(parentBeforePip.getLeash(), Integer.MAX_VALUE - 1);
+ }
+
+ final Rect startBounds = pipChange.getStartAbsBounds();
+ final Rect endBounds = pipChange.getEndAbsBounds();
+ final SurfaceControl pipLeash = getLeash(pipChange);
+
+ PictureInPictureParams params = null;
+ if (pipChange.getTaskInfo() != null) {
+ // single activity
+ params = getPipParams(pipChange);
+ } else if (parentBeforePip != null && parentBeforePip.getTaskInfo() != null) {
+ // multi activity
+ params = getPipParams(parentBeforePip);
+ }
+ final Rect sourceRectHint = PipBoundsAlgorithm.getValidSourceHintRect(params, endBounds,
+ startBounds);
+
+ // We define delta = startRotation - endRotation, so we need to flip the sign.
+ final int delta = -getFixedRotationDelta(info, pipChange, mPipDisplayLayoutState);
+ if (delta != ROTATION_0) {
+ // Update PiP target change in place to prepare for fixed rotation;
+ handleExpandFixedRotation(pipChange, delta);
+ }
+
+ PipExpandAnimator animator = mPipExpandAnimatorSupplier.get(mContext, pipLeash,
+ startTransaction, finishTransaction, endBounds, startBounds, endBounds,
+ sourceRectHint, delta);
+ animator.setAnimationEndCallback(() -> {
+ if (parentBeforePip != null) {
+ // TODO b/377362511: Animate local leash instead to also handle letterbox case.
+ // For multi-activity, set the crop to be null
+ finishTransaction.setCrop(pipLeash, null);
+ }
+ finishTransition();
+ });
+ cacheAndStartTransitionAnimator(animator);
+ saveReentryState();
+ return true;
+ }
+
+ private boolean startExpandToSplitAnimation(@NonNull TransitionInfo info,
+ @NonNull SurfaceControl.Transaction startTransaction,
+ @NonNull SurfaceControl.Transaction finishTransaction,
+ @NonNull Transitions.TransitionFinishCallback finishCallback) {
+ WindowContainerToken pipToken = mPipTransitionState.getPipTaskToken();
+
+ // Expanding PiP to Split-screen makes sense only if we are dealing with multi-activity PiP
+ // and the lastParentBeforePip is still in one of the split-stages.
+ //
+ // This means we should be animating the PiP activity leash, since we do the reparenting
+ // of the PiP activity back to its original task in startWCT.
+ TransitionInfo.Change pipChange = null;
+ for (TransitionInfo.Change change : info.getChanges()) {
+ if (change.getTaskInfo() == null
+ && change.getLastParent() != null
+ && change.getLastParent().equals(pipToken)) {
+ pipChange = change;
+ break;
+ }
+ }
+ // failsafe
+ if (pipChange == null || pipChange.getLeash() == null) {
+ return false;
+ }
+ mFinishCallback = finishCallback;
+
+ // Get the original parent before PiP. If original task hosting the PiP activity was
+ // already visible, then it's not participating in this transition; in that case,
+ // parentBeforePip would be null.
+ final TransitionInfo.Change parentBeforePip = getChangeByToken(info, pipChange.getParent());
+
+ final Rect startBounds = pipChange.getStartAbsBounds();
+ final Rect endBounds = pipChange.getEndAbsBounds();
+ if (parentBeforePip != null) {
+ // Since we have the parent task amongst the targets, all PiP activity
+ // leash translations will be relative to the original task, NOT the root leash.
+ startBounds.offset(-parentBeforePip.getStartAbsBounds().left,
+ -parentBeforePip.getStartAbsBounds().top);
+ endBounds.offset(-parentBeforePip.getEndAbsBounds().left,
+ -parentBeforePip.getEndAbsBounds().top);
+ }
+
+ final SurfaceControl pipLeash = pipChange.getLeash();
+ PipExpandAnimator animator = mPipExpandAnimatorSupplier.get(mContext, pipLeash,
+ startTransaction, finishTransaction, endBounds, startBounds, endBounds,
+ null /* srcRectHint */, ROTATION_0 /* delta */);
+
+
+ mSplitScreenControllerOptional.ifPresent(splitController -> {
+ splitController.finishEnterSplitScreen(finishTransaction);
+ });
+
+ animator.setAnimationEndCallback(() -> {
+ if (parentBeforePip == null) {
+ // After PipExpandAnimator is done modifying finishTransaction, we need to make
+ // sure PiP activity leash is offset at origin relative to its task as we reparent
+ // targets back from the transition root leash.
+ finishTransaction.setPosition(pipLeash, 0, 0);
+ }
+ finishTransition();
+ });
+ cacheAndStartTransitionAnimator(animator);
+ saveReentryState();
+ return true;
+ }
+
+ private void finishTransition() {
+ final int currentState = mPipTransitionState.getState();
+ if (currentState != PipTransitionState.EXITING_PIP) {
+ ProtoLog.e(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "Unexpected state %s as we are finishing an exit-via-expand transition",
+ mPipTransitionState);
+ }
+ mPipTransitionState.setState(PipTransitionState.EXITED_PIP);
+
+ if (mFinishCallback != null) {
+ // Need to unset mFinishCallback first because onTransitionFinished can re-enter this
+ // handler if there is a pending PiP animation.
+ final Transitions.TransitionFinishCallback finishCallback = mFinishCallback;
+ mFinishCallback = null;
+ finishCallback.onTransitionFinished(null /* finishWct */);
+ }
+ }
+
+ private void handleExpandFixedRotation(TransitionInfo.Change outPipTaskChange, int delta) {
+ final Rect endBounds = outPipTaskChange.getEndAbsBounds();
+ final int width = endBounds.width();
+ final int height = endBounds.height();
+ final int left = endBounds.left;
+ final int top = endBounds.top;
+ int newTop, newLeft;
+
+ if (delta == Surface.ROTATION_90) {
+ newLeft = top;
+ newTop = -(left + width);
+ } else {
+ newLeft = -(height + top);
+ newTop = left;
+ }
+ // Modify the endBounds, rotating and placing them potentially off-screen, so that
+ // as we translate and rotate around the origin, we place them right into the target.
+ endBounds.set(newLeft, newTop, newLeft + height, newTop + width);
+ }
+
+ private void saveReentryState() {
+ float snapFraction = mPipBoundsAlgorithm.getSnapFraction(
+ mPipBoundsState.getBounds());
+ mPipBoundsState.saveReentryState(snapFraction);
+ }
+
+ private void cacheAndStartTransitionAnimator(@NonNull ValueAnimator animator) {
+ mTransitionAnimator = animator;
+ mTransitionAnimator.start();
+ }
+
+ @VisibleForTesting
+ interface PipExpandAnimatorSupplier {
+ PipExpandAnimator get(Context context,
+ @NonNull SurfaceControl leash,
+ SurfaceControl.Transaction startTransaction,
+ SurfaceControl.Transaction finishTransaction,
+ @NonNull Rect baseBounds,
+ @NonNull Rect startBounds,
+ @NonNull Rect endBounds,
+ @Nullable Rect sourceRectHint,
+ @Surface.Rotation int rotation);
+ }
+
+ @VisibleForTesting
+ void setPipExpandAnimatorSupplier(@NonNull PipExpandAnimatorSupplier supplier) {
+ mPipExpandAnimatorSupplier = supplier;
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/transition/PipTransitionUtils.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/transition/PipTransitionUtils.java
new file mode 100644
index 0000000..01cda6c
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/transition/PipTransitionUtils.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.pip2.phone.transition;
+
+import static android.app.WindowConfiguration.ROTATION_UNDEFINED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.view.Surface.ROTATION_0;
+
+import android.annotation.NonNull;
+import android.app.PictureInPictureParams;
+import android.view.Surface;
+import android.view.SurfaceControl;
+import android.window.TransitionInfo;
+import android.window.WindowContainerToken;
+
+import androidx.annotation.Nullable;
+
+import com.android.internal.util.Preconditions;
+import com.android.wm.shell.common.pip.PipDisplayLayoutState;
+
+/**
+ * A set of utility methods to help resolve PiP transitions.
+ */
+public class PipTransitionUtils {
+
+ /**
+ * @return change for a pinned mode task; null if no such task is in the list of changes.
+ */
+ @Nullable
+ public static TransitionInfo.Change getPipChange(TransitionInfo info) {
+ for (TransitionInfo.Change change : info.getChanges()) {
+ if (change.getTaskInfo() != null
+ && change.getTaskInfo().getWindowingMode() == WINDOWING_MODE_PINNED) {
+ return change;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @return change for a task with the provided token; null if no task with such token found.
+ */
+ @Nullable
+ public static TransitionInfo.Change getChangeByToken(TransitionInfo info,
+ WindowContainerToken token) {
+ for (TransitionInfo.Change change : info.getChanges()) {
+ if (change.getTaskInfo() != null
+ && change.getTaskInfo().getToken().equals(token)) {
+ return change;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @return the leash to interact with the container this change represents.
+ * @throws NullPointerException if the leash is null.
+ */
+ @NonNull
+ public static SurfaceControl getLeash(TransitionInfo.Change change) {
+ SurfaceControl leash = change.getLeash();
+ Preconditions.checkNotNull(leash, "Leash is null for change=" + change);
+ return leash;
+ }
+
+ /**
+ * Get the rotation delta in a potential fixed rotation transition.
+ *
+ * Whenever PiP participates in fixed rotation, its actual orientation isn't updated
+ * in the initial transition as per the async rotation convention.
+ *
+ * @param pipChange PiP change to verify that PiP task's rotation wasn't updated already.
+ * @param pipDisplayLayoutState display layout state that PiP component keeps track of.
+ */
+ @Surface.Rotation
+ public static int getFixedRotationDelta(@NonNull TransitionInfo info,
+ @NonNull TransitionInfo.Change pipChange,
+ @NonNull PipDisplayLayoutState pipDisplayLayoutState) {
+ TransitionInfo.Change fixedRotationChange = findFixedRotationChange(info);
+ int startRotation = pipChange.getStartRotation();
+ if (pipChange.getEndRotation() != ROTATION_UNDEFINED
+ && startRotation != pipChange.getEndRotation()) {
+ // If PiP change was collected along with the display change and the orientation change
+ // happened in sync with the PiP change, then do not treat this as fixed-rotation case.
+ return ROTATION_0;
+ }
+
+ int endRotation = fixedRotationChange != null
+ ? fixedRotationChange.getEndFixedRotation() : pipDisplayLayoutState.getRotation();
+ int delta = endRotation == ROTATION_UNDEFINED ? ROTATION_0
+ : startRotation - endRotation;
+ return delta;
+ }
+
+ /**
+ * Gets a change amongst the transition targets that is in a different final orientation than
+ * the display, signalling a potential fixed rotation transition.
+ */
+ @Nullable
+ public static TransitionInfo.Change findFixedRotationChange(@NonNull TransitionInfo info) {
+ for (int i = info.getChanges().size() - 1; i >= 0; --i) {
+ final TransitionInfo.Change change = info.getChanges().get(i);
+ if (change.getEndFixedRotation() != ROTATION_UNDEFINED) {
+ return change;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @return {@link PictureInPictureParams} provided by the client from the PiP change.
+ */
+ @NonNull
+ public static PictureInPictureParams getPipParams(@NonNull TransitionInfo.Change pipChange) {
+ return pipChange.getTaskInfo().pictureInPictureParams != null
+ ? pipChange.getTaskInfo().pictureInPictureParams
+ : new PictureInPictureParams.Builder().build();
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
index 4f2e028..2fa0966 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
@@ -381,7 +381,8 @@
private void notifyRunningTaskAppeared(RunningTaskInfo taskInfo) {
if (mListener == null
|| !shouldEnableRunningTasksForDesktopMode()
- || taskInfo.realActivity == null) {
+ || taskInfo.realActivity == null
+ || excludeTaskFromGeneratedList(taskInfo)) {
return;
}
try {
@@ -397,7 +398,8 @@
private void notifyRunningTaskChanged(RunningTaskInfo taskInfo) {
if (mListener == null
|| !shouldEnableRunningTasksForDesktopMode()
- || taskInfo.realActivity == null) {
+ || taskInfo.realActivity == null
+ || excludeTaskFromGeneratedList(taskInfo)) {
return;
}
try {
@@ -413,7 +415,8 @@
private void notifyRunningTaskVanished(RunningTaskInfo taskInfo) {
if (mListener == null
|| !shouldEnableRunningTasksForDesktopMode()
- || taskInfo.realActivity == null) {
+ || taskInfo.realActivity == null
+ || excludeTaskFromGeneratedList(taskInfo)) {
return;
}
try {
@@ -430,7 +433,8 @@
if (mListener == null
|| !DesktopModeFlags.ENABLE_TASK_STACK_OBSERVER_IN_SHELL.isTrue()
|| taskInfo.realActivity == null
- || enableShellTopTaskTracking()) {
+ || enableShellTopTaskTracking()
+ || excludeTaskFromGeneratedList(taskInfo)) {
return;
}
try {
@@ -447,7 +451,8 @@
if (mListener == null
|| !DesktopModeFlags.ENABLE_TASK_STACK_OBSERVER_IN_SHELL.isTrue()
|| taskInfo.realActivity == null
- || enableShellTopTaskTracking()) {
+ || enableShellTopTaskTracking()
+ || excludeTaskFromGeneratedList(taskInfo)) {
return;
}
try {
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 a969845..847a038 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
@@ -796,7 +796,8 @@
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
" unhandled root taskId=%d", taskInfo.taskId);
}
- } else if (TransitionUtil.isDividerBar(change)) {
+ } else if (TransitionUtil.isDividerBar(change)
+ || TransitionUtil.isDimLayer(change)) {
final RemoteAnimationTarget target = TransitionUtil.newTarget(change,
belowLayers - i, info, t, mLeashMap);
// Add this as a app and we will separate them on launcher side by window type.
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 a799b7f..77a7c54 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
@@ -40,11 +40,13 @@
import static com.android.wm.shell.Flags.enableFlexibleTwoAppSplit;
import static com.android.wm.shell.common.split.SplitLayout.PARALLAX_ALIGN_CENTER;
import static com.android.wm.shell.common.split.SplitLayout.PARALLAX_FLEX;
+import static com.android.wm.shell.common.split.SplitLayout.RESTING_DIM_LAYER;
import static com.android.wm.shell.common.split.SplitScreenUtils.reverseSplitPosition;
import static com.android.wm.shell.common.split.SplitScreenUtils.splitFailureMessage;
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN;
import static com.android.wm.shell.shared.TransitionUtil.isClosingType;
import static com.android.wm.shell.shared.TransitionUtil.isOpeningType;
+import static com.android.wm.shell.shared.split.SplitScreenConstants.FLAG_IS_DIM_LAYER;
import static com.android.wm.shell.shared.split.SplitScreenConstants.FLAG_IS_DIVIDER_BAR;
import static com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_2_10_90;
import static com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_2_50_50;
@@ -1315,6 +1317,10 @@
WindowContainerTransaction noFocus = new WindowContainerTransaction();
noFocus.setFocusable(mRootTaskInfo.token, false);
mSyncQueue.queue(noFocus);
+ // Remove touch layers, since offscreen apps coming onscreen will not need their touch
+ // layers anymore. populateTouchZones() is called in the end callback to inflate new touch
+ // layers in the appropriate places.
+ mSplitLayout.removeTouchZones();
mSplitLayout.playSwapAnimation(t, topLeftStage, bottomRightStage,
insets -> {
@@ -1335,6 +1341,7 @@
mSyncQueue.runInSync(st -> {
mSplitLayout.updateStateWithCurrentPosition();
updateSurfaceBounds(mSplitLayout, st, false /* applyResizingOffset */);
+ mSplitLayout.populateTouchZones();
// updateSurfaceBounds(), above, officially puts the two apps in their new
// stages. Starting on the next frame, all calculations are made using the
@@ -1824,6 +1831,14 @@
// Ensure divider surface are re-parented back into the hierarchy at the end of the
// transition. See Transition#buildFinishTransaction for more detail.
finishT.reparent(mSplitLayout.getDividerLeash(), mRootTaskLeash);
+ if (Flags.enableFlexibleSplit()) {
+ mStageOrderOperator.getActiveStages().forEach(stage -> {
+ finishT.reparent(stage.mDimLayer, stage.mRootLeash);
+ });
+ } else if (Flags.enableFlexibleTwoAppSplit()) {
+ finishT.reparent(mMainStage.mDimLayer, mMainStage.mRootLeash);
+ finishT.reparent(mSideStage.mDimLayer, mSideStage.mRootLeash);
+ }
updateSurfaceBounds(mSplitLayout, finishT, false /* applyResizingOffset */);
finishT.show(mRootTaskLeash);
@@ -3540,6 +3555,9 @@
finishEnterSplitScreen(finishT);
addDividerBarToTransition(info, true /* show */);
+ if (Flags.enableFlexibleTwoAppSplit()) {
+ addAllDimLayersToTransition(info, true /* show */);
+ }
return true;
}
@@ -3790,6 +3808,9 @@
}
addDividerBarToTransition(info, false /* show */);
+ if (Flags.enableFlexibleTwoAppSplit()) {
+ addAllDimLayersToTransition(info, false /* show */);
+ }
}
/** Call this when the recents animation canceled during split-screen. */
@@ -3836,6 +3857,19 @@
returnToApp);
mPausingTasks.clear();
if (returnToApp) {
+ // Reparent auxiliary surfaces (divider bar and dim layers) back onto their
+ // original roots.
+ if (Flags.enableFlexibleSplit()) {
+ mStageOrderOperator.getActiveStages().forEach(stage -> {
+ finishT.reparent(stage.mDimLayer, stage.mRootLeash);
+ finishT.setLayer(stage.mDimLayer, RESTING_DIM_LAYER);
+ });
+ } else if (Flags.enableFlexibleTwoAppSplit()) {
+ finishT.reparent(mMainStage.mDimLayer, mMainStage.mRootLeash);
+ finishT.reparent(mSideStage.mDimLayer, mSideStage.mRootLeash);
+ finishT.setLayer(mMainStage.mDimLayer, RESTING_DIM_LAYER);
+ finishT.setLayer(mSideStage.mDimLayer, RESTING_DIM_LAYER);
+ }
updateSurfaceBounds(mSplitLayout, finishT,
false /* applyResizingOffset */);
finishT.reparent(mSplitLayout.getDividerLeash(), mRootTaskLeash);
@@ -3902,6 +3936,39 @@
info.addChange(barChange);
}
+ /** Add dim layers to the transition, so that they can be hidden/shown when animation starts. */
+ private void addAllDimLayersToTransition(@NonNull TransitionInfo info, boolean show) {
+ if (Flags.enableFlexibleSplit()) {
+ List<StageTaskListener> stages = mStageOrderOperator.getActiveStages();
+ for (int i = 0; i < stages.size(); i++) {
+ final StageTaskListener stage = stages.get(i);
+ mSplitState.getCurrentLayout().get(i).roundOut(mTempRect1);
+ addDimLayerToTransition(info, show, stage, mTempRect1);
+ }
+ } else {
+ addDimLayerToTransition(info, show, mMainStage, getMainStageBounds());
+ addDimLayerToTransition(info, show, mSideStage, getSideStageBounds());
+ }
+ }
+
+ /** Adds a single dim layer to the given TransitionInfo. */
+ private void addDimLayerToTransition(@NonNull TransitionInfo info, boolean show,
+ StageTaskListener stage, Rect bounds) {
+ final SurfaceControl dimLayer = stage.mDimLayer;
+ if (dimLayer == null || !dimLayer.isValid()) {
+ Slog.w(TAG, "addDimLayerToTransition but leash was released or not created");
+ } else {
+ final TransitionInfo.Change change =
+ new TransitionInfo.Change(null /* token */, dimLayer);
+ change.setParent(mRootTaskInfo.token);
+ change.setStartAbsBounds(bounds);
+ change.setEndAbsBounds(bounds);
+ change.setMode(show ? TRANSIT_TO_FRONT : TRANSIT_TO_BACK);
+ change.setFlags(FLAG_IS_DIM_LAYER);
+ info.addChange(change);
+ }
+ }
+
@NeverCompile
@Override
public void dump(@NonNull PrintWriter pw, String prefix) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
index c5994f8..e132c5e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
@@ -681,7 +681,8 @@
// C. The background of the adaptive icon is grayscale, and the foreground of the
// adaptive icon forms a certain contrast with the theme color.
// D. Didn't specify icon background color.
- if (!iconColor.mIsBgComplex && mTmpAttrs.mIconBgColor == Color.TRANSPARENT
+ if (iconForeground != null
+ && !iconColor.mIsBgComplex && mTmpAttrs.mIconBgColor == Color.TRANSPARENT
&& (isRgbSimilarInHsv(mThemeColor, iconColor.mBgColor)
|| (iconColor.mIsBgGrayscale
&& !isRgbSimilarInHsv(mThemeColor, iconColor.mFgColor)))) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenWindowCreator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenWindowCreator.java
index cc962ac..caed194 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenWindowCreator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenWindowCreator.java
@@ -368,8 +368,12 @@
mStartingWindowRecordManager.addRecord(taskId, tView);
}
- private void removeWindowInner(@NonNull View decorView, boolean hideView) {
+ private void removeWindowInner(@NonNull View decorView, StartingWindowRemovalInfo info,
+ boolean hideView) {
requestTopUi(false);
+ if (info.windowAnimationLeash != null && info.windowAnimationLeash.isValid()) {
+ info.windowAnimationLeash.release();
+ }
if (decorView.getParent() == null) {
Slog.w(TAG, "This root view has no parent, never been added to a ViewRootImpl?");
return;
@@ -452,22 +456,22 @@
if (mSplashView == null) {
// shouldn't happen, the app window may be drawn earlier than starting window?
Slog.e(TAG, "Found empty splash screen, remove!");
- removeWindowInner(mRootView, false);
+ removeWindowInner(mRootView, info, false);
return true;
}
if (immediately
|| mSuggestType == STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN) {
- removeWindowInner(mRootView, false);
+ removeWindowInner(mRootView, info, false);
} else {
if (info.playRevealAnimation) {
mSplashscreenContentDrawer.applyExitAnimation(mSplashView,
info.windowAnimationLeash, info.mainFrame,
- () -> removeWindowInner(mRootView, true),
+ () -> removeWindowInner(mRootView, info, true),
mCreateTime, info.roundedCornerRadius);
} else {
// the SplashScreenView has been copied to client, hide the view to skip
// default exit animation
- removeWindowInner(mRootView, true);
+ removeWindowInner(mRootView, info, true);
}
}
return true;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
index dd5439a..7871179 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
@@ -339,6 +339,7 @@
taskInfo,
taskSurface,
mMainHandler,
+ mMainExecutor,
mBgExecutor,
mMainChoreographer,
mSyncQueue,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
index 23bb2aa..49510c8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
@@ -48,6 +48,8 @@
import android.view.ViewConfiguration;
import android.view.WindowInsets;
import android.view.WindowManager;
+import android.view.WindowManagerGlobal;
+import android.window.DesktopModeFlags;
import android.window.WindowContainerTransaction;
import com.android.internal.annotations.VisibleForTesting;
@@ -58,6 +60,7 @@
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.shared.annotations.ShellBackgroundThread;
+import com.android.wm.shell.shared.annotations.ShellMainThread;
import com.android.wm.shell.windowdecor.common.viewhost.WindowDecorViewHost;
import com.android.wm.shell.windowdecor.common.viewhost.WindowDecorViewHostSupplier;
import com.android.wm.shell.windowdecor.extension.TaskInfoKt;
@@ -69,6 +72,7 @@
*/
public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearLayout> {
private final Handler mHandler;
+ private final @ShellMainThread ShellExecutor mMainExecutor;
private final @ShellBackgroundThread ShellExecutor mBgExecutor;
private final Choreographer mChoreographer;
private final SyncTransactionQueue mSyncQueue;
@@ -90,6 +94,7 @@
RunningTaskInfo taskInfo,
SurfaceControl taskSurface,
Handler handler,
+ @ShellMainThread ShellExecutor mainExecutor,
@ShellBackgroundThread ShellExecutor bgExecutor,
Choreographer choreographer,
SyncTransactionQueue syncQueue,
@@ -97,6 +102,7 @@
super(context, userContext, displayController, taskOrganizer, taskInfo,
taskSurface, windowDecorViewHostSupplier);
mHandler = handler;
+ mMainExecutor = mainExecutor;
mBgExecutor = bgExecutor;
mChoreographer = choreographer;
mSyncQueue = syncQueue;
@@ -287,8 +293,14 @@
if (oldDecorationSurface != mDecorationContainerSurface || mDragResizeListener == null) {
closeDragResizeListener();
+ final ShellExecutor bgExecutor =
+ DesktopModeFlags.ENABLE_DRAG_RESIZE_SET_UP_IN_BG_THREAD.isTrue()
+ ? mBgExecutor : mMainExecutor;
mDragResizeListener = new DragResizeInputListener(
mContext,
+ WindowManagerGlobal.getWindowSession(),
+ mMainExecutor,
+ bgExecutor,
mTaskInfo,
mHandler,
mChoreographer,
@@ -299,17 +311,19 @@
mSurfaceControlTransactionSupplier,
mDisplayController);
}
-
+ final DragResizeInputListener newListener = mDragResizeListener;
final int touchSlop = ViewConfiguration.get(mResult.mRootView.getContext())
.getScaledTouchSlop();
-
final Resources res = mResult.mRootView.getResources();
- mDragResizeListener.setGeometry(new DragResizeWindowGeometry(0 /* taskCornerRadius */,
- new Size(mResult.mWidth, mResult.mHeight),
- getResizeEdgeHandleSize(res),
- getResizeHandleEdgeInset(res), getFineResizeCornerSize(res),
- getLargeResizeCornerSize(res), DragResizeWindowGeometry.DisabledEdge.NONE),
- touchSlop);
+ final DragResizeWindowGeometry newGeometry = new DragResizeWindowGeometry(
+ 0 /* taskCornerRadius */,
+ new Size(mResult.mWidth, mResult.mHeight),
+ getResizeEdgeHandleSize(res),
+ getResizeHandleEdgeInset(res), getFineResizeCornerSize(res),
+ getLargeResizeCornerSize(res), DragResizeWindowGeometry.DisabledEdge.NONE);
+ newListener.addInitializedCallback(() -> {
+ mDragResizeListener.setGeometry(newGeometry, touchSlop);
+ });
}
/**
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 add2c54..5a6ea21 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
@@ -984,7 +984,7 @@
mDesktopTasksController.onDesktopWindowClose(
wct, mDisplayId, decoration.mTaskInfo);
final IBinder transition = mTaskOperations.closeTask(mTaskToken, wct);
- if (transition != null && runOnTransitionStart != null) {
+ if (transition != null) {
runOnTransitionStart.invoke(transition);
}
}
@@ -1476,16 +1476,13 @@
relevantDecor.mTaskInfo.configuration.windowConfiguration.getBounds());
boolean dragFromStatusBarAllowed = false;
final int windowingMode = relevantDecor.mTaskInfo.getWindowingMode();
- if (DesktopModeStatus.canEnterDesktopMode(mContext)) {
+ if (DesktopModeStatus.canEnterDesktopMode(mContext)
+ || BubbleAnythingFlagHelper.enableBubbleToFullscreen()) {
// In proto2 any full screen or multi-window task can be dragged to
// freeform.
dragFromStatusBarAllowed = windowingMode == WINDOWING_MODE_FULLSCREEN
|| windowingMode == WINDOWING_MODE_MULTI_WINDOW;
}
- if (BubbleAnythingFlagHelper.enableBubbleToFullscreen()) {
- // TODO(b/388851898): add support for split screen (multi-window wm mode)
- dragFromStatusBarAllowed = windowingMode == WINDOWING_MODE_FULLSCREEN;
- }
final boolean shouldStartTransitionDrag =
relevantDecor.checkTouchEventInFocusedCaptionHandle(ev)
|| DesktopModeFlags.ENABLE_HANDLE_INPUT_FIX.isTrue();
@@ -1534,7 +1531,11 @@
// Do not create an indicator at all if we're not past transition height.
DisplayLayout layout = mDisplayController
.getDisplayLayout(relevantDecor.mTaskInfo.displayId);
- if (ev.getRawY() < 2 * layout.stableInsets().top
+ // It's possible task is not at the top of the screen (e.g. bottom of vertical
+ // Splitscreen)
+ final int taskTop = relevantDecor.mTaskInfo.configuration.windowConfiguration
+ .getBounds().top;
+ if (ev.getRawY() < 2 * layout.stableInsets().top + taskTop
&& mMoveToDesktopAnimator == null) {
return;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
index 3fb9463..dca376f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
@@ -68,6 +68,7 @@
import android.view.ViewConfiguration;
import android.view.WindowInsets;
import android.view.WindowManager;
+import android.view.WindowManagerGlobal;
import android.widget.ImageButton;
import android.window.DesktopModeFlags;
import android.window.TaskSnapshot;
@@ -479,7 +480,7 @@
if (shouldDelayUpdate) {
return;
}
- updateDragResizeListener(mDecorationContainerSurface, inFullImmersive);
+ updateDragResizeListenerIfNeeded(mDecorationContainerSurface, inFullImmersive);
}
@@ -587,7 +588,7 @@
closeMaximizeMenu();
notifyNoCaptionHandle();
}
- updateDragResizeListener(oldDecorationSurface, inFullImmersive);
+ updateDragResizeListenerIfNeeded(oldDecorationSurface, inFullImmersive);
updateMaximizeMenu(startT, inFullImmersive);
Trace.endSection(); // DesktopModeWindowDecoration#relayout
}
@@ -665,22 +666,42 @@
return mUserContext.getUser();
}
- private void updateDragResizeListener(SurfaceControl oldDecorationSurface,
+ private void updateDragResizeListenerIfNeeded(@Nullable SurfaceControl containerSurface,
boolean inFullImmersive) {
+ final boolean taskPositionChanged = !mTaskInfo.positionInParent.equals(mPositionInParent);
if (!isDragResizable(mTaskInfo, inFullImmersive)) {
- if (!mTaskInfo.positionInParent.equals(mPositionInParent)) {
+ if (taskPositionChanged) {
// We still want to track caption bar's exclusion region on a non-resizeable task.
updateExclusionRegion(inFullImmersive);
}
closeDragResizeListener();
return;
}
+ updateDragResizeListener(containerSurface,
+ (geometryChanged) -> {
+ if (geometryChanged || taskPositionChanged) {
+ updateExclusionRegion(inFullImmersive);
+ }
+ });
+ }
- if (oldDecorationSurface != mDecorationContainerSurface || mDragResizeListener == null) {
+ private void updateDragResizeListener(@Nullable SurfaceControl containerSurface,
+ Consumer<Boolean> onUpdateFinished) {
+ final boolean containerSurfaceChanged = containerSurface != mDecorationContainerSurface;
+ final boolean isFirstDragResizeListener = mDragResizeListener == null;
+ final boolean shouldCreateListener = containerSurfaceChanged || isFirstDragResizeListener;
+ if (containerSurfaceChanged) {
closeDragResizeListener();
- Trace.beginSection("DesktopModeWindowDecoration#relayout-DragResizeInputListener");
+ }
+ if (shouldCreateListener) {
+ final ShellExecutor bgExecutor =
+ DesktopModeFlags.ENABLE_DRAG_RESIZE_SET_UP_IN_BG_THREAD.isTrue()
+ ? mBgExecutor : mMainExecutor;
mDragResizeListener = new DragResizeInputListener(
mContext,
+ WindowManagerGlobal.getWindowSession(),
+ mMainExecutor,
+ bgExecutor,
mTaskInfo,
mHandler,
mChoreographer,
@@ -691,24 +712,20 @@
mSurfaceControlTransactionSupplier,
mDisplayController,
mDesktopModeEventLogger);
- Trace.endSection();
}
-
+ final DragResizeInputListener newListener = mDragResizeListener;
final int touchSlop = ViewConfiguration.get(mResult.mRootView.getContext())
.getScaledTouchSlop();
-
- // If either task geometry or position have changed, update this task's
- // exclusion region listener
final Resources res = mResult.mRootView.getResources();
- if (mDragResizeListener.setGeometry(
- new DragResizeWindowGeometry(mRelayoutParams.mCornerRadius,
- new Size(mResult.mWidth, mResult.mHeight),
- getResizeEdgeHandleSize(res), getResizeHandleEdgeInset(res),
- getFineResizeCornerSize(res), getLargeResizeCornerSize(res),
- mDisabledResizingEdge), touchSlop)
- || !mTaskInfo.positionInParent.equals(mPositionInParent)) {
- updateExclusionRegion(inFullImmersive);
- }
+ final DragResizeWindowGeometry newGeometry = new DragResizeWindowGeometry(
+ mRelayoutParams.mCornerRadius,
+ new Size(mResult.mWidth, mResult.mHeight),
+ getResizeEdgeHandleSize(res), getResizeHandleEdgeInset(res),
+ getFineResizeCornerSize(res), getLargeResizeCornerSize(res),
+ mDisabledResizingEdge);
+ newListener.addInitializedCallback(() -> {
+ onUpdateFinished.accept(newListener.setGeometry(newGeometry, touchSlop));
+ });
}
private static boolean isDragResizable(ActivityManager.RunningTaskInfo taskInfo,
@@ -803,8 +820,7 @@
if (!mTaskInfo.isVisible()) {
closeMaximizeMenu();
} else {
- final int menuWidth = calculateMaximizeMenuWidth();
- mMaximizeMenu.positionMenu(calculateMaximizeMenuPosition(menuWidth), startT);
+ mMaximizeMenu.positionMenu(startT);
}
}
@@ -1069,27 +1085,7 @@
return Resources.ID_NULL;
}
- private int calculateMaximizeMenuWidth() {
- final boolean showImmersive = DesktopModeFlags.ENABLE_FULLY_IMMERSIVE_IN_DESKTOP.isTrue()
- && TaskInfoKt.getRequestingImmersive(mTaskInfo);
- final boolean showMaximize = true;
- final boolean showSnaps = mTaskInfo.isResizeable;
- int showCount = 0;
- if (showImmersive) showCount++;
- if (showMaximize) showCount++;
- if (showSnaps) showCount++;
- return switch (showCount) {
- case 1 -> loadDimensionPixelSize(mContext.getResources(),
- R.dimen.desktop_mode_maximize_menu_width_one_options);
- case 2 -> loadDimensionPixelSize(mContext.getResources(),
- R.dimen.desktop_mode_maximize_menu_width_two_options);
- case 3 -> loadDimensionPixelSize(mContext.getResources(),
- R.dimen.desktop_mode_maximize_menu_width_three_options);
- default -> throw new IllegalArgumentException("");
- };
- }
-
- private PointF calculateMaximizeMenuPosition(int menuWidth) {
+ private PointF calculateMaximizeMenuPosition(int menuWidth, int menuHeight) {
final PointF position = new PointF();
final Resources resources = mContext.getResources();
final DisplayLayout displayLayout =
@@ -1105,9 +1101,6 @@
final int[] maximizeButtonLocation = new int[2];
maximizeWindowButton.getLocationInWindow(maximizeButtonLocation);
- final int menuHeight = loadDimensionPixelSize(
- resources, R.dimen.desktop_mode_maximize_menu_height);
-
float menuLeft = (mPositionInParent.x + maximizeButtonLocation[0] - ((float) (menuWidth
- maximizeWindowButton.getWidth()) / 2));
float menuTop = (mPositionInParent.y + captionHeight);
@@ -1294,17 +1287,16 @@
* Create and display maximize menu window
*/
void createMaximizeMenu() {
- final int menuWidth = calculateMaximizeMenuWidth();
mMaximizeMenu = mMaximizeMenuFactory.create(mSyncQueue, mRootTaskDisplayAreaOrganizer,
mDisplayController, mTaskInfo, mContext,
- calculateMaximizeMenuPosition(menuWidth), mSurfaceControlTransactionSupplier);
+ (width, height) -> calculateMaximizeMenuPosition(width, height),
+ mSurfaceControlTransactionSupplier);
mMaximizeMenu.show(
/* isTaskInImmersiveMode= */
DesktopModeFlags.ENABLE_FULLY_IMMERSIVE_IN_DESKTOP.isTrue()
&& mDesktopUserRepositories.getProfile(mTaskInfo.userId)
.isTaskInFullImmersiveState(mTaskInfo.taskId),
- /* menuWidth= */ menuWidth,
/* showImmersiveOption= */
DesktopModeFlags.ENABLE_FULLY_IMMERSIVE_IN_DESKTOP.isTrue()
&& TaskInfoKt.getRequestingImmersive(mTaskInfo),
@@ -1736,7 +1728,8 @@
*/
private Region getGlobalExclusionRegion(boolean inFullImmersive) {
Region exclusionRegion;
- if (mDragResizeListener != null && isDragResizable(mTaskInfo, inFullImmersive)) {
+ if (mDragResizeListener != null
+ && isDragResizable(mTaskInfo, inFullImmersive)) {
exclusionRegion = mDragResizeListener.getCornersRegion();
} else {
exclusionRegion = new Region();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
index b531079..7a4a834 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
@@ -43,6 +43,7 @@
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
+import android.os.Trace;
import android.util.Size;
import android.view.Choreographer;
import android.view.IWindowSession;
@@ -54,14 +55,19 @@
import android.view.SurfaceControl;
import android.view.View;
import android.view.ViewConfiguration;
-import android.view.WindowManagerGlobal;
import android.window.InputTransferToken;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayLayout;
+import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.desktopmode.DesktopModeEventLogger;
+import com.android.wm.shell.shared.annotations.ShellBackgroundThread;
+import com.android.wm.shell.shared.annotations.ShellMainThread;
+import java.util.ArrayList;
+import java.util.List;
import java.util.function.Consumer;
import java.util.function.Supplier;
@@ -73,28 +79,45 @@
*/
class DragResizeInputListener implements AutoCloseable {
private static final String TAG = "DragResizeInputListener";
- private final IWindowSession mWindowSession = WindowManagerGlobal.getWindowSession();
+ private final IWindowSession mWindowSession;
+ private final TaskResizeInputEventReceiverFactory mEventReceiverFactory;
+ private final Supplier<SurfaceControl.Builder> mSurfaceControlBuilderSupplier;
private final Supplier<SurfaceControl.Transaction> mSurfaceControlTransactionSupplier;
private final int mDisplayId;
- private final IBinder mClientToken;
+ @VisibleForTesting
+ final IBinder mClientToken;
private final SurfaceControl mDecorationSurface;
- private final InputChannel mInputChannel;
- private final TaskResizeInputEventReceiver mInputEventReceiver;
+ private InputChannel mInputChannel;
+ private TaskResizeInputEventReceiver mInputEventReceiver;
private final Context mContext;
+ private final @ShellBackgroundThread ShellExecutor mBgExecutor;
private final RunningTaskInfo mTaskInfo;
- private final SurfaceControl mInputSinkSurface;
- private final IBinder mSinkClientToken;
- private final InputChannel mSinkInputChannel;
+ private final Handler mHandler;
+ private final Choreographer mChoreographer;
+ private SurfaceControl mInputSinkSurface;
+ @VisibleForTesting
+ final IBinder mSinkClientToken;
+ private InputChannel mSinkInputChannel;
private final DisplayController mDisplayController;
+ /** TODO: b/396490344 - this desktop-specific class should be abstracted out of here. */
private final DesktopModeEventLogger mDesktopModeEventLogger;
+ private final DragPositioningCallback mDragPositioningCallback;
private final Region mTouchRegion = new Region();
+ private final List<Runnable> mOnInitializedCallbacks = new ArrayList<>();
+
+ private final Runnable mInitInputChannels;
+ private boolean mClosed = false;
DragResizeInputListener(
Context context,
+ IWindowSession windowSession,
+ @ShellMainThread ShellExecutor mainExecutor,
+ @ShellBackgroundThread ShellExecutor bgExecutor,
+ TaskResizeInputEventReceiverFactory eventReceiverFactory,
RunningTaskInfo taskInfo,
Handler handler,
Choreographer choreographer,
@@ -106,74 +129,93 @@
DisplayController displayController,
DesktopModeEventLogger desktopModeEventLogger) {
mContext = context;
+ mWindowSession = windowSession;
+ mBgExecutor = bgExecutor;
+ mEventReceiverFactory = eventReceiverFactory;
mTaskInfo = taskInfo;
- mSurfaceControlTransactionSupplier = surfaceControlTransactionSupplier;
+ mHandler = handler;
+ mChoreographer = choreographer;
mDisplayId = displayId;
mDecorationSurface = decorationSurface;
+ mDragPositioningCallback = callback;
+ mSurfaceControlBuilderSupplier = surfaceControlBuilderSupplier;
+ mSurfaceControlTransactionSupplier = surfaceControlTransactionSupplier;
mDisplayController = displayController;
mDesktopModeEventLogger = desktopModeEventLogger;
mClientToken = new Binder();
- final InputTransferToken inputTransferToken = new InputTransferToken();
- mInputChannel = new InputChannel();
- try {
- mWindowSession.grantInputChannel(
- mDisplayId,
- mDecorationSurface,
- mClientToken,
- null /* hostInputToken */,
- FLAG_NOT_FOCUSABLE,
- PRIVATE_FLAG_TRUSTED_OVERLAY,
- INPUT_FEATURE_SPY,
- TYPE_APPLICATION,
- null /* windowToken */,
- inputTransferToken,
- TAG + " of " + decorationSurface.toString(),
- mInputChannel);
- } catch (RemoteException e) {
- e.rethrowFromSystemServer();
- }
-
- mInputEventReceiver = new TaskResizeInputEventReceiver(context, mTaskInfo, mInputChannel,
- callback,
- handler, choreographer, () -> {
- final DisplayLayout layout = mDisplayController.getDisplayLayout(mDisplayId);
- return new Size(layout.width(), layout.height());
- }, this::updateSinkInputChannel, mDesktopModeEventLogger);
- mInputEventReceiver.setTouchSlop(ViewConfiguration.get(context).getScaledTouchSlop());
-
- mInputSinkSurface = surfaceControlBuilderSupplier.get()
- .setName("TaskInputSink of " + decorationSurface)
- .setContainerLayer()
- .setParent(mDecorationSurface)
- .setCallsite("DragResizeInputListener.constructor")
- .build();
- mSurfaceControlTransactionSupplier.get()
- .setLayer(mInputSinkSurface, WindowDecoration.INPUT_SINK_Z_ORDER)
- .show(mInputSinkSurface)
- .apply();
mSinkClientToken = new Binder();
- mSinkInputChannel = new InputChannel();
- try {
- mWindowSession.grantInputChannel(
- mDisplayId,
- mInputSinkSurface,
- mSinkClientToken,
- null /* hostInputToken */,
- FLAG_NOT_FOCUSABLE,
- 0 /* privateFlags */,
- INPUT_FEATURE_NO_INPUT_CHANNEL,
- TYPE_INPUT_CONSUMER,
- null /* windowToken */,
- inputTransferToken,
- "TaskInputSink of " + decorationSurface,
- mSinkInputChannel);
- } catch (RemoteException e) {
- e.rethrowFromSystemServer();
- }
+
+ // Setting up input channels for both the resize listener and the input sink requires
+ // multiple blocking binder calls, so it's moved to a bg thread to keep the shell.main
+ // thread free.
+ // The input event receiver must be created back in the shell.main thread though because
+ // its geometry and util methods are updated/queried from the shell.main thread.
+ mInitInputChannels = () -> {
+ final InputSetUpResult result = setUpInputChannels(mDisplayId, mWindowSession,
+ mDecorationSurface, mClientToken, mSinkClientToken,
+ mSurfaceControlBuilderSupplier,
+ mSurfaceControlTransactionSupplier);
+ mainExecutor.execute(() -> {
+ if (mClosed) {
+ return;
+ }
+ mInputSinkSurface = result.mInputSinkSurface;
+ mInputChannel = result.mInputChannel;
+ mSinkInputChannel = result.mSinkInputChannel;
+ Trace.beginSection("DragResizeInputListener#ctor-initReceiver");
+ mInputEventReceiver = mEventReceiverFactory.create(
+ mContext,
+ mTaskInfo,
+ mInputChannel,
+ mDragPositioningCallback,
+ mHandler,
+ mChoreographer,
+ () -> {
+ final DisplayLayout layout =
+ mDisplayController.getDisplayLayout(mDisplayId);
+ return new Size(layout.width(), layout.height());
+ },
+ this::updateSinkInputChannel,
+ mDesktopModeEventLogger);
+ mInputEventReceiver.setTouchSlop(
+ ViewConfiguration.get(mContext).getScaledTouchSlop());
+ for (Runnable initCallback : mOnInitializedCallbacks) {
+ initCallback.run();
+ }
+ mOnInitializedCallbacks.clear();
+ Trace.endSection();
+ });
+ };
+ bgExecutor.execute(mInitInputChannels);
}
DragResizeInputListener(
Context context,
+ IWindowSession windowSession,
+ @ShellMainThread ShellExecutor mainExecutor,
+ @ShellBackgroundThread ShellExecutor bgExecutor,
+ RunningTaskInfo taskInfo,
+ Handler handler,
+ Choreographer choreographer,
+ int displayId,
+ SurfaceControl decorationSurface,
+ DragPositioningCallback callback,
+ Supplier<SurfaceControl.Builder> surfaceControlBuilderSupplier,
+ Supplier<SurfaceControl.Transaction> surfaceControlTransactionSupplier,
+ DisplayController displayController,
+ DesktopModeEventLogger desktopModeEventLogger) {
+ this(context, windowSession, mainExecutor, bgExecutor,
+ new DefaultTaskResizeInputEventReceiverFactory(), taskInfo,
+ handler, choreographer, displayId, decorationSurface, callback,
+ surfaceControlBuilderSupplier, surfaceControlTransactionSupplier,
+ displayController, desktopModeEventLogger);
+ }
+
+ DragResizeInputListener(
+ Context context,
+ IWindowSession windowSession,
+ @ShellMainThread ShellExecutor mainExecutor,
+ @ShellBackgroundThread ShellExecutor bgExecutor,
RunningTaskInfo taskInfo,
Handler handler,
Choreographer choreographer,
@@ -183,9 +225,84 @@
Supplier<SurfaceControl.Builder> surfaceControlBuilderSupplier,
Supplier<SurfaceControl.Transaction> surfaceControlTransactionSupplier,
DisplayController displayController) {
- this(context, taskInfo, handler, choreographer, displayId, decorationSurface, callback,
- surfaceControlBuilderSupplier, surfaceControlTransactionSupplier, displayController,
- new DesktopModeEventLogger());
+ this(context, windowSession, mainExecutor, bgExecutor, taskInfo,
+ handler, choreographer, displayId, decorationSurface, callback,
+ surfaceControlBuilderSupplier, surfaceControlTransactionSupplier,
+ displayController, new DesktopModeEventLogger());
+ }
+
+ /**
+ * Registers a callback to be invoked when the input listener has finished initializing. If
+ * already finished, the callback will be invoked immediately.
+ */
+ void addInitializedCallback(Runnable onReady) {
+ if (mInputEventReceiver != null) {
+ onReady.run();
+ return;
+ }
+ mOnInitializedCallbacks.add(onReady);
+ }
+
+ @ShellBackgroundThread
+ private static InputSetUpResult setUpInputChannels(
+ int displayId,
+ @NonNull IWindowSession windowSession,
+ @NonNull SurfaceControl decorationSurface,
+ @NonNull IBinder clientToken,
+ @NonNull IBinder sinkClientToken,
+ @NonNull Supplier<SurfaceControl.Builder> surfaceControlBuilderSupplier,
+ @NonNull Supplier<SurfaceControl.Transaction> surfaceControlTransactionSupplier) {
+ Trace.beginSection("DragResizeInputListener#setUpInputChannels");
+ final InputTransferToken inputTransferToken = new InputTransferToken();
+ final InputChannel inputChannel = new InputChannel();
+ final InputChannel sinkInputChannel = new InputChannel();
+ try {
+ windowSession.grantInputChannel(
+ displayId,
+ decorationSurface,
+ clientToken,
+ null /* hostInputToken */,
+ FLAG_NOT_FOCUSABLE,
+ PRIVATE_FLAG_TRUSTED_OVERLAY,
+ INPUT_FEATURE_SPY,
+ TYPE_APPLICATION,
+ null /* windowToken */,
+ inputTransferToken,
+ TAG + " of " + decorationSurface,
+ inputChannel);
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
+
+ final SurfaceControl inputSinkSurface = surfaceControlBuilderSupplier.get()
+ .setName("TaskInputSink of " + decorationSurface)
+ .setContainerLayer()
+ .setParent(decorationSurface)
+ .setCallsite("DragResizeInputListener.setUpInputChannels")
+ .build();
+ surfaceControlTransactionSupplier.get()
+ .setLayer(inputSinkSurface, WindowDecoration.INPUT_SINK_Z_ORDER)
+ .show(inputSinkSurface)
+ .apply();
+ try {
+ windowSession.grantInputChannel(
+ displayId,
+ inputSinkSurface,
+ sinkClientToken,
+ null /* hostInputToken */,
+ FLAG_NOT_FOCUSABLE,
+ 0 /* privateFlags */,
+ INPUT_FEATURE_NO_INPUT_CHANNEL,
+ TYPE_INPUT_CONSUMER,
+ null /* windowToken */,
+ inputTransferToken,
+ "TaskInputSink of " + decorationSurface,
+ sinkInputChannel);
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
+ Trace.endSection();
+ return new InputSetUpResult(inputSinkSurface, inputChannel, sinkInputChannel);
}
/**
@@ -268,35 +385,101 @@
}
boolean shouldHandleEvent(@NonNull MotionEvent e, @NonNull Point offset) {
- return mInputEventReceiver.shouldHandleEvent(e, offset);
+ return mInputEventReceiver != null && mInputEventReceiver.shouldHandleEvent(e, offset);
}
boolean isHandlingDragResize() {
- return mInputEventReceiver.isHandlingEvents();
+ return mInputEventReceiver != null && mInputEventReceiver.isHandlingEvents();
}
@Override
public void close() {
- mInputEventReceiver.dispose();
- mInputChannel.dispose();
- try {
- mWindowSession.remove(mClientToken);
- } catch (RemoteException e) {
- e.rethrowFromSystemServer();
+ mClosed = true;
+ if (mInitInputChannels != null) {
+ mBgExecutor.removeCallbacks(mInitInputChannels);
+ }
+ if (mInputEventReceiver != null) {
+ mInputEventReceiver.dispose();
+ }
+ if (mInputChannel != null) {
+ mInputChannel.dispose();
+ }
+ if (mSinkInputChannel != null) {
+ mSinkInputChannel.dispose();
}
- mSinkInputChannel.dispose();
- try {
- mWindowSession.remove(mSinkClientToken);
- } catch (RemoteException e) {
- e.rethrowFromSystemServer();
+ if (mInputSinkSurface != null) {
+ mSurfaceControlTransactionSupplier.get()
+ .remove(mInputSinkSurface)
+ .apply();
}
- mSurfaceControlTransactionSupplier.get()
- .remove(mInputSinkSurface)
- .apply();
+
+ mBgExecutor.execute(() -> {
+ try {
+ mWindowSession.remove(mClientToken);
+ mWindowSession.remove(mSinkClientToken);
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
+ });
}
- private static class TaskResizeInputEventReceiver extends InputEventReceiver implements
+ private static class InputSetUpResult {
+ final @NonNull SurfaceControl mInputSinkSurface;
+ final @NonNull InputChannel mInputChannel;
+ final @NonNull InputChannel mSinkInputChannel;
+
+ InputSetUpResult(@NonNull SurfaceControl inputSinkSurface,
+ @NonNull InputChannel inputChannel,
+ @NonNull InputChannel sinkInputChannel) {
+ mInputSinkSurface = inputSinkSurface;
+ mInputChannel = inputChannel;
+ mSinkInputChannel = sinkInputChannel;
+ }
+ }
+
+ /** A factory that creates {@link TaskResizeInputEventReceiver}s. */
+ interface TaskResizeInputEventReceiverFactory {
+ @NonNull
+ TaskResizeInputEventReceiver create(
+ @NonNull Context context,
+ @NonNull RunningTaskInfo taskInfo,
+ @NonNull InputChannel inputChannel,
+ @NonNull DragPositioningCallback callback,
+ @NonNull Handler handler,
+ @NonNull Choreographer choreographer,
+ @NonNull Supplier<Size> displayLayoutSizeSupplier,
+ @NonNull Consumer<Region> touchRegionConsumer,
+ @NonNull DesktopModeEventLogger desktopModeEventLogger
+ );
+ }
+
+ /** A default implementation of {@link TaskResizeInputEventReceiverFactory}. */
+ static class DefaultTaskResizeInputEventReceiverFactory
+ implements TaskResizeInputEventReceiverFactory {
+ @Override
+ @NonNull
+ public TaskResizeInputEventReceiver create(
+ @NonNull Context context,
+ @NonNull RunningTaskInfo taskInfo,
+ @NonNull InputChannel inputChannel,
+ @NonNull DragPositioningCallback callback,
+ @NonNull Handler handler,
+ @NonNull Choreographer choreographer,
+ @NonNull Supplier<Size> displayLayoutSizeSupplier,
+ @NonNull Consumer<Region> touchRegionConsumer,
+ @NonNull DesktopModeEventLogger desktopModeEventLogger) {
+ return new TaskResizeInputEventReceiver(context, taskInfo, inputChannel, callback,
+ handler, choreographer, displayLayoutSizeSupplier, touchRegionConsumer,
+ desktopModeEventLogger);
+ }
+ }
+
+ /**
+ * An input event receiver to handle motion events on the task's corners and edges for
+ * drag-resizing, as well as keeping the input sink updated.
+ */
+ static class TaskResizeInputEventReceiver extends InputEventReceiver implements
DragDetector.MotionEventHandler {
@NonNull private final Context mContext;
@NonNull private final RunningTaskInfo mTaskInfo;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt
index 38accce..ad3525a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt
@@ -90,7 +90,7 @@
private val displayController: DisplayController,
private val taskInfo: RunningTaskInfo,
private val decorWindowContext: Context,
- private val menuPosition: PointF,
+ private val positionSupplier: (Int, Int) -> PointF,
private val transactionSupplier: Supplier<Transaction> = Supplier { Transaction() }
) {
private var maximizeMenu: AdditionalViewHostViewContainer? = null
@@ -100,19 +100,19 @@
private val cornerRadius = loadDimensionPixelSize(
R.dimen.desktop_mode_maximize_menu_corner_radius
).toFloat()
- private val menuHeight = loadDimensionPixelSize(R.dimen.desktop_mode_maximize_menu_height)
+ private lateinit var menuPosition: PointF
private val menuPadding = loadDimensionPixelSize(R.dimen.desktop_mode_menu_padding)
/** Position the menu relative to the caption's position. */
- fun positionMenu(position: PointF, t: Transaction) {
- menuPosition.set(position)
+ fun positionMenu(t: Transaction) {
+ menuPosition = positionSupplier(maximizeMenuView?.measureWidth() ?: 0,
+ maximizeMenuView?.measureHeight() ?: 0)
t.setPosition(leash, menuPosition.x, menuPosition.y)
}
/** Creates and shows the maximize window. */
fun show(
isTaskInImmersiveMode: Boolean,
- menuWidth: Int,
showImmersiveOption: Boolean,
showSnapOptions: Boolean,
onMaximizeOrRestoreClickListener: () -> Unit,
@@ -125,7 +125,6 @@
if (maximizeMenu != null) return
createMaximizeMenu(
isTaskInImmersiveMode = isTaskInImmersiveMode,
- menuWidth = menuWidth,
showImmersiveOption = showImmersiveOption,
showSnapOptions = showSnapOptions,
onMaximizeClickListener = onMaximizeOrRestoreClickListener,
@@ -161,7 +160,6 @@
/** Create a maximize menu that is attached to the display area. */
private fun createMaximizeMenu(
isTaskInImmersiveMode: Boolean,
- menuWidth: Int,
showImmersiveOption: Boolean,
showSnapOptions: Boolean,
onMaximizeClickListener: () -> Unit,
@@ -178,16 +176,6 @@
.setName("Maximize Menu")
.setContainerLayer()
.build()
- val lp = WindowManager.LayoutParams(
- menuWidth,
- menuHeight,
- WindowManager.LayoutParams.TYPE_APPLICATION,
- WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
- or WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
- PixelFormat.TRANSPARENT
- )
- lp.title = "Maximize Menu for Task=" + taskInfo.taskId
- lp.setTrustedOverlay()
val windowManager = WindowlessWindowManager(
taskInfo.configuration,
leash,
@@ -207,7 +195,6 @@
MaximizeMenuView.ImmersiveConfig.Hidden
},
showSnapOptions = showSnapOptions,
- menuHeight = menuHeight,
menuPadding = menuPadding,
).also { menuView ->
menuView.bind(taskInfo)
@@ -217,6 +204,19 @@
menuView.onRightSnapClickListener = onRightSnapClickListener
menuView.onMenuHoverListener = onHoverListener
menuView.onOutsideTouchListener = onOutsideTouchListener
+ val menuWidth = menuView.measureWidth()
+ val menuHeight = menuView.measureHeight()
+ menuPosition = positionSupplier(menuWidth, menuHeight)
+ val lp = WindowManager.LayoutParams(
+ menuWidth.toInt(),
+ menuHeight.toInt(),
+ WindowManager.LayoutParams.TYPE_APPLICATION,
+ WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+ or WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
+ PixelFormat.TRANSPARENT
+ )
+ lp.title = "Maximize Menu for Task=" + taskInfo.taskId
+ lp.setTrustedOverlay()
viewHost.setView(menuView.rootView, lp)
}
@@ -268,7 +268,6 @@
private val sizeToggleDirection: SizeToggleDirection,
immersiveConfig: ImmersiveConfig,
showSnapOptions: Boolean,
- private val menuHeight: Int,
private val menuPadding: Int
) {
val rootView = LayoutInflater.from(context)
@@ -583,7 +582,7 @@
// the menu.
val value = animatedValue as Float
val topPadding = menuPadding -
- ((1 - value) * menuHeight).toInt()
+ ((1 - value) * measureHeight()).toInt()
container.setPadding(menuPadding, topPadding,
menuPadding, menuPadding)
}
@@ -604,7 +603,7 @@
}
},
ObjectAnimator.ofFloat(rootView, TRANSLATION_Y,
- (STARTING_MENU_HEIGHT_SCALE - 1) * menuHeight, 0f).apply {
+ (STARTING_MENU_HEIGHT_SCALE - 1) * measureHeight(), 0f).apply {
duration = OPEN_MENU_HEIGHT_ANIMATION_DURATION_MS
interpolator = EMPHASIZED_DECELERATE
},
@@ -667,7 +666,7 @@
// the menu.
val value = animatedValue as Float
val topPadding = menuPadding -
- ((1 - value) * menuHeight).toInt()
+ ((1 - value) * measureHeight()).toInt()
container.setPadding(menuPadding, topPadding,
menuPadding, menuPadding)
}
@@ -688,7 +687,7 @@
}
},
ObjectAnimator.ofFloat(rootView, TRANSLATION_Y,
- 0f, (STARTING_MENU_HEIGHT_SCALE - 1) * menuHeight).apply {
+ 0f, (STARTING_MENU_HEIGHT_SCALE - 1) * measureHeight()).apply {
duration = CLOSE_MENU_HEIGHT_ANIMATION_DURATION_MS
interpolator = FAST_OUT_LINEAR_IN
},
@@ -792,6 +791,18 @@
)
}
+ /** Measure width of the root view of this menu. */
+ fun measureWidth() : Int {
+ rootView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
+ return rootView.getMeasuredWidth()
+ }
+
+ /** Measure height of the root view of this menu. */
+ fun measureHeight() : Int {
+ rootView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
+ return rootView.getMeasuredHeight()
+ }
+
private fun deactivateSnapOptions() {
// TODO(b/346440693): the background/colorStateList set on these buttons is overridden
// to a static resource & color on manually tracked hover events, which defeats the
@@ -1036,7 +1047,7 @@
displayController: DisplayController,
taskInfo: RunningTaskInfo,
decorWindowContext: Context,
- menuPosition: PointF,
+ positionSupplier: (Int, Int) -> PointF,
transactionSupplier: Supplier<Transaction>
): MaximizeMenu
}
@@ -1049,7 +1060,7 @@
displayController: DisplayController,
taskInfo: RunningTaskInfo,
decorWindowContext: Context,
- menuPosition: PointF,
+ positionSupplier: (Int, Int) -> PointF,
transactionSupplier: Supplier<Transaction>
): MaximizeMenu {
return MaximizeMenu(
@@ -1058,7 +1069,7 @@
displayController,
taskInfo,
decorWindowContext,
- menuPosition,
+ positionSupplier,
transactionSupplier
)
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
index 25dadfd..4002dc5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
@@ -361,6 +361,8 @@
}
outResult.mRootView = rootView;
+ final boolean fontScaleChanged = mWindowDecorConfig != null
+ && mWindowDecorConfig.fontScale != mTaskInfo.configuration.fontScale;
final int oldDensityDpi = mWindowDecorConfig != null
? mWindowDecorConfig.densityDpi : DENSITY_DPI_UNDEFINED;
final int oldNightMode = mWindowDecorConfig != null
@@ -375,7 +377,8 @@
|| mDisplay.getDisplayId() != mTaskInfo.displayId
|| oldLayoutResId != mLayoutResId
|| oldNightMode != newNightMode
- || mDecorWindowContext == null) {
+ || mDecorWindowContext == null
+ || fontScaleChanged) {
releaseViews(wct);
if (!obtainDisplayOrRegisterListener()) {
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
index 4a09614..a5592f8 100644
--- 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
@@ -50,9 +50,8 @@
@VisibleForTesting
val viewHostAdapter: SurfaceControlViewHostAdapter =
SurfaceControlViewHostAdapter(context, display),
+ private val rootView: FrameLayout = FrameLayout(context)
) : WindowDecorViewHost, Warmable {
- @VisibleForTesting val rootView = FrameLayout(context)
-
private var currentUpdateJob: Job? = null
override val surfaceControl: SurfaceControl
@@ -131,8 +130,10 @@
Trace.beginSection("ReusableWindowDecorViewHost#updateViewHost")
viewHostAdapter.prepareViewHost(configuration, touchableRegion)
onDrawTransaction?.let { viewHostAdapter.applyTransactionOnDraw(it) }
- rootView.removeAllViews()
- rootView.addView(view)
+ if (view.parent != rootView) {
+ rootView.removeAllViews()
+ rootView.addView(view)
+ }
viewHostAdapter.updateView(rootView, attrs)
Trace.endSection()
}
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/EnterDesktopWithDrag.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/EnterDesktopWithDrag.kt
index 2115f70..af2840e 100644
--- a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/EnterDesktopWithDrag.kt
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/EnterDesktopWithDrag.kt
@@ -45,6 +45,7 @@
tapl.setExpectedRotation(rotation.value)
ChangeDisplayOrientationRule.setRotation(rotation)
tapl.enableTransientTaskbar(false)
+ testApp.exit(wmHelper)
}
@Test
diff --git a/libs/WindowManager/Shell/tests/unittest/Android.bp b/libs/WindowManager/Shell/tests/unittest/Android.bp
index bf5e374..bff12d0 100644
--- a/libs/WindowManager/Shell/tests/unittest/Android.bp
+++ b/libs/WindowManager/Shell/tests/unittest/Android.bp
@@ -45,6 +45,7 @@
"androidx.test.rules",
"androidx.test.ext.junit",
"androidx.datastore_datastore",
+ "androidx.core_core-animation-testing",
"kotlinx_coroutines_test",
"androidx.dynamicanimation_dynamicanimation",
"dagger2",
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayControllerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayControllerTests.java
index d3de0f7..3d5e949 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayControllerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayControllerTests.java
@@ -16,26 +16,52 @@
package com.android.wm.shell.common;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
-import android.content.Context;
+import android.content.res.Configuration;
+import android.graphics.RectF;
import android.hardware.display.DisplayManager;
+import android.hardware.display.DisplayTopology;
+import android.os.RemoteException;
+import android.platform.test.annotations.EnableFlags;
+import android.testing.TestableContext;
+import android.util.SparseArray;
+import android.view.Display;
+import android.view.DisplayAdjustments;
+import android.view.IDisplayWindowListener;
import android.view.IWindowManager;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
+import com.android.dx.mockito.inline.extended.ExtendedMockito;
+import com.android.dx.mockito.inline.extended.StaticMockitoSession;
+import com.android.window.flags.Flags;
import com.android.wm.shell.ShellTestCase;
+import com.android.wm.shell.TestSyncExecutor;
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
import com.android.wm.shell.sysui.ShellInit;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.quality.Strictness;
+
+import java.util.function.Consumer;
/**
* Tests for the display controller.
@@ -46,23 +72,163 @@
@SmallTest
@RunWith(AndroidJUnit4.class)
public class DisplayControllerTests extends ShellTestCase {
-
- private @Mock Context mContext;
- private @Mock IWindowManager mWM;
- private @Mock ShellInit mShellInit;
- private @Mock ShellExecutor mMainExecutor;
- private @Mock DisplayManager mDisplayManager;
+ @Mock private IWindowManager mWM;
+ @Mock private ShellInit mShellInit;
+ @Mock private DisplayManager mDisplayManager;
+ @Mock private DisplayTopology mMockTopology;
+ @Mock private DisplayController.OnDisplaysChangedListener mListener;
+ private StaticMockitoSession mMockitoSession;
+ private TestSyncExecutor mMainExecutor;
+ private IDisplayWindowListener mDisplayContainerListener;
+ private Consumer<DisplayTopology> mCapturedTopologyListener;
+ private Display mMockDisplay;
private DisplayController mController;
+ private static final int DISPLAY_ID_0 = 0;
+ private static final int DISPLAY_ID_1 = 1;
+ private static final RectF DISPLAY_ABS_BOUNDS_0 = new RectF(10, 10, 20, 20);
+ private static final RectF DISPLAY_ABS_BOUNDS_1 = new RectF(11, 11, 22, 22);
@Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
+ public void setUp() throws RemoteException {
+ mMockitoSession =
+ ExtendedMockito.mockitoSession()
+ .initMocks(this)
+ .mockStatic(DesktopModeStatus.class)
+ .strictness(Strictness.LENIENT)
+ .startMocking();
+
+ mContext = spy(new TestableContext(
+ androidx.test.platform.app.InstrumentationRegistry.getInstrumentation()
+ .getContext(), null));
+
+ mMainExecutor = new TestSyncExecutor();
mController = new DisplayController(
mContext, mWM, mShellInit, mMainExecutor, mDisplayManager);
+
+ mMockDisplay = mock(Display.class);
+ when(mMockDisplay.getDisplayAdjustments()).thenReturn(
+ new DisplayAdjustments(new Configuration()));
+ when(mDisplayManager.getDisplay(anyInt())).thenReturn(mMockDisplay);
+ when(mDisplayManager.getDisplayTopology()).thenReturn(mMockTopology);
+ doAnswer(invocation -> {
+ mDisplayContainerListener = invocation.getArgument(0);
+ return new int[]{DISPLAY_ID_0};
+ }).when(mWM).registerDisplayWindowListener(any());
+ doAnswer(invocation -> {
+ mCapturedTopologyListener = invocation.getArgument(1);
+ return null;
+ }).when(mDisplayManager).registerTopologyListener(any(), any());
+ SparseArray<RectF> absoluteBounds = new SparseArray<>();
+ absoluteBounds.put(DISPLAY_ID_0, DISPLAY_ABS_BOUNDS_0);
+ absoluteBounds.put(DISPLAY_ID_1, DISPLAY_ABS_BOUNDS_1);
+ when(mMockTopology.getAbsoluteBounds()).thenReturn(absoluteBounds);
+ }
+
+ @After
+ public void tearDown() {
+ if (mMockitoSession != null) {
+ mMockitoSession.finishMocking();
+ }
}
@Test
public void instantiateController_addInitCallback() {
verify(mShellInit, times(1)).addInitCallback(any(), eq(mController));
}
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_CONNECTED_DISPLAYS_WINDOW_DRAG)
+ public void onInit_canEnterDesktopMode_registerListeners() throws RemoteException {
+ ExtendedMockito.doReturn(true)
+ .when(() -> DesktopModeStatus.canEnterDesktopMode(any()));
+
+ mController.onInit();
+
+ assertNotNull(mController.getDisplayContext(DISPLAY_ID_0));
+ verify(mWM).registerDisplayWindowListener(any());
+ verify(mDisplayManager).registerTopologyListener(eq(mMainExecutor), any());
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_CONNECTED_DISPLAYS_WINDOW_DRAG)
+ public void onInit_canNotEnterDesktopMode_onlyRegisterDisplayWindowListener()
+ throws RemoteException {
+ ExtendedMockito.doReturn(false)
+ .when(() -> DesktopModeStatus.canEnterDesktopMode(any()));
+
+ mController.onInit();
+
+ assertNotNull(mController.getDisplayContext(DISPLAY_ID_0));
+ verify(mWM).registerDisplayWindowListener(any());
+ verify(mDisplayManager, never()).registerTopologyListener(any(), any());
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_CONNECTED_DISPLAYS_WINDOW_DRAG)
+ public void addDisplayWindowListener_notifiesExistingDisplaysAndTopology() {
+ ExtendedMockito.doReturn(true)
+ .when(() -> DesktopModeStatus.canEnterDesktopMode(any()));
+
+ mController.onInit();
+ mController.addDisplayWindowListener(mListener);
+
+ verify(mListener).onDisplayAdded(eq(DISPLAY_ID_0));
+ verify(mListener).onTopologyChanged(eq(mMockTopology));
+ }
+
+ @Test
+ public void onDisplayAddedAndRemoved_updatesDisplayContexts() throws RemoteException {
+ mController.onInit();
+ mController.addDisplayWindowListener(mListener);
+
+ mDisplayContainerListener.onDisplayAdded(DISPLAY_ID_1);
+
+ verify(mListener).onDisplayAdded(eq(DISPLAY_ID_0));
+ verify(mListener).onDisplayAdded(eq(DISPLAY_ID_1));
+ assertNotNull(mController.getDisplayContext(DISPLAY_ID_1));
+ verify(mContext).createDisplayContext(eq(mMockDisplay));
+
+ mDisplayContainerListener.onDisplayRemoved(DISPLAY_ID_1);
+
+ assertNull(mController.getDisplayContext(DISPLAY_ID_1));
+ verify(mListener).onDisplayRemoved(eq(DISPLAY_ID_1));
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_CONNECTED_DISPLAYS_WINDOW_DRAG)
+ public void onDisplayTopologyChanged_updateDisplayLayout() throws RemoteException {
+ ExtendedMockito.doReturn(true)
+ .when(() -> DesktopModeStatus.canEnterDesktopMode(any()));
+ mController.onInit();
+ mController.addDisplayWindowListener(mListener);
+ mDisplayContainerListener.onDisplayAdded(DISPLAY_ID_1);
+
+ mCapturedTopologyListener.accept(mMockTopology);
+
+ assertEquals(DISPLAY_ABS_BOUNDS_0, mController.getDisplayLayout(DISPLAY_ID_0)
+ .globalBoundsDp());
+ assertEquals(DISPLAY_ABS_BOUNDS_1, mController.getDisplayLayout(DISPLAY_ID_1)
+ .globalBoundsDp());
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_CONNECTED_DISPLAYS_WINDOW_DRAG)
+ public void onDisplayTopologyChanged_topologyBeforeDisplayAdded_appliesBoundsOnAdd()
+ throws RemoteException {
+ ExtendedMockito.doReturn(true)
+ .when(() -> DesktopModeStatus.canEnterDesktopMode(any()));
+ mController.onInit();
+ mController.addDisplayWindowListener(mListener);
+
+ mCapturedTopologyListener.accept(mMockTopology);
+
+ assertNull(mController.getDisplayLayout(DISPLAY_ID_1));
+
+ mDisplayContainerListener.onDisplayAdded(DISPLAY_ID_1);
+
+ assertEquals(DISPLAY_ABS_BOUNDS_0,
+ mController.getDisplayLayout(DISPLAY_ID_0).globalBoundsDp());
+ assertEquals(DISPLAY_ABS_BOUNDS_1,
+ mController.getDisplayLayout(DISPLAY_ID_1).globalBoundsDp());
+ }
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/WindowContainerTransactionSupplierTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/WindowContainerTransactionSupplierTest.kt
new file mode 100644
index 0000000..c91ef5e
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/WindowContainerTransactionSupplierTest.kt
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2025 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.testing.AndroidTestingRunner
+import android.window.WindowContainerTransaction
+import androidx.test.filters.SmallTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * Tests for [WindowContainerTransactionSupplier].
+ *
+ * Build/Install/Run:
+ * atest WMShellUnitTests:WindowContainerTransactionSupplierTest
+ */
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class WindowContainerTransactionSupplierTest {
+
+ @Test
+ fun `WindowContainerTransactionSupplier supplies a WindowContainerTransaction`() {
+ val supplier = WindowContainerTransactionSupplier()
+ SuppliersUtilsTest.assertSupplierProvidesValue(supplier) {
+ it is WindowContainerTransaction
+ }
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PhonePipKeepClearAlgorithmTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PhonePipKeepClearAlgorithmTest.java
similarity index 97%
rename from libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PhonePipKeepClearAlgorithmTest.java
rename to libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PhonePipKeepClearAlgorithmTest.java
index e3798e9..a6c35f1 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PhonePipKeepClearAlgorithmTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PhonePipKeepClearAlgorithmTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.wm.shell.pip.phone;
+package com.android.wm.shell.common.pip;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -29,9 +29,6 @@
import androidx.test.filters.SmallTest;
import com.android.wm.shell.ShellTestCase;
-import com.android.wm.shell.common.pip.PhonePipKeepClearAlgorithm;
-import com.android.wm.shell.common.pip.PipBoundsAlgorithm;
-import com.android.wm.shell.common.pip.PipBoundsState;
import org.junit.Before;
import org.junit.Test;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PhoneSizeSpecSourceTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PhoneSizeSpecSourceTest.java
similarity index 97%
rename from libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PhoneSizeSpecSourceTest.java
rename to libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PhoneSizeSpecSourceTest.java
index 85f1da5..737735c 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PhoneSizeSpecSourceTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PhoneSizeSpecSourceTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.wm.shell.pip.phone;
+package com.android.wm.shell.common.pip;
import static org.mockito.Mockito.when;
@@ -27,9 +27,6 @@
import com.android.wm.shell.R;
import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.common.DisplayLayout;
-import com.android.wm.shell.common.pip.PhoneSizeSpecSource;
-import com.android.wm.shell.common.pip.PipDisplayLayoutState;
-import com.android.wm.shell.common.pip.SizeSpecSource;
import org.junit.Assert;
import org.junit.Before;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsAlgorithmTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipBoundsAlgorithmTest.java
similarity index 97%
rename from libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsAlgorithmTest.java
rename to libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipBoundsAlgorithmTest.java
index 080b0ae..6bda225 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsAlgorithmTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipBoundsAlgorithmTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2020 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.wm.shell.pip;
+package com.android.wm.shell.common.pip;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@@ -32,13 +32,6 @@
import com.android.wm.shell.R;
import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.common.DisplayLayout;
-import com.android.wm.shell.common.pip.PhoneSizeSpecSource;
-import com.android.wm.shell.common.pip.PipBoundsAlgorithm;
-import com.android.wm.shell.common.pip.PipBoundsState;
-import com.android.wm.shell.common.pip.PipDisplayLayoutState;
-import com.android.wm.shell.common.pip.PipKeepClearAlgorithmInterface;
-import com.android.wm.shell.common.pip.PipSnapAlgorithm;
-import com.android.wm.shell.common.pip.SizeSpecSource;
import org.junit.Before;
import org.junit.Test;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsStateTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipBoundsStateTest.java
similarity index 96%
rename from libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsStateTest.java
rename to libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipBoundsStateTest.java
index 304da75f..ad664ac 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsStateTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipBoundsStateTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2020 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.wm.shell.pip;
+package com.android.wm.shell.common.pip;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@@ -36,10 +36,6 @@
import com.android.internal.util.function.TriConsumer;
import com.android.wm.shell.R;
import com.android.wm.shell.ShellTestCase;
-import com.android.wm.shell.common.pip.PhoneSizeSpecSource;
-import com.android.wm.shell.common.pip.PipBoundsState;
-import com.android.wm.shell.common.pip.PipDisplayLayoutState;
-import com.android.wm.shell.common.pip.SizeSpecSource;
import org.junit.Before;
import org.junit.Test;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipDoubleTapHelperTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipDoubleTapHelperTest.java
similarity index 96%
rename from libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipDoubleTapHelperTest.java
rename to libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipDoubleTapHelperTest.java
index b583acd..1756aad 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipDoubleTapHelperTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipDoubleTapHelperTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.wm.shell.pip.phone;
+package com.android.wm.shell.common.pip;
import static com.android.wm.shell.common.pip.PipDoubleTapHelper.SIZE_SPEC_CUSTOM;
import static com.android.wm.shell.common.pip.PipDoubleTapHelper.SIZE_SPEC_DEFAULT;
@@ -29,8 +29,6 @@
import android.testing.AndroidTestingRunner;
import com.android.wm.shell.ShellTestCase;
-import com.android.wm.shell.common.pip.PipBoundsState;
-import com.android.wm.shell.common.pip.PipDoubleTapHelper;
import org.junit.Assert;
import org.junit.Before;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipSnapAlgorithmTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipSnapAlgorithmTest.java
similarity index 97%
rename from libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipSnapAlgorithmTest.java
rename to libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipSnapAlgorithmTest.java
index ac13d7f..3e71ab3 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipSnapAlgorithmTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipSnapAlgorithmTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2020 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.wm.shell.pip;
+package com.android.wm.shell.common.pip;
import static org.junit.Assert.assertEquals;
@@ -25,8 +25,6 @@
import androidx.test.filters.SmallTest;
import com.android.wm.shell.ShellTestCase;
-import com.android.wm.shell.common.pip.PipBoundsState;
-import com.android.wm.shell.common.pip.PipSnapAlgorithm;
import org.junit.Before;
import org.junit.Test;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/FlexParallaxSpecTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/FlexParallaxSpecTests.java
new file mode 100644
index 0000000..22a85fc
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/FlexParallaxSpecTests.java
@@ -0,0 +1,401 @@
+/*
+ * Copyright (C) 2025 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.split;
+
+import static android.view.WindowManager.DOCKED_INVALID;
+import static android.view.WindowManager.DOCKED_LEFT;
+import static android.view.WindowManager.DOCKED_RIGHT;
+
+import static com.android.wm.shell.common.split.ResizingEffectPolicy.DEFAULT_OFFSCREEN_DIM;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.when;
+
+import android.graphics.Point;
+import android.graphics.Rect;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.wm.shell.common.split.DividerSnapAlgorithm.SnapTarget;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(AndroidJUnit4.class)
+public class FlexParallaxSpecTests {
+ ParallaxSpec mFlexSpec = new FlexParallaxSpec();
+
+ Rect mDisplayBounds = new Rect(0, 0, 1000, 1000);
+ Rect mRetreatingSurface = new Rect(0, 0, 1000, 1000);
+ Rect mRetreatingContent = new Rect(0, 0, 1000, 1000);
+ Rect mAdvancingSurface = new Rect(0, 0, 1000, 1000);
+ Rect mAdvancingContent = new Rect(0, 0, 1000, 1000);
+ boolean mIsLeftRightSplit;
+ boolean mTopLeftShrink;
+
+ int mDimmingSide;
+ float mDimValue;
+ Point mRetreatingParallax = new Point(0, 0);
+ Point mAdvancingParallax = new Point(0, 0);
+
+ @Mock DividerSnapAlgorithm mockSnapAlgorithm;
+ @Mock SnapTarget mockStartEdge;
+ @Mock SnapTarget mockFirstTarget;
+ @Mock SnapTarget mockMiddleTarget;
+ @Mock SnapTarget mockLastTarget;
+ @Mock SnapTarget mockEndEdge;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ when(mockSnapAlgorithm.getDismissStartTarget()).thenReturn(mockStartEdge);
+ when(mockSnapAlgorithm.getFirstSplitTarget()).thenReturn(mockFirstTarget);
+ when(mockSnapAlgorithm.getMiddleTarget()).thenReturn(mockMiddleTarget);
+ when(mockSnapAlgorithm.getLastSplitTarget()).thenReturn(mockLastTarget);
+ when(mockSnapAlgorithm.getDismissEndTarget()).thenReturn(mockEndEdge);
+
+ when(mockStartEdge.getPosition()).thenReturn(0);
+ when(mockFirstTarget.getPosition()).thenReturn(250);
+ when(mockMiddleTarget.getPosition()).thenReturn(500);
+ when(mockLastTarget.getPosition()).thenReturn(750);
+ when(mockEndEdge.getPosition()).thenReturn(1000);
+ }
+
+ @Test
+ public void testHorizontalDragFromCenter() {
+ mIsLeftRightSplit = true;
+ simulateDragFromCenterToLeft(125);
+ assertThat(mDimmingSide).isEqualTo(DOCKED_LEFT);
+ assertThat(mDimValue).isGreaterThan(DEFAULT_OFFSCREEN_DIM);
+ assertThat(mDimValue).isLessThan(1f);
+ assertThat(mRetreatingParallax.x).isGreaterThan(0);
+ assertThat(mRetreatingParallax.y).isEqualTo(0);
+ assertThat(mAdvancingParallax.x).isEqualTo(0);
+ assertThat(mAdvancingParallax.y).isEqualTo(0);
+
+ simulateDragFromCenterToLeft(250);
+ assertThat(mDimmingSide).isEqualTo(DOCKED_LEFT);
+ assertThat(mDimValue).isEqualTo(DEFAULT_OFFSCREEN_DIM);
+ assertThat(mRetreatingParallax.x).isGreaterThan(0);
+ assertThat(mRetreatingParallax.y).isEqualTo(0);
+ assertThat(mAdvancingParallax.x).isEqualTo(0);
+ assertThat(mAdvancingParallax.y).isEqualTo(0);
+
+ simulateDragFromCenterToLeft(375);
+ assertThat(mDimmingSide).isEqualTo(DOCKED_LEFT);
+ assertThat(mDimValue).isGreaterThan(0f);
+ assertThat(mDimValue).isLessThan(DEFAULT_OFFSCREEN_DIM);
+ assertThat(mRetreatingParallax.x).isGreaterThan(0);
+ assertThat(mRetreatingParallax.y).isEqualTo(0);
+ assertThat(mAdvancingParallax.x).isEqualTo(0);
+ assertThat(mAdvancingParallax.y).isEqualTo(0);
+
+ simulateDragFromCenterToRight(500);
+ assertThat(mDimmingSide).isEqualTo(DOCKED_INVALID);
+ assertThat(mDimValue).isEqualTo(0f);
+ assertThat(mRetreatingParallax.x).isEqualTo(0);
+ assertThat(mRetreatingParallax.y).isEqualTo(0);
+ assertThat(mAdvancingParallax.x).isEqualTo(0);
+ assertThat(mAdvancingParallax.y).isEqualTo(0);
+
+ simulateDragFromCenterToRight(625);
+ assertThat(mDimmingSide).isEqualTo(DOCKED_RIGHT);
+ assertThat(mDimValue).isGreaterThan(0f);
+ assertThat(mDimValue).isLessThan(DEFAULT_OFFSCREEN_DIM);
+ assertThat(mRetreatingParallax.x).isEqualTo(0);
+ assertThat(mRetreatingParallax.y).isEqualTo(0);
+ assertThat(mAdvancingParallax.x).isEqualTo(0);
+ assertThat(mAdvancingParallax.y).isEqualTo(0);
+
+ simulateDragFromCenterToRight(750);
+ assertThat(mDimmingSide).isEqualTo(DOCKED_RIGHT);
+ assertThat(mDimValue).isEqualTo(DEFAULT_OFFSCREEN_DIM);
+ assertThat(mRetreatingParallax.x).isEqualTo(0);
+ assertThat(mRetreatingParallax.y).isEqualTo(0);
+ assertThat(mAdvancingParallax.x).isEqualTo(0);
+ assertThat(mAdvancingParallax.y).isEqualTo(0);
+
+ simulateDragFromCenterToRight(875);
+ assertThat(mDimmingSide).isEqualTo(DOCKED_RIGHT);
+ assertThat(mDimValue).isGreaterThan(DEFAULT_OFFSCREEN_DIM);
+ assertThat(mDimValue).isLessThan(1f);
+ assertThat(mRetreatingParallax.x).isEqualTo(0);
+ assertThat(mRetreatingParallax.y).isEqualTo(0);
+ assertThat(mAdvancingParallax.x).isEqualTo(0);
+ assertThat(mAdvancingParallax.y).isEqualTo(0);
+ }
+
+ @Test
+ public void testHorizontalDragFromLeft() {
+ mIsLeftRightSplit = true;
+ simulateDragFromLeftToLeft(125);
+ assertThat(mDimmingSide).isEqualTo(DOCKED_LEFT);
+ assertThat(mDimValue).isGreaterThan(DEFAULT_OFFSCREEN_DIM);
+ assertThat(mDimValue).isLessThan(1f);
+ assertThat(mRetreatingParallax.x).isGreaterThan(0);
+ assertThat(mRetreatingParallax.y).isEqualTo(0);
+ assertThat(mAdvancingParallax.x).isEqualTo(0);
+ assertThat(mAdvancingParallax.y).isEqualTo(0);
+
+ simulateDragFromLeftToLeft(250);
+ assertThat(mDimmingSide).isEqualTo(DOCKED_LEFT);
+ assertThat(mDimValue).isEqualTo(DEFAULT_OFFSCREEN_DIM);
+ assertThat(mRetreatingParallax.x).isEqualTo(0);
+ assertThat(mRetreatingParallax.y).isEqualTo(0);
+ assertThat(mAdvancingParallax.x).isEqualTo(0);
+ assertThat(mAdvancingParallax.y).isEqualTo(0);
+
+ simulateDragFromLeftToCenter(375);
+ assertThat(mDimmingSide).isEqualTo(DOCKED_LEFT);
+ assertThat(mDimValue).isGreaterThan(0f);
+ assertThat(mDimValue).isLessThan(DEFAULT_OFFSCREEN_DIM);
+ assertThat(mRetreatingParallax.x).isLessThan(0);
+ assertThat(mRetreatingParallax.y).isEqualTo(0);
+ assertThat(mAdvancingParallax.x).isEqualTo(0);
+ assertThat(mAdvancingParallax.y).isEqualTo(0);
+
+ simulateDragFromLeftToCenter(500);
+ assertThat(mDimmingSide).isEqualTo(DOCKED_INVALID);
+ assertThat(mDimValue).isEqualTo(0f);
+ assertThat(mRetreatingParallax.x).isLessThan(0);
+ assertThat(mRetreatingParallax.y).isEqualTo(0);
+ assertThat(mAdvancingParallax.x).isEqualTo(0);
+ assertThat(mAdvancingParallax.y).isEqualTo(0);
+
+ simulateDragFromLeftToRight(625);
+ assertThat(mDimmingSide).isEqualTo(DOCKED_RIGHT);
+ assertThat(mDimValue).isGreaterThan(0f);
+ assertThat(mDimValue).isLessThan(DEFAULT_OFFSCREEN_DIM);
+ assertThat(mRetreatingParallax.x).isLessThan(0);
+ assertThat(mRetreatingParallax.y).isEqualTo(0);
+ assertThat(mAdvancingParallax.x).isEqualTo(0);
+ assertThat(mAdvancingParallax.y).isEqualTo(0);
+
+ simulateDragFromLeftToRight(750);
+ assertThat(mDimmingSide).isEqualTo(DOCKED_RIGHT);
+ assertThat(mDimValue).isEqualTo(DEFAULT_OFFSCREEN_DIM);
+ assertThat(mRetreatingParallax.x).isLessThan(0);
+ assertThat(mRetreatingParallax.y).isEqualTo(0);
+ assertThat(mAdvancingParallax.x).isEqualTo(0);
+ assertThat(mAdvancingParallax.y).isEqualTo(0);
+
+ simulateDragFromLeftToRight(875);
+ assertThat(mDimmingSide).isEqualTo(DOCKED_RIGHT);
+ assertThat(mDimValue).isGreaterThan(DEFAULT_OFFSCREEN_DIM);
+ assertThat(mDimValue).isLessThan(1f);
+ assertThat(mRetreatingParallax.x).isLessThan(0);
+ assertThat(mRetreatingParallax.y).isEqualTo(0);
+ assertThat(mAdvancingParallax.x).isGreaterThan(0);
+ assertThat(mAdvancingParallax.y).isEqualTo(0);
+ }
+
+ @Test
+ public void testHorizontalDragFromRight() {
+ mIsLeftRightSplit = true;
+
+ simulateDragFromRightToLeft(125);
+ assertThat(mDimmingSide).isEqualTo(DOCKED_LEFT);
+ assertThat(mDimValue).isGreaterThan(DEFAULT_OFFSCREEN_DIM);
+ assertThat(mDimValue).isLessThan(1f);
+ assertThat(mRetreatingParallax.x).isGreaterThan(0);
+ assertThat(mRetreatingParallax.y).isEqualTo(0);
+ assertThat(mAdvancingParallax.x).isEqualTo(0);
+ assertThat(mAdvancingParallax.y).isEqualTo(0);
+
+ simulateDragFromRightToLeft(250);
+ assertThat(mDimmingSide).isEqualTo(DOCKED_LEFT);
+ assertThat(mDimValue).isEqualTo(DEFAULT_OFFSCREEN_DIM);
+ assertThat(mRetreatingParallax.x).isGreaterThan(0);
+ assertThat(mRetreatingParallax.y).isEqualTo(0);
+ assertThat(mAdvancingParallax.x).isEqualTo(0);
+ assertThat(mAdvancingParallax.y).isEqualTo(0);
+
+ simulateDragFromRightToLeft(375);
+ assertThat(mDimmingSide).isEqualTo(DOCKED_LEFT);
+ assertThat(mDimValue).isGreaterThan(0f);
+ assertThat(mDimValue).isLessThan(DEFAULT_OFFSCREEN_DIM);
+ assertThat(mRetreatingParallax.x).isGreaterThan(0);
+ assertThat(mRetreatingParallax.y).isEqualTo(0);
+ assertThat(mAdvancingParallax.x).isEqualTo(0);
+ assertThat(mAdvancingParallax.y).isEqualTo(0);
+
+ simulateDragFromRightToCenter(500);
+ assertThat(mDimmingSide).isEqualTo(DOCKED_INVALID);
+ assertThat(mDimValue).isEqualTo(0f);
+ assertThat(mRetreatingParallax.x).isLessThan(0);
+ assertThat(mRetreatingParallax.y).isEqualTo(0);
+ assertThat(mAdvancingParallax.x).isEqualTo(0);
+ assertThat(mAdvancingParallax.y).isEqualTo(0);
+
+ simulateDragFromRightToCenter(625);
+ assertThat(mDimmingSide).isEqualTo(DOCKED_RIGHT);
+ assertThat(mDimValue).isGreaterThan(0f);
+ assertThat(mDimValue).isLessThan(DEFAULT_OFFSCREEN_DIM);
+ assertThat(mRetreatingParallax.x).isLessThan(0);
+ assertThat(mRetreatingParallax.y).isEqualTo(0);
+ assertThat(mAdvancingParallax.x).isEqualTo(0);
+ assertThat(mAdvancingParallax.y).isEqualTo(0);
+
+ simulateDragFromRightToRight(750);
+ assertThat(mDimmingSide).isEqualTo(DOCKED_RIGHT);
+ assertThat(mDimValue).isEqualTo(DEFAULT_OFFSCREEN_DIM);
+ assertThat(mRetreatingParallax.x).isEqualTo(0);
+ assertThat(mRetreatingParallax.y).isEqualTo(0);
+ assertThat(mAdvancingParallax.x).isEqualTo(0);
+ assertThat(mAdvancingParallax.y).isEqualTo(0);
+
+ simulateDragFromRightToRight(875);
+ assertThat(mDimmingSide).isEqualTo(DOCKED_RIGHT);
+ assertThat(mDimValue).isGreaterThan(DEFAULT_OFFSCREEN_DIM);
+ assertThat(mDimValue).isLessThan(1f);
+ assertThat(mRetreatingParallax.x).isEqualTo(0);
+ assertThat(mRetreatingParallax.y).isEqualTo(0);
+ assertThat(mAdvancingParallax.x).isEqualTo(0);
+ assertThat(mAdvancingParallax.y).isEqualTo(0);
+ }
+
+ private void simulateDragFromCenterToLeft(int to) {
+ int from = 500;
+
+ mRetreatingSurface = flexOffscreenAppLeft(to);
+ mRetreatingContent = onscreenAppLeft(from);
+ mAdvancingSurface = onscreenAppRight(to);
+ mAdvancingContent = onscreenAppRight(from);
+
+ calculateDimAndParallax(from, to);
+ }
+
+ private void simulateDragFromCenterToRight(int to) {
+ int from = 500;
+
+ mRetreatingSurface = flexOffscreenAppRight(to);
+ mRetreatingContent = onscreenAppRight(from);
+ mAdvancingSurface = onscreenAppLeft(to);
+ mAdvancingContent = onscreenAppLeft(from);
+
+ calculateDimAndParallax(from, to);
+ }
+
+ private void simulateDragFromLeftToLeft(int to) {
+ int from = 250;
+
+ mRetreatingSurface = flexOffscreenAppLeft(to);
+ mRetreatingContent = fullOffscreenAppLeft(from);
+ mAdvancingSurface = onscreenAppRight(to);
+ mAdvancingContent = onscreenAppRight(from);
+
+ calculateDimAndParallax(from, to);
+ }
+
+ private void simulateDragFromLeftToCenter(int to) {
+ int from = 250;
+
+ mRetreatingSurface = onscreenAppRight(to);
+ mRetreatingContent = onscreenAppRight(from);
+ mAdvancingSurface = fullOffscreenAppLeft(to);
+ mAdvancingContent = fullOffscreenAppLeft(from);
+
+ calculateDimAndParallax(from, to);
+ }
+
+ private void simulateDragFromLeftToRight(int to) {
+ int from = 250;
+
+ mRetreatingSurface = flexOffscreenAppRight(to);
+ mRetreatingContent = onscreenAppRight(from);
+ mAdvancingSurface = fullOffscreenAppLeft(to);
+ mAdvancingContent = fullOffscreenAppLeft(from);
+
+ calculateDimAndParallax(from, to);
+ }
+
+ private void simulateDragFromRightToLeft(int to) {
+ int from = 750;
+
+ mRetreatingSurface = flexOffscreenAppLeft(to);
+ mRetreatingContent = onscreenAppLeft(from);
+ mAdvancingSurface = fullOffscreenAppRight(to);
+ mAdvancingContent = fullOffscreenAppRight(from);
+
+ calculateDimAndParallax(from, to);
+ }
+
+ private void simulateDragFromRightToCenter(int to) {
+ int from = 750;
+
+ mRetreatingSurface = onscreenAppLeft(to);
+ mRetreatingContent = onscreenAppLeft(from);
+ mAdvancingSurface = fullOffscreenAppRight(to);
+ mAdvancingContent = fullOffscreenAppRight(from);
+
+ calculateDimAndParallax(from, to);
+ }
+
+ private void simulateDragFromRightToRight(int to) {
+ int from = 750;
+
+ mRetreatingSurface = flexOffscreenAppRight(to);
+ mRetreatingContent = fullOffscreenAppRight(from);
+ mAdvancingSurface = onscreenAppLeft(to);
+ mAdvancingContent = onscreenAppLeft(from);
+
+ calculateDimAndParallax(from, to);
+ }
+
+ private Rect flexOffscreenAppLeft(int pos) {
+ return new Rect(pos - (1000 - pos), 0, pos, 1000);
+ }
+
+ private Rect onscreenAppLeft(int pos) {
+ return new Rect(0, 0, pos, 1000);
+ }
+
+ private Rect fullOffscreenAppLeft(int pos) {
+ return new Rect(Math.min(0, pos - 750), 0, pos, 1000);
+ }
+
+ private Rect flexOffscreenAppRight(int pos) {
+ return new Rect(pos, 0, pos * 2, 1000);
+ }
+
+ private Rect onscreenAppRight(int pos) {
+ return new Rect(pos, 0, 1000, 1000);
+ }
+
+ private Rect fullOffscreenAppRight(int pos) {
+ return new Rect(pos, 0, Math.max(pos + 750, 1000), 1000);
+ }
+
+ private void calculateDimAndParallax(int from, int to) {
+ resetParallax();
+ mTopLeftShrink = to < from;
+ mDimmingSide = mFlexSpec.getDimmingSide(to, mockSnapAlgorithm, mIsLeftRightSplit);
+ mDimValue = mFlexSpec.getDimValue(to, mockSnapAlgorithm);
+ mFlexSpec.getParallax(mRetreatingParallax, mAdvancingParallax, to, mockSnapAlgorithm,
+ mIsLeftRightSplit, mDisplayBounds, mRetreatingSurface, mRetreatingContent,
+ mAdvancingSurface, mAdvancingContent, mDimmingSide, mTopLeftShrink);
+ }
+
+ private void resetParallax() {
+ mRetreatingParallax.set(0, 0);
+ mAdvancingParallax.set(0, 0);
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/events/ReachabilityGestureListenerFactoryTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/events/ReachabilityGestureListenerFactoryTest.kt
new file mode 100644
index 0000000..a5f6ced
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/events/ReachabilityGestureListenerFactoryTest.kt
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2025 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.compatui.letterbox.events
+
+import android.graphics.Rect
+import android.testing.AndroidTestingRunner
+import android.window.WindowContainerToken
+import android.window.WindowContainerTransaction
+import androidx.test.filters.SmallTest
+import com.android.wm.shell.ShellTestCase
+import com.android.wm.shell.common.WindowContainerTransactionSupplier
+import com.android.wm.shell.compatui.letterbox.LetterboxEvents.motionEventAt
+import com.android.wm.shell.transition.Transitions
+import com.android.wm.shell.transition.Transitions.TRANSIT_MOVE_LETTERBOX_REACHABILITY
+import java.util.function.Consumer
+import kotlin.test.assertEquals
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.verify
+
+/**
+ * Tests for [ReachabilityGestureListenerFactory].
+ *
+ * Build/Install/Run:
+ * atest WMShellUnitTests:ReachabilityGestureListenerFactoryTest
+ */
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class ReachabilityGestureListenerFactoryTest : ShellTestCase() {
+
+ @Test
+ fun `When invoked a ReachabilityGestureListenerFactory is created`() {
+ runTestScenario { r ->
+ r.invokeCreate()
+
+ r.checkReachabilityGestureListenerCreated()
+ }
+ }
+
+ @Test
+ fun `Right parameters are used for creation`() {
+ runTestScenario { r ->
+ r.invokeCreate()
+
+ r.checkRightParamsAreUsed()
+ }
+ }
+
+ /**
+ * Runs a test scenario providing a Robot.
+ */
+ fun runTestScenario(consumer: Consumer<ReachabilityGestureListenerFactoryRobotTest>) {
+ val robot = ReachabilityGestureListenerFactoryRobotTest()
+ consumer.accept(robot)
+ }
+
+ class ReachabilityGestureListenerFactoryRobotTest {
+
+ companion object {
+ @JvmStatic
+ private val TASK_ID = 1
+
+ @JvmStatic
+ private val TOKEN = mock<WindowContainerToken>()
+ }
+
+ private val transitions: Transitions
+ private val animationHandler: Transitions.TransitionHandler
+ private val factory: ReachabilityGestureListenerFactory
+ private val wctSupplier: WindowContainerTransactionSupplier
+ private val wct: WindowContainerTransaction
+ private lateinit var obtainedResult: Any
+
+ init {
+ transitions = mock<Transitions>()
+ animationHandler = mock<Transitions.TransitionHandler>()
+ wctSupplier = mock<WindowContainerTransactionSupplier>()
+ wct = mock<WindowContainerTransaction>()
+ doReturn(wct).`when`(wctSupplier).get()
+ factory = ReachabilityGestureListenerFactory(transitions, animationHandler, wctSupplier)
+ }
+
+ fun invokeCreate(taskId: Int = TASK_ID, token: WindowContainerToken? = TOKEN) {
+ obtainedResult = factory.createReachabilityGestureListener(taskId, token)
+ }
+
+ fun checkReachabilityGestureListenerCreated(expected: Boolean = true) {
+ assertEquals(expected, obtainedResult is ReachabilityGestureListener)
+ }
+
+ fun checkRightParamsAreUsed(taskId: Int = TASK_ID, token: WindowContainerToken? = TOKEN) {
+ with(obtainedResult as ReachabilityGestureListener) {
+ // Click outside the bounds
+ updateActivityBounds(Rect(0, 0, 10, 20))
+ onDoubleTap(motionEventAt(50f, 100f))
+ // WindowContainerTransactionSupplier is invoked to create a
+ // WindowContainerTransaction
+ verify(wctSupplier).get()
+ // Verify the right params are passed to startAppCompatReachability()
+ verify(wct).setReachabilityOffset(
+ token!!,
+ taskId,
+ 50,
+ 100
+ )
+ // startTransition() is invoked on Transitions with the right parameters
+ verify(transitions).startTransition(
+ TRANSIT_MOVE_LETTERBOX_REACHABILITY,
+ wct,
+ animationHandler
+ )
+ }
+ }
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/events/ReachabilityGestureListenerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/events/ReachabilityGestureListenerTest.kt
new file mode 100644
index 0000000..bc10ea5
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/events/ReachabilityGestureListenerTest.kt
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2025 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.compatui.letterbox.events
+
+import android.graphics.Rect
+import android.testing.AndroidTestingRunner
+import android.window.WindowContainerToken
+import android.window.WindowContainerTransaction
+import androidx.test.filters.SmallTest
+import com.android.wm.shell.ShellTestCase
+import com.android.wm.shell.common.WindowContainerTransactionSupplier
+import com.android.wm.shell.compatui.letterbox.LetterboxEvents.motionEventAt
+import com.android.wm.shell.compatui.letterbox.asMode
+import com.android.wm.shell.transition.Transitions
+import com.android.wm.shell.transition.Transitions.TRANSIT_MOVE_LETTERBOX_REACHABILITY
+import java.util.function.Consumer
+import kotlin.test.assertEquals
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.verify
+
+/**
+ * Tests for [ReachabilityGestureListener].
+ *
+ * Build/Install/Run:
+ * atest WMShellUnitTests:ReachabilityGestureListenerTest
+ */
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class ReachabilityGestureListenerTest : ShellTestCase() {
+
+ @Test
+ fun `Only events outside the bounds are handled`() {
+ runTestScenario { r ->
+ r.updateActivityBounds(Rect(0, 0, 100, 200))
+ r.sendMotionEvent(50, 100)
+
+ r.verifyReachabilityTransitionCreated(expected = false, 50, 100)
+ r.verifyReachabilityTransitionStarted(expected = false)
+ r.verifyEventIsHandled(expected = false)
+
+ r.updateActivityBounds(Rect(0, 0, 10, 50))
+ r.sendMotionEvent(50, 100)
+
+ r.verifyReachabilityTransitionCreated(expected = true, 50, 100)
+ r.verifyReachabilityTransitionStarted(expected = true)
+ r.verifyEventIsHandled(expected = true)
+ }
+ }
+
+ /**
+ * Runs a test scenario providing a Robot.
+ */
+ fun runTestScenario(consumer: Consumer<ReachabilityGestureListenerRobotTest>) {
+ val robot = ReachabilityGestureListenerRobotTest()
+ consumer.accept(robot)
+ }
+
+ class ReachabilityGestureListenerRobotTest(
+ taskId: Int = TASK_ID,
+ token: WindowContainerToken? = TOKEN
+ ) {
+
+ companion object {
+ @JvmStatic
+ private val TASK_ID = 1
+
+ @JvmStatic
+ private val TOKEN = mock<WindowContainerToken>()
+ }
+
+ private val reachabilityListener: ReachabilityGestureListener
+ private val transitions: Transitions
+ private val animationHandler: Transitions.TransitionHandler
+ private val wctSupplier: WindowContainerTransactionSupplier
+ private val wct: WindowContainerTransaction
+ private var eventHandled = false
+
+ init {
+ transitions = mock<Transitions>()
+ animationHandler = mock<Transitions.TransitionHandler>()
+ wctSupplier = mock<WindowContainerTransactionSupplier>()
+ wct = mock<WindowContainerTransaction>()
+ doReturn(wct).`when`(wctSupplier).get()
+ reachabilityListener =
+ ReachabilityGestureListener(
+ taskId,
+ token,
+ transitions,
+ animationHandler,
+ wctSupplier
+ )
+ }
+
+ fun updateActivityBounds(activityBounds: Rect) {
+ reachabilityListener.updateActivityBounds(activityBounds)
+ }
+
+ fun sendMotionEvent(x: Int, y: Int) {
+ eventHandled = reachabilityListener.onDoubleTap(motionEventAt(x.toFloat(), y.toFloat()))
+ }
+
+ fun verifyReachabilityTransitionCreated(
+ expected: Boolean,
+ x: Int,
+ y: Int,
+ taskId: Int = TASK_ID,
+ token: WindowContainerToken? = TOKEN
+ ) {
+ verify(wct, expected.asMode()).setReachabilityOffset(
+ token!!,
+ taskId,
+ x,
+ y
+ )
+ }
+
+ fun verifyReachabilityTransitionStarted(expected: Boolean = true) {
+ verify(transitions, expected.asMode()).startTransition(
+ TRANSIT_MOVE_LETTERBOX_REACHABILITY,
+ wct,
+ animationHandler
+ )
+ }
+
+ fun verifyEventIsHandled(expected: Boolean) {
+ assertEquals(expected, eventHandled)
+ }
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopMixedTransitionHandlerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopMixedTransitionHandlerTest.kt
index 77cd1e5..e9f92cf 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopMixedTransitionHandlerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopMixedTransitionHandlerTest.kt
@@ -127,26 +127,6 @@
}
@Test
- fun startMinimizedModeTransition_callsFreeformTaskTransitionHandler() {
- val wct = WindowContainerTransaction()
- val taskId = 1
- val isLastTask = false
- whenever(
- freeformTaskTransitionHandler.startMinimizedModeTransition(
- any(),
- anyInt(),
- anyBoolean(),
- )
- )
- .thenReturn(mock())
-
- mixedHandler.startMinimizedModeTransition(wct, taskId, isLastTask)
-
- verify(freeformTaskTransitionHandler)
- .startMinimizedModeTransition(eq(wct), eq(taskId), eq(isLastTask))
- }
-
- @Test
@DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_EXIT_TRANSITIONS_BUGFIX)
fun startRemoveTransition_callsFreeformTaskTransitionHandler() {
val wct = WindowContainerTransaction()
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopRepositoryTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopRepositoryTest.kt
index 8510441..ed9b97d 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopRepositoryTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopRepositoryTest.kt
@@ -55,6 +55,8 @@
import org.mockito.Mockito.inOrder
import org.mockito.Mockito.spy
import org.mockito.kotlin.any
+import org.mockito.kotlin.clearInvocations
+import org.mockito.kotlin.eq
import org.mockito.kotlin.never
import org.mockito.kotlin.times
import org.mockito.kotlin.verify
@@ -894,12 +896,12 @@
val taskId = 1
val listener = TestListener()
repo.addActiveTaskListener(listener)
- repo.addTask(DEFAULT_DISPLAY, taskId, isVisible = true)
+ repo.addTask(THIRD_DISPLAY, taskId, isVisible = true)
repo.removeTask(THIRD_DISPLAY, taskId)
assertThat(repo.isActiveTask(taskId)).isFalse()
- assertThat(listener.activeChangesOnDefaultDisplay).isEqualTo(2)
+ assertThat(listener.activeChangesOnThirdDisplay).isEqualTo(2)
}
@Test
@@ -917,7 +919,7 @@
fun removeTask_updatesTaskVisibility() {
repo.addDesk(displayId = THIRD_DISPLAY, deskId = THIRD_DISPLAY)
val taskId = 1
- repo.addTask(DEFAULT_DISPLAY, taskId, isVisible = true)
+ repo.addTask(THIRD_DISPLAY, taskId, isVisible = true)
repo.removeTask(THIRD_DISPLAY, taskId)
@@ -1106,6 +1108,30 @@
}
@Test
+ @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun setTaskInFullImmersiveState_inDesk_savedAsInImmersiveState() {
+ repo.addDesk(DEFAULT_DISPLAY, deskId = 6)
+ repo.addTaskToDesk(DEFAULT_DISPLAY, deskId = 6, taskId = 10, isVisible = true)
+ assertThat(repo.isTaskInFullImmersiveState(6)).isFalse()
+
+ repo.setTaskInFullImmersiveStateInDesk(deskId = 6, taskId = 10, immersive = true)
+
+ assertThat(repo.isTaskInFullImmersiveState(taskId = 10)).isTrue()
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun removeTaskInFullImmersiveState_inDesk_removedAsInImmersiveState() {
+ repo.addDesk(DEFAULT_DISPLAY, deskId = 6)
+ repo.addTaskToDesk(DEFAULT_DISPLAY, deskId = 6, taskId = 10, isVisible = true)
+ repo.setTaskInFullImmersiveStateInDesk(deskId = 6, taskId = 10, immersive = true)
+
+ repo.setTaskInFullImmersiveStateInDesk(deskId = 6, taskId = 10, immersive = false)
+
+ assertThat(repo.isTaskInFullImmersiveState(taskId = 10)).isFalse()
+ }
+
+ @Test
fun removeTaskInFullImmersiveState_otherWasImmersive_otherRemainsImmersive() {
repo.setTaskInFullImmersiveState(DEFAULT_DISPLAY, taskId = 1, immersive = true)
@@ -1274,14 +1300,146 @@
assertEquals(SECOND_DISPLAY, repo.getDisplayForDesk(deskId = 8))
}
+ @Test
+ @EnableFlags(FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun setDeskActive() {
+ repo.addDesk(DEFAULT_DISPLAY, deskId = 6)
+
+ repo.setActiveDesk(DEFAULT_DISPLAY, deskId = 6)
+
+ assertThat(repo.getActiveDeskId(DEFAULT_DISPLAY)).isEqualTo(6)
+ }
+
+ @Test
+ @EnableFlags(FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun setDeskInactive() {
+ repo.addDesk(DEFAULT_DISPLAY, deskId = 6)
+ repo.setActiveDesk(DEFAULT_DISPLAY, deskId = 6)
+
+ repo.setDeskInactive(deskId = 6)
+
+ assertThat(repo.getActiveDeskId(DEFAULT_DISPLAY)).isNull()
+ }
+
+ @Test
+ @EnableFlags(FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun getDeskIdForTask() {
+ repo.addDesk(DEFAULT_DISPLAY, deskId = 6)
+ repo.addTaskToDesk(DEFAULT_DISPLAY, deskId = 6, taskId = 10, isVisible = true)
+
+ assertThat(repo.getDeskIdForTask(10)).isEqualTo(6)
+ }
+
+ @Test
+ @EnableFlags(FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun removeTaskFromDesk_clearsBoundsBeforeMaximize() {
+ repo.addDesk(DEFAULT_DISPLAY, deskId = 6)
+ repo.addTaskToDesk(DEFAULT_DISPLAY, deskId = 6, taskId = 10, isVisible = true)
+ repo.saveBoundsBeforeMaximize(taskId = 10, bounds = Rect(10, 10, 100, 100))
+
+ repo.removeTaskFromDesk(deskId = 6, taskId = 10)
+
+ assertThat(repo.removeBoundsBeforeMaximize(taskId = 10)).isNull()
+ }
+
+ @Test
+ @EnableFlags(FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun removeTaskFromDesk_clearsBoundsBeforeImmersive() {
+ repo.addDesk(DEFAULT_DISPLAY, deskId = 6)
+ repo.addTaskToDesk(DEFAULT_DISPLAY, deskId = 6, taskId = 10, isVisible = true)
+ repo.saveBoundsBeforeFullImmersive(taskId = 10, bounds = Rect(10, 10, 100, 100))
+
+ repo.removeTaskFromDesk(deskId = 6, taskId = 10)
+
+ assertThat(repo.removeBoundsBeforeFullImmersive(taskId = 10)).isNull()
+ }
+
+ @Test
+ @EnableFlags(FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun removeTaskFromDesk_removesFromZOrderList() {
+ repo.addDesk(DEFAULT_DISPLAY, deskId = 6)
+ repo.addTaskToDesk(DEFAULT_DISPLAY, deskId = 6, taskId = 10, isVisible = true)
+
+ repo.removeTaskFromDesk(deskId = 6, taskId = 10)
+
+ assertThat(repo.getFreeformTasksIdsInDeskInZOrder(deskId = 6)).doesNotContain(10)
+ }
+
+ @Test
+ @EnableFlags(FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun removeTaskFromDesk_removesFromMinimized() {
+ repo.addDesk(DEFAULT_DISPLAY, deskId = 6)
+ repo.addTaskToDesk(DEFAULT_DISPLAY, deskId = 6, taskId = 10, isVisible = true)
+ repo.minimizeTaskInDesk(DEFAULT_DISPLAY, deskId = 6, taskId = 10)
+
+ repo.removeTaskFromDesk(deskId = 6, taskId = 10)
+
+ assertThat(repo.getMinimizedTaskIdsInDesk(deskId = 6)).doesNotContain(10)
+ }
+
+ @Test
+ @EnableFlags(FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun removeTaskFromDesk_removesFromImmersive() {
+ repo.addDesk(DEFAULT_DISPLAY, deskId = 6)
+ repo.addTaskToDesk(DEFAULT_DISPLAY, deskId = 6, taskId = 10, isVisible = true)
+ repo.setTaskInFullImmersiveStateInDesk(deskId = 6, taskId = 10, immersive = true)
+
+ repo.removeTaskFromDesk(deskId = 6, taskId = 10)
+
+ assertThat(repo.isTaskInFullImmersiveState(taskId = 10)).isFalse()
+ }
+
+ @Test
+ @EnableFlags(FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun removeTaskFromDesk_removesFromActiveTasks() {
+ repo.addDesk(DEFAULT_DISPLAY, deskId = 6)
+ repo.addTaskToDesk(DEFAULT_DISPLAY, deskId = 6, taskId = 10, isVisible = true)
+
+ repo.removeTaskFromDesk(deskId = 6, taskId = 10)
+
+ assertThat(repo.isActiveTaskInDesk(taskId = 10, deskId = 6)).isFalse()
+ }
+
+ @Test
+ @EnableFlags(FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun removeTaskFromDesk_removesFromVisibleTasks() {
+ repo.addDesk(DEFAULT_DISPLAY, deskId = 6)
+ repo.addTaskToDesk(DEFAULT_DISPLAY, deskId = 6, taskId = 10, isVisible = true)
+
+ repo.removeTaskFromDesk(deskId = 6, taskId = 10)
+
+ assertThat(repo.isVisibleTaskInDesk(taskId = 10, deskId = 6)).isFalse()
+ }
+
+ @Test
+ @EnableFlags(FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND, FLAG_ENABLE_DESKTOP_WINDOWING_PERSISTENCE)
+ fun removeTaskFromDesk_updatesPersistence() = runTest {
+ repo.addDesk(DEFAULT_DISPLAY, deskId = 6)
+ repo.addTaskToDesk(DEFAULT_DISPLAY, deskId = 6, taskId = 10, isVisible = true)
+ clearInvocations(persistentRepository)
+
+ repo.removeTaskFromDesk(deskId = 6, taskId = 10)
+
+ verify(persistentRepository)
+ .addOrUpdateDesktop(
+ userId = eq(DEFAULT_USER_ID),
+ desktopId = eq(6),
+ visibleTasks = any(),
+ minimizedTasks = any(),
+ freeformTasksInZOrder = any(),
+ )
+ }
+
class TestListener : DesktopRepository.ActiveTasksListener {
var activeChangesOnDefaultDisplay = 0
var activeChangesOnSecondaryDisplay = 0
+ var activeChangesOnThirdDisplay = 0
override fun onActiveTasksChanged(displayId: Int) {
when (displayId) {
DEFAULT_DISPLAY -> activeChangesOnDefaultDisplay++
SECOND_DISPLAY -> activeChangesOnSecondaryDisplay++
+ THIRD_DISPLAY -> activeChangesOnThirdDisplay++
else -> fail("Active task listener received unexpected display id: $displayId")
}
}
@@ -1290,9 +1448,11 @@
class TestVisibilityListener : DesktopRepository.VisibleTasksListener {
var visibleTasksCountOnDefaultDisplay = 0
var visibleTasksCountOnSecondaryDisplay = 0
+ var visibleTasksCountOnThirdDisplay = 0
var visibleChangesOnDefaultDisplay = 0
var visibleChangesOnSecondaryDisplay = 0
+ var visibleChangesOnThirdDisplay = 0
override fun onTasksVisibilityChanged(displayId: Int, visibleTasksCount: Int) {
when (displayId) {
@@ -1304,6 +1464,10 @@
visibleTasksCountOnSecondaryDisplay = visibleTasksCount
visibleChangesOnSecondaryDisplay++
}
+ THIRD_DISPLAY -> {
+ visibleTasksCountOnThirdDisplay = visibleTasksCount
+ visibleChangesOnThirdDisplay++
+ }
else -> fail("Visible task listener received unexpected display id: $displayId")
}
}
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 08a4bb2..fcd92ac 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
@@ -285,7 +285,7 @@
private val DEFAULT_PORTRAIT_BOUNDS = Rect(200, 165, 1400, 2085)
private val RESIZABLE_LANDSCAPE_BOUNDS = Rect(25, 435, 1575, 1635)
private val RESIZABLE_PORTRAIT_BOUNDS = Rect(680, 75, 1880, 1275)
- private val UNRESIZABLE_LANDSCAPE_BOUNDS = Rect(25, 449, 1575, 1611)
+ private val UNRESIZABLE_LANDSCAPE_BOUNDS = Rect(25, 448, 1575, 1611)
private val UNRESIZABLE_PORTRAIT_BOUNDS = Rect(830, 75, 1730, 1275)
private val wallpaperToken = MockToken().token()
private val homeComponentName = ComponentName(HOME_LAUNCHER_PACKAGE_NAME, /* class */ "")
@@ -327,8 +327,10 @@
desktopModeCompatPolicy = spy(DesktopModeCompatPolicy(spyContext))
whenever(shellTaskOrganizer.getRunningTasks(anyInt())).thenAnswer { runningTasks }
- whenever(transitions.startTransition(anyInt(), any(), isNull())).thenAnswer { Binder() }
+ whenever(transitions.startTransition(anyInt(), any(), anyOrNull())).thenAnswer { Binder() }
whenever(enterDesktopTransitionHandler.moveToDesktop(any(), any())).thenAnswer { Binder() }
+ whenever(exitDesktopTransitionHandler.startTransition(any(), any(), any(), any()))
+ .thenReturn(Binder())
whenever(displayController.getDisplayLayout(anyInt())).thenReturn(displayLayout)
whenever(displayController.getDisplayContext(anyInt())).thenReturn(mockDisplayContext)
whenever(displayController.getDisplay(anyInt())).thenReturn(display)
@@ -917,7 +919,10 @@
}
@Test
- @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+ @DisableFlags(
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY,
+ Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND,
+ )
fun showDesktopApps_twoDisplays_bringsToFrontOnlyOneDisplay_desktopWallpaperDisabled() {
taskRepository.addDesk(displayId = SECOND_DISPLAY, deskId = SECOND_DISPLAY)
val homeTaskDefaultDisplay = setUpHomeTask(DEFAULT_DISPLAY)
@@ -2039,6 +2044,30 @@
}
@Test
+ @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun moveToFullscreen_fromDesk_reparentsToTaskDisplayArea() {
+ val task = setUpFreeformTask()
+ val tda = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY)!!
+
+ controller.moveToFullscreen(task.taskId, transitionSource = UNKNOWN)
+
+ val wct = getLatestExitDesktopWct()
+ wct.assertHop(ReparentPredicate(token = task.token, parentToken = tda.token, toTop = true))
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun moveToFullscreen_fromDesk_deactivatesDesk() {
+ val task = setUpFreeformTask()
+ val tda = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY)!!
+
+ controller.moveToFullscreen(task.taskId, transitionSource = UNKNOWN)
+
+ val wct = getLatestExitDesktopWct()
+ verify(desksOrganizer).deactivateDesk(wct, deskId = 0)
+ }
+
+ @Test
fun moveToFullscreen_tdaFullscreen_windowingModeSetToUndefined() {
val task = setUpFreeformTask()
val tda = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY)!!
@@ -2053,6 +2082,7 @@
@Test
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WALLPAPER_ACTIVITY_FOR_SYSTEM_USER)
+ @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
fun moveToFullscreen_tdaFullscreen_windowingModeUndefined_removesWallpaperActivity() {
whenever(DesktopModeStatus.enterDesktopByDefaultOnFreeformDisplay(context)).thenReturn(true)
val homeTask = setUpHomeTask()
@@ -2078,6 +2108,60 @@
}
@Test
+ @EnableFlags(
+ Flags.FLAG_ENABLE_DESKTOP_WALLPAPER_ACTIVITY_FOR_SYSTEM_USER,
+ Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND,
+ )
+ fun moveToFullscreen_tdaFullscreen_windowingModeUndefined_removesWallpaperActivity_multiDesksEnabled() {
+ whenever(DesktopModeStatus.enterDesktopByDefaultOnFreeformDisplay(context)).thenReturn(true)
+ setUpHomeTask()
+ val task = setUpFreeformTask()
+ assertNotNull(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY))
+ .configuration
+ .windowConfiguration
+ .windowingMode = WINDOWING_MODE_FULLSCREEN
+
+ controller.moveToFullscreen(task.taskId, transitionSource = UNKNOWN)
+
+ val wct = getLatestExitDesktopWct()
+ val taskChange = assertNotNull(wct.changes[task.token.asBinder()])
+ verify(desktopModeEnterExitTransitionListener)
+ .onExitDesktopModeTransitionStarted(FULLSCREEN_ANIMATION_DURATION)
+ assertThat(taskChange.windowingMode).isEqualTo(WINDOWING_MODE_UNDEFINED)
+ // Removes wallpaper activity when leaving desktop
+ wct.assertReorder(wallpaperToken, toTop = false)
+ }
+
+ @Test
+ @EnableFlags(
+ Flags.FLAG_ENABLE_DESKTOP_WALLPAPER_ACTIVITY_FOR_SYSTEM_USER,
+ Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND,
+ )
+ fun moveToFullscreen_tdaFullscreen_windowingModeUndefined_homeBehindFullscreen_multiDesksEnabled() {
+ whenever(DesktopModeStatus.enterDesktopByDefaultOnFreeformDisplay(context)).thenReturn(true)
+ val homeTask = setUpHomeTask()
+ val task = setUpFreeformTask()
+ assertNotNull(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY))
+ .configuration
+ .windowConfiguration
+ .windowingMode = WINDOWING_MODE_FULLSCREEN
+
+ controller.moveToFullscreen(task.taskId, transitionSource = UNKNOWN)
+
+ val wct = getLatestExitDesktopWct()
+ val taskChange = assertNotNull(wct.changes[task.token.asBinder()])
+ verify(desktopModeEnterExitTransitionListener)
+ .onExitDesktopModeTransitionStarted(FULLSCREEN_ANIMATION_DURATION)
+ assertThat(taskChange.windowingMode).isEqualTo(WINDOWING_MODE_UNDEFINED)
+ // Moves home task behind the fullscreen task
+ val homeReorderIndex = wct.indexOfReorder(homeTask, toTop = true)
+ val fullscreenReorderIndex = wct.indexOfReorder(task, toTop = true)
+ assertThat(homeReorderIndex).isNotEqualTo(-1)
+ assertThat(fullscreenReorderIndex).isNotEqualTo(-1)
+ assertThat(fullscreenReorderIndex).isGreaterThan(homeReorderIndex)
+ }
+
+ @Test
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WALLPAPER_ACTIVITY_FOR_SYSTEM_USER)
fun moveToFullscreen_tdaFreeform_enforcedDesktop_doesNotReorderHome() {
whenever(DesktopModeStatus.enterDesktopByDefaultOnFreeformDisplay(context)).thenReturn(true)
@@ -2093,9 +2177,9 @@
val wct = getLatestExitDesktopWct()
verify(desktopModeEnterExitTransitionListener)
.onExitDesktopModeTransitionStarted(FULLSCREEN_ANIMATION_DURATION)
- assertThat(wct.hierarchyOps).hasSize(1)
// Removes wallpaper activity when leaving desktop but doesn't reorder home or the task
- wct.assertReorderAt(index = 0, wallpaperToken, toTop = false)
+ wct.assertReorder(wallpaperToken, toTop = false)
+ wct.assertWithoutHop(ReorderPredicate(homeTask.token, toTop = null))
}
@Test
@@ -2113,6 +2197,7 @@
@Test
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WALLPAPER_ACTIVITY_FOR_SYSTEM_USER)
+ @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
fun moveToFullscreen_tdaFreeform_windowingModeFullscreen_removesWallpaperActivity() {
val homeTask = setUpHomeTask()
val task = setUpFreeformTask()
@@ -2138,6 +2223,61 @@
}
@Test
+ @EnableFlags(
+ Flags.FLAG_ENABLE_DESKTOP_WALLPAPER_ACTIVITY_FOR_SYSTEM_USER,
+ Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND,
+ )
+ fun moveToFullscreen_tdaFreeform_windowingModeFullscreen_removesWallpaperActivity_multiDesksEnabled() {
+ val homeTask = setUpHomeTask()
+ val task = setUpFreeformTask()
+
+ assertNotNull(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY))
+ .configuration
+ .windowConfiguration
+ .windowingMode = WINDOWING_MODE_FREEFORM
+
+ controller.moveToFullscreen(task.taskId, transitionSource = UNKNOWN)
+
+ val wct = getLatestExitDesktopWct()
+ val taskChange = assertNotNull(wct.changes[task.token.asBinder()])
+ assertThat(taskChange.windowingMode).isEqualTo(WINDOWING_MODE_FULLSCREEN)
+ verify(desktopModeEnterExitTransitionListener)
+ .onExitDesktopModeTransitionStarted(FULLSCREEN_ANIMATION_DURATION)
+ // Removes wallpaper activity when leaving desktop
+ wct.assertReorder(wallpaperToken, toTop = false)
+ }
+
+ @Test
+ @EnableFlags(
+ Flags.FLAG_ENABLE_DESKTOP_WALLPAPER_ACTIVITY_FOR_SYSTEM_USER,
+ Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND,
+ )
+ fun moveToFullscreen_tdaFreeform_windowingModeFullscreen_homeBehindFullscreen_multiDesksEnabled() {
+ val homeTask = setUpHomeTask()
+ val task = setUpFreeformTask()
+
+ assertNotNull(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY))
+ .configuration
+ .windowConfiguration
+ .windowingMode = WINDOWING_MODE_FREEFORM
+
+ controller.moveToFullscreen(task.taskId, transitionSource = UNKNOWN)
+
+ val wct = getLatestExitDesktopWct()
+ val taskChange = assertNotNull(wct.changes[task.token.asBinder()])
+ assertThat(taskChange.windowingMode).isEqualTo(WINDOWING_MODE_FULLSCREEN)
+ verify(desktopModeEnterExitTransitionListener)
+ .onExitDesktopModeTransitionStarted(FULLSCREEN_ANIMATION_DURATION)
+ // Moves home task behind the fullscreen task
+ val homeReorderIndex = wct.indexOfReorder(homeTask, toTop = true)
+ val fullscreenReorderIndex = wct.indexOfReorder(task, toTop = true)
+ assertThat(homeReorderIndex).isNotEqualTo(-1)
+ assertThat(fullscreenReorderIndex).isNotEqualTo(-1)
+ assertThat(fullscreenReorderIndex).isGreaterThan(homeReorderIndex)
+ }
+
+ @Test
+ @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
fun moveToFullscreen_multipleVisibleNonMinimizedTasks_doesNotRemoveWallpaperActivity() {
val homeTask = setUpHomeTask()
val task1 = setUpFreeformTask()
@@ -2164,6 +2304,29 @@
}
@Test
+ @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun moveToFullscreen_multipleVisibleNonMinimizedTasks_doesNotRemoveWallpaperActivity_multiDesksEnabled() {
+ val homeTask = setUpHomeTask()
+ val task1 = setUpFreeformTask()
+ // Setup task2
+ setUpFreeformTask()
+
+ val tdaInfo = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY)
+ assertNotNull(tdaInfo).configuration.windowConfiguration.windowingMode =
+ WINDOWING_MODE_FULLSCREEN
+
+ controller.moveToFullscreen(task1.taskId, transitionSource = UNKNOWN)
+
+ val wct = getLatestExitDesktopWct()
+ val task1Change = assertNotNull(wct.changes[task1.token.asBinder()])
+ assertThat(task1Change.windowingMode).isEqualTo(WINDOWING_MODE_UNDEFINED)
+ verify(desktopModeEnterExitTransitionListener)
+ .onExitDesktopModeTransitionStarted(FULLSCREEN_ANIMATION_DURATION)
+ // Does not remove wallpaper activity, as desktop still has a visible desktop task
+ wct.assertWithoutHop(ReorderPredicate(wallpaperToken, toTop = false))
+ }
+
+ @Test
fun moveToFullscreen_nonExistentTask_doesNothing() {
controller.moveToFullscreen(999, transitionSource = UNKNOWN)
verifyExitDesktopWCTNotExecuted()
@@ -2737,7 +2900,10 @@
}
@Test
- @EnableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_PIP)
+ @EnableFlags(
+ FLAG_ENABLE_DESKTOP_WINDOWING_PIP,
+ Flags.FLAG_ENABLE_DESKTOP_WALLPAPER_ACTIVITY_FOR_SYSTEM_USER,
+ )
fun onDesktopWindowClose_minimizedPipNotPresent_exitDesktop() {
val freeformTask = setUpFreeformTask()
val pipTask = setUpPipTask(autoEnterEnabled = true)
@@ -2752,10 +2918,34 @@
val wct = WindowContainerTransaction()
controller.onDesktopWindowClose(wct, displayId = DEFAULT_DISPLAY, freeformTask)
- // Remove wallpaper operation
- wct.hierarchyOps.any { hop ->
- hop.type == HIERARCHY_OP_TYPE_REMOVE_TASK && hop.container == wallpaperToken.asBinder()
- }
+ // Moves wallpaper activity to back when leaving desktop
+ wct.assertReorder(wallpaperToken, toTop = false)
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun onDesktopWindowClose_lastWindow_deactivatesDesk() {
+ val task = setUpFreeformTask()
+ val wct = WindowContainerTransaction()
+
+ controller.onDesktopWindowClose(wct, displayId = DEFAULT_DISPLAY, task)
+
+ verify(desksOrganizer).deactivateDesk(wct, deskId = 0)
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun onDesktopWindowClose_lastWindow_addsPendingDeactivateTransition() {
+ val task = setUpFreeformTask()
+ val wct = WindowContainerTransaction()
+
+ val transition = Binder()
+ val runOnTransitStart =
+ controller.onDesktopWindowClose(wct, displayId = DEFAULT_DISPLAY, task)
+ runOnTransitStart(transition)
+
+ verify(desksTransitionsObserver)
+ .addPendingTransition(DeskTransition.DeactivateDesk(transition, deskId = 0))
}
@Test
@@ -2782,6 +2972,48 @@
}
@Test
+ @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun onDesktopWindowMinimize_lastWindow_deactivatesDesk() {
+ val task = setUpFreeformTask()
+ val transition = Binder()
+ whenever(
+ freeformTaskTransitionStarter.startMinimizedModeTransition(
+ any(),
+ anyInt(),
+ anyBoolean(),
+ )
+ )
+ .thenReturn(transition)
+
+ controller.minimizeTask(task, MinimizeReason.MINIMIZE_BUTTON)
+
+ val captor = argumentCaptor<WindowContainerTransaction>()
+ verify(freeformTaskTransitionStarter)
+ .startMinimizedModeTransition(captor.capture(), eq(task.taskId), eq(true))
+ verify(desksOrganizer).deactivateDesk(captor.firstValue, deskId = 0)
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun onDesktopWindowMinimize_lastWindow_addsPendingDeactivateTransition() {
+ val task = setUpFreeformTask()
+ val transition = Binder()
+ whenever(
+ freeformTaskTransitionStarter.startMinimizedModeTransition(
+ any(),
+ anyInt(),
+ anyBoolean(),
+ )
+ )
+ .thenReturn(transition)
+
+ controller.minimizeTask(task, MinimizeReason.MINIMIZE_BUTTON)
+
+ verify(desksTransitionsObserver)
+ .addPendingTransition(DeskTransition.DeactivateDesk(token = transition, deskId = 0))
+ }
+
+ @Test
fun onPipTaskMinimize_autoEnterEnabled_startPipTransition() {
val task = setUpPipTask(autoEnterEnabled = true)
val handler = mock(TransitionHandler::class.java)
@@ -2993,6 +3225,24 @@
}
@Test
+ fun onDesktopWindowMinimize_triesToStopTiling() {
+ val task = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
+ val transition = Binder()
+ whenever(
+ freeformTaskTransitionStarter.startMinimizedModeTransition(
+ any(),
+ anyInt(),
+ anyBoolean(),
+ )
+ )
+ .thenReturn(transition)
+
+ controller.minimizeTask(task, MinimizeReason.MINIMIZE_BUTTON)
+
+ verify(snapEventHandler).removeTaskIfTiled(eq(DEFAULT_DISPLAY), eq(task.taskId))
+ }
+
+ @Test
fun handleRequest_fullscreenTask_freeformVisible_returnSwitchToFreeformWCT() {
val homeTask = setUpHomeTask()
val freeformTask = setUpFreeformTask()
@@ -4033,10 +4283,11 @@
val taskChange = assertNotNull(wct.changes[task2.token.asBinder()])
assertThat(taskChange.windowingMode)
.isEqualTo(WINDOWING_MODE_UNDEFINED) // inherited FULLSCREEN
- wct.assertReorderAt(index = 0, wallpaperToken, toTop = false)
+ wct.assertReorder(wallpaperToken, toTop = false)
}
@Test
+ @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
fun moveFocusedTaskToFullscreen_multipleVisibleTasks_doesNotRemoveWallpaperActivity() {
val homeTask = setUpHomeTask()
val task1 = setUpFreeformTask()
@@ -4060,7 +4311,56 @@
}
@Test
- @EnableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_PIP)
+ @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun moveFocusedTaskToFullscreen_multipleVisibleTasks_doesNotRemoveWallpaperActivity_multiDesksEnabled() {
+ val homeTask = setUpHomeTask()
+ val task1 = setUpFreeformTask()
+ val task2 = setUpFreeformTask()
+ val task3 = setUpFreeformTask()
+
+ task1.isFocused = false
+ task2.isFocused = true
+ task3.isFocused = false
+ controller.enterFullscreen(DEFAULT_DISPLAY, transitionSource = UNKNOWN)
+
+ val wct = getLatestExitDesktopWct()
+ val taskChange = assertNotNull(wct.changes[task2.token.asBinder()])
+ assertThat(taskChange.windowingMode)
+ .isEqualTo(WINDOWING_MODE_UNDEFINED) // inherited FULLSCREEN
+ // Does not remove wallpaper activity
+ wct.assertWithoutHop(ReorderPredicate(wallpaperToken, toTop = null))
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun moveFocusedTaskToFullscreen_multipleVisibleTasks_fullscreenOverHome_multiDesksEnabled() {
+ val homeTask = setUpHomeTask()
+ val task1 = setUpFreeformTask()
+ val task2 = setUpFreeformTask()
+ val task3 = setUpFreeformTask()
+
+ task1.isFocused = false
+ task2.isFocused = true
+ task3.isFocused = false
+ controller.enterFullscreen(DEFAULT_DISPLAY, transitionSource = UNKNOWN)
+
+ val wct = getLatestExitDesktopWct()
+ val taskChange = assertNotNull(wct.changes[task2.token.asBinder()])
+ assertThat(taskChange.windowingMode)
+ .isEqualTo(WINDOWING_MODE_UNDEFINED) // inherited FULLSCREEN
+ // Moves home task behind the fullscreen task
+ val homeReorderIndex = wct.indexOfReorder(homeTask, toTop = true)
+ val fullscreenReorderIndex = wct.indexOfReorder(task2, toTop = true)
+ assertThat(homeReorderIndex).isNotEqualTo(-1)
+ assertThat(fullscreenReorderIndex).isNotEqualTo(-1)
+ assertThat(fullscreenReorderIndex).isGreaterThan(homeReorderIndex)
+ }
+
+ @Test
+ @EnableFlags(
+ FLAG_ENABLE_DESKTOP_WINDOWING_PIP,
+ Flags.FLAG_ENABLE_DESKTOP_WALLPAPER_ACTIVITY_FOR_SYSTEM_USER,
+ )
fun moveFocusedTaskToFullscreen_minimizedPipPresent_removeWallpaperActivity() {
val freeformTask = setUpFreeformTask()
val pipTask = setUpPipTask(autoEnterEnabled = true)
@@ -4078,10 +4378,8 @@
val taskChange = assertNotNull(wct.changes[freeformTask.token.asBinder()])
assertThat(taskChange.windowingMode)
.isEqualTo(WINDOWING_MODE_UNDEFINED) // inherited FULLSCREEN
- // Remove wallpaper operation
- wct.hierarchyOps.any { hop ->
- hop.type == HIERARCHY_OP_TYPE_REMOVE_TASK && hop.container == wallpaperToken.asBinder()
- }
+ // Moves wallpaper activity to back when leaving desktop
+ wct.assertReorder(wallpaperToken, toTop = false)
}
@Test
@@ -6327,15 +6625,46 @@
assertThat(hierarchyOps.none(predicate)).isTrue()
}
+private fun WindowContainerTransaction.indexOfReorder(
+ task: RunningTaskInfo,
+ toTop: Boolean? = null,
+): Int {
+ val hop = hierarchyOps.singleOrNull(ReorderPredicate(task.token, toTop)) ?: return -1
+ return hierarchyOps.indexOf(hop)
+}
+
+private class ReorderPredicate(val token: WindowContainerToken, val toTop: Boolean? = null) :
+ ((WindowContainerTransaction.HierarchyOp) -> Boolean) {
+ override fun invoke(hop: WindowContainerTransaction.HierarchyOp): Boolean =
+ hop.type == HIERARCHY_OP_TYPE_REORDER &&
+ (toTop == null || hop.toTop == toTop) &&
+ hop.container == token.asBinder()
+}
+
+private class ReparentPredicate(
+ val token: WindowContainerToken,
+ val parentToken: WindowContainerToken,
+ val toTop: Boolean? = null,
+) : ((WindowContainerTransaction.HierarchyOp) -> Boolean) {
+ override fun invoke(hop: WindowContainerTransaction.HierarchyOp): Boolean =
+ hop.isReparent &&
+ (toTop == null || hop.toTop == toTop) &&
+ hop.container == token.asBinder() &&
+ hop.newParent == parentToken.asBinder()
+}
+
private fun WindowContainerTransaction.assertReorder(
task: RunningTaskInfo,
toTop: Boolean? = null,
) {
- assertHop { hop ->
- hop.type == HIERARCHY_OP_TYPE_REORDER &&
- (toTop == null || hop.toTop == toTop) &&
- hop.container == task.token.asBinder()
- }
+ assertReorder(task.token, toTop)
+}
+
+private fun WindowContainerTransaction.assertReorder(
+ token: WindowContainerToken,
+ toTop: Boolean? = null,
+) {
+ assertHop(ReorderPredicate(token, toTop))
}
private fun WindowContainerTransaction.assertReorderAt(
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserverTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserverTest.kt
index c29edec..dd577f4 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserverTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserverTest.kt
@@ -24,6 +24,7 @@
import android.content.Intent
import android.os.Binder
import android.os.IBinder
+import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import android.view.Display.DEFAULT_DISPLAY
import android.view.WindowManager
@@ -168,7 +169,8 @@
@Test
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION)
- fun backNavigation_withCloseTransitionLastTask_taskMinimized() {
+ @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WALLPAPER_ACTIVITY_FOR_SYSTEM_USER)
+ fun backNavigation_withCloseTransitionLastTask_wallpaperActivityClosed_taskMinimized() {
val task = createTaskInfo(1)
val transition = mock<IBinder>()
whenever(taskRepository.getVisibleTaskCount(any())).thenReturn(1)
@@ -193,6 +195,35 @@
}
@Test
+ @EnableFlags(
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION,
+ Flags.FLAG_ENABLE_DESKTOP_WALLPAPER_ACTIVITY_FOR_SYSTEM_USER,
+ )
+ fun backNavigation_withCloseTransitionLastTask_wallpaperActivityReordered_taskMinimized() {
+ val task = createTaskInfo(1)
+ val transition = mock<IBinder>()
+ whenever(taskRepository.getVisibleTaskCount(any())).thenReturn(1)
+ whenever(taskRepository.isClosingTask(task.taskId)).thenReturn(false)
+ whenever(backAnimationController.latestTriggerBackTask).thenReturn(task.taskId)
+
+ transitionObserver.onTransitionReady(
+ transition = transition,
+ info = createBackNavigationTransition(task, TRANSIT_CLOSE, true, TRANSIT_TO_BACK),
+ startTransaction = mock(),
+ finishTransaction = mock(),
+ )
+
+ verify(taskRepository).minimizeTask(task.displayId, task.taskId)
+ val pendingTransition =
+ DesktopMixedTransitionHandler.PendingMixedTransition.Minimize(
+ transition,
+ task.taskId,
+ isLastTask = true,
+ )
+ verify(mixedHandler).addPendingMixedTransition(pendingTransition)
+ }
+
+ @Test
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION)
fun backNavigation_nullTaskInfo_taskNotMinimized() {
val task = createTaskInfo(1)
@@ -434,6 +465,7 @@
task: RunningTaskInfo?,
type: Int = TRANSIT_TO_BACK,
withWallpaper: Boolean = false,
+ wallpaperChangeMode: Int = TRANSIT_CLOSE,
): TransitionInfo {
return TransitionInfo(type, /* flags= */ 0).apply {
addChange(
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/desktopwallpaperactivity/DesktopWallpaperActivityTokenProviderTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/desktopwallpaperactivity/DesktopWallpaperActivityTokenProviderTest.kt
new file mode 100644
index 0000000..aa4e9aa
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/desktopwallpaperactivity/DesktopWallpaperActivityTokenProviderTest.kt
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2025 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.desktopmode.desktopwallpaperactivity
+
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper.RunWithLooper
+import android.view.Display.DEFAULT_DISPLAY
+import androidx.test.filters.SmallTest
+import com.android.wm.shell.MockToken
+import com.android.wm.shell.ShellTestCase
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * Test class for [DesktopWallpaperActivityTokenProvider]
+ *
+ * Usage: atest WMShellUnitTests:DesktopWallpaperActivityTokenProviderTest
+ */
+@SmallTest
+@RunWithLooper
+@RunWith(AndroidTestingRunner::class)
+class DesktopWallpaperActivityTokenProviderTest : ShellTestCase() {
+
+ private lateinit var provider: DesktopWallpaperActivityTokenProvider
+ private val DEFAULT_DISPLAY = 0
+ private val SECONDARY_DISPLAY = 1
+
+ @Before
+ fun setUp() {
+ provider = DesktopWallpaperActivityTokenProvider()
+ }
+
+ @Test
+ fun setToken_setsTokenForDisplay() {
+ val token = MockToken().token()
+
+ provider.setToken(token, DEFAULT_DISPLAY)
+
+ assertThat(provider.getToken(DEFAULT_DISPLAY)).isEqualTo(token)
+ }
+
+ @Test
+ fun setToken_overwritesExistingTokenForDisplay() {
+ val token1 = MockToken().token()
+ val token2 = MockToken().token()
+
+ provider.setToken(token1, DEFAULT_DISPLAY)
+ provider.setToken(token2, DEFAULT_DISPLAY)
+
+ assertThat(provider.getToken(DEFAULT_DISPLAY)).isEqualTo(token2)
+ }
+
+ @Test
+ fun getToken_returnsNullForNonExistentDisplay() {
+ assertThat(provider.getToken(SECONDARY_DISPLAY)).isNull()
+ }
+
+ @Test
+ fun removeToken_removesTokenForDisplay() {
+ val token = MockToken().token()
+
+ provider.setToken(token, DEFAULT_DISPLAY)
+ provider.removeToken(DEFAULT_DISPLAY)
+
+ assertThat(provider.getToken(DEFAULT_DISPLAY)).isNull()
+ }
+
+ @Test
+ fun removeToken_withToken_removesTokenForDisplay() {
+ val token = MockToken().token()
+
+ provider.setToken(token, DEFAULT_DISPLAY)
+ provider.removeToken(token)
+
+ assertThat(provider.getToken(DEFAULT_DISPLAY)).isNull()
+ }
+
+ @Test
+ fun removeToken_doesNothingForNonExistentDisplay() {
+ provider.removeToken(SECONDARY_DISPLAY)
+
+ assertThat(provider.getToken(SECONDARY_DISPLAY)).isNull()
+ }
+
+ @Test
+ fun removeToken_withNonExistentToken_doesNothing() {
+ val token1 = MockToken().token()
+ val token2 = MockToken().token()
+
+ provider.setToken(token1, DEFAULT_DISPLAY)
+ provider.removeToken(token2)
+
+ assertThat(provider.getToken(DEFAULT_DISPLAY)).isEqualTo(token1)
+ }
+
+ @Test
+ fun multipleDisplays_tokensAreIndependent() {
+ val token1 = MockToken().token()
+ val token2 = MockToken().token()
+
+ provider.setToken(token1, DEFAULT_DISPLAY)
+ provider.setToken(token2, SECONDARY_DISPLAY)
+
+ assertThat(provider.getToken(DEFAULT_DISPLAY)).isEqualTo(token1)
+ assertThat(provider.getToken(SECONDARY_DISPLAY)).isEqualTo(token2)
+
+ provider.removeToken(DEFAULT_DISPLAY)
+
+ assertThat(provider.getToken(DEFAULT_DISPLAY)).isNull()
+ assertThat(provider.getToken(SECONDARY_DISPLAY)).isEqualTo(token2)
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/multidesks/DesksTransitionObserverTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/multidesks/DesksTransitionObserverTest.kt
index 9f09e3f..4dcf669 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/multidesks/DesksTransitionObserverTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/multidesks/DesksTransitionObserverTest.kt
@@ -20,6 +20,7 @@
import android.platform.test.flag.junit.SetFlagsRule
import android.testing.AndroidTestingRunner
import android.view.Display.DEFAULT_DISPLAY
+import android.view.WindowManager.TRANSIT_CHANGE
import android.view.WindowManager.TRANSIT_CLOSE
import android.view.WindowManager.TRANSIT_TO_FRONT
import android.window.TransitionInfo
@@ -177,4 +178,70 @@
assertThat(repository.getActiveDeskId(DEFAULT_DISPLAY)).isEqualTo(deskId)
assertThat(repository.getActiveTaskIdsInDesk(deskId)).contains(task.taskId)
}
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun onTransitionReady_deactivateDesk_updatesRepository() {
+ val transition = Binder()
+ val deskChange = Change(mock(), mock())
+ whenever(mockDesksOrganizer.isDeskChange(deskChange, deskId = 5)).thenReturn(true)
+ val deactivateTransition = DeskTransition.DeactivateDesk(transition, deskId = 5)
+ repository.addDesk(DEFAULT_DISPLAY, deskId = 5)
+ repository.setActiveDesk(DEFAULT_DISPLAY, deskId = 5)
+
+ observer.addPendingTransition(deactivateTransition)
+ observer.onTransitionReady(
+ transition = transition,
+ info = TransitionInfo(TRANSIT_CHANGE, /* flags= */ 0).apply { addChange(deskChange) },
+ )
+
+ assertThat(repository.getActiveDeskId(DEFAULT_DISPLAY)).isNull()
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun onTransitionReady_deactivateDeskWithExitingTask_updatesRepository() {
+ val transition = Binder()
+ val exitingTask = createFreeformTask(DEFAULT_DISPLAY)
+ val exitingTaskChange = Change(mock(), mock()).apply { taskInfo = exitingTask }
+ whenever(mockDesksOrganizer.getDeskAtEnd(exitingTaskChange)).thenReturn(null)
+ val deactivateTransition = DeskTransition.DeactivateDesk(transition, deskId = 5)
+ repository.addDesk(DEFAULT_DISPLAY, deskId = 5)
+ repository.setActiveDesk(DEFAULT_DISPLAY, deskId = 5)
+ repository.addTaskToDesk(
+ displayId = DEFAULT_DISPLAY,
+ deskId = 5,
+ taskId = exitingTask.taskId,
+ isVisible = true,
+ )
+ assertThat(repository.isActiveTaskInDesk(deskId = 5, taskId = exitingTask.taskId)).isTrue()
+
+ observer.addPendingTransition(deactivateTransition)
+ observer.onTransitionReady(
+ transition = transition,
+ info =
+ TransitionInfo(TRANSIT_CHANGE, /* flags= */ 0).apply {
+ addChange(exitingTaskChange)
+ },
+ )
+
+ assertThat(repository.isActiveTaskInDesk(deskId = 5, taskId = exitingTask.taskId)).isFalse()
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun onTransitionReady_deactivateDeskWithoutVisibleChange_updatesRepository() {
+ val transition = Binder()
+ val deactivateTransition = DeskTransition.DeactivateDesk(transition, deskId = 5)
+ repository.addDesk(DEFAULT_DISPLAY, deskId = 5)
+ repository.setActiveDesk(DEFAULT_DISPLAY, deskId = 5)
+
+ observer.addPendingTransition(deactivateTransition)
+ observer.onTransitionReady(
+ transition = transition,
+ info = TransitionInfo(TRANSIT_CHANGE, /* flags= */ 0),
+ )
+
+ assertThat(repository.getActiveDeskId(DEFAULT_DISPLAY)).isNull()
+ }
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/multidesks/RootTaskDesksOrganizerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/multidesks/RootTaskDesksOrganizerTest.kt
index 4d4b153..8b10ca1 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/multidesks/RootTaskDesksOrganizerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/multidesks/RootTaskDesksOrganizerTest.kt
@@ -23,11 +23,13 @@
import android.window.TransitionInfo
import android.window.WindowContainerTransaction
import android.window.WindowContainerTransaction.HierarchyOp
+import android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_LAUNCH_ROOT
import androidx.test.filters.SmallTest
import com.android.wm.shell.ShellTaskOrganizer
import com.android.wm.shell.ShellTestCase
import com.android.wm.shell.TestShellExecutor
import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFreeformTask
+import com.android.wm.shell.desktopmode.multidesks.RootTaskDesksOrganizer.DeskRoot
import com.android.wm.shell.sysui.ShellCommandHandler
import com.android.wm.shell.sysui.ShellInit
import com.google.common.truth.Truth.assertThat
@@ -104,54 +106,45 @@
@Test
fun testOnTaskVanished_removesRoot() {
- val callback = FakeOnCreateCallback()
- organizer.createDesk(Display.DEFAULT_DISPLAY, callback)
- val freeformRoot = createFreeformTask().apply { parentTaskId = -1 }
- organizer.onTaskAppeared(freeformRoot, SurfaceControl())
+ val desk = createDesk()
- organizer.onTaskVanished(freeformRoot)
+ organizer.onTaskVanished(desk.taskInfo)
- assertThat(organizer.roots.contains(freeformRoot.taskId)).isFalse()
+ assertThat(organizer.roots.contains(desk.deskId)).isFalse()
}
@Test
fun testDesktopWindowAppearsInDesk() {
- organizer.createDesk(Display.DEFAULT_DISPLAY, FakeOnCreateCallback())
- val freeformRoot = createFreeformTask().apply { parentTaskId = -1 }
- organizer.onTaskAppeared(freeformRoot, SurfaceControl())
- val child = createFreeformTask().apply { parentTaskId = freeformRoot.taskId }
+ val desk = createDesk()
+ val child = createFreeformTask().apply { parentTaskId = desk.deskId }
organizer.onTaskAppeared(child, SurfaceControl())
- assertThat(organizer.roots[freeformRoot.taskId].children).contains(child.taskId)
+ assertThat(desk.children).contains(child.taskId)
}
@Test
fun testDesktopWindowDisappearsFromDesk() {
- organizer.createDesk(Display.DEFAULT_DISPLAY, FakeOnCreateCallback())
- val freeformRoot = createFreeformTask().apply { parentTaskId = -1 }
- organizer.onTaskAppeared(freeformRoot, SurfaceControl())
- val child = createFreeformTask().apply { parentTaskId = freeformRoot.taskId }
+ val desk = createDesk()
+ val child = createFreeformTask().apply { parentTaskId = desk.deskId }
organizer.onTaskAppeared(child, SurfaceControl())
organizer.onTaskVanished(child)
- assertThat(organizer.roots[freeformRoot.taskId].children).doesNotContain(child.taskId)
+ assertThat(desk.children).doesNotContain(child.taskId)
}
@Test
fun testRemoveDesk() {
- organizer.createDesk(Display.DEFAULT_DISPLAY, FakeOnCreateCallback())
- val freeformRoot = createFreeformTask().apply { parentTaskId = -1 }
- organizer.onTaskAppeared(freeformRoot, SurfaceControl())
+ val desk = createDesk()
val wct = WindowContainerTransaction()
- organizer.removeDesk(wct, freeformRoot.taskId)
+ organizer.removeDesk(wct, desk.deskId)
assertThat(
wct.hierarchyOps.any { hop ->
hop.type == HierarchyOp.HIERARCHY_OP_TYPE_REMOVE_ROOT_TASK &&
- hop.container == freeformRoot.token.asBinder()
+ hop.container == desk.taskInfo.token.asBinder()
}
)
.isTrue()
@@ -167,25 +160,23 @@
@Test
fun testActivateDesk() {
- organizer.createDesk(Display.DEFAULT_DISPLAY, FakeOnCreateCallback())
- val freeformRoot = createFreeformTask().apply { parentTaskId = -1 }
- organizer.onTaskAppeared(freeformRoot, SurfaceControl())
+ val desk = createDesk()
val wct = WindowContainerTransaction()
- organizer.activateDesk(wct, freeformRoot.taskId)
+ organizer.activateDesk(wct, desk.deskId)
assertThat(
wct.hierarchyOps.any { hop ->
hop.type == HierarchyOp.HIERARCHY_OP_TYPE_REORDER &&
hop.toTop &&
- hop.container == freeformRoot.token.asBinder()
+ hop.container == desk.taskInfo.token.asBinder()
}
)
.isTrue()
assertThat(
wct.hierarchyOps.any { hop ->
hop.type == HierarchyOp.HIERARCHY_OP_TYPE_SET_LAUNCH_ROOT &&
- hop.container == freeformRoot.token.asBinder()
+ hop.container == desk.taskInfo.token.asBinder()
}
)
.isTrue()
@@ -201,20 +192,18 @@
@Test
fun testMoveTaskToDesk() {
- organizer.createDesk(Display.DEFAULT_DISPLAY, FakeOnCreateCallback())
- val freeformRoot = createFreeformTask().apply { parentTaskId = -1 }
- organizer.onTaskAppeared(freeformRoot, SurfaceControl())
+ val desk = createDesk()
val desktopTask = createFreeformTask().apply { parentTaskId = -1 }
val wct = WindowContainerTransaction()
- organizer.moveTaskToDesk(wct, freeformRoot.taskId, desktopTask)
+ organizer.moveTaskToDesk(wct, desk.deskId, desktopTask)
assertThat(
wct.hierarchyOps.any { hop ->
hop.isReparent &&
hop.toTop &&
hop.container == desktopTask.token.asBinder() &&
- hop.newParent == freeformRoot.token.asBinder()
+ hop.newParent == desk.taskInfo.token.asBinder()
}
)
.isTrue()
@@ -240,17 +229,15 @@
@Test
fun testGetDeskAtEnd() {
- organizer.createDesk(Display.DEFAULT_DISPLAY, FakeOnCreateCallback())
- val freeformRoot = createFreeformTask().apply { parentTaskId = -1 }
- organizer.onTaskAppeared(freeformRoot, SurfaceControl())
+ val desk = createDesk()
- val task = createFreeformTask().apply { parentTaskId = freeformRoot.taskId }
+ val task = createFreeformTask().apply { parentTaskId = desk.deskId }
val endDesk =
organizer.getDeskAtEnd(
TransitionInfo.Change(task.token, SurfaceControl()).apply { taskInfo = task }
)
- assertThat(endDesk).isEqualTo(freeformRoot.taskId)
+ assertThat(endDesk).isEqualTo(desk.deskId)
}
@Test
@@ -273,6 +260,47 @@
assertThat(isActive).isTrue()
}
+ @Test
+ fun deactivateDesk_clearsLaunchRoot() {
+ val wct = WindowContainerTransaction()
+ val desk = createDesk()
+ organizer.activateDesk(wct, desk.deskId)
+
+ organizer.deactivateDesk(wct, desk.deskId)
+
+ assertThat(
+ wct.hierarchyOps.any { hop ->
+ hop.type == HIERARCHY_OP_TYPE_SET_LAUNCH_ROOT &&
+ hop.container == desk.taskInfo.token.asBinder() &&
+ hop.windowingModes == null &&
+ hop.activityTypes == null
+ }
+ )
+ .isTrue()
+ }
+
+ @Test
+ fun isDeskChange() {
+ val desk = createDesk()
+
+ assertThat(
+ organizer.isDeskChange(
+ TransitionInfo.Change(desk.taskInfo.token, desk.leash).apply {
+ taskInfo = desk.taskInfo
+ },
+ desk.deskId,
+ )
+ )
+ .isTrue()
+ }
+
+ private fun createDesk(): DeskRoot {
+ organizer.createDesk(Display.DEFAULT_DISPLAY, FakeOnCreateCallback())
+ val freeformRoot = createFreeformTask().apply { parentTaskId = -1 }
+ organizer.onTaskAppeared(freeformRoot, SurfaceControl())
+ return organizer.roots[freeformRoot.taskId]
+ }
+
private class FakeOnCreateCallback : DesksOrganizer.OnCreateCallback {
var deskId: Int? = null
val created: Boolean
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipSchedulerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipSchedulerTest.java
index 8e0381e..0c19529 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipSchedulerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipSchedulerTest.java
@@ -19,6 +19,7 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.when;
@@ -26,6 +27,7 @@
import static org.mockito.kotlin.VerificationKt.times;
import static org.mockito.kotlin.VerificationKt.verify;
+import android.app.ActivityManager;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Matrix;
@@ -44,15 +46,19 @@
import com.android.wm.shell.pip.PipTransitionController;
import com.android.wm.shell.pip2.PipSurfaceTransactionHelper;
import com.android.wm.shell.pip2.animation.PipAlphaAnimator;
+import com.android.wm.shell.splitscreen.SplitScreenController;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
+import org.mockito.ArgumentMatchers;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.util.Optional;
+
/**
* Unit test against {@link PipScheduler}
*/
@@ -77,6 +83,8 @@
@Mock private PipSurfaceTransactionHelper.SurfaceControlTransactionFactory mMockFactory;
@Mock private SurfaceControl.Transaction mMockTransaction;
@Mock private PipAlphaAnimator mMockAlphaAnimator;
+ @Mock private SplitScreenController mMockSplitScreenController;
+
@Captor private ArgumentCaptor<Runnable> mRunnableArgumentCaptor;
@Captor private ArgumentCaptor<WindowContainerTransaction> mWctArgumentCaptor;
@@ -93,7 +101,8 @@
.thenReturn(mMockTransaction);
mPipScheduler = new PipScheduler(mMockContext, mMockPipBoundsState, mMockMainExecutor,
- mMockPipTransitionState, mMockPipDesktopState);
+ mMockPipTransitionState, Optional.of(mMockSplitScreenController),
+ mMockPipDesktopState);
mPipScheduler.setPipTransitionController(mMockPipTransitionController);
mPipScheduler.setSurfaceControlTransactionFactory(mMockFactory);
mPipScheduler.setPipAlphaAnimatorSupplier((context, leash, startTx, finishTx, direction) ->
@@ -119,12 +128,18 @@
assertNotNull(mRunnableArgumentCaptor.getValue());
mRunnableArgumentCaptor.getValue().run();
- verify(mMockPipTransitionController, never()).startExpandTransition(any());
+ verify(mMockPipTransitionController, never()).startExpandTransition(any(), anyBoolean());
}
@Test
- public void scheduleExitPipViaExpand_exitTransitionCalled() {
+ public void scheduleExitPipViaExpand_noSplit_expandTransitionCalled() {
setMockPipTaskToken();
+ ActivityManager.RunningTaskInfo pipTaskInfo = getTaskInfoWithLastParentBeforePip(1);
+ when(mMockPipTransitionState.getPipTaskInfo()).thenReturn(pipTaskInfo);
+
+ // Make sure task with the id = 1 isn't in split-screen.
+ when(mMockSplitScreenController.isTaskInSplitScreen(
+ ArgumentMatchers.eq(1))).thenReturn(false);
mPipScheduler.scheduleExitPipViaExpand();
@@ -132,7 +147,29 @@
assertNotNull(mRunnableArgumentCaptor.getValue());
mRunnableArgumentCaptor.getValue().run();
- verify(mMockPipTransitionController, times(1)).startExpandTransition(any());
+ verify(mMockPipTransitionController, times(1)).startExpandTransition(any(), anyBoolean());
+ }
+
+ @Test
+ public void scheduleExitPipViaExpand_lastParentInSplit_prepareSplitAndExpand() {
+ setMockPipTaskToken();
+ ActivityManager.RunningTaskInfo pipTaskInfo = getTaskInfoWithLastParentBeforePip(1);
+ when(mMockPipTransitionState.getPipTaskInfo()).thenReturn(pipTaskInfo);
+
+ // Make sure task with the id = 1 is in split-screen.
+ when(mMockSplitScreenController.isTaskInSplitScreen(
+ ArgumentMatchers.eq(1))).thenReturn(true);
+
+ mPipScheduler.scheduleExitPipViaExpand();
+
+ verify(mMockMainExecutor, times(1)).execute(mRunnableArgumentCaptor.capture());
+ assertNotNull(mRunnableArgumentCaptor.getValue());
+ mRunnableArgumentCaptor.getValue().run();
+
+ // We need to both prepare the split screen with the last parent and start expanding.
+ verify(mMockSplitScreenController,
+ times(1)).prepareEnterSplitScreen(any(), any(), anyInt());
+ verify(mMockPipTransitionController, times(1)).startExpandTransition(any(), anyBoolean());
}
@Test
@@ -259,4 +296,10 @@
private void setMockPipTaskToken() {
when(mMockPipTransitionState.getPipTaskToken()).thenReturn(mMockPipTaskToken);
}
+
+ private ActivityManager.RunningTaskInfo getTaskInfoWithLastParentBeforePip(int lastParentId) {
+ final ActivityManager.RunningTaskInfo taskInfo = new ActivityManager.RunningTaskInfo();
+ taskInfo.lastParentTaskIdBeforePip = lastParentId;
+ return taskInfo;
+ }
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipTouchStateTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipTouchStateTest.java
new file mode 100644
index 0000000..2e389b7
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipTouchStateTest.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.pip2.phone;
+
+import static android.view.MotionEvent.ACTION_BUTTON_PRESS;
+import static android.view.MotionEvent.ACTION_DOWN;
+import static android.view.MotionEvent.ACTION_MOVE;
+import static android.view.MotionEvent.ACTION_UP;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.os.SystemClock;
+import android.testing.AndroidTestingRunner;
+import android.view.MotionEvent;
+import android.view.ViewConfiguration;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.wm.shell.ShellTestCase;
+import com.android.wm.shell.TestShellExecutor;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.CountDownLatch;
+
+@RunWith(AndroidTestingRunner.class)
+@SmallTest
+public class PipTouchStateTest extends ShellTestCase {
+
+ private PipTouchState mTouchState;
+ private CountDownLatch mDoubleTapCallbackTriggeredLatch;
+ private CountDownLatch mHoverExitCallbackTriggeredLatch;
+ private TestShellExecutor mMainExecutor;
+
+ @Before
+ public void setUp() throws Exception {
+ mMainExecutor = new TestShellExecutor();
+ mDoubleTapCallbackTriggeredLatch = new CountDownLatch(1);
+ mHoverExitCallbackTriggeredLatch = new CountDownLatch(1);
+ mTouchState = new PipTouchState(ViewConfiguration.get(getContext()),
+ mDoubleTapCallbackTriggeredLatch::countDown,
+ mHoverExitCallbackTriggeredLatch::countDown,
+ mMainExecutor);
+ assertFalse(mTouchState.isDoubleTap());
+ assertFalse(mTouchState.isWaitingForDoubleTap());
+ }
+
+ @Test
+ public void testDoubleTapLongSingleTap_notDoubleTapAndNotWaiting() {
+ final long currentTime = SystemClock.uptimeMillis();
+
+ mTouchState.onTouchEvent(createMotionEvent(ACTION_DOWN, currentTime, 0, 0));
+ mTouchState.onTouchEvent(createMotionEvent(ACTION_UP,
+ currentTime + PipTouchState.DOUBLE_TAP_TIMEOUT + 10, 0, 0));
+ assertFalse(mTouchState.isDoubleTap());
+ assertFalse(mTouchState.isWaitingForDoubleTap());
+ assertTrue(mTouchState.getDoubleTapTimeoutCallbackDelay() == -1);
+ }
+
+ @Test
+ public void testDoubleTapTimeout_timeoutCallbackCalled() throws Exception {
+ final long currentTime = SystemClock.uptimeMillis();
+
+ mTouchState.onTouchEvent(createMotionEvent(ACTION_DOWN, currentTime, 0, 0));
+ mTouchState.onTouchEvent(createMotionEvent(ACTION_UP,
+ currentTime + PipTouchState.DOUBLE_TAP_TIMEOUT - 10, 0, 0));
+ assertFalse(mTouchState.isDoubleTap());
+ assertTrue(mTouchState.isWaitingForDoubleTap());
+
+ assertTrue(mTouchState.getDoubleTapTimeoutCallbackDelay() == 10);
+ mTouchState.scheduleDoubleTapTimeoutCallback();
+
+ mMainExecutor.flushAll();
+ assertTrue(mDoubleTapCallbackTriggeredLatch.getCount() == 0);
+ }
+
+ @Test
+ public void testDoubleTapDrag_doubleTapCanceled() {
+ final long currentTime = SystemClock.uptimeMillis();
+
+ mTouchState.onTouchEvent(createMotionEvent(ACTION_DOWN, currentTime, 0, 0));
+ mTouchState.onTouchEvent(createMotionEvent(ACTION_MOVE, currentTime + 10, 500, 500));
+ mTouchState.onTouchEvent(createMotionEvent(ACTION_UP, currentTime + 20, 500, 500));
+ assertTrue(mTouchState.isDragging());
+ assertFalse(mTouchState.isDoubleTap());
+ assertFalse(mTouchState.isWaitingForDoubleTap());
+ assertTrue(mTouchState.getDoubleTapTimeoutCallbackDelay() == -1);
+ }
+
+ @Test
+ public void testDoubleTap_doubleTapRegistered() {
+ final long currentTime = SystemClock.uptimeMillis();
+
+ mTouchState.onTouchEvent(createMotionEvent(ACTION_DOWN, currentTime, 0, 0));
+ mTouchState.onTouchEvent(createMotionEvent(ACTION_UP, currentTime + 10, 0, 0));
+ mTouchState.onTouchEvent(createMotionEvent(ACTION_DOWN,
+ currentTime + PipTouchState.DOUBLE_TAP_TIMEOUT - 20, 0, 0));
+ mTouchState.onTouchEvent(createMotionEvent(ACTION_UP,
+ currentTime + PipTouchState.DOUBLE_TAP_TIMEOUT - 10, 0, 0));
+ assertTrue(mTouchState.isDoubleTap());
+ assertFalse(mTouchState.isWaitingForDoubleTap());
+ assertTrue(mTouchState.getDoubleTapTimeoutCallbackDelay() == -1);
+ }
+
+ @Test
+ public void testHoverExitTimeout_timeoutCallbackCalled() throws Exception {
+ mTouchState.scheduleHoverExitTimeoutCallback();
+ mMainExecutor.flushAll();
+ assertTrue(mHoverExitCallbackTriggeredLatch.getCount() == 0);
+ }
+
+ @Test
+ public void testHoverExitTimeout_timeoutCallbackNotCalled() throws Exception {
+ mTouchState.scheduleHoverExitTimeoutCallback();
+ assertTrue(mHoverExitCallbackTriggeredLatch.getCount() == 1);
+ }
+
+ @Test
+ public void testHoverExitTimeout_timeoutCallbackNotCalled_ifButtonPress() throws Exception {
+ mTouchState.scheduleHoverExitTimeoutCallback();
+ mTouchState.onTouchEvent(createMotionEvent(ACTION_BUTTON_PRESS, SystemClock.uptimeMillis(),
+ 0, 0));
+ mMainExecutor.flushAll();
+ assertTrue(mHoverExitCallbackTriggeredLatch.getCount() == 1);
+ }
+
+ private MotionEvent createMotionEvent(int action, long eventTime, float x, float y) {
+ return MotionEvent.obtain(0, eventTime, action, x, y, 0);
+ }
+
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/transition/PipExpandHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/transition/PipExpandHandlerTest.java
new file mode 100644
index 0000000..2a22842
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/transition/PipExpandHandlerTest.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.pip2.phone.transition;
+
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.view.WindowManager.TRANSIT_CHANGE;
+
+import static com.android.wm.shell.transition.Transitions.TRANSIT_EXIT_PIP;
+import static com.android.wm.shell.transition.Transitions.TRANSIT_EXIT_PIP_TO_SPLIT;
+
+import static org.junit.Assert.assertNull;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.mockito.kotlin.VerificationKt.times;
+import static org.mockito.kotlin.VerificationKt.verify;
+
+import android.annotation.Nullable;
+import android.app.ActivityManager;
+import android.app.PictureInPictureParams;
+import android.app.WindowConfiguration;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Rect;
+import android.os.IBinder;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.view.Surface;
+import android.view.SurfaceControl;
+import android.view.WindowManager;
+import android.window.TransitionInfo;
+import android.window.TransitionRequestInfo;
+import android.window.WindowContainerToken;
+import android.window.WindowContainerTransaction;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.wm.shell.common.pip.PipBoundsAlgorithm;
+import com.android.wm.shell.common.pip.PipBoundsState;
+import com.android.wm.shell.common.pip.PipDisplayLayoutState;
+import com.android.wm.shell.pip2.animation.PipExpandAnimator;
+import com.android.wm.shell.pip2.phone.PipTransitionState;
+import com.android.wm.shell.splitscreen.SplitScreenController;
+import com.android.wm.shell.transition.TransitionInfoBuilder;
+import com.android.wm.shell.util.StubTransaction;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.Optional;
+
+/**
+ * Unit test against {@link PipExpandHandler}
+ */
+
+@SmallTest
+@TestableLooper.RunWithLooper
+@RunWith(AndroidTestingRunner.class)
+public class PipExpandHandlerTest {
+ @Mock private Context mMockContext;
+ @Mock private PipBoundsState mMockPipBoundsState;
+ @Mock private PipBoundsAlgorithm mMockPipBoundsAlgorithm;
+ @Mock private PipTransitionState mMockPipTransitionState;
+ @Mock private PipDisplayLayoutState mMockPipDisplayLayoutState;
+ @Mock private SplitScreenController mMockSplitScreenController;
+
+ @Mock private IBinder mMockTransitionToken;
+ @Mock private TransitionRequestInfo mMockRequestInfo;
+ @Mock private StubTransaction mStartT;
+ @Mock private StubTransaction mFinishT;
+ @Mock private SurfaceControl mPipLeash;
+
+ @Mock private PipExpandAnimator mMockPipExpandAnimator;
+
+ @Surface.Rotation
+ private static final int DISPLAY_ROTATION = Surface.ROTATION_0;
+
+ private static final float SNAP_FRACTION = 1.5f;
+ private static final Rect PIP_BOUNDS = new Rect(0, 0, 100, 100);
+ private static final Rect DISPLAY_BOUNDS = new Rect(0, 0, 1000, 1000);
+ private static final Rect RIGHT_HALF_DISPLAY_BOUNDS = new Rect(500, 0, 1000, 1000);
+
+ private PipExpandHandler mPipExpandHandler;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ when(mMockPipBoundsState.getBounds()).thenReturn(PIP_BOUNDS);
+ when(mMockPipBoundsAlgorithm.getSnapFraction(eq(PIP_BOUNDS))).thenReturn(SNAP_FRACTION);
+ when(mMockPipDisplayLayoutState.getRotation()).thenReturn(DISPLAY_ROTATION);
+
+ mPipExpandHandler = new PipExpandHandler(mMockContext, mMockPipBoundsState,
+ mMockPipBoundsAlgorithm, mMockPipTransitionState, mMockPipDisplayLayoutState,
+ Optional.of(mMockSplitScreenController));
+ mPipExpandHandler.setPipExpandAnimatorSupplier((context, leash, startTransaction,
+ finishTransaction, baseBounds, startBounds, endBounds,
+ sourceRectHint, rotation) -> mMockPipExpandAnimator);
+ }
+
+ @Test
+ public void handleRequest_returnNull() {
+ // All expand from PiP transitions are started in Shell, so handleRequest shouldn't be
+ // returning any non-null WCT
+ WindowContainerTransaction wct = mPipExpandHandler.handleRequest(
+ mMockTransitionToken, mMockRequestInfo);
+ assertNull(wct);
+ }
+
+ @Test
+ public void startAnimation_transitExit_startExpandAnimator() {
+ final ActivityManager.RunningTaskInfo pipTaskInfo = createPipTaskInfo(
+ 1, WINDOWING_MODE_FULLSCREEN, new PictureInPictureParams.Builder().build());
+
+ final TransitionInfo info = getExpandFromPipTransitionInfo(
+ TRANSIT_EXIT_PIP, pipTaskInfo, null /* lastParent */, false /* toSplit */);
+ final WindowContainerToken pipToken = pipTaskInfo.getToken();
+ when(mMockPipTransitionState.getPipTaskToken()).thenReturn(pipToken);
+
+ mPipExpandHandler.startAnimation(mMockTransitionToken, info, mStartT, mFinishT,
+ (wct) -> {});
+
+ verify(mMockPipExpandAnimator, times(1)).start();
+ verify(mMockPipBoundsState, times(1)).saveReentryState(SNAP_FRACTION);
+ }
+
+ @Test
+ public void startAnimation_transitExitToSplit_startExpandAnimator() {
+ // The task info of the task that was pinned while we were in PiP.
+ final WindowContainerToken pipToken = createPipTaskInfo(1, WINDOWING_MODE_FULLSCREEN,
+ new PictureInPictureParams.Builder().build()).getToken();
+ when(mMockPipTransitionState.getPipTaskToken()).thenReturn(pipToken);
+
+ // Change representing the ActivityRecord we are animating in the multi-activity PiP case;
+ // make sure change's taskInfo=null as this is an activity, but let lastParent be PiP token.
+ final TransitionInfo info = getExpandFromPipTransitionInfo(
+ TRANSIT_EXIT_PIP_TO_SPLIT, null /* taskInfo */, pipToken, true /* toSplit */);
+
+ mPipExpandHandler.startAnimation(mMockTransitionToken, info, mStartT, mFinishT,
+ (wct) -> {});
+
+ verify(mMockSplitScreenController, times(1)).finishEnterSplitScreen(eq(mFinishT));
+ verify(mMockPipExpandAnimator, times(1)).start();
+ verify(mMockPipBoundsState, times(1)).saveReentryState(SNAP_FRACTION);
+ }
+
+ private TransitionInfo getExpandFromPipTransitionInfo(@WindowManager.TransitionType int type,
+ @Nullable ActivityManager.RunningTaskInfo pipTaskInfo,
+ @Nullable WindowContainerToken lastParent, boolean toSplit) {
+ final TransitionInfo info = new TransitionInfoBuilder(type)
+ .addChange(TRANSIT_CHANGE, pipTaskInfo).build();
+ final TransitionInfo.Change pipChange = info.getChanges().getFirst();
+ pipChange.setRotation(DISPLAY_ROTATION,
+ WindowConfiguration.ROTATION_UNDEFINED);
+ pipChange.setStartAbsBounds(PIP_BOUNDS);
+ pipChange.setEndAbsBounds(toSplit ? RIGHT_HALF_DISPLAY_BOUNDS : DISPLAY_BOUNDS);
+ pipChange.setLeash(mPipLeash);
+ pipChange.setLastParent(lastParent);
+ return info;
+ }
+
+ private static ActivityManager.RunningTaskInfo createPipTaskInfo(int taskId,
+ int windowingMode, PictureInPictureParams params) {
+ ActivityManager.RunningTaskInfo taskInfo = new ActivityManager.RunningTaskInfo();
+ taskInfo.taskId = taskId;
+ taskInfo.configuration.windowConfiguration.setWindowingMode(windowingMode);
+ taskInfo.token = mock(WindowContainerToken.class);
+ taskInfo.baseIntent = mock(Intent.class);
+ taskInfo.pictureInPictureParams = params;
+ return taskInfo;
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
index 5028479..a546b3e 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
@@ -107,6 +107,7 @@
@RunWith(AndroidJUnit4.class)
@SmallTest
public class RecentTasksControllerTest extends ShellTestCase {
+ private static final String SYSTEM_UI_PACKAGE_NAME = "com.android.systemui";
@Mock
private Context mContext;
@@ -582,6 +583,19 @@
@Test
@EnableFlags({Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE,
Flags.FLAG_ENABLE_DESKTOP_WINDOWING_TASKBAR_RUNNING_APPS})
+ public void onTaskAdded_orDesktopWallpaperActivity_doesNotTriggerOnRunningTaskAppeared()
+ throws Exception {
+ RunningTaskInfo taskInfo = makeDesktopWallpaperActivityTaskInfo(/* taskId= */10);
+ mRecentTasksControllerReal.registerRecentTasksListener(mRecentTasksListener);
+
+ mRecentTasksControllerReal.onTaskAdded(taskInfo);
+
+ verify(mRecentTasksListener, never()).onRunningTaskAppeared(any());
+ }
+
+ @Test
+ @EnableFlags({Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE,
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_TASKBAR_RUNNING_APPS})
public void taskWindowingModeChanged_desktopRunningAppsEnabled_triggersOnRunningTaskChanged()
throws Exception {
mRecentTasksControllerReal.registerRecentTasksListener(mRecentTasksListener);
@@ -593,6 +607,19 @@
}
@Test
+ @EnableFlags({Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE,
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_TASKBAR_RUNNING_APPS})
+ public void taskInfoChanged_forDesktopWallpaperActivity_doesNotTriggerOnRunningTaskChanged()
+ throws Exception {
+ RunningTaskInfo taskInfo = makeDesktopWallpaperActivityTaskInfo(/* taskId= */10);
+ mRecentTasksControllerReal.registerRecentTasksListener(mRecentTasksListener);
+
+ mRecentTasksControllerReal.onTaskRunningInfoChanged(taskInfo);
+
+ verify(mRecentTasksListener, never()).onRunningTaskChanged(any());
+ }
+
+ @Test
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
@DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_TASKBAR_RUNNING_APPS)
public void
@@ -619,6 +646,20 @@
verify(mRecentTasksListener).onRunningTaskVanished(taskInfo);
}
+
+ @Test
+ @EnableFlags({Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE,
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_TASKBAR_RUNNING_APPS})
+ public void onTaskRemoved_forDesktopWallpaperActivity_doesNotTriggerOnRunningTaskVanished()
+ throws Exception {
+ RunningTaskInfo taskInfo = makeDesktopWallpaperActivityTaskInfo(/* taskId= */10);
+ mRecentTasksControllerReal.registerRecentTasksListener(mRecentTasksListener);
+
+ mRecentTasksControllerReal.onTaskRemoved(taskInfo);
+
+ verify(mRecentTasksListener, never()).onRunningTaskVanished(any());
+ }
+
@Test
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
@DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_TASKBAR_RUNNING_APPS)
@@ -659,6 +700,18 @@
}
@Test
+ @EnableFlags(Flags.FLAG_ENABLE_TASK_STACK_OBSERVER_IN_SHELL)
+ public void onDesktopWallpaperActivityMovedToFront_doesNotTriggerOnTaskMovedToFront()
+ throws Exception {
+ RunningTaskInfo taskInfo = makeDesktopWallpaperActivityTaskInfo(/* taskId= */10);
+ mRecentTasksControllerReal.registerRecentTasksListener(mRecentTasksListener);
+
+ mRecentTasksControllerReal.onTaskMovedToFrontThroughTransition(taskInfo);
+
+ verify(mRecentTasksListener, never()).onTaskMovedToFront(any());
+ }
+
+ @Test
public void getNullSplitBoundsNonSplitTask() {
SplitBounds sb = mRecentTasksController.getSplitBoundsForTaskId(3);
assertNull("splitBounds should be null for non-split task", sb);
@@ -829,16 +882,25 @@
* Helper to create a running task with a given task id.
*/
private RunningTaskInfo makeRunningTaskInfo(int taskId) {
+ return makeRunningTaskInfo(taskId, new ComponentName("com." + taskId, "Activity" + taskId));
+ }
+
+ private RunningTaskInfo makeRunningTaskInfo(int taskId, ComponentName intentComponent) {
RunningTaskInfo info = new RunningTaskInfo();
info.taskId = taskId;
info.realActivity = new ComponentName("testPackage", "testClass");
Intent intent = new Intent();
- intent.setComponent(new ComponentName("com." + taskId, "Activity" + taskId));
+ intent.setComponent(intentComponent);
info.baseIntent = intent;
info.lastNonFullscreenBounds = new Rect();
return info;
}
+ private RunningTaskInfo makeDesktopWallpaperActivityTaskInfo(int taskId) {
+ return makeRunningTaskInfo(taskId, new ComponentName(SYSTEM_UI_PACKAGE_NAME,
+ DesktopWallpaperActivity.class.getName()));
+ }
+
/**
* Helper to set the raw task list on the controller.
*/
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/bubbles/DropTargetManagerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/bubbles/DropTargetManagerTest.kt
index efb91c5..180a691 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/bubbles/DropTargetManagerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/bubbles/DropTargetManagerTest.kt
@@ -16,23 +16,33 @@
package com.android.wm.shell.shared.bubbles
+import android.content.Context
import android.graphics.Rect
+import android.view.View
+import android.widget.FrameLayout
+import androidx.core.animation.AnimatorTestRule
+import androidx.test.core.app.ApplicationProvider.getApplicationContext
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import androidx.test.platform.app.InstrumentationRegistry
import com.google.common.truth.Truth.assertThat
+import kotlin.test.assertFails
import org.junit.Before
+import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import kotlin.test.assertFails
/** Unit tests for [DropTargetManager]. */
@SmallTest
@RunWith(AndroidJUnit4::class)
class DropTargetManagerTest {
+ @get:Rule val animatorTestRule = AnimatorTestRule()
+
+ private val context = getApplicationContext<Context>()
private lateinit var dropTargetManager: DropTargetManager
private lateinit var dragZoneChangedListener: FakeDragZoneChangedListener
- private val dropTarget = Rect(0, 0, 0, 0)
+ private lateinit var container: FrameLayout
// create 3 drop zones that are horizontally next to each other
// -------------------------------------------------
@@ -43,15 +53,20 @@
// | | | |
// -------------------------------------------------
private val bubbleLeftDragZone =
- DragZone.Bubble.Left(bounds = Rect(0, 0, 100, 100), dropTarget = dropTarget)
+ DragZone.Bubble.Left(bounds = Rect(0, 0, 100, 100), dropTarget = Rect(0, 0, 50, 200))
private val dismissDragZone = DragZone.Dismiss(bounds = Rect(100, 0, 200, 100))
private val bubbleRightDragZone =
- DragZone.Bubble.Right(bounds = Rect(200, 0, 300, 100), dropTarget = dropTarget)
+ DragZone.Bubble.Right(bounds = Rect(200, 0, 300, 100), dropTarget = Rect(200, 0, 280, 150))
+
+ private val dropTargetView: View
+ get() = container.getChildAt(0)
@Before
fun setUp() {
+ container = FrameLayout(context)
dragZoneChangedListener = FakeDragZoneChangedListener()
- dropTargetManager = DropTargetManager(isLayoutRtl = false, dragZoneChangedListener)
+ dropTargetManager =
+ DropTargetManager(context, container, isLayoutRtl = false, dragZoneChangedListener)
}
@Test
@@ -79,17 +94,21 @@
DraggedObject.Bubble(BubbleBarLocation.LEFT),
listOf(bubbleLeftDragZone, bubbleRightDragZone, dismissDragZone)
)
- dropTargetManager.onDragUpdated(
- bubbleRightDragZone.bounds.centerX(),
- bubbleRightDragZone.bounds.centerY()
- )
+ InstrumentationRegistry.getInstrumentation().runOnMainSync {
+ dropTargetManager.onDragUpdated(
+ bubbleRightDragZone.bounds.centerX(),
+ bubbleRightDragZone.bounds.centerY()
+ )
+ }
assertThat(dragZoneChangedListener.fromDragZone).isEqualTo(bubbleLeftDragZone)
assertThat(dragZoneChangedListener.toDragZone).isEqualTo(bubbleRightDragZone)
- dropTargetManager.onDragUpdated(
- dismissDragZone.bounds.centerX(),
- dismissDragZone.bounds.centerY()
- )
+ InstrumentationRegistry.getInstrumentation().runOnMainSync {
+ dropTargetManager.onDragUpdated(
+ dismissDragZone.bounds.centerX(),
+ dismissDragZone.bounds.centerY()
+ )
+ }
assertThat(dragZoneChangedListener.fromDragZone).isEqualTo(bubbleRightDragZone)
assertThat(dragZoneChangedListener.toDragZone).isEqualTo(dismissDragZone)
}
@@ -100,10 +119,12 @@
DraggedObject.Bubble(BubbleBarLocation.LEFT),
listOf(bubbleLeftDragZone, bubbleRightDragZone, dismissDragZone)
)
- dropTargetManager.onDragUpdated(
- bubbleLeftDragZone.bounds.centerX(),
- bubbleLeftDragZone.bounds.centerY()
- )
+ InstrumentationRegistry.getInstrumentation().runOnMainSync {
+ dropTargetManager.onDragUpdated(
+ bubbleLeftDragZone.bounds.centerX(),
+ bubbleLeftDragZone.bounds.centerY()
+ )
+ }
assertThat(dragZoneChangedListener.fromDragZone).isNull()
assertThat(dragZoneChangedListener.toDragZone).isNull()
}
@@ -118,7 +139,9 @@
val pointY = 200
assertThat(bubbleLeftDragZone.contains(pointX, pointY)).isFalse()
assertThat(bubbleRightDragZone.contains(pointX, pointY)).isFalse()
- dropTargetManager.onDragUpdated(pointX, pointY)
+ InstrumentationRegistry.getInstrumentation().runOnMainSync {
+ dropTargetManager.onDragUpdated(pointX, pointY)
+ }
assertThat(dragZoneChangedListener.fromDragZone).isNull()
assertThat(dragZoneChangedListener.toDragZone).isNull()
}
@@ -135,27 +158,30 @@
// drag to a point that is within both the bubble right zone and split zone
val (pointX, pointY) =
- Pair(
- bubbleRightDragZone.bounds.centerX(),
- bubbleRightDragZone.bounds.centerY()
- )
+ Pair(bubbleRightDragZone.bounds.centerX(), bubbleRightDragZone.bounds.centerY())
assertThat(splitDragZone.contains(pointX, pointY)).isTrue()
- dropTargetManager.onDragUpdated(pointX, pointY)
+ InstrumentationRegistry.getInstrumentation().runOnMainSync {
+ dropTargetManager.onDragUpdated(pointX, pointY)
+ }
// verify we dragged to the bubble right zone because that has higher priority than split
assertThat(dragZoneChangedListener.fromDragZone).isEqualTo(bubbleLeftDragZone)
assertThat(dragZoneChangedListener.toDragZone).isEqualTo(bubbleRightDragZone)
- dropTargetManager.onDragUpdated(
- bubbleRightDragZone.bounds.centerX(),
- 150 // below the bubble and dismiss drag zones but within split
- )
+ InstrumentationRegistry.getInstrumentation().runOnMainSync {
+ dropTargetManager.onDragUpdated(
+ bubbleRightDragZone.bounds.centerX(),
+ 150 // below the bubble and dismiss drag zones but within split
+ )
+ }
assertThat(dragZoneChangedListener.fromDragZone).isEqualTo(bubbleRightDragZone)
assertThat(dragZoneChangedListener.toDragZone).isEqualTo(splitDragZone)
val (dismissPointX, dismissPointY) =
Pair(dismissDragZone.bounds.centerX(), dismissDragZone.bounds.centerY())
assertThat(splitDragZone.contains(dismissPointX, dismissPointY)).isTrue()
- dropTargetManager.onDragUpdated(dismissPointX, dismissPointY)
+ InstrumentationRegistry.getInstrumentation().runOnMainSync {
+ dropTargetManager.onDragUpdated(dismissPointX, dismissPointY)
+ }
assertThat(dragZoneChangedListener.fromDragZone).isEqualTo(splitDragZone)
assertThat(dragZoneChangedListener.toDragZone).isEqualTo(dismissDragZone)
}
@@ -166,7 +192,9 @@
DraggedObject.Bubble(BubbleBarLocation.LEFT),
listOf(bubbleLeftDragZone, bubbleRightDragZone, dismissDragZone)
)
- dropTargetManager.onDragEnded()
+ InstrumentationRegistry.getInstrumentation().runOnMainSync {
+ dropTargetManager.onDragEnded()
+ }
dropTargetManager.onDragUpdated(
bubbleRightDragZone.bounds.centerX(),
bubbleRightDragZone.bounds.centerY()
@@ -175,6 +203,129 @@
assertThat(dragZoneChangedListener.toDragZone).isNull()
}
+ @Test
+ fun onDragStarted_dropTargetAddedToContainer() {
+ dropTargetManager.onDragStarted(
+ DraggedObject.Bubble(BubbleBarLocation.LEFT),
+ listOf(bubbleLeftDragZone, bubbleRightDragZone)
+ )
+ assertThat(container.childCount).isEqualTo(1)
+ assertThat(dropTargetView.alpha).isEqualTo(0)
+ }
+
+ @Test
+ fun onDragEnded_dropTargetRemovedFromContainer() {
+ dropTargetManager.onDragStarted(
+ DraggedObject.Bubble(BubbleBarLocation.LEFT),
+ listOf(bubbleLeftDragZone, bubbleRightDragZone)
+ )
+ assertThat(container.childCount).isEqualTo(1)
+
+ InstrumentationRegistry.getInstrumentation().runOnMainSync {
+ dropTargetManager.onDragEnded()
+ animatorTestRule.advanceTimeBy(250)
+ }
+ assertThat(container.childCount).isEqualTo(0)
+ }
+
+ @Test
+ fun startNewDrag_beforeDropTargetRemoved() {
+ dropTargetManager.onDragStarted(
+ DraggedObject.Bubble(BubbleBarLocation.LEFT),
+ listOf(bubbleLeftDragZone, bubbleRightDragZone)
+ )
+ assertThat(container.childCount).isEqualTo(1)
+
+ InstrumentationRegistry.getInstrumentation().runOnMainSync {
+ dropTargetManager.onDragEnded()
+ // advance the timer by 100ms so the animation doesn't complete
+ animatorTestRule.advanceTimeBy(100)
+ }
+ assertThat(container.childCount).isEqualTo(1)
+
+ InstrumentationRegistry.getInstrumentation().runOnMainSync {
+ dropTargetManager.onDragStarted(
+ DraggedObject.Bubble(BubbleBarLocation.LEFT),
+ listOf(bubbleLeftDragZone, bubbleRightDragZone)
+ )
+ }
+ assertThat(container.childCount).isEqualTo(1)
+ }
+
+ @Test
+ fun updateDragZone_withDropTarget_dropTargetUpdated() {
+ dropTargetManager.onDragStarted(
+ DraggedObject.Bubble(BubbleBarLocation.LEFT),
+ listOf(dismissDragZone, bubbleLeftDragZone, bubbleRightDragZone)
+ )
+
+ InstrumentationRegistry.getInstrumentation().runOnMainSync {
+ dropTargetManager.onDragUpdated(
+ bubbleRightDragZone.bounds.centerX(),
+ bubbleRightDragZone.bounds.centerY()
+ )
+ animatorTestRule.advanceTimeBy(250)
+ }
+
+ assertThat(dropTargetView.alpha).isEqualTo(1)
+ verifyDropTargetPosition(bubbleRightDragZone.dropTarget)
+ }
+
+ @Test
+ fun updateDragZone_withoutDropTarget_dropTargetHidden() {
+ dropTargetManager.onDragStarted(
+ DraggedObject.Bubble(BubbleBarLocation.LEFT),
+ listOf(dismissDragZone, bubbleLeftDragZone, bubbleRightDragZone)
+ )
+
+ InstrumentationRegistry.getInstrumentation().runOnMainSync {
+ dropTargetManager.onDragUpdated(
+ dismissDragZone.bounds.centerX(),
+ dismissDragZone.bounds.centerY()
+ )
+ animatorTestRule.advanceTimeBy(250)
+ }
+
+ assertThat(dropTargetView.alpha).isEqualTo(0)
+ }
+
+ @Test
+ fun updateDragZone_betweenZonesWithDropTarget_dropTargetUpdated() {
+ dropTargetManager.onDragStarted(
+ DraggedObject.Bubble(BubbleBarLocation.LEFT),
+ listOf(dismissDragZone, bubbleLeftDragZone, bubbleRightDragZone)
+ )
+
+ InstrumentationRegistry.getInstrumentation().runOnMainSync {
+ dropTargetManager.onDragUpdated(
+ bubbleRightDragZone.bounds.centerX(),
+ bubbleRightDragZone.bounds.centerY()
+ )
+ animatorTestRule.advanceTimeBy(250)
+ }
+
+ assertThat(dropTargetView.alpha).isEqualTo(1)
+ verifyDropTargetPosition(bubbleRightDragZone.dropTarget)
+
+ InstrumentationRegistry.getInstrumentation().runOnMainSync {
+ dropTargetManager.onDragUpdated(
+ bubbleLeftDragZone.bounds.centerX(),
+ bubbleLeftDragZone.bounds.centerY()
+ )
+ animatorTestRule.advanceTimeBy(250)
+ }
+
+ assertThat(dropTargetView.alpha).isEqualTo(1)
+ verifyDropTargetPosition(bubbleLeftDragZone.dropTarget)
+ }
+
+ private fun verifyDropTargetPosition(rect: Rect) {
+ assertThat(dropTargetView.scaleX).isEqualTo(rect.width())
+ assertThat(dropTargetView.scaleY).isEqualTo(rect.height())
+ assertThat(dropTargetView.translationX).isEqualTo(rect.exactCenterX())
+ assertThat(dropTargetView.translationY).isEqualTo(rect.exactCenterY())
+ }
+
private class FakeDragZoneChangedListener : DropTargetManager.DragZoneChangedListener {
var initialDragZone: DragZone? = null
var fromDragZone: DragZone? = null
@@ -183,6 +334,7 @@
override fun onInitialDragZoneSet(dragZone: DragZone) {
initialDragZone = dragZone
}
+
override fun onDragZoneChanged(from: DragZone, to: DragZone) {
fromDragZone = from
toDragZone = to
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatusTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatusTest.kt
index 741a0fd..4082ffd 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatusTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatusTest.kt
@@ -22,8 +22,6 @@
import android.platform.test.annotations.EnableFlags
import android.platform.test.annotations.Presubmit
import android.platform.test.flag.junit.SetFlagsRule
-import android.provider.Settings
-import android.provider.Settings.Global.DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES
import android.window.DesktopModeFlags
import androidx.test.filters.SmallTest
import com.android.internal.R
@@ -63,14 +61,12 @@
doReturn(context.contentResolver).whenever(mockContext).contentResolver
resetDesktopModeFlagsCache()
resetEnforceDeviceRestriction()
- resetFlagOverride()
}
@After
fun tearDown() {
resetDesktopModeFlagsCache()
resetEnforceDeviceRestriction()
- resetFlagOverride()
}
@DisableFlags(
@@ -246,18 +242,11 @@
cachedToggleOverride.set(null, null)
}
- private fun resetFlagOverride() {
- Settings.Global.putString(
- context.contentResolver,
- DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES, null
- )
- }
-
private fun setFlagOverride(override: DesktopModeFlags.ToggleOverride) {
- Settings.Global.putInt(
- context.contentResolver,
- DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES, override.setting
- )
+ val cachedToggleOverride =
+ DesktopModeFlags::class.java.getDeclaredField("sCachedToggleOverride")
+ cachedToggleOverride.isAccessible = true
+ cachedToggleOverride.set(null, override)
}
private fun setDeviceEligibleForDesktopMode(eligible: Boolean) {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
index 71c821d..c4f70ac2 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
@@ -120,6 +120,7 @@
import kotlin.Unit;
import kotlin.jvm.functions.Function0;
import kotlin.jvm.functions.Function1;
+import kotlin.jvm.functions.Function2;
import kotlinx.coroutines.CoroutineScope;
import kotlinx.coroutines.MainCoroutineDispatcher;
@@ -998,8 +999,8 @@
createMaximizeMenu(decoration);
- verify(menu).show(anyBoolean(), anyInt(), anyBoolean(), anyBoolean(), any(), any(), any(),
- any(), mOnMaxMenuHoverChangeListener.capture(), any());
+ verify(menu).show(anyBoolean(), anyBoolean(), anyBoolean(), any(), any(), any(), any(),
+ mOnMaxMenuHoverChangeListener.capture(), any());
assertTrue(decoration.isMaximizeMenuActive());
}
@@ -1011,8 +1012,8 @@
new FakeMaximizeMenuFactory(menu));
decoration.setAppHeaderMaximizeButtonHovered(false);
createMaximizeMenu(decoration);
- verify(menu).show(anyBoolean(), anyInt(), anyBoolean(), anyBoolean(), any(), any(), any(),
- any(), mOnMaxMenuHoverChangeListener.capture(), any());
+ verify(menu).show(anyBoolean(), anyBoolean(), anyBoolean(), any(), any(), any(), any(),
+ mOnMaxMenuHoverChangeListener.capture(), any());
mOnMaxMenuHoverChangeListener.getValue().invoke(false);
@@ -1050,8 +1051,8 @@
final DesktopModeWindowDecoration decoration = createWindowDecoration(taskInfo,
new FakeMaximizeMenuFactory(menu));
createMaximizeMenu(decoration);
- verify(menu).show(anyBoolean(), anyInt(), anyBoolean(), anyBoolean(), any(), any(), any(),
- any(), mOnMaxMenuHoverChangeListener.capture(), any());
+ verify(menu).show(anyBoolean(), anyBoolean(), anyBoolean(), any(), any(), any(), any(),
+ mOnMaxMenuHoverChangeListener.capture(), any());
mOnMaxMenuHoverChangeListener.getValue().invoke(true);
@@ -1065,8 +1066,8 @@
final DesktopModeWindowDecoration decoration = createWindowDecoration(taskInfo,
new FakeMaximizeMenuFactory(menu));
createMaximizeMenu(decoration);
- verify(menu).show(anyBoolean(), anyInt(), anyBoolean(), anyBoolean(), any(), any(), any(),
- any(), mOnMaxMenuHoverChangeListener.capture(), any());
+ verify(menu).show(anyBoolean(), anyBoolean(), anyBoolean(), any(), any(), any(), any(),
+ mOnMaxMenuHoverChangeListener.capture(), any());
decoration.setAppHeaderMaximizeButtonHovered(true);
@@ -1086,7 +1087,6 @@
verify(menu).show(
anyBoolean(),
- anyInt(),
/* showImmersiveOption= */ eq(true),
anyBoolean(),
any(),
@@ -1111,7 +1111,6 @@
verify(menu).show(
anyBoolean(),
- anyInt(),
/* showImmersiveOption= */ eq(false),
anyBoolean(),
any(),
@@ -1136,7 +1135,6 @@
verify(menu).show(
anyBoolean(),
- anyInt(),
anyBoolean(),
/* showSnapOptions= */ eq(true),
any(),
@@ -1161,7 +1159,6 @@
verify(menu).show(
anyBoolean(),
- anyInt(),
anyBoolean(),
/* showSnapOptions= */ eq(false),
any(),
@@ -1766,7 +1763,9 @@
@NonNull RootTaskDisplayAreaOrganizer rootTdaOrganizer,
@NonNull DisplayController displayController,
@NonNull ActivityManager.RunningTaskInfo taskInfo,
- @NonNull Context decorWindowContext, @NonNull PointF menuPosition,
+ @NonNull Context decorWindowContext,
+ @NonNull Function2<? super Integer,? super Integer,? extends PointF>
+ positionSupplier,
@NonNull Supplier<SurfaceControl.Transaction> transactionSupplier) {
return mMaximizeMenu;
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeInputListenerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeInputListenerTest.kt
new file mode 100644
index 0000000..7341e09
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeInputListenerTest.kt
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2025 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
+
+import android.app.ActivityManager
+import android.content.Context
+import android.graphics.Region
+import android.os.Handler
+import android.os.Looper
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.util.Size
+import android.view.Choreographer
+import android.view.Display
+import android.view.IWindowSession
+import android.view.InputChannel
+import android.view.SurfaceControl
+import androidx.test.filters.SmallTest
+import com.android.wm.shell.ShellTestCase
+import com.android.wm.shell.TestHandler
+import com.android.wm.shell.TestRunningTaskInfoBuilder
+import com.android.wm.shell.TestShellExecutor
+import com.android.wm.shell.common.DisplayController
+import com.android.wm.shell.desktopmode.DesktopModeEventLogger
+import com.android.wm.shell.util.StubTransaction
+import com.android.wm.shell.windowdecor.DragResizeInputListener.TaskResizeInputEventReceiver
+import com.google.common.truth.Truth.assertThat
+import java.util.function.Consumer
+import java.util.function.Supplier
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.any
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.kotlin.anyOrNull
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.never
+import org.mockito.kotlin.verify
+
+/**
+ * Tests for [DragResizeInputListener].
+ *
+ * Build/Install/Run:
+ * atest WMShellUnitTests:DragResizeInputListenerTest
+ */
+@SmallTest
+@TestableLooper.RunWithLooper
+@RunWith(AndroidTestingRunner::class)
+class DragResizeInputListenerTest : ShellTestCase() {
+ private val testMainExecutor = TestShellExecutor()
+ private val testBgExecutor = TestShellExecutor()
+ private val mockWindowSession = mock<IWindowSession>()
+ private val mockInputEventReceiver = mock<TaskResizeInputEventReceiver>()
+
+ @Test
+ fun testGrantInputChannelOffMainThread() {
+ create()
+ testMainExecutor.flushAll()
+
+ verifyNoInputChannelGrantRequests()
+ }
+
+ @Test
+ fun testInitializationCallback_waitsForBgSetup() {
+ val inputListener = create()
+
+ val callback = TestInitializationCallback()
+ inputListener.addInitializedCallback(callback)
+ assertThat(callback.initialized).isFalse()
+
+ testBgExecutor.flushAll()
+ testMainExecutor.flushAll()
+
+ assertThat(callback.initialized).isTrue()
+ }
+
+ @Test
+ fun testInitializationCallback_alreadyInitialized_callsBackImmediately() {
+ val inputListener = create()
+ testBgExecutor.flushAll()
+ testMainExecutor.flushAll()
+
+ val callback = TestInitializationCallback()
+ inputListener.addInitializedCallback(callback)
+
+ assertThat(callback.initialized).isTrue()
+ }
+
+ @Test
+ fun testClose_beforeBgSetup_cancelsBgSetup() {
+ val inputListener = create()
+
+ inputListener.close()
+ testBgExecutor.flushAll()
+
+ verifyNoInputChannelGrantRequests()
+ }
+
+ @Test
+ fun testClose_beforeBgSetupResultSet_cancelsInit() {
+ val inputListener = create()
+ val callback = TestInitializationCallback()
+ inputListener.addInitializedCallback(callback)
+
+ testBgExecutor.flushAll()
+ inputListener.close()
+ testMainExecutor.flushAll()
+
+ assertThat(callback.initialized).isFalse()
+ }
+
+ @Test
+ fun testClose_afterInit_disposesOfReceiver() {
+ val inputListener = create()
+
+ testBgExecutor.flushAll()
+ testMainExecutor.flushAll()
+ inputListener.close()
+
+ verify(mockInputEventReceiver).dispose()
+ }
+
+ @Test
+ fun testClose_afterInit_removesTokens() {
+ val inputListener = create()
+
+ inputListener.close()
+ testBgExecutor.flushAll()
+
+ verify(mockWindowSession).remove(inputListener.mClientToken)
+ verify(mockWindowSession).remove(inputListener.mSinkClientToken)
+ }
+
+ private fun verifyNoInputChannelGrantRequests() {
+ verify(mockWindowSession, never())
+ .grantInputChannel(
+ anyInt(),
+ any(),
+ any(),
+ anyOrNull(),
+ anyInt(),
+ anyInt(),
+ anyInt(),
+ anyInt(),
+ anyOrNull(),
+ any(),
+ any(),
+ any(),
+ )
+ }
+
+ private fun create(): DragResizeInputListener =
+ DragResizeInputListener(
+ context,
+ mockWindowSession,
+ testMainExecutor,
+ testBgExecutor,
+ TestTaskResizeInputEventReceiverFactory(mockInputEventReceiver),
+ TestRunningTaskInfoBuilder().build(),
+ TestHandler(Looper.getMainLooper()),
+ mock<Choreographer>(),
+ Display.DEFAULT_DISPLAY,
+ mock<SurfaceControl>(),
+ mock<DragPositioningCallback>(),
+ { SurfaceControl.Builder() },
+ { StubTransaction() },
+ mock<DisplayController>(),
+ mock<DesktopModeEventLogger>(),
+ )
+
+ private class TestInitializationCallback : Runnable {
+ var initialized: Boolean = false
+ private set
+
+ override fun run() {
+ initialized = true
+ }
+ }
+
+ private class TestTaskResizeInputEventReceiverFactory(
+ private val mockInputEventReceiver: TaskResizeInputEventReceiver
+ ) : DragResizeInputListener.TaskResizeInputEventReceiverFactory {
+ override fun create(
+ context: Context,
+ taskInfo: ActivityManager.RunningTaskInfo,
+ inputChannel: InputChannel,
+ callback: DragPositioningCallback,
+ handler: Handler,
+ choreographer: Choreographer,
+ displayLayoutSizeSupplier: Supplier<Size?>,
+ touchRegionConsumer: Consumer<Region?>,
+ desktopModeEventLogger: DesktopModeEventLogger,
+ ): TaskResizeInputEventReceiver = mockInputEventReceiver
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
index aa1f82e..af01623 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
@@ -40,6 +40,7 @@
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.argThat;
+import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.inOrder;
@@ -386,6 +387,49 @@
verify(mMockWindowDecorViewHost).updateView(same(mMockView), any(), any(), any(), any());
}
+
+ @Test
+ public void testReinflateViewsOnFontScaleChange() {
+ final Display defaultDisplay = mock(Display.class);
+ doReturn(defaultDisplay).when(mMockDisplayController)
+ .getDisplay(Display.DEFAULT_DISPLAY);
+
+ final ActivityManager.RunningTaskInfo taskInfo = new TestRunningTaskInfoBuilder()
+ .setVisible(true)
+ .setDisplayId(Display.DEFAULT_DISPLAY)
+ .build();
+ final TestWindowDecoration windowDecor = spy(createWindowDecoration(taskInfo));
+ windowDecor.relayout(taskInfo, true /* hasGlobalFocus */, Region.obtain());
+ clearInvocations(windowDecor);
+ final ActivityManager.RunningTaskInfo taskInfo2 = new TestRunningTaskInfoBuilder()
+ .setVisible(true)
+ .setDisplayId(Display.DEFAULT_DISPLAY)
+ .build();
+ taskInfo2.configuration.fontScale = taskInfo.configuration.fontScale + 1;
+ windowDecor.relayout(taskInfo2, true /* hasGlobalFocus */, Region.obtain());
+ // WindowDecoration#releaseViews should be called since the font scale has changed.
+ verify(windowDecor).releaseViews(any());
+ }
+
+ @Test
+ public void testViewNotReinflatedWhenFontScaleNotChanged() {
+ final Display defaultDisplay = mock(Display.class);
+ doReturn(defaultDisplay).when(mMockDisplayController)
+ .getDisplay(Display.DEFAULT_DISPLAY);
+
+ final ActivityManager.RunningTaskInfo taskInfo = new TestRunningTaskInfoBuilder()
+ .setVisible(true)
+ .setDisplayId(Display.DEFAULT_DISPLAY)
+ .build();
+ final TestWindowDecoration windowDecor = spy(createWindowDecoration(taskInfo));
+ windowDecor.relayout(taskInfo, true /* hasGlobalFocus */, Region.obtain());
+ clearInvocations(windowDecor);
+ windowDecor.relayout(taskInfo, true /* hasGlobalFocus */, Region.obtain());
+ // WindowDecoration#releaseViews should be called since task info (and therefore the
+ // fontScale) has not changed.
+ verify(windowDecor, never()).releaseViews(any());
+ }
+
@Test
public void testAddViewHostViewContainer() {
final Display defaultDisplay = mock(Display.class);
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
index d99a482..c86730e 100644
--- 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
@@ -20,6 +20,7 @@
import android.view.SurfaceControl
import android.view.View
import android.view.WindowManager
+import android.widget.FrameLayout
import androidx.test.filters.SmallTest
import com.android.wm.shell.ShellTestCase
import com.google.common.truth.Truth.assertThat
@@ -30,6 +31,9 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.mock
+import org.mockito.Mockito.times
+import org.mockito.kotlin.clearInvocations
+import org.mockito.kotlin.never
import org.mockito.kotlin.spy
import org.mockito.kotlin.verify
@@ -47,24 +51,46 @@
fun update_differentView_replacesView() = runTest {
val view = View(context)
val lp = WindowManager.LayoutParams()
- val reusableVH = createReusableViewHost()
- reusableVH.updateView(view, lp, context.resources.configuration, null)
+ val rootView = FrameLayout(context)
+ val reusableVH = createReusableViewHost(rootView)
+ reusableVH.updateView(view, lp, context.resources.configuration)
- assertThat(reusableVH.rootView.childCount).isEqualTo(1)
- assertThat(reusableVH.rootView.getChildAt(0)).isEqualTo(view)
+ assertThat(rootView.childCount).isEqualTo(1)
+ assertThat(rootView.getChildAt(0)).isEqualTo(view)
val newView = View(context)
val newLp = WindowManager.LayoutParams()
- reusableVH.updateView(newView, newLp, context.resources.configuration, null)
+ reusableVH.updateView(newView, newLp, context.resources.configuration)
- assertThat(reusableVH.rootView.childCount).isEqualTo(1)
- assertThat(reusableVH.rootView.getChildAt(0)).isEqualTo(newView)
+ assertThat(rootView.childCount).isEqualTo(1)
+ assertThat(rootView.getChildAt(0)).isEqualTo(newView)
+ }
+
+ @Test
+ fun update_sameView_doesNotReplaceView() = runTest {
+ val view = View(context)
+ val lp = WindowManager.LayoutParams()
+ val spyRootView = spy(FrameLayout(context))
+ val reusableVH = createReusableViewHost(spyRootView)
+ reusableVH.updateView(view, lp, context.resources.configuration)
+
+ verify(spyRootView, times(1)).removeAllViews()
+ assertThat(spyRootView.childCount).isEqualTo(1)
+ assertThat(spyRootView.getChildAt(0)).isEqualTo(view)
+
+ reusableVH.updateView(view, lp, context.resources.configuration)
+
+ clearInvocations(spyRootView)
+ verify(spyRootView, never()).removeAllViews()
+ assertThat(spyRootView.childCount).isEqualTo(1)
+ assertThat(spyRootView.getChildAt(0)).isEqualTo(view)
}
@OptIn(ExperimentalCoroutinesApi::class)
@Test
fun updateView_clearsPendingAsyncJob() = runTest {
- val reusableVH = createReusableViewHost()
+ val rootView = FrameLayout(context)
+ val reusableVH = createReusableViewHost(rootView)
val asyncView = View(context)
val syncView = View(context)
val asyncAttrs = WindowManager.LayoutParams(100, 100)
@@ -83,7 +109,6 @@
view = syncView,
attrs = syncAttrs,
configuration = context.resources.configuration,
- onDrawTransaction = null,
)
// Would run coroutine if it hadn't been cancelled.
@@ -91,7 +116,7 @@
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(rootView.getChildAt(0)).isEqualTo(syncView)
assertThat(reusableVH.view()!!.layoutParams.width).isEqualTo(syncAttrs.width)
}
@@ -118,7 +143,8 @@
@OptIn(ExperimentalCoroutinesApi::class)
@Test
fun updateViewAsync_clearsPendingAsyncJob() = runTest {
- val reusableVH = createReusableViewHost()
+ val rootView = FrameLayout(context)
+ val reusableVH = createReusableViewHost(rootView)
val view = View(context)
reusableVH.updateViewAsync(
@@ -136,7 +162,7 @@
advanceUntilIdle()
assertThat(reusableVH.viewHostAdapter.isInitialized()).isTrue()
- assertThat(reusableVH.rootView.getChildAt(0)).isEqualTo(otherView)
+ assertThat(rootView.getChildAt(0)).isEqualTo(otherView)
}
@Test
@@ -148,7 +174,6 @@
view = view,
attrs = WindowManager.LayoutParams(100, 100),
configuration = context.resources.configuration,
- onDrawTransaction = null,
)
val t = mock(SurfaceControl.Transaction::class.java)
@@ -159,19 +184,23 @@
@Test
fun warmUp_addsRootView() = runTest {
- val reusableVH = createReusableViewHost().apply { warmUp() }
+ val rootView = FrameLayout(context)
+ val reusableVH = createReusableViewHost(rootView).apply { warmUp() }
assertThat(reusableVH.viewHostAdapter.isInitialized()).isTrue()
- assertThat(reusableVH.view()).isEqualTo(reusableVH.rootView)
+ assertThat(reusableVH.view()).isEqualTo(rootView)
}
- private fun CoroutineScope.createReusableViewHost() =
+ private fun CoroutineScope.createReusableViewHost(
+ rootView: FrameLayout = FrameLayout(context)
+ ) =
ReusableWindowDecorViewHost(
context = context,
mainScope = this,
display = context.display,
id = 1,
viewHostAdapter = spy(SurfaceControlViewHostAdapter(context, context.display)),
+ rootView
)
private fun ReusableWindowDecorViewHost.view(): View? = viewHostAdapter.viewHost?.view
diff --git a/libs/androidfw/AssetManager2.cpp b/libs/androidfw/AssetManager2.cpp
index 0fa31c7..f5e10d9 100644
--- a/libs/androidfw/AssetManager2.cpp
+++ b/libs/androidfw/AssetManager2.cpp
@@ -1467,8 +1467,6 @@
}
const StringPiece16 kAttr16 = u"attr";
- const static std::u16string kAttrPrivate16 = u"^attr-private";
-
for (const PackageGroup& package_group : package_groups_) {
for (const ConfiguredPackage& package_impl : package_group.packages_) {
const LoadedPackage* package = package_impl.loaded_package_;
@@ -1480,12 +1478,13 @@
base::expected<uint32_t, NullOrIOError> resid = package->FindEntryByName(type16, entry16);
if (UNLIKELY(IsIOError(resid))) {
return base::unexpected(resid.error());
- }
+ }
if (!resid.has_value() && kAttr16 == type16) {
// Private attributes in libraries (such as the framework) are sometimes encoded
// under the type '^attr-private' in order to leave the ID space of public 'attr'
// free for future additions. Check '^attr-private' for the same name.
+ const static std::u16string kAttrPrivate16 = u"^attr-private";
resid = package->FindEntryByName(kAttrPrivate16, entry16);
}
diff --git a/libs/androidfw/LocaleDataLookup.cpp b/libs/androidfw/LocaleDataLookup.cpp
index ea9e9a2..9aacdcb 100644
--- a/libs/androidfw/LocaleDataLookup.cpp
+++ b/libs/androidfw/LocaleDataLookup.cpp
@@ -14871,12 +14871,22 @@
case 0x656E4154u: // en-AT -> en-150
case 0x656E4245u: // en-BE -> en-150
case 0x656E4348u: // en-CH -> en-150
+ case 0x656E435Au: // en-CZ -> en-150
case 0x656E4445u: // en-DE -> en-150
case 0x656E444Bu: // en-DK -> en-150
+ case 0x656E4553u: // en-ES -> en-150
case 0x656E4649u: // en-FI -> en-150
+ case 0x656E4652u: // en-FR -> en-150
+ case 0x656E4855u: // en-HU -> en-150
+ case 0x656E4954u: // en-IT -> en-150
case 0x656E4E4Cu: // en-NL -> en-150
+ case 0x656E4E4Fu: // en-NO -> en-150
+ case 0x656E504Cu: // en-PL -> en-150
+ case 0x656E5054u: // en-PT -> en-150
+ case 0x656E524Fu: // en-RO -> en-150
case 0x656E5345u: // en-SE -> en-150
case 0x656E5349u: // en-SI -> en-150
+ case 0x656E534Bu: // en-SK -> en-150
return 0x656E80A1u;
case 0x65734152u: // es-AR -> es-419
case 0x6573424Fu: // es-BO -> es-419
diff --git a/libs/hwui/jni/Shader.cpp b/libs/hwui/jni/Shader.cpp
index c025089..45f0fe0 100644
--- a/libs/hwui/jni/Shader.cpp
+++ b/libs/hwui/jni/Shader.cpp
@@ -356,6 +356,10 @@
UpdateChild(env, builder, name.c_str(), childEffect);
}
+static void RuntimeShader_no(JNIEnv* env) {
+ jniThrowRuntimeException(env, "Not supported");
+}
+
///////////////////////////////////////////////////////////////////////////////////////////////
static const JNINativeMethod gShaderMethods[] = {
@@ -385,6 +389,7 @@
static const JNINativeMethod gRuntimeShaderMethods[] = {
{"nativeGetFinalizer", "()J", (void*)RuntimeShader_getNativeFinalizer},
+ {"nativeCreateShader", "(JJ)J", (void*)RuntimeShader_no},
{"nativeCreateShader", "(JJJ)J", (void*)RuntimeShader_create},
{"nativeCreateBuilder", "(Ljava/lang/String;)J", (void*)RuntimeShader_createShaderBuilder},
{"nativeUpdateUniforms", "(JLjava/lang/String;[FZ)V",
diff --git a/location/Android.bp b/location/Android.bp
index bc02d1f..80556a2 100644
--- a/location/Android.bp
+++ b/location/Android.bp
@@ -42,6 +42,7 @@
"FlaggedApi",
],
},
+ jarjar_prefix: "com.android.internal.hidden_from_bootclasspath",
}
platform_compat_config {
diff --git a/media/java/android/media/AudioDeviceVolumeManager.java b/media/java/android/media/AudioDeviceVolumeManager.java
index e1fbfea..892a861 100644
--- a/media/java/android/media/AudioDeviceVolumeManager.java
+++ b/media/java/android/media/AudioDeviceVolumeManager.java
@@ -86,10 +86,10 @@
/**
* @hide
* Interface to receive volume changes on a device that behaves in absolute volume mode.
- * @see #setDeviceAbsoluteMultiVolumeBehavior(AudioDeviceAttributes, List, Executor,
- * OnAudioDeviceVolumeChangeListener)
- * @see #setDeviceAbsoluteVolumeBehavior(AudioDeviceAttributes, VolumeInfo, Executor,
- * OnAudioDeviceVolumeChangeListener)
+ * @see #setDeviceAbsoluteMultiVolumeBehavior(AudioDeviceAttributes, List, boolean, Executor,
+ * OnAudioDeviceVolumeChangedListener)
+ * @see #setDeviceAbsoluteVolumeBehavior(AudioDeviceAttributes, VolumeInfo, boolean, Executor,
+ * OnAudioDeviceVolumeChangedListener)
*/
public interface OnAudioDeviceVolumeChangedListener {
/**
@@ -203,6 +203,9 @@
* volume updates to apply on that device
* @param device the audio device set to absolute volume mode
* @param volume the type of volume this device responds to
+ * @param handlesVolumeAdjustment whether the controller handles volume adjustments separately
+ * from volume changes. If true, adjustments from {@link AudioManager#adjustStreamVolume}
+ * will be sent via {@link OnAudioDeviceVolumeChangedListener#onAudioDeviceVolumeAdjusted}.
* @param executor the Executor used for receiving volume updates through the listener
* @param vclistener the callback for volume updates
*/
@@ -211,13 +214,13 @@
public void setDeviceAbsoluteVolumeBehavior(
@NonNull AudioDeviceAttributes device,
@NonNull VolumeInfo volume,
+ boolean handlesVolumeAdjustment,
@NonNull @CallbackExecutor Executor executor,
- @NonNull OnAudioDeviceVolumeChangedListener vclistener,
- boolean handlesVolumeAdjustment) {
+ @NonNull OnAudioDeviceVolumeChangedListener vclistener) {
final ArrayList<VolumeInfo> volumes = new ArrayList<>(1);
volumes.add(volume);
- setDeviceAbsoluteMultiVolumeBehavior(device, volumes, executor, vclistener,
- handlesVolumeAdjustment);
+ setDeviceAbsoluteMultiVolumeBehavior(device, volumes, handlesVolumeAdjustment, executor,
+ vclistener);
}
/**
@@ -226,20 +229,20 @@
* registers a listener for receiving volume updates to apply on that device
* @param device the audio device set to absolute multi-volume mode
* @param volumes the list of volumes the given device responds to
+ * @param handlesVolumeAdjustment whether the controller handles volume adjustments separately
+ * from volume changes. If true, adjustments from {@link AudioManager#adjustStreamVolume}
+ * will be sent via {@link OnAudioDeviceVolumeChangedListener#onAudioDeviceVolumeAdjusted}.
* @param executor the Executor used for receiving volume updates through the listener
* @param vclistener the callback for volume updates
- * @param handlesVolumeAdjustment whether the controller handles volume adjustments separately
- * from volume changes. If true, adjustments from {@link AudioManager#adjustStreamVolume}
- * will be sent via {@link OnAudioDeviceVolumeChangedListener#onAudioDeviceVolumeAdjusted}.
*/
@RequiresPermission(anyOf = { android.Manifest.permission.MODIFY_AUDIO_ROUTING,
android.Manifest.permission.BLUETOOTH_PRIVILEGED })
public void setDeviceAbsoluteMultiVolumeBehavior(
@NonNull AudioDeviceAttributes device,
@NonNull List<VolumeInfo> volumes,
+ boolean handlesVolumeAdjustment,
@NonNull @CallbackExecutor Executor executor,
- @NonNull OnAudioDeviceVolumeChangedListener vclistener,
- boolean handlesVolumeAdjustment) {
+ @NonNull OnAudioDeviceVolumeChangedListener vclistener) {
baseSetDeviceAbsoluteMultiVolumeBehavior(device, volumes, executor, vclistener,
handlesVolumeAdjustment, AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
}
@@ -249,11 +252,14 @@
* Configures a device to use absolute volume model, and registers a listener for receiving
* volume updates to apply on that device.
*
- * Should be used instead of {@link #setDeviceAbsoluteVolumeBehavior} when there is no reliable
- * way to set the device's volume to a percentage.
+ * <p>Should be used instead of {@link #setDeviceAbsoluteVolumeBehavior} when there is no
+ * reliable way to set the device's volume to a percentage.
*
* @param device the audio device set to absolute volume mode
* @param volume the type of volume this device responds to
+ * @param handlesVolumeAdjustment whether the controller handles volume adjustments separately
+ * from volume changes. If true, adjustments from {@link AudioManager#adjustStreamVolume}
+ * will be sent via {@link OnAudioDeviceVolumeChangedListener#onAudioDeviceVolumeAdjusted}.
* @param executor the Executor used for receiving volume updates through the listener
* @param vclistener the callback for volume updates
*/
@@ -262,13 +268,13 @@
public void setDeviceAbsoluteVolumeAdjustOnlyBehavior(
@NonNull AudioDeviceAttributes device,
@NonNull VolumeInfo volume,
+ boolean handlesVolumeAdjustment,
@NonNull @CallbackExecutor Executor executor,
- @NonNull OnAudioDeviceVolumeChangedListener vclistener,
- boolean handlesVolumeAdjustment) {
+ @NonNull OnAudioDeviceVolumeChangedListener vclistener) {
final ArrayList<VolumeInfo> volumes = new ArrayList<>(1);
volumes.add(volume);
- setDeviceAbsoluteMultiVolumeAdjustOnlyBehavior(device, volumes, executor, vclistener,
- handlesVolumeAdjustment);
+ setDeviceAbsoluteMultiVolumeAdjustOnlyBehavior(device, volumes, handlesVolumeAdjustment,
+ executor, vclistener);
}
/**
@@ -276,11 +282,14 @@
* Configures a device to use absolute volume model applied to different volume types, and
* registers a listener for receiving volume updates to apply on that device.
*
- * Should be used instead of {@link #setDeviceAbsoluteMultiVolumeBehavior} when there is
+ * <p>Should be used instead of {@link #setDeviceAbsoluteMultiVolumeBehavior} when there is
* no reliable way to set the device's volume to a percentage.
*
* @param device the audio device set to absolute multi-volume mode
* @param volumes the list of volumes the given device responds to
+ * @param handlesVolumeAdjustment whether the controller handles volume adjustments separately
+ * from volume changes. If true, adjustments from {@link AudioManager#adjustStreamVolume}
+ * will be sent via {@link OnAudioDeviceVolumeChangedListener#onAudioDeviceVolumeAdjusted}.
* @param executor the Executor used for receiving volume updates through the listener
* @param vclistener the callback for volume updates
*/
@@ -289,16 +298,16 @@
public void setDeviceAbsoluteMultiVolumeAdjustOnlyBehavior(
@NonNull AudioDeviceAttributes device,
@NonNull List<VolumeInfo> volumes,
+ boolean handlesVolumeAdjustment,
@NonNull @CallbackExecutor Executor executor,
- @NonNull OnAudioDeviceVolumeChangedListener vclistener,
- boolean handlesVolumeAdjustment) {
+ @NonNull OnAudioDeviceVolumeChangedListener vclistener) {
baseSetDeviceAbsoluteMultiVolumeBehavior(device, volumes, executor, vclistener,
handlesVolumeAdjustment, AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY);
}
/**
* Base method for configuring a device to use absolute volume behavior, or one of its variants.
- * See {@link AudioManager#AbsoluteDeviceVolumeBehavior} for a list of allowed behaviors.
+ * See {@link AudioManager.AbsoluteDeviceVolumeBehavior} for a list of allowed behaviors.
*
* @param behavior the variant of absolute device volume behavior to adopt
*/
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index 12d7f33..e01cb92 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -1754,13 +1754,21 @@
@UnsupportedAppUsage
public static int setDeviceConnectionState(AudioDeviceAttributes attributes, int state,
int codecFormat) {
+ return setDeviceConnectionState(attributes, state, codecFormat, false /*deviceSwitch*/);
+ }
+
+ /**
+ * @hide
+ */
+ public static int setDeviceConnectionState(AudioDeviceAttributes attributes, int state,
+ int codecFormat, boolean deviceSwitch) {
android.media.audio.common.AudioPort port =
AidlConversion.api2aidl_AudioDeviceAttributes_AudioPort(attributes);
Parcel parcel = Parcel.obtain();
port.writeToParcel(parcel, 0);
parcel.setDataPosition(0);
try {
- return setDeviceConnectionState(state, parcel, codecFormat);
+ return setDeviceConnectionState(state, parcel, codecFormat, deviceSwitch);
} finally {
parcel.recycle();
}
@@ -1769,7 +1777,10 @@
* @hide
*/
@UnsupportedAppUsage
- public static native int setDeviceConnectionState(int state, Parcel parcel, int codecFormat);
+ public static native int setDeviceConnectionState(int state, Parcel parcel, int codecFormat,
+ boolean deviceSwitch);
+
+
/** @hide */
@UnsupportedAppUsage
public static native int getDeviceConnectionState(int device, String device_address);
diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java
index 23f87ab..b8259ef 100644
--- a/media/java/android/media/ExifInterface.java
+++ b/media/java/android/media/ExifInterface.java
@@ -2037,9 +2037,10 @@
// Ignore exceptions in order to keep the compatibility with the old versions of
// ExifInterface.
mIsSupportedFile = false;
- Log.w(TAG, "Invalid image: ExifInterface got an unsupported image format file"
- + "(ExifInterface supports JPEG and some RAW image formats only) "
- + "or a corrupted JPEG file to ExifInterface.", e);
+ Log.d(
+ TAG,
+ "Invalid image: ExifInterface got an unsupported or corrupted image file",
+ e);
} finally {
addDefaultValuesForCompatibility();
diff --git a/media/java/android/media/RingtoneManager.java b/media/java/android/media/RingtoneManager.java
index 0f24654..0213481 100644
--- a/media/java/android/media/RingtoneManager.java
+++ b/media/java/android/media/RingtoneManager.java
@@ -60,6 +60,7 @@
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
+import java.util.Objects;
/**
* RingtoneManager provides access to ringtones, notification, and other types
@@ -810,9 +811,7 @@
// Don't set the stream type
Ringtone ringtone = getRingtone(context, ringtoneUri, -1 /* streamType */,
volumeShaperConfig, false);
- if (Flags.enableRingtoneHapticsCustomization()
- && Utils.isRingtoneVibrationSettingsSupported(context)
- && Utils.hasVibration(ringtoneUri) && hasHapticChannels(ringtoneUri)) {
+ if (muteHapticChannelForVibration(context, ringtoneUri)) {
audioAttributes = new AudioAttributes.Builder(
audioAttributes).setHapticChannelsMuted(true).build();
}
@@ -1305,4 +1304,19 @@
default: throw new IllegalArgumentException();
}
}
+
+ private static boolean muteHapticChannelForVibration(Context context, Uri ringtoneUri) {
+ final Uri vibrationUri = Utils.getVibrationUri(ringtoneUri);
+ // No vibration is specified
+ if (vibrationUri == null) {
+ return false;
+ }
+ // The user specified the synchronized pattern
+ if (Objects.equals(vibrationUri.toString(), Utils.SYNCHRONIZED_VIBRATION)) {
+ return false;
+ }
+ return Flags.enableRingtoneHapticsCustomization()
+ && Utils.isRingtoneVibrationSettingsSupported(context)
+ && hasHapticChannels(ringtoneUri);
+ }
}
diff --git a/media/java/android/media/Utils.java b/media/java/android/media/Utils.java
index 11bd221..d6e27b0 100644
--- a/media/java/android/media/Utils.java
+++ b/media/java/android/media/Utils.java
@@ -66,6 +66,8 @@
public static final String VIBRATION_URI_PARAM = "vibration_uri";
+ public static final String SYNCHRONIZED_VIBRATION = "synchronized";
+
/**
* Sorts distinct (non-intersecting) range array in ascending order.
* @throws java.lang.IllegalArgumentException if ranges are not distinct
@@ -757,8 +759,8 @@
return null;
}
String filePath = vibrationUri.getPath();
- if (filePath == null) {
- Log.w(TAG, "The file path is null.");
+ if (filePath == null || filePath.equals(Utils.SYNCHRONIZED_VIBRATION)) {
+ Log.w(TAG, "Ignore the vibration parsing for file:" + filePath);
return null;
}
File vibrationFile = new File(filePath);
diff --git a/packages/CompanionDeviceManager/res/values-hr/strings.xml b/packages/CompanionDeviceManager/res/values-hr/strings.xml
index d002c9c..c5ed386 100644
--- a/packages/CompanionDeviceManager/res/values-hr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hr/strings.xml
@@ -27,7 +27,7 @@
<string name="chooser_title_non_profile" msgid="6035023914517087400">"Odaberite uređaj kojim će upravljati aplikacija <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string>
<string name="chooser_title" msgid="2235819929238267637">"Odaberite profil <xliff:g id="PROFILE_NAME">%1$s</xliff:g> koji želite postaviti"</string>
<string name="single_device_title" msgid="4199861437545438606">"Traži se <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string>
- <string name="summary_watch" msgid="8134580124808507407">"Aplikacija će moći sinkronizirati podatke kao što je ime pozivatelja i pristupiti tim dopuštenjima na vašem uređaju <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>"</string>
+ <string name="summary_watch" msgid="8134580124808507407">"Aplikacija će moći sinkronizirati podatke kao što je ime pozivatelja i pristupiti tim dopuštenjima na vašem <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Dopustiti aplikaciji <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> da upravlja uređajem <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string>
<string name="profile_name_glasses" msgid="3506504967216601277">"uređaj"</string>
<string name="summary_glasses" msgid="5469208629679579157">"Aplikacija će moći pristupati ovim dopuštenjima na vašem uređaju <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>"</string>
diff --git a/packages/CompanionDeviceManager/res/values-km/strings.xml b/packages/CompanionDeviceManager/res/values-km/strings.xml
index 77e2396..3f6eacf 100644
--- a/packages/CompanionDeviceManager/res/values-km/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-km/strings.xml
@@ -18,7 +18,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4470785958457506021">"កម្មវិធីគ្រប់គ្រងឧបករណ៍ដៃគូ"</string>
<string name="confirmation_title" msgid="2244241995958340998">"អនុញ្ញាតឱ្យកម្មវិធី <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ចូលប្រើ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ឬ?"</string>
- <string name="message_discovery_soft_timeout" msgid="473346859407859161">"សូមប្រាកដថា<xliff:g id="DEVICE_TYPE">%1$s</xliff:g>នេះបានបើក<xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> និងទុក<xliff:g id="PROFILE_NAME">%3$s</xliff:g>នៅជិតអ្នក។"</string>
+ <string name="message_discovery_soft_timeout" msgid="473346859407859161">"សូមប្រាកដថា<xliff:g id="DEVICE_TYPE">%1$s</xliff:g>នេះបានបើក<xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> និងទុក<xliff:g id="PROFILE_NAME">%3$s</xliff:g>របស់អ្នកនៅជិតអ្នក។"</string>
<string name="message_discovery_hard_timeout" msgid="677514663495711424">"រកមិនឃើញឧបករណ៍ទេ។ សូមព្យាយាមម្ដងទៀតនៅពេលក្រោយ។"</string>
<string name="discovery_bluetooth" msgid="5693557668470016164">"ប៊្លូធូស"</string>
<string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ko/strings.xml b/packages/CompanionDeviceManager/res/values-ko/strings.xml
index ee4db7d..0b4274e 100644
--- a/packages/CompanionDeviceManager/res/values-ko/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ko/strings.xml
@@ -18,12 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4470785958457506021">"부속 기기 관리자"</string>
<string name="confirmation_title" msgid="2244241995958340998">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> 앱에서 <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>에 액세스하도록 허용하시겠습니까?"</string>
- <string name="message_discovery_soft_timeout" msgid="473346859407859161">"이 <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>에서 <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> 기능을 사용 설정하고 <xliff:g id="PROFILE_NAME">%3$s</xliff:g> 기기를 근처에 두세요."</string>
+ <string name="message_discovery_soft_timeout" msgid="473346859407859161">"이 <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>에서 <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> 기능을 사용 설정하고 <xliff:g id="PROFILE_NAME">%3$s</xliff:g>을(를) 근처에 두세요."</string>
<string name="message_discovery_hard_timeout" msgid="677514663495711424">"기기를 찾을 수 없습니다. 나중에 다시 시도해 주세요."</string>
<string name="discovery_bluetooth" msgid="5693557668470016164">"블루투스"</string>
<string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string>
<string name="discovery_mixed" msgid="7071466134150760127">"블루투스 및 Wi-Fi"</string>
- <string name="profile_name_watch" msgid="576290739483672360">"시계"</string>
+ <string name="profile_name_watch" msgid="576290739483672360">"워치"</string>
<string name="chooser_title_non_profile" msgid="6035023914517087400">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>에서 관리할 기기 선택"</string>
<string name="chooser_title" msgid="2235819929238267637">"설정할 <xliff:g id="PROFILE_NAME">%1$s</xliff:g> 선택"</string>
<string name="single_device_title" msgid="4199861437545438606">"<xliff:g id="PROFILE_NAME">%1$s</xliff:g> 찾는 중"</string>
diff --git a/packages/CompanionDeviceManager/res/values-tr/strings.xml b/packages/CompanionDeviceManager/res/values-tr/strings.xml
index 8ba76bc..86c0e46 100644
--- a/packages/CompanionDeviceManager/res/values-tr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-tr/strings.xml
@@ -23,7 +23,7 @@
<string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string>
<string name="discovery_wifi" msgid="1551782459721758773">"Kablosuz"</string>
<string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth ve Kablosuz"</string>
- <string name="profile_name_watch" msgid="576290739483672360">"saat"</string>
+ <string name="profile_name_watch" msgid="576290739483672360">"Saat"</string>
<string name="chooser_title_non_profile" msgid="6035023914517087400">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> tarafından yönetilecek bir cihaz seçin"</string>
<string name="chooser_title" msgid="2235819929238267637">"Ayarlamak için bir <xliff:g id="PROFILE_NAME">%1$s</xliff:g> seçin"</string>
<string name="single_device_title" msgid="4199861437545438606">"<xliff:g id="PROFILE_NAME">%1$s</xliff:g> aranıyor"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ur/strings.xml b/packages/CompanionDeviceManager/res/values-ur/strings.xml
index f517742..8c50d81 100644
--- a/packages/CompanionDeviceManager/res/values-ur/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ur/strings.xml
@@ -23,9 +23,9 @@
<string name="discovery_bluetooth" msgid="5693557668470016164">"بلوٹوتھ"</string>
<string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string>
<string name="discovery_mixed" msgid="7071466134150760127">"بلوٹوتھ اور Wi-Fi"</string>
- <string name="profile_name_watch" msgid="576290739483672360">"دیکھیں"</string>
+ <string name="profile_name_watch" msgid="576290739483672360">"گھڑی"</string>
<string name="chooser_title_non_profile" msgid="6035023914517087400">"کوئی آلہ منتخب کریں جس کا نظم و نسق <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> کرے"</string>
- <string name="chooser_title" msgid="2235819929238267637">"سیٹ اپ کرنے کے لیے <xliff:g id="PROFILE_NAME">%1$s</xliff:g> کا انتخاب کریں"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"سیٹ اپ کرنے کے لیے ایک <xliff:g id="PROFILE_NAME">%1$s</xliff:g> کا انتخاب کریں"</string>
<string name="single_device_title" msgid="4199861437545438606">"<xliff:g id="PROFILE_NAME">%1$s</xliff:g> کو تلاش کیا جا رہا ہے"</string>
<string name="summary_watch" msgid="8134580124808507407">"اس ایپ کو آپ کے <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> پر کسی کال کرنے والے کے نام جیسی معلومات کی مطابقت پذیری کرنے اور ان اجازتوں تک رسائی کی اجازت ہوگی"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> کو <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> کا نظم کرنے کی اجازت دیں؟"</string>
diff --git a/packages/InputDevices/res/values-af/strings.xml b/packages/InputDevices/res/values-af/strings.xml
index e364576..273cfa0 100644
--- a/packages/InputDevices/res/values-af/strings.xml
+++ b/packages/InputDevices/res/values-af/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serwies (Cyrillies)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegryns (Cyrillies)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"Roemeens"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-am/strings.xml b/packages/InputDevices/res/values-am/strings.xml
index db5a7d4..8593253 100644
--- a/packages/InputDevices/res/values-am/strings.xml
+++ b/packages/InputDevices/res/values-am/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"ሰርቢያኛ (ሲሪሊክኛ)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"ሞንቴኔግሮኛ (ሲሪሊክኛ)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"ሮማኒያኛ"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-ar/strings.xml b/packages/InputDevices/res/values-ar/strings.xml
index 6d917da..67b7b6a 100644
--- a/packages/InputDevices/res/values-ar/strings.xml
+++ b/packages/InputDevices/res/values-ar/strings.xml
@@ -57,4 +57,5 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"الصربية (السيريلية)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"لغة الجبل الأسود (السيريلية)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"الرومانية"</string>
+ <string name="keyboard_layout_english_india" msgid="7962353311188603367">"الإنجليزية (الهند)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-as/strings.xml b/packages/InputDevices/res/values-as/strings.xml
index c4eaafb..e6540e4 100644
--- a/packages/InputDevices/res/values-as/strings.xml
+++ b/packages/InputDevices/res/values-as/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"ছাৰ্বিয়ান (চিৰিলিক)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"মণ্টেনেগ্ৰিণ (চিৰিলিক)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"ৰোমানিয়ান"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-az/strings.xml b/packages/InputDevices/res/values-az/strings.xml
index d71c396..aa93a92 100644
--- a/packages/InputDevices/res/values-az/strings.xml
+++ b/packages/InputDevices/res/values-az/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serb dili (Kiril)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Monteneqro dili (Kiril)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"Rumın dili"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-b+sr+Latn/strings.xml b/packages/InputDevices/res/values-b+sr+Latn/strings.xml
index e670ed4..1d21a06 100644
--- a/packages/InputDevices/res/values-b+sr+Latn/strings.xml
+++ b/packages/InputDevices/res/values-b+sr+Latn/strings.xml
@@ -57,4 +57,5 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"srpski (ćirilica)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"crnogorski (ćirilica)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"rumunski"</string>
+ <string name="keyboard_layout_english_india" msgid="7962353311188603367">"engleski (Indija)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-be/strings.xml b/packages/InputDevices/res/values-be/strings.xml
index c8c04d4..b374a61 100644
--- a/packages/InputDevices/res/values-be/strings.xml
+++ b/packages/InputDevices/res/values-be/strings.xml
@@ -57,4 +57,5 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Сербская (кірыліца)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Чарнагорская (кірыліца)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"Румынская"</string>
+ <string name="keyboard_layout_english_india" msgid="7962353311188603367">"Англійская (Індыя)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-bg/strings.xml b/packages/InputDevices/res/values-bg/strings.xml
index 82c3965..ceb7e37 100644
--- a/packages/InputDevices/res/values-bg/strings.xml
+++ b/packages/InputDevices/res/values-bg/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"сръбски (кирилица)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"черногорски (кирилица)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"румънски"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-bn/strings.xml b/packages/InputDevices/res/values-bn/strings.xml
index de54cdf..369a803 100644
--- a/packages/InputDevices/res/values-bn/strings.xml
+++ b/packages/InputDevices/res/values-bn/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"সার্বিয়ান (সিরিলিক)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"মন্টেনেগ্রিন (সিরিলিক)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"রোমানিয়ান"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-bs/strings.xml b/packages/InputDevices/res/values-bs/strings.xml
index 9b7b331..6b6b23f 100644
--- a/packages/InputDevices/res/values-bs/strings.xml
+++ b/packages/InputDevices/res/values-bs/strings.xml
@@ -57,4 +57,5 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"srpski (ćirilica)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"crnogorski (ćirilica)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"rumunski"</string>
+ <string name="keyboard_layout_english_india" msgid="7962353311188603367">"engleski (Indija)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-ca/strings.xml b/packages/InputDevices/res/values-ca/strings.xml
index 874e06b..bbf3946 100644
--- a/packages/InputDevices/res/values-ca/strings.xml
+++ b/packages/InputDevices/res/values-ca/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbi (ciríl·lic)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrí (ciríl·lic)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"Romanès"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-cs/strings.xml b/packages/InputDevices/res/values-cs/strings.xml
index c7a4896..e88aa97 100644
--- a/packages/InputDevices/res/values-cs/strings.xml
+++ b/packages/InputDevices/res/values-cs/strings.xml
@@ -57,4 +57,5 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"srbština (cyrilice)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"černohorština (cyrilice)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"rumunština"</string>
+ <string name="keyboard_layout_english_india" msgid="7962353311188603367">"angličtina (Indie)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-da/strings.xml b/packages/InputDevices/res/values-da/strings.xml
index 246baba..00a2a620 100644
--- a/packages/InputDevices/res/values-da/strings.xml
+++ b/packages/InputDevices/res/values-da/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbisk (kyrillisk)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrinsk (kyrillisk)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"Rumænsk"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-de/strings.xml b/packages/InputDevices/res/values-de/strings.xml
index 21a939a..717c597 100644
--- a/packages/InputDevices/res/values-de/strings.xml
+++ b/packages/InputDevices/res/values-de/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbisch (kyrillisch)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrinisch (kyrillisch)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"Rumänisch"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-el/strings.xml b/packages/InputDevices/res/values-el/strings.xml
index eabb90c..02b7f1f 100644
--- a/packages/InputDevices/res/values-el/strings.xml
+++ b/packages/InputDevices/res/values-el/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Σερβικά (Κυριλλικά)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Μαυροβουνιακά (Κυριλλικά)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"Ρουμανικά"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-en-rAU/strings.xml b/packages/InputDevices/res/values-en-rAU/strings.xml
index 7b72cba..1cdcc55 100644
--- a/packages/InputDevices/res/values-en-rAU/strings.xml
+++ b/packages/InputDevices/res/values-en-rAU/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbian (Cyrillic)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrin (Cyrillic)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"Romanian"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-en-rCA/strings.xml b/packages/InputDevices/res/values-en-rCA/strings.xml
index d78dce2..36e0988 100644
--- a/packages/InputDevices/res/values-en-rCA/strings.xml
+++ b/packages/InputDevices/res/values-en-rCA/strings.xml
@@ -57,4 +57,5 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbian (Cyrillic)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrin (Cyrillic)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"Romanian"</string>
+ <string name="keyboard_layout_english_india" msgid="7962353311188603367">"English (India)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-en-rGB/strings.xml b/packages/InputDevices/res/values-en-rGB/strings.xml
index 7b72cba..1cdcc55 100644
--- a/packages/InputDevices/res/values-en-rGB/strings.xml
+++ b/packages/InputDevices/res/values-en-rGB/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbian (Cyrillic)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrin (Cyrillic)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"Romanian"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-en-rIN/strings.xml b/packages/InputDevices/res/values-en-rIN/strings.xml
index 7b72cba..1cdcc55 100644
--- a/packages/InputDevices/res/values-en-rIN/strings.xml
+++ b/packages/InputDevices/res/values-en-rIN/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbian (Cyrillic)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrin (Cyrillic)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"Romanian"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-es-rUS/strings.xml b/packages/InputDevices/res/values-es-rUS/strings.xml
index 2a4035a..edd7657 100644
--- a/packages/InputDevices/res/values-es-rUS/strings.xml
+++ b/packages/InputDevices/res/values-es-rUS/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbio (cirílico)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrino (cirílico)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"Rumano"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-es/strings.xml b/packages/InputDevices/res/values-es/strings.xml
index ba1ef20..b522845 100644
--- a/packages/InputDevices/res/values-es/strings.xml
+++ b/packages/InputDevices/res/values-es/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbio (cirílico)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrino (cirílico)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"Rumano"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-et/strings.xml b/packages/InputDevices/res/values-et/strings.xml
index 99f3626..82670dd 100644
--- a/packages/InputDevices/res/values-et/strings.xml
+++ b/packages/InputDevices/res/values-et/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"serbia (kirillitsa)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"montenegro (kirillitsa)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"rumeenia"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-eu/strings.xml b/packages/InputDevices/res/values-eu/strings.xml
index 9fae4f9..b777b8c 100644
--- a/packages/InputDevices/res/values-eu/strings.xml
+++ b/packages/InputDevices/res/values-eu/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbiarra (zirilikoa)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegroarra (zirilikoa)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"Errumaniera"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-fa/strings.xml b/packages/InputDevices/res/values-fa/strings.xml
index cbc6b65..9ec7a34 100644
--- a/packages/InputDevices/res/values-fa/strings.xml
+++ b/packages/InputDevices/res/values-fa/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"صربی (سیریلیک)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"مونتهنگرویی (سیریلیک)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"رومانیایی"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-fi/strings.xml b/packages/InputDevices/res/values-fi/strings.xml
index 736d7cb..6825ea9 100644
--- a/packages/InputDevices/res/values-fi/strings.xml
+++ b/packages/InputDevices/res/values-fi/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"serbia (kyrillinen)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"montenegro (kyrillinen)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"romania"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-fr-rCA/strings.xml b/packages/InputDevices/res/values-fr-rCA/strings.xml
index 7b99d3b..353d7ad 100644
--- a/packages/InputDevices/res/values-fr-rCA/strings.xml
+++ b/packages/InputDevices/res/values-fr-rCA/strings.xml
@@ -57,4 +57,5 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbe (cyrillique)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Monténégrin (cyrillique)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"Roumain"</string>
+ <string name="keyboard_layout_english_india" msgid="7962353311188603367">"Anglais (Inde)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-fr/strings.xml b/packages/InputDevices/res/values-fr/strings.xml
index 8628f8f..fb4d144 100644
--- a/packages/InputDevices/res/values-fr/strings.xml
+++ b/packages/InputDevices/res/values-fr/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbe (cyrillique)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Monténégrin (cyrillique)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"Roumain"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-gl/strings.xml b/packages/InputDevices/res/values-gl/strings.xml
index 5e681e6..925adf9 100644
--- a/packages/InputDevices/res/values-gl/strings.xml
+++ b/packages/InputDevices/res/values-gl/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbio (cirílico)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrino (cirílico)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"Romanés"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-gu/strings.xml b/packages/InputDevices/res/values-gu/strings.xml
index a5a522e..60965dc 100644
--- a/packages/InputDevices/res/values-gu/strings.xml
+++ b/packages/InputDevices/res/values-gu/strings.xml
@@ -57,4 +57,5 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"સર્બિયન (સિરિલિક)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"મોંટેનેગ્રીન (સિરિલિક)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"રોમાનિયન"</string>
+ <string name="keyboard_layout_english_india" msgid="7962353311188603367">"અંગ્રેજી (ભારત)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-hi/strings.xml b/packages/InputDevices/res/values-hi/strings.xml
index ad9c980..1751979 100644
--- a/packages/InputDevices/res/values-hi/strings.xml
+++ b/packages/InputDevices/res/values-hi/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"सर्बियन (सिरिलिक)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"मोंटेनेग्रिन (सिरिलिक)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"रोमेनियन"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-hr/strings.xml b/packages/InputDevices/res/values-hr/strings.xml
index b7e8ee4..746eb03 100644
--- a/packages/InputDevices/res/values-hr/strings.xml
+++ b/packages/InputDevices/res/values-hr/strings.xml
@@ -57,4 +57,5 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"srpski (ćirilica)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"crnogorski (ćirilica)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"rumunjski"</string>
+ <string name="keyboard_layout_english_india" msgid="7962353311188603367">"engleski (Indija)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-hu/strings.xml b/packages/InputDevices/res/values-hu/strings.xml
index 756cc08..c83ba84 100644
--- a/packages/InputDevices/res/values-hu/strings.xml
+++ b/packages/InputDevices/res/values-hu/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"szerb (cirill betűs)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"montenegrói (cirill betűs)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"román"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-hy/strings.xml b/packages/InputDevices/res/values-hy/strings.xml
index eced5cd..718f8d1 100644
--- a/packages/InputDevices/res/values-hy/strings.xml
+++ b/packages/InputDevices/res/values-hy/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"սերբերեն (կյուրեղատառ)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"չեռնոգորերեն (կյուրեղատառ)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"Ռումիներեն"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-in/strings.xml b/packages/InputDevices/res/values-in/strings.xml
index e871d19..ba2e5bd3 100644
--- a/packages/InputDevices/res/values-in/strings.xml
+++ b/packages/InputDevices/res/values-in/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbia (Sirilik)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegro (Sirilik)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"Rumania"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-is/strings.xml b/packages/InputDevices/res/values-is/strings.xml
index ec5d98b..842119d 100644
--- a/packages/InputDevices/res/values-is/strings.xml
+++ b/packages/InputDevices/res/values-is/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbneska (kyrillískt)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Svartfellska (kyrillískt)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"rúmenska"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-it/strings.xml b/packages/InputDevices/res/values-it/strings.xml
index 06ceb7af..f7f76e0 100644
--- a/packages/InputDevices/res/values-it/strings.xml
+++ b/packages/InputDevices/res/values-it/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbo (cirillico)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrino (cirillico)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"Rumeno"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-iw/strings.xml b/packages/InputDevices/res/values-iw/strings.xml
index 85f9656..0df5d20 100644
--- a/packages/InputDevices/res/values-iw/strings.xml
+++ b/packages/InputDevices/res/values-iw/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"סרבית (אותיות קיריליות)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"מונטנגרית (אותיות קיריליות)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"רומנית"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-ja/strings.xml b/packages/InputDevices/res/values-ja/strings.xml
index 4c6de70..41c244c 100644
--- a/packages/InputDevices/res/values-ja/strings.xml
+++ b/packages/InputDevices/res/values-ja/strings.xml
@@ -57,4 +57,5 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"セルビア語(キリル)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"モンテネグロ語(キリル)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"ルーマニア語"</string>
+ <string name="keyboard_layout_english_india" msgid="7962353311188603367">"英語(インド)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-ka/strings.xml b/packages/InputDevices/res/values-ka/strings.xml
index 7232c1a..0a9ba3f 100644
--- a/packages/InputDevices/res/values-ka/strings.xml
+++ b/packages/InputDevices/res/values-ka/strings.xml
@@ -57,4 +57,5 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"სერბული (კირილიცა)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"მონტენეგრული (კირილიცა)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"რუმინული"</string>
+ <string name="keyboard_layout_english_india" msgid="7962353311188603367">"ინგლისური (ინდოეთი)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-kk/strings.xml b/packages/InputDevices/res/values-kk/strings.xml
index 278c868..60ad838 100644
--- a/packages/InputDevices/res/values-kk/strings.xml
+++ b/packages/InputDevices/res/values-kk/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Сербия (кириллица)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Черногория (кириллица)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"Румын"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-km/strings.xml b/packages/InputDevices/res/values-km/strings.xml
index 2eaeaa7..936c925 100644
--- a/packages/InputDevices/res/values-km/strings.xml
+++ b/packages/InputDevices/res/values-km/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"សែប៊ី (ស៊ីរីលីក)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"ម៉ុងតេណេហ្គ្រោ (ស៊ីរីលីក)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"រ៉ូម៉ានី"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-kn/strings.xml b/packages/InputDevices/res/values-kn/strings.xml
index 8039039..2453951 100644
--- a/packages/InputDevices/res/values-kn/strings.xml
+++ b/packages/InputDevices/res/values-kn/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"ಸೆರ್ಬಿಯನ್ (ಸಿರಿಲಿಕ್)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"ಮೊಂಟೆನೆಗ್ರಿನ್ (ಸಿರಿಲಿಕ್)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"ರೊಮೇನಿಯನ್"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-ko/strings.xml b/packages/InputDevices/res/values-ko/strings.xml
index de1bb3d..07975a4 100644
--- a/packages/InputDevices/res/values-ko/strings.xml
+++ b/packages/InputDevices/res/values-ko/strings.xml
@@ -57,4 +57,5 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"세르비아어(키릴 자모)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"몬테네그로어(키릴)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"루마니아어"</string>
+ <string name="keyboard_layout_english_india" msgid="7962353311188603367">"영어(인도)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-ky/strings.xml b/packages/InputDevices/res/values-ky/strings.xml
index 47bf7b7..f6d018e 100644
--- a/packages/InputDevices/res/values-ky/strings.xml
+++ b/packages/InputDevices/res/values-ky/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Сербче (Кирилл)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Черногориялыкча (Кирилл)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"Румынча"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-lo/strings.xml b/packages/InputDevices/res/values-lo/strings.xml
index 6a35f23..61f8f71 100644
--- a/packages/InputDevices/res/values-lo/strings.xml
+++ b/packages/InputDevices/res/values-lo/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"ເຊີບຽນ (ຊີຣິວລິກ)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"ມອນເທເນກຣິນ (ຊີຣິວລິກ)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"ໂຣມານຽນ"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-lt/strings.xml b/packages/InputDevices/res/values-lt/strings.xml
index 4bf9223..fc9941f 100644
--- a/packages/InputDevices/res/values-lt/strings.xml
+++ b/packages/InputDevices/res/values-lt/strings.xml
@@ -57,4 +57,5 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbų (kirilica)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Juodkalniečių (kirilica)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"Rumunų"</string>
+ <string name="keyboard_layout_english_india" msgid="7962353311188603367">"Anglų k. (Indija)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-lv/strings.xml b/packages/InputDevices/res/values-lv/strings.xml
index 90d690ca..cc2c94c 100644
--- a/packages/InputDevices/res/values-lv/strings.xml
+++ b/packages/InputDevices/res/values-lv/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbu (kirilica)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Melnkalniešu (kirilica)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"Rumāņu"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-mk/strings.xml b/packages/InputDevices/res/values-mk/strings.xml
index 4c80a80..60981d6 100644
--- a/packages/InputDevices/res/values-mk/strings.xml
+++ b/packages/InputDevices/res/values-mk/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"српски (кирилица)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"црногорски (кирилица)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"романски"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-ml/strings.xml b/packages/InputDevices/res/values-ml/strings.xml
index 41ea10f..8064c74 100644
--- a/packages/InputDevices/res/values-ml/strings.xml
+++ b/packages/InputDevices/res/values-ml/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"സെർബിയൻ (സിറിലിക്)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"മോണ്ടിനെഗ്രിൻ (സിറിലിക്)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"റൊമേനിയൻ"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-mn/strings.xml b/packages/InputDevices/res/values-mn/strings.xml
index 056e728..547ce49 100644
--- a/packages/InputDevices/res/values-mn/strings.xml
+++ b/packages/InputDevices/res/values-mn/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Серби (кирилл)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Монтенегро (кирилл)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"Румын"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-mr/strings.xml b/packages/InputDevices/res/values-mr/strings.xml
index fe032fe..25bdfab 100644
--- a/packages/InputDevices/res/values-mr/strings.xml
+++ b/packages/InputDevices/res/values-mr/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"सर्बियन (सिरिलिक)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"मॉन्टेनेग्रिन (सिरिलिक)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"रोमानियन"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-ms/strings.xml b/packages/InputDevices/res/values-ms/strings.xml
index f9d18a1..b6e36ab 100644
--- a/packages/InputDevices/res/values-ms/strings.xml
+++ b/packages/InputDevices/res/values-ms/strings.xml
@@ -57,4 +57,5 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbia (Cyril)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrin (Cyril)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"Bahasa Romania"</string>
+ <string name="keyboard_layout_english_india" msgid="7962353311188603367">"Bahasa Inggeris (India)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-my/strings.xml b/packages/InputDevices/res/values-my/strings.xml
index 47498e0..4ef5aab 100644
--- a/packages/InputDevices/res/values-my/strings.xml
+++ b/packages/InputDevices/res/values-my/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"ဆားဘီးယား (စီရီလစ်)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"မွန်တီနီဂရင်း (စီရီလစ်)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"ရိုမေးနီးယား"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-nb/strings.xml b/packages/InputDevices/res/values-nb/strings.xml
index 954462c..837e246 100644
--- a/packages/InputDevices/res/values-nb/strings.xml
+++ b/packages/InputDevices/res/values-nb/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbisk (kyrillisk)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrisk (kyrillisk)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"Rumensk"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-ne/strings.xml b/packages/InputDevices/res/values-ne/strings.xml
index e2804d4..0ab1ea6 100644
--- a/packages/InputDevices/res/values-ne/strings.xml
+++ b/packages/InputDevices/res/values-ne/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"सर्बियाली (सिरिलिक)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"मोन्टेनिग्रिन (सिरिलिक)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"रोमानियाली"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-nl/strings.xml b/packages/InputDevices/res/values-nl/strings.xml
index 67f78ba..5c175fb 100644
--- a/packages/InputDevices/res/values-nl/strings.xml
+++ b/packages/InputDevices/res/values-nl/strings.xml
@@ -57,4 +57,5 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Servisch (Cyrillisch)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrijns (Cyrillisch)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"Roemeens"</string>
+ <string name="keyboard_layout_english_india" msgid="7962353311188603367">"Engels (India)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-or/strings.xml b/packages/InputDevices/res/values-or/strings.xml
index c6e020c..97f9088 100644
--- a/packages/InputDevices/res/values-or/strings.xml
+++ b/packages/InputDevices/res/values-or/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"ସର୍ବିଆନ (ସିରିଲିକ)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"ମଣ୍ଟେନେଗ୍ରିନ (ସିରିଲିକ)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"ରୋମାନିଆନ"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-pa/strings.xml b/packages/InputDevices/res/values-pa/strings.xml
index 29c3b7d..343418e 100644
--- a/packages/InputDevices/res/values-pa/strings.xml
+++ b/packages/InputDevices/res/values-pa/strings.xml
@@ -57,4 +57,5 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"ਸਰਬੀਆਈ (ਸਿਰਿਲਿਕ)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"ਮਾਂਟੇਨੀਗਰਿਨ (ਸਿਰਿਲਿਕ)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"ਰੋਮਾਨੀਆਈ"</string>
+ <string name="keyboard_layout_english_india" msgid="7962353311188603367">"ਅੰਗਰੇਜ਼ੀ (ਭਾਰਤ)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-pl/strings.xml b/packages/InputDevices/res/values-pl/strings.xml
index 8ce00d3..0fd962b 100644
--- a/packages/InputDevices/res/values-pl/strings.xml
+++ b/packages/InputDevices/res/values-pl/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"serbski (cyrylica)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"czarnogórski (cyrylica)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"rumuński"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-pt-rBR/strings.xml b/packages/InputDevices/res/values-pt-rBR/strings.xml
index 3b1fc9b..e649b58 100644
--- a/packages/InputDevices/res/values-pt-rBR/strings.xml
+++ b/packages/InputDevices/res/values-pt-rBR/strings.xml
@@ -57,4 +57,5 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Sérvio (cirílico)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrino (cirílico)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"Romeno"</string>
+ <string name="keyboard_layout_english_india" msgid="7962353311188603367">"Inglês (Índia)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-pt-rPT/strings.xml b/packages/InputDevices/res/values-pt-rPT/strings.xml
index 163108d..cd0a046 100644
--- a/packages/InputDevices/res/values-pt-rPT/strings.xml
+++ b/packages/InputDevices/res/values-pt-rPT/strings.xml
@@ -57,4 +57,5 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Sérvio (cirílico)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrino (cirílico)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"Romeno"</string>
+ <string name="keyboard_layout_english_india" msgid="7962353311188603367">"Inglês (Índia)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-pt/strings.xml b/packages/InputDevices/res/values-pt/strings.xml
index 3b1fc9b..e649b58 100644
--- a/packages/InputDevices/res/values-pt/strings.xml
+++ b/packages/InputDevices/res/values-pt/strings.xml
@@ -57,4 +57,5 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Sérvio (cirílico)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrino (cirílico)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"Romeno"</string>
+ <string name="keyboard_layout_english_india" msgid="7962353311188603367">"Inglês (Índia)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-ro/strings.xml b/packages/InputDevices/res/values-ro/strings.xml
index 78c99ce..169378d 100644
--- a/packages/InputDevices/res/values-ro/strings.xml
+++ b/packages/InputDevices/res/values-ro/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Sârbă (caractere chirilice)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Muntenegreană (Chirilică)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"Română"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-ru/strings.xml b/packages/InputDevices/res/values-ru/strings.xml
index 183b00e..2d5a6b0 100644
--- a/packages/InputDevices/res/values-ru/strings.xml
+++ b/packages/InputDevices/res/values-ru/strings.xml
@@ -57,4 +57,5 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Сербский (кириллица)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Черногорский (кириллица)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"Румынский"</string>
+ <string name="keyboard_layout_english_india" msgid="7962353311188603367">"Английский (Индия)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-si/strings.xml b/packages/InputDevices/res/values-si/strings.xml
index 78d1010..ba27136 100644
--- a/packages/InputDevices/res/values-si/strings.xml
+++ b/packages/InputDevices/res/values-si/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"සර්බියානු (සිරිලික්)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"මොන්ටෙනේග්රීන් (සිරිලික්)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"රුමේනියානු"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-sk/strings.xml b/packages/InputDevices/res/values-sk/strings.xml
index c269085..8ae45be 100644
--- a/packages/InputDevices/res/values-sk/strings.xml
+++ b/packages/InputDevices/res/values-sk/strings.xml
@@ -57,4 +57,5 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"srbčina (cyrilika)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"čiernohorčina (cyrilika)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"rumunčina"</string>
+ <string name="keyboard_layout_english_india" msgid="7962353311188603367">"angličtina (India)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-sl/strings.xml b/packages/InputDevices/res/values-sl/strings.xml
index d2e9fd1..ced6ab1 100644
--- a/packages/InputDevices/res/values-sl/strings.xml
+++ b/packages/InputDevices/res/values-sl/strings.xml
@@ -57,4 +57,5 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"srbščina (cirilica)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"črnogorščina (cirilica)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"romunščina"</string>
+ <string name="keyboard_layout_english_india" msgid="7962353311188603367">"angleščina (Indija)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-sq/strings.xml b/packages/InputDevices/res/values-sq/strings.xml
index 066129e..c77de92 100644
--- a/packages/InputDevices/res/values-sq/strings.xml
+++ b/packages/InputDevices/res/values-sq/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbisht (cirilike)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Malazisht (cirilike)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"Rumanisht"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-sr/strings.xml b/packages/InputDevices/res/values-sr/strings.xml
index e4fed03..0c0748d 100644
--- a/packages/InputDevices/res/values-sr/strings.xml
+++ b/packages/InputDevices/res/values-sr/strings.xml
@@ -57,4 +57,5 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"српски (ћирилица)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"црногорски (ћирилица)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"румунски"</string>
+ <string name="keyboard_layout_english_india" msgid="7962353311188603367">"енглески (Индија)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-sv/strings.xml b/packages/InputDevices/res/values-sv/strings.xml
index 4eaf856..5701d01 100644
--- a/packages/InputDevices/res/values-sv/strings.xml
+++ b/packages/InputDevices/res/values-sv/strings.xml
@@ -57,4 +57,5 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"serbiska (kyrilliskt)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"montenegrinska (kyrilliskt)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"rumänska"</string>
+ <string name="keyboard_layout_english_india" msgid="7962353311188603367">"engelska (Indien)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-sw/strings.xml b/packages/InputDevices/res/values-sw/strings.xml
index 30b52b2..d9ac91f8 100644
--- a/packages/InputDevices/res/values-sw/strings.xml
+++ b/packages/InputDevices/res/values-sw/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Kiserbia (Kisiriliki)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Kimontenegri (Kisiriliki)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"Kiromania"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-ta/strings.xml b/packages/InputDevices/res/values-ta/strings.xml
index d60084c..fc91d696 100644
--- a/packages/InputDevices/res/values-ta/strings.xml
+++ b/packages/InputDevices/res/values-ta/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"செர்பியன் (சிரிலிக்)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"மாண்டினெக்ரன் (சிரிலிக்)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"ரோமானியன்"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-te/strings.xml b/packages/InputDevices/res/values-te/strings.xml
index 2f40442..f164736 100644
--- a/packages/InputDevices/res/values-te/strings.xml
+++ b/packages/InputDevices/res/values-te/strings.xml
@@ -57,4 +57,5 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"సెర్బియన్ (సిరిలిక్)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"మాంటెనెగ్రిన్ (సిరిలిక్)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"రొమేనియన్"</string>
+ <string name="keyboard_layout_english_india" msgid="7962353311188603367">"ఇంగ్లీష్ (భారతదేశం)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-th/strings.xml b/packages/InputDevices/res/values-th/strings.xml
index ae10f04..1538fdb 100644
--- a/packages/InputDevices/res/values-th/strings.xml
+++ b/packages/InputDevices/res/values-th/strings.xml
@@ -57,4 +57,5 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"เซอร์เบีย (ซีริลลิก)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"มอนเตเนโกร (ซีริลลิก)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"โรมาเนีย"</string>
+ <string name="keyboard_layout_english_india" msgid="7962353311188603367">"อังกฤษ (อินเดีย)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-tl/strings.xml b/packages/InputDevices/res/values-tl/strings.xml
index dc0d1f5..ea815d5 100644
--- a/packages/InputDevices/res/values-tl/strings.xml
+++ b/packages/InputDevices/res/values-tl/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbian (Cyrillic)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrin (Cyrillic)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"Romanian"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-tr/strings.xml b/packages/InputDevices/res/values-tr/strings.xml
index 2e7084d..3a40c84 100644
--- a/packages/InputDevices/res/values-tr/strings.xml
+++ b/packages/InputDevices/res/values-tr/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Sırpça (Kiril)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Karadağca (Kiril)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"Rumence"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-uk/strings.xml b/packages/InputDevices/res/values-uk/strings.xml
index 01d34e3..0e0d562 100644
--- a/packages/InputDevices/res/values-uk/strings.xml
+++ b/packages/InputDevices/res/values-uk/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Сербська (кирилиця)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Чорногорська (кирилиця)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"Румунська"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-ur/strings.xml b/packages/InputDevices/res/values-ur/strings.xml
index 94cd329..44721b8 100644
--- a/packages/InputDevices/res/values-ur/strings.xml
+++ b/packages/InputDevices/res/values-ur/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"سربیائی (سیریلک)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"مونٹے نیگریائی (سیریلک)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"رومانیائی"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-uz/strings.xml b/packages/InputDevices/res/values-uz/strings.xml
index e63fc09..776c1c7 100644
--- a/packages/InputDevices/res/values-uz/strings.xml
+++ b/packages/InputDevices/res/values-uz/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serb (kirill)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Chernogor (kirill)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"Rumin"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-vi/strings.xml b/packages/InputDevices/res/values-vi/strings.xml
index 8384c3e..1fcba42 100644
--- a/packages/InputDevices/res/values-vi/strings.xml
+++ b/packages/InputDevices/res/values-vi/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Tiếng Serbia (Chữ Kirin)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Tiếng Montenegro (Chữ Kirin)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"Tiếng Romania"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-zh-rCN/strings.xml b/packages/InputDevices/res/values-zh-rCN/strings.xml
index e3a8af3..cb7f6cb 100644
--- a/packages/InputDevices/res/values-zh-rCN/strings.xml
+++ b/packages/InputDevices/res/values-zh-rCN/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"塞尔维亚语(西里尔字母)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"黑山语(西里尔字母)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"罗马尼亚语"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-zh-rHK/strings.xml b/packages/InputDevices/res/values-zh-rHK/strings.xml
index 56681b8..c718760 100644
--- a/packages/InputDevices/res/values-zh-rHK/strings.xml
+++ b/packages/InputDevices/res/values-zh-rHK/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"塞爾維亞文 (西里爾字母)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"蒙特內哥羅文 (西里爾字母)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"羅馬尼亞文"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-zh-rTW/strings.xml b/packages/InputDevices/res/values-zh-rTW/strings.xml
index 60c085b..68cf9b0 100644
--- a/packages/InputDevices/res/values-zh-rTW/strings.xml
+++ b/packages/InputDevices/res/values-zh-rTW/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"塞爾維亞文 (西里爾字母)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"蒙特內哥羅文 (西里爾字母)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"羅馬尼亞文"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-zu/strings.xml b/packages/InputDevices/res/values-zu/strings.xml
index 6697333..4ae9e47 100644
--- a/packages/InputDevices/res/values-zu/strings.xml
+++ b/packages/InputDevices/res/values-zu/strings.xml
@@ -57,4 +57,6 @@
<string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbian (Cyrillic)"</string>
<string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrin (Cyrillic)"</string>
<string name="keyboard_layout_romanian" msgid="8698989892731726903">"IsiRomanian"</string>
+ <!-- no translation found for keyboard_layout_english_india (7962353311188603367) -->
+ <skip />
</resources>
diff --git a/packages/LocalTransport/src/com/android/localtransport/LocalTransport.java b/packages/LocalTransport/src/com/android/localtransport/LocalTransport.java
index a3b06e8..5590ca72 100644
--- a/packages/LocalTransport/src/com/android/localtransport/LocalTransport.java
+++ b/packages/LocalTransport/src/com/android/localtransport/LocalTransport.java
@@ -23,6 +23,7 @@
import android.app.backup.BackupDataInput;
import android.app.backup.BackupDataOutput;
import android.app.backup.BackupManagerMonitor;
+import android.app.backup.BackupRestoreEventLogger;
import android.app.backup.BackupRestoreEventLogger.DataTypeResult;
import android.app.backup.BackupTransport;
import android.app.backup.RestoreDescription;
@@ -38,6 +39,7 @@
import android.system.StructStat;
import android.util.ArrayMap;
import android.util.Base64;
+import android.util.Dumpable;
import android.util.Log;
import com.android.tools.r8.keepanno.annotations.KeepTarget;
@@ -51,6 +53,8 @@
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -59,11 +63,14 @@
/**
* Backup transport for stashing stuff into a known location on disk, and
* later restoring from there. For testing only.
+ *
+ * <p>Note: the quickest way to build and sync this class is:
+ * {@code m LocalTransport && adb install $OUT/system/priv-app/LocalTransport/LocalTransport.apk}
*/
public class LocalTransport extends BackupTransport {
- private static final String TAG = "LocalTransport";
- private static final boolean DEBUG = false;
+ static final String TAG = "LocalTransport";
+ static final boolean DEBUG = Log.isLoggable(TAG, Log.VERBOSE);
private static final String TRANSPORT_DIR_NAME
= "com.android.localtransport.LocalTransport";
@@ -124,6 +131,8 @@
}
public LocalTransport(Context context, LocalTransportParameters parameters) {
+ Log.i(TAG, "Creating LocalTransport for user " + context.getUserId()
+ + " (DEBUG=" + DEBUG + ")");
mContext = context;
mParameters = parameters;
makeDataDirs();
@@ -910,35 +919,68 @@
return mMonitor;
}
- private class TestBackupManagerMonitor extends BackupManagerMonitor {
+ private class TestBackupManagerMonitor extends BackupManagerMonitor implements Dumpable {
+
+ private final List<DataTypeResult> mReceivedResults = new ArrayList<>();
+ private int mNumberReceivedEvents;
+
@Override
public void onEvent(Bundle event) {
- if (event == null || !mParameters.logAgentResults()) {
+ if (event == null) {
+ if (DEBUG) {
+ Log.w(TAG, "onEvent() called with null");
+ }
return;
}
-
- if (event.getInt(BackupManagerMonitor.EXTRA_LOG_EVENT_ID)
- == BackupManagerMonitor.LOG_EVENT_ID_AGENT_LOGGING_RESULTS) {
- Log.i(TAG, "agent_logging_results {");
- ArrayList<DataTypeResult> results = event.getParcelableArrayList(
- BackupManagerMonitor.EXTRA_LOG_AGENT_LOGGING_RESULTS,
- DataTypeResult.class);
- for (DataTypeResult result : results) {
- Log.i(TAG, "\tdataType: " + result.getDataType());
- Log.i(TAG, "\tsuccessCount: " + result.getSuccessCount());
- Log.i(TAG, "\tfailCount: " + result.getFailCount());
- Log.i(TAG, "\tmetadataHash: " + Arrays.toString(result.getMetadataHash()));
-
- if (!result.getErrors().isEmpty()) {
- Log.i(TAG, "\terrors {");
- for (String error : result.getErrors().keySet()) {
- Log.i(TAG, "\t\t" + error + ": " + result.getErrors().get(error));
- }
- Log.i(TAG, "\t}");
- }
-
- Log.i(TAG, "}");
+ int eventId = event.getInt(BackupManagerMonitor.EXTRA_LOG_EVENT_ID);
+ if (eventId != BackupManagerMonitor.LOG_EVENT_ID_AGENT_LOGGING_RESULTS) {
+ if (DEBUG) Log.v(TAG, "ignoring event with id " + eventId);
+ return;
+ }
+ mNumberReceivedEvents++;
+ boolean logResults = mParameters.logAgentResults();
+ ArrayList<DataTypeResult> results = event.getParcelableArrayList(
+ BackupManagerMonitor.EXTRA_LOG_AGENT_LOGGING_RESULTS,
+ DataTypeResult.class);
+ int size = results.size();
+ if (size == 0) {
+ if (logResults) {
+ Log.i(TAG, "no agent_logging_results on event #" + mNumberReceivedEvents);
}
+ return;
+ }
+ if (logResults) {
+ Log.i(TAG, "agent_logging_results {");
+ }
+ for (int i = 0; i < size; i++) {
+ var result = results.get(i);
+ mReceivedResults.add(result);
+ if (logResults) {
+ Log.i(TAG, "\t" + BackupRestoreEventLogger.toString(result));
+ }
+ }
+ if (logResults) {
+ Log.i(TAG, "}");
+ }
+ }
+
+ @Override
+ public void dump(PrintWriter pw, String[] args) {
+ pw.println("TestBackupManagerMonitor");
+ pw.printf("%d events received", mNumberReceivedEvents);
+ if (mNumberReceivedEvents == 0) {
+ pw.println();
+ return;
+ }
+ int size = mReceivedResults.size();
+ if (size == 0) {
+ pw.println("; no results on them");
+ return;
+ }
+ pw.printf("; %d results on them:\n", size);
+ for (int i = 0; i < size; i++) {
+ DataTypeResult result = mReceivedResults.get(i);
+ pw.printf(" #%d: %s\n", i, BackupRestoreEventLogger.toString(result));
}
}
}
@@ -953,4 +995,60 @@
}
return mParameters.noRestrictedModePackages();
}
+
+ @Override
+ public String toString() {
+ try {
+ try (StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw)) {
+ dump(pw, /* args= */ null);
+ pw.flush();
+ return sw.toString();
+ }
+ } catch (IOException e) {
+ // Shouldn't happen...
+ Log.e(TAG, "toString(): failed to dump", e);
+ return super.toString();
+ }
+ }
+
+ void dump(PrintWriter pw, String[] args) {
+ pw.printf("mDataDir: %s\n", mDataDir);
+ pw.printf("mCurrentSetDir: %s\n", mCurrentSetDir);
+ pw.printf("mCurrentSetIncrementalDir: %s\n", mCurrentSetIncrementalDir);
+ pw.printf("mCurrentSetFullDir: %s\n", mCurrentSetFullDir);
+
+ pw.printf("mRestorePackages: %s\n", Arrays.toString(mRestorePackages));
+ pw.printf("mRestorePackage: %d\n", mRestorePackage);
+ pw.printf("mRestoreType: %d\n", mRestoreType);
+ pw.printf("mRestoreSetDir: %s\n", mRestoreSetDir);
+ pw.printf("mRestoreSetIncrementalDir: %s\n", mRestoreSetIncrementalDir);
+ pw.printf("mRestoreSetFullDir: %s\n", mRestoreSetFullDir);
+
+ pw.printf("mFullTargetPackage: %s\n", mFullTargetPackage);
+ pw.printf("mSocket: %s\n", mSocket);
+ pw.printf("mSocketInputStream: %s\n", mSocketInputStream);
+ pw.printf("mFullBackupOutputStream: %s\n", mFullBackupOutputStream);
+ dumpByteArray(pw, "mFullBackupBuffer", mFullBackupBuffer);
+ pw.printf("mFullBackupSize: %d\n", mFullBackupSize);
+
+ pw.printf("mCurFullRestoreStream: %s\n", mCurFullRestoreStream);
+ dumpByteArray(pw, "mFullRestoreBuffer", mFullRestoreBuffer);
+ if (mParameters == null) {
+ pw.println("No LocalTransportParameters");
+ } else {
+ pw.println(mParameters);
+ }
+ if (mMonitor instanceof Dumpable) {
+ ((Dumpable) mMonitor).dump(pw, args);
+ }
+
+ pw.printf("currentDestinationString(): %s\n", currentDestinationString());
+ pw.printf("dataManagementIntent(): %s\n", dataManagementIntent());
+ pw.printf("dataManagementIntentLabel(): %s\n", dataManagementIntentLabel());
+ pw.printf("transportDirName(): %s\n", transportDirName());
+ }
+
+ private void dumpByteArray(PrintWriter pw, String name, byte[] array) {
+ pw.printf("%s size: %d\n", name, (array == null ? 0 : array.length));
+ }
}
diff --git a/packages/LocalTransport/src/com/android/localtransport/LocalTransportParameters.java b/packages/LocalTransport/src/com/android/localtransport/LocalTransportParameters.java
index c980913..c7cfc5b 100644
--- a/packages/LocalTransport/src/com/android/localtransport/LocalTransportParameters.java
+++ b/packages/LocalTransport/src/com/android/localtransport/LocalTransportParameters.java
@@ -16,11 +16,15 @@
package com.android.localtransport;
+import static com.android.localtransport.LocalTransport.DEBUG;
+import static com.android.localtransport.LocalTransport.TAG;
+
import android.content.ContentResolver;
import android.os.Handler;
import android.provider.Settings;
import android.util.KeyValueListParser;
import android.util.KeyValueSettingObserver;
+import android.util.Log;
import java.util.Arrays;
import java.util.List;
@@ -76,15 +80,30 @@
}
public String getSettingValue(ContentResolver resolver) {
- return Settings.Secure.getString(resolver, SETTING);
+ String value = Settings.Secure.getString(resolver, SETTING);
+ if (DEBUG) {
+ Log.d(TAG, "LocalTransportParameters.getSettingValue(): returning " + value);
+ }
+ return value;
}
public void update(KeyValueListParser parser) {
- mFakeEncryptionFlag = parser.getBoolean(KEY_FAKE_ENCRYPTION_FLAG, false);
- mIsNonIncrementalOnly = parser.getBoolean(KEY_NON_INCREMENTAL_ONLY, false);
- mIsDeviceTransfer = parser.getBoolean(KEY_IS_DEVICE_TRANSFER, false);
- mIsEncrypted = parser.getBoolean(KEY_IS_ENCRYPTED, false);
- mLogAgentResults = parser.getBoolean(KEY_LOG_AGENT_RESULTS, /* def */ false);
+ mFakeEncryptionFlag = parser.getBoolean(KEY_FAKE_ENCRYPTION_FLAG, /* def= */ false);
+ mIsNonIncrementalOnly = parser.getBoolean(KEY_NON_INCREMENTAL_ONLY, /* def= */ false);
+ mIsDeviceTransfer = parser.getBoolean(KEY_IS_DEVICE_TRANSFER, /* def= */ false);
+ mIsEncrypted = parser.getBoolean(KEY_IS_ENCRYPTED, /* def= */ false);
+ mLogAgentResults = parser.getBoolean(KEY_LOG_AGENT_RESULTS, /* def= */ false);
mNoRestrictedModePackages = parser.getString(KEY_NO_RESTRICTED_MODE_PACKAGES, /* def */ "");
}
+
+ @Override
+ public String toString() {
+ return "LocalTransportParameters[mFakeEncryptionFlag=" + mFakeEncryptionFlag
+ + ", mIsNonIncrementalOnly=" + mIsNonIncrementalOnly
+ + ", mIsDeviceTransfer=" + mIsDeviceTransfer
+ + ", mIsEncrypted=" + mIsEncrypted
+ + ", mLogAgentResults=" + mLogAgentResults
+ + ", noRestrictedModePackages()=" + noRestrictedModePackages()
+ + "]";
+ }
}
diff --git a/packages/LocalTransport/src/com/android/localtransport/LocalTransportService.java b/packages/LocalTransport/src/com/android/localtransport/LocalTransportService.java
index ac4f418..2f6c57a 100644
--- a/packages/LocalTransport/src/com/android/localtransport/LocalTransportService.java
+++ b/packages/LocalTransport/src/com/android/localtransport/LocalTransportService.java
@@ -16,15 +16,28 @@
package com.android.localtransport;
+import static com.android.localtransport.LocalTransport.DEBUG;
+import static com.android.localtransport.LocalTransport.TAG;
+
+import android.annotation.Nullable;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
+import android.util.Log;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
public class LocalTransportService extends Service {
- private static LocalTransport sTransport = null;
+
+ @Nullable
+ private static LocalTransport sTransport;
@Override
public void onCreate() {
+ if (DEBUG) {
+ Log.d(TAG, "LocalTransportService.onCreate()");
+ }
if (sTransport == null) {
LocalTransportParameters parameters =
new LocalTransportParameters(getMainThreadHandler(), getContentResolver());
@@ -35,11 +48,27 @@
@Override
public void onDestroy() {
+ if (DEBUG) {
+ Log.d(TAG, "LocalTransportService.onDestroy()");
+ }
sTransport.getParameters().stop();
}
@Override
public IBinder onBind(Intent intent) {
+ if (DEBUG) {
+ Log.d(TAG, "LocalTransportService.onBind(" + intent + "): parameters="
+ + sTransport.getParameters());
+ }
return sTransport.getBinder();
}
+
+ @Override
+ protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ if (sTransport == null) {
+ pw.println("No sTransport");
+ return;
+ }
+ sTransport.dump(pw, args);
+ }
}
diff --git a/packages/PackageInstaller/res/values-or/strings.xml b/packages/PackageInstaller/res/values-or/strings.xml
index b99bf1a..dab2401 100644
--- a/packages/PackageInstaller/res/values-or/strings.xml
+++ b/packages/PackageInstaller/res/values-or/strings.xml
@@ -58,7 +58,7 @@
<string name="uninstall_application_title" msgid="4045420072401428123">"ଆପ୍କୁ ଅନଇନଷ୍ଟଲ୍ କରନ୍ତୁ"</string>
<string name="uninstall_update_title" msgid="824411791011583031">"ଅପଡେଟ୍ ଅନଇନଷ୍ଟଲ୍ କରନ୍ତୁ"</string>
<string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> ହେଉଛି ନିମ୍ନ ଆପ୍ର ଏକ ଅଂଶ।"</string>
- <string name="uninstall_application_text" msgid="3816830743706143980">"ଆପଣ ଏହି ଆପ୍ ଅନଇନଷ୍ଟଲ୍ କରିବାକୁ ଚାହାଁନ୍ତି କି?"</string>
+ <string name="uninstall_application_text" msgid="3816830743706143980">"ଆପଣ ଏହି ଆପ ଅନଇନଷ୍ଟଲ କରିବାକୁ ଚାହାଁନ୍ତି କି?"</string>
<string name="archive_application_text" msgid="8482325710714386348">"ଆପଣଙ୍କ ବ୍ୟକ୍ତିଗତ ଡାଟା ସେଭ ହୋଇଯିବ"</string>
<string name="archive_application_text_all_users" msgid="3151229641681672580">"ସମସ୍ତ ୟୁଜରଙ୍କ ପାଇଁ ଏହି ଆପକୁ ଆର୍କାଇଭ କରିବେ? ଆପଣଙ୍କ ବ୍ୟକ୍ତିଗତ ଡାଟା ସେଭ ହୋଇଯିବ"</string>
<string name="archive_application_text_current_user_work_profile" msgid="1450487362134779752">"ଆପଣଙ୍କ ୱାର୍କ ପ୍ରୋଫାଇଲରେ ଏହି ଆପକୁ ଆର୍କାଇଭ କରିବେ? ଆପଣଙ୍କ ବ୍ୟକ୍ତିଗତ ଡାଟା ସେଭ ହୋଇଯିବ"</string>
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/InstallLaunch.kt b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/InstallLaunch.kt
index c61a2ac..481023e 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/InstallLaunch.kt
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/InstallLaunch.kt
@@ -16,9 +16,6 @@
package com.android.packageinstaller.v2.ui
-import android.app.Activity.RESULT_CANCELED
-import android.app.Activity.RESULT_FIRST_USER
-import android.app.Activity.RESULT_OK
import android.app.AppOpsManager
import android.content.ActivityNotFoundException
import android.content.Intent
@@ -67,6 +64,7 @@
InstallLaunch::class.java.packageName + ".callingPkgName"
private val LOG_TAG = InstallLaunch::class.java.simpleName
private const val TAG_DIALOG = "dialog"
+ private const val ARGS_SAVED_INTENT = "saved_intent"
}
/**
@@ -96,7 +94,15 @@
intent.getStringExtra(EXTRA_CALLING_PKG_NAME),
intent.getIntExtra(EXTRA_CALLING_PKG_UID, Process.INVALID_UID)
)
- installViewModel!!.preprocessIntent(intent, info)
+
+ var savedIntent: Intent? = null
+ if (savedInstanceState != null) {
+ savedIntent = savedInstanceState.getParcelable(ARGS_SAVED_INTENT, Intent::class.java)
+ }
+ if (!intent.filterEquals(savedIntent)) {
+ installViewModel!!.preprocessIntent(intent, info)
+ }
+
installViewModel!!.currentInstallStage.observe(this) { installStage: InstallStage ->
onInstallStageChange(installStage)
}
@@ -344,6 +350,11 @@
appOpsManager!!.stopWatchingMode(listener)
}
+ override fun onSaveInstanceState(outState: Bundle) {
+ outState.putParcelable(ARGS_SAVED_INTENT, intent)
+ super.onSaveInstanceState(outState)
+ }
+
override fun onDestroy() {
super.onDestroy()
while (activeUnknownSourcesListeners.isNotEmpty()) {
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/UninstallLaunch.kt b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/UninstallLaunch.kt
index c4ca272..0a02845e 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/UninstallLaunch.kt
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/UninstallLaunch.kt
@@ -16,7 +16,6 @@
package com.android.packageinstaller.v2.ui
-import android.app.Activity
import android.app.NotificationManager
import android.content.Intent
import android.os.Bundle
@@ -51,6 +50,7 @@
UninstallLaunch::class.java.packageName + ".callingActivityName"
val LOG_TAG = UninstallLaunch::class.java.simpleName
private const val TAG_DIALOG = "dialog"
+ private const val ARGS_SAVED_INTENT = "saved_intent"
}
private var uninstallViewModel: UninstallViewModel? = null
@@ -76,7 +76,15 @@
intent.getStringExtra(EXTRA_CALLING_ACTIVITY_NAME),
intent.getIntExtra(EXTRA_CALLING_PKG_UID, Process.INVALID_UID)
)
- uninstallViewModel!!.preprocessIntent(intent, callerInfo)
+
+ var savedIntent: Intent? = null
+ if (savedInstanceState != null) {
+ savedIntent = savedInstanceState.getParcelable(ARGS_SAVED_INTENT, Intent::class.java)
+ }
+ if (!intent.filterEquals(savedIntent)) {
+ uninstallViewModel!!.preprocessIntent(intent, callerInfo)
+ }
+
uninstallViewModel!!.currentUninstallStage.observe(this) { uninstallStage: UninstallStage ->
onUninstallStageChange(uninstallStage)
}
@@ -171,6 +179,11 @@
Log.d(LOG_TAG, "Cancelling uninstall")
}
uninstallViewModel!!.cancelUninstall()
- setResult(Activity.RESULT_FIRST_USER, null, true)
+ setResult(RESULT_FIRST_USER, null, true)
+ }
+
+ override fun onSaveInstanceState(outState: Bundle) {
+ outState.putParcelable(ARGS_SAVED_INTENT, intent)
+ super.onSaveInstanceState(outState)
}
}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/v2/viewmodel/InstallViewModel.kt b/packages/PackageInstaller/src/com/android/packageinstaller/v2/viewmodel/InstallViewModel.kt
index 388e03f..5a2b122 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/v2/viewmodel/InstallViewModel.kt
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/v2/viewmodel/InstallViewModel.kt
@@ -49,6 +49,20 @@
_currentInstallStage.value = installStage
}
}
+
+ // Since staging is an async operation, we will get the staging result later in time.
+ // Result of the file staging will be set in InstallRepository#mStagingResult.
+ // As such, mCurrentInstallStage will need to add another MutableLiveData
+ // as a data source
+ _currentInstallStage.addSource(
+ repository.stagingResult.distinctUntilChanged()
+ ) { installStage: InstallStage ->
+ if (installStage.stageCode != InstallStage.STAGE_READY) {
+ _currentInstallStage.value = installStage
+ } else {
+ checkIfAllowedAndInitiateInstall()
+ }
+ }
}
fun preprocessIntent(intent: Intent, callerInfo: InstallRepository.CallerInfo) {
@@ -56,18 +70,7 @@
if (stage.stageCode == InstallStage.STAGE_ABORTED) {
_currentInstallStage.value = stage
} else {
- // Since staging is an async operation, we will get the staging result later in time.
- // Result of the file staging will be set in InstallRepository#mStagingResult.
- // As such, mCurrentInstallStage will need to add another MutableLiveData
- // as a data source
repository.stageForInstall()
- _currentInstallStage.addSource(repository.stagingResult) { installStage: InstallStage ->
- if (installStage.stageCode != InstallStage.STAGE_READY) {
- _currentInstallStage.value = installStage
- } else {
- checkIfAllowedAndInitiateInstall()
- }
- }
}
}
diff --git a/packages/SettingsLib/SettingsTheme/src/com/android/settingslib/widget/SettingsBasePreferenceFragment.kt b/packages/SettingsLib/SettingsTheme/src/com/android/settingslib/widget/SettingsBasePreferenceFragment.kt
index bfaeb42..8d12f01 100644
--- a/packages/SettingsLib/SettingsTheme/src/com/android/settingslib/widget/SettingsBasePreferenceFragment.kt
+++ b/packages/SettingsLib/SettingsTheme/src/com/android/settingslib/widget/SettingsBasePreferenceFragment.kt
@@ -17,7 +17,9 @@
package com.android.settingslib.widget
import android.os.Bundle
+import android.view.LayoutInflater;
import android.view.View
+import android.view.ViewGroup;
import androidx.annotation.CallSuper
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.PreferenceScreen
@@ -27,6 +29,15 @@
abstract class SettingsBasePreferenceFragment : PreferenceFragmentCompat() {
@CallSuper
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ return super.onCreateView(inflater, container, savedInstanceState)
+ }
+
+ @CallSuper
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
if (SettingsThemeHelper.isExpressiveTheme(requireContext())) {
diff --git a/packages/SettingsLib/Spa/spa/Android.bp b/packages/SettingsLib/Spa/spa/Android.bp
index ac44a1b..5aeea9c 100644
--- a/packages/SettingsLib/Spa/spa/Android.bp
+++ b/packages/SettingsLib/Spa/spa/Android.bp
@@ -24,7 +24,9 @@
srcs: ["src/**/*.kt"],
use_resource_processor: true,
static_libs: [
+ "MPAndroidChart",
"SettingsLibColor",
+ "aconfig_settingstheme_exported_flags_java_lib",
"androidx.compose.animation_animation",
"androidx.compose.material3_material3",
"androidx.compose.material_material-icons-extended",
@@ -36,7 +38,6 @@
"androidx.navigation_navigation-compose",
"com.google.android.material_material",
"lottie_compose",
- "MPAndroidChart",
],
kotlincflags: [
"-Xjvm-default=all",
diff --git a/packages/SettingsLib/Spa/spa/build.gradle.kts b/packages/SettingsLib/Spa/spa/build.gradle.kts
index 1396629..de1fa4e 100644
--- a/packages/SettingsLib/Spa/spa/build.gradle.kts
+++ b/packages/SettingsLib/Spa/spa/build.gradle.kts
@@ -51,6 +51,7 @@
dependencies {
api(project(":SettingsLibColor"))
+ api(project(":SettingsLib:SettingsTheme"))
api("androidx.appcompat:appcompat:1.7.0")
api("androidx.compose.material3:material3:1.4.0-alpha05")
api("androidx.compose.material:material-icons-extended")
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsTheme.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsTheme.kt
index f948d51..badf7ae 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsTheme.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsTheme.kt
@@ -22,6 +22,7 @@
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import com.android.settingslib.spa.framework.util.SystemProperties
+import com.android.settingslib.widget.theme.flags.Flags
/**
* The Material 3 Theme for Settings.
@@ -42,5 +43,7 @@
}
}
-val isSpaExpressiveEnabled
- by lazy { SystemProperties.getBoolean("is_expressive_design_enabled", false) }
+val isSpaExpressiveEnabled by lazy {
+ SystemProperties.getBoolean("is_expressive_design_enabled", false) ||
+ Flags.isExpressiveDesignEnabled()
+}
diff --git a/packages/SettingsLib/Spa/tests/Android.bp b/packages/SettingsLib/Spa/tests/Android.bp
index 871449e..315b400 100644
--- a/packages/SettingsLib/Spa/tests/Android.bp
+++ b/packages/SettingsLib/Spa/tests/Android.bp
@@ -30,10 +30,14 @@
static_libs: [
"SpaLib",
"SpaLibTestUtils",
+ "aconfig_settingstheme_exported_flags_java_lib",
"androidx.compose.runtime_runtime",
"androidx.test.ext.junit",
"androidx.test.runner",
+ "flag-junit",
+ "flag-junit-base",
"mockito-target-minus-junit4",
+ "platform-test-annotations",
],
kotlincflags: ["-Xjvm-default=all"],
sdk_version: "current",
diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/button/ActionButtonsTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/button/ActionButtonsTest.kt
index 8d9bac6..bab02b0 100644
--- a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/button/ActionButtonsTest.kt
+++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/button/ActionButtonsTest.kt
@@ -16,6 +16,8 @@
package com.android.settingslib.spa.widget.button
+import android.platform.test.annotations.RequiresFlagsDisabled
+import android.platform.test.flag.junit.DeviceFlagsValueProvider
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.Launch
import androidx.compose.material.icons.outlined.Close
@@ -28,6 +30,7 @@
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.settingslib.widget.theme.flags.Flags.FLAG_IS_EXPRESSIVE_DESIGN_ENABLED
import com.google.common.truth.Truth.assertThat
import org.junit.Rule
import org.junit.Test
@@ -37,6 +40,8 @@
class ActionButtonsTest {
@get:Rule
val composeTestRule = createComposeRule()
+ @get:Rule
+ val mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule()
@Test
fun button_displayed() {
@@ -54,6 +59,7 @@
composeTestRule.onNodeWithText("Open").assertIsDisplayed()
}
+ @RequiresFlagsDisabled(FLAG_IS_EXPRESSIVE_DESIGN_ENABLED)
@Test
fun button_clickable() {
var clicked by mutableStateOf(false)
diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/scaffold/CustomizedAppBarTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/scaffold/CustomizedAppBarTest.kt
index 0a4f0d9..89206ba 100644
--- a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/scaffold/CustomizedAppBarTest.kt
+++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/scaffold/CustomizedAppBarTest.kt
@@ -16,6 +16,8 @@
package com.android.settingslib.spa.widget.scaffold
+import android.platform.test.annotations.RequiresFlagsDisabled
+import android.platform.test.flag.junit.DeviceFlagsValueProvider
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.lazy.LazyColumn
@@ -52,6 +54,7 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.settingslib.spa.testutils.rootWidth
import com.android.settingslib.spa.testutils.setContentForSizeAssertions
+import com.android.settingslib.widget.theme.flags.Flags.FLAG_IS_EXPRESSIVE_DESIGN_ENABLED
import com.google.common.truth.Truth.assertThat
import org.junit.Rule
import org.junit.Test
@@ -62,6 +65,8 @@
class CustomizedAppBarTest {
@get:Rule val rule = createComposeRule()
+ @get:Rule
+ val mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule()
@Test
fun smallTopAppBar_expandsToScreen() {
@@ -97,6 +102,7 @@
assertThat(textStyle).isEqualTo(expectedTextStyle)
}
+ @RequiresFlagsDisabled(FLAG_IS_EXPRESSIVE_DESIGN_ENABLED)
@Test
fun smallTopAppBar_contentColor() {
var titleColor: Color = Color.Unspecified
diff --git a/packages/SettingsLib/res/drawable/ic_1x_mobiledata_updated.xml b/packages/SettingsLib/res/drawable/ic_1x_mobiledata_updated.xml
new file mode 100644
index 0000000..bd2fad2
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_1x_mobiledata_updated.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright (C) 2025 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="17dp"
+ android:height="12.88dp"
+ android:viewportWidth="13.53"
+ android:viewportHeight="10.25">
+ <path
+ android:pathData="M3.738,10.252C3.468,10.252 3.234,10.154 3.038,9.958C2.847,9.757 2.751,9.522 2.751,9.251L2.751,2.587L1.372,3.497C1.167,3.628 0.943,3.672 0.7,3.63C0.462,3.588 0.276,3.467 0.14,3.266C0.01,3.065 -0.032,2.844 0.014,2.601C0.066,2.358 0.192,2.172 0.392,2.041L3.185,0.2C3.265,0.149 3.344,0.104 3.423,0.067C3.507,0.025 3.619,0.004 3.759,0.004C4.03,0.004 4.259,0.102 4.445,0.298C4.637,0.494 4.732,0.734 4.732,1.019L4.732,9.251C4.732,9.522 4.634,9.757 4.438,9.958C4.242,10.154 4.009,10.252 3.738,10.252ZM12.582,10.245C12.391,10.245 12.218,10.194 12.064,10.091C11.915,9.984 11.796,9.848 11.707,9.685L9.803,6.038L9.593,5.961L7.332,1.411C7.136,1.084 7.127,0.769 7.304,0.466C7.482,0.163 7.755,0.011 8.123,0.011C8.301,0.011 8.466,0.065 8.62,0.172C8.779,0.279 8.903,0.415 8.991,0.578L10.783,4.015L11.014,4.05L13.373,8.796C13.569,9.132 13.581,9.459 13.408,9.776C13.236,10.089 12.96,10.245 12.582,10.245ZM7.92,10.238C7.57,10.238 7.309,10.089 7.136,9.79C6.968,9.491 6.978,9.186 7.164,8.873L9.621,4.008L9.817,4.008L11.63,0.557C11.719,0.398 11.836,0.27 11.98,0.172C12.125,0.069 12.288,0.018 12.47,0.018C12.816,0.018 13.075,0.163 13.247,0.452C13.42,0.741 13.411,1.047 13.219,1.369L10.909,5.982L10.762,5.989L8.781,9.713C8.697,9.867 8.578,9.993 8.424,10.091C8.27,10.189 8.102,10.238 7.92,10.238Z"
+ android:fillColor="#000"/>
+</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_3g_mobiledata_updated.xml b/packages/SettingsLib/res/drawable/ic_3g_mobiledata_updated.xml
new file mode 100644
index 0000000..8e632e6
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_3g_mobiledata_updated.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright (C) 2025 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="17dp"
+ android:height="12.21dp"
+ android:viewportWidth="14.51"
+ android:viewportHeight="10.42">
+ <path
+ android:pathData="M2.827,10.416C2.225,10.416 1.726,10.311 1.329,10.101C0.937,9.891 0.629,9.606 0.405,9.247C0.181,8.888 0.051,8.58 0.013,8.323C-0.019,8.066 0.023,7.849 0.139,7.672C0.256,7.49 0.415,7.371 0.615,7.315C0.816,7.254 1.003,7.259 1.175,7.329C1.353,7.394 1.481,7.495 1.56,7.63C1.644,7.765 1.733,7.922 1.826,8.099C1.92,8.272 2.041,8.416 2.19,8.533C2.34,8.65 2.533,8.708 2.771,8.708C3.089,8.708 3.343,8.615 3.534,8.428C3.726,8.237 3.821,7.959 3.821,7.595L3.821,6.888C3.821,6.529 3.726,6.256 3.534,6.069C3.348,5.882 3.077,5.789 2.722,5.789L2.456,5.789C2.251,5.789 2.071,5.714 1.917,5.565C1.768,5.416 1.693,5.236 1.693,5.026C1.693,4.816 1.768,4.636 1.917,4.487C2.067,4.338 2.244,4.263 2.449,4.263L2.666,4.263C2.984,4.263 3.222,4.177 3.38,4.004C3.544,3.831 3.625,3.558 3.625,3.185L3.625,2.618C3.625,2.315 3.544,2.084 3.38,1.925C3.217,1.766 2.998,1.687 2.722,1.687C2.531,1.687 2.37,1.729 2.239,1.813C2.109,1.892 1.999,2.004 1.91,2.149C1.822,2.294 1.738,2.427 1.658,2.548C1.579,2.665 1.453,2.756 1.28,2.821C1.108,2.882 0.926,2.882 0.734,2.821C0.543,2.756 0.391,2.632 0.279,2.45C0.172,2.268 0.142,2.049 0.188,1.792C0.24,1.531 0.384,1.248 0.622,0.945C0.86,0.642 1.159,0.408 1.518,0.245C1.882,0.082 2.326,0 2.848,0C3.67,0 4.323,0.215 4.808,0.644C5.294,1.069 5.536,1.636 5.536,2.345L5.536,2.8C5.536,3.332 5.417,3.768 5.179,4.109C4.941,4.445 4.598,4.69 4.15,4.844L4.15,4.9C4.678,5.017 5.086,5.259 5.375,5.628C5.669,5.992 5.816,6.484 5.816,7.105L5.816,7.679C5.816,8.514 5.55,9.179 5.018,9.674C4.491,10.169 3.761,10.416 2.827,10.416ZM10.943,10.416C9.819,10.411 8.92,10.031 8.248,9.275C7.581,8.514 7.247,7.406 7.247,5.95L7.247,4.417C7.247,2.975 7.588,1.878 8.269,1.127C8.951,0.371 9.863,-0.005 11.006,0C11.52,0 11.954,0.075 12.308,0.224C12.668,0.369 12.973,0.576 13.225,0.847C13.482,1.113 13.659,1.374 13.757,1.631C13.855,1.883 13.862,2.121 13.778,2.345C13.694,2.569 13.55,2.732 13.344,2.835C13.144,2.938 12.948,2.968 12.756,2.926C12.565,2.884 12.416,2.802 12.308,2.681C12.201,2.555 12.091,2.422 11.979,2.282C11.867,2.142 11.727,2.032 11.559,1.953C11.391,1.869 11.191,1.827 10.957,1.827C10.439,1.822 10.024,2.011 9.711,2.394C9.403,2.777 9.249,3.358 9.249,4.137L9.249,6.293C9.249,7.063 9.408,7.644 9.725,8.036C10.047,8.428 10.467,8.624 10.985,8.624C11.489,8.624 11.884,8.477 12.168,8.183C12.453,7.889 12.607,7.474 12.63,6.937L12.63,6.265L11.657,6.265C11.452,6.265 11.275,6.188 11.125,6.034C10.976,5.875 10.901,5.689 10.901,5.474C10.901,5.255 10.978,5.068 11.132,4.914C11.291,4.755 11.48,4.676 11.699,4.676L13.666,4.676C13.9,4.676 14.098,4.755 14.261,4.914C14.425,5.073 14.509,5.269 14.513,5.502L14.513,6.538C14.513,7.77 14.191,8.724 13.547,9.401C12.908,10.078 12.04,10.416 10.943,10.416Z"
+ android:fillColor="#000"/>
+</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_4g_lte_mobiledata_updated.xml b/packages/SettingsLib/res/drawable/ic_4g_lte_mobiledata_updated.xml
new file mode 100644
index 0000000..bba359e
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_4g_lte_mobiledata_updated.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright (C) 2025 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="34dp"
+ android:height="14.07dp"
+ android:viewportWidth="27.29"
+ android:viewportHeight="11.29">
+ <path
+ android:pathData="M4.552,11.195C4.286,11.195 4.058,11.099 3.866,10.908C3.68,10.717 3.586,10.488 3.586,10.222L3.586,8.171L3.74,7.891L3.74,2.823L4.72,3.53L3.712,3.53L1.808,7.366L4.37,7.366L4.797,7.275L5.777,7.275C6.015,7.275 6.218,7.359 6.386,7.527C6.554,7.695 6.638,7.898 6.638,8.136C6.638,8.369 6.554,8.57 6.386,8.738C6.218,8.906 6.015,8.99 5.777,8.99L1.192,8.99C0.856,8.99 0.572,8.88 0.338,8.661C0.11,8.442 -0.005,8.169 -0.005,7.842C-0.005,7.683 0.016,7.569 0.058,7.499C0.1,7.424 0.142,7.35 0.184,7.275L3.124,1.633C3.222,1.446 3.374,1.283 3.579,1.143C3.789,1.003 4.013,0.933 4.251,0.933C4.606,0.933 4.905,1.061 5.147,1.318C5.39,1.57 5.511,1.876 5.511,2.235L5.511,10.222C5.511,10.488 5.416,10.717 5.224,10.908C5.038,11.099 4.814,11.195 4.552,11.195ZM11.303,11.286C10.179,11.281 9.28,10.901 8.608,10.145C7.941,9.384 7.607,8.276 7.607,6.82L7.607,5.287C7.607,3.845 7.948,2.748 8.629,1.997C9.311,1.241 10.223,0.865 11.366,0.87C11.88,0.87 12.314,0.945 12.668,1.094C13.028,1.239 13.333,1.446 13.585,1.717C13.842,1.983 14.019,2.244 14.117,2.501C14.215,2.753 14.222,2.991 14.138,3.215C14.054,3.439 13.91,3.602 13.704,3.705C13.504,3.808 13.308,3.838 13.116,3.796C12.925,3.754 12.776,3.672 12.668,3.551C12.561,3.425 12.451,3.292 12.339,3.152C12.227,3.012 12.087,2.902 11.919,2.823C11.751,2.739 11.551,2.697 11.317,2.697C10.799,2.692 10.384,2.881 10.071,3.264C9.763,3.647 9.609,4.228 9.609,5.007L9.609,7.163C9.609,7.933 9.768,8.514 10.085,8.906C10.407,9.298 10.827,9.494 11.345,9.494C11.849,9.494 12.244,9.347 12.528,9.053C12.813,8.759 12.967,8.344 12.99,7.807L12.99,7.135L12.017,7.135C11.812,7.135 11.635,7.058 11.485,6.904C11.336,6.745 11.261,6.559 11.261,6.344C11.261,6.125 11.338,5.938 11.492,5.784C11.651,5.625 11.84,5.546 12.059,5.546L14.026,5.546C14.26,5.546 14.458,5.625 14.621,5.784C14.785,5.943 14.869,6.139 14.873,6.372L14.873,7.408C14.873,8.64 14.551,9.594 13.907,10.271C13.268,10.948 12.4,11.286 11.303,11.286ZM16.641,6.09C16.434,6.09 16.256,6.016 16.108,5.867C15.962,5.719 15.89,5.543 15.89,5.338L15.89,0.689C15.89,0.501 15.957,0.34 16.091,0.206C16.226,0.069 16.385,0 16.57,0C16.758,0 16.919,0.069 17.053,0.206C17.187,0.34 17.255,0.501 17.255,0.689L17.255,4.83L18.54,4.83C18.713,4.83 18.863,4.892 18.989,5.015C19.115,5.138 19.178,5.286 19.178,5.46C19.178,5.631 19.115,5.779 18.989,5.905C18.863,6.028 18.713,6.09 18.54,6.09L16.641,6.09ZM20.979,6.166C20.792,6.166 20.63,6.098 20.496,5.964C20.365,5.827 20.299,5.664 20.299,5.477L20.299,0.731L21.664,0.731L21.664,5.477C21.664,5.664 21.597,5.827 21.462,5.964C21.328,6.098 21.167,6.166 20.979,6.166ZM19.648,1.331C19.474,1.331 19.324,1.27 19.198,1.147C19.075,1.023 19.014,0.876 19.014,0.706C19.014,0.532 19.075,0.384 19.198,0.26C19.324,0.137 19.474,0.076 19.648,0.076L22.306,0.076C22.48,0.076 22.628,0.137 22.751,0.26C22.877,0.384 22.941,0.532 22.941,0.706C22.941,0.876 22.877,1.023 22.751,1.147C22.628,1.27 22.48,1.331 22.306,1.331L19.648,1.331ZM24.553,6.09C24.346,6.09 24.168,6.016 24.019,5.867C23.874,5.719 23.801,5.543 23.801,5.338L23.801,0.823C23.801,0.619 23.874,0.444 24.019,0.298C24.168,0.15 24.346,0.076 24.553,0.076L26.59,0.076C26.763,0.076 26.912,0.137 27.035,0.26C27.161,0.384 27.224,0.531 27.224,0.701C27.224,0.872 27.161,1.019 27.035,1.142C26.912,1.266 26.763,1.327 26.59,1.327L25.158,1.327L25.158,4.838L26.657,4.838C26.831,4.838 26.979,4.9 27.102,5.023C27.225,5.146 27.287,5.293 27.287,5.464C27.287,5.635 27.225,5.782 27.102,5.905C26.979,6.028 26.831,6.09 26.657,6.09L24.553,6.09ZM24.637,3.595L24.637,2.444L26.3,2.444C26.46,2.444 26.595,2.5 26.707,2.612C26.822,2.724 26.88,2.86 26.88,3.02C26.88,3.177 26.822,3.312 26.707,3.427C26.595,3.539 26.46,3.595 26.3,3.595L24.637,3.595Z"
+ android:fillColor="#000"/>
+</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_4g_lte_plus_mobiledata_updated.xml b/packages/SettingsLib/res/drawable/ic_4g_lte_plus_mobiledata_updated.xml
new file mode 100644
index 0000000..cb6fd50
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_4g_lte_plus_mobiledata_updated.xml
@@ -0,0 +1,27 @@
+<!--
+ Copyright (C) 2025 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="34dp"
+ android:height="11.93dp"
+ android:viewportWidth="32.18"
+ android:viewportHeight="11.29">
+ <path
+ android:pathData="M4.552,11.195C4.286,11.195 4.058,11.099 3.866,10.908C3.68,10.717 3.586,10.488 3.586,10.222L3.586,8.171L3.74,7.891L3.74,2.823L4.72,3.53L3.712,3.53L1.808,7.366L4.37,7.366L4.797,7.275L5.777,7.275C6.015,7.275 6.218,7.359 6.386,7.527C6.554,7.695 6.638,7.898 6.638,8.136C6.638,8.369 6.554,8.57 6.386,8.738C6.218,8.906 6.015,8.99 5.777,8.99L1.192,8.99C0.856,8.99 0.572,8.88 0.338,8.661C0.11,8.442 -0.005,8.169 -0.005,7.842C-0.005,7.683 0.016,7.569 0.058,7.499C0.1,7.424 0.142,7.35 0.184,7.275L3.124,1.633C3.222,1.446 3.374,1.283 3.579,1.143C3.789,1.003 4.013,0.933 4.251,0.933C4.606,0.933 4.905,1.061 5.147,1.318C5.39,1.57 5.511,1.876 5.511,2.235L5.511,10.222C5.511,10.488 5.416,10.717 5.224,10.908C5.038,11.099 4.814,11.195 4.552,11.195ZM11.303,11.286C10.179,11.281 9.28,10.901 8.608,10.145C7.941,9.384 7.607,8.276 7.607,6.82L7.607,5.287C7.607,3.845 7.948,2.748 8.629,1.997C9.311,1.241 10.223,0.865 11.366,0.87C11.88,0.87 12.314,0.945 12.668,1.094C13.028,1.239 13.333,1.446 13.585,1.717C13.842,1.983 14.019,2.244 14.117,2.501C14.215,2.753 14.222,2.991 14.138,3.215C14.054,3.439 13.91,3.602 13.704,3.705C13.504,3.808 13.308,3.838 13.116,3.796C12.925,3.754 12.776,3.672 12.668,3.551C12.561,3.425 12.451,3.292 12.339,3.152C12.227,3.012 12.087,2.902 11.919,2.823C11.751,2.739 11.551,2.697 11.317,2.697C10.799,2.692 10.384,2.881 10.071,3.264C9.763,3.647 9.609,4.228 9.609,5.007L9.609,7.163C9.609,7.933 9.768,8.514 10.085,8.906C10.407,9.298 10.827,9.494 11.345,9.494C11.849,9.494 12.244,9.347 12.528,9.053C12.813,8.759 12.967,8.344 12.99,7.807L12.99,7.135L12.017,7.135C11.812,7.135 11.635,7.058 11.485,6.904C11.336,6.745 11.261,6.559 11.261,6.344C11.261,6.125 11.338,5.938 11.492,5.784C11.651,5.625 11.84,5.546 12.059,5.546L14.026,5.546C14.26,5.546 14.458,5.625 14.621,5.784C14.785,5.943 14.869,6.139 14.873,6.372L14.873,7.408C14.873,8.64 14.551,9.594 13.907,10.271C13.268,10.948 12.4,11.286 11.303,11.286ZM16.641,6.09C16.434,6.09 16.256,6.016 16.108,5.867C15.962,5.719 15.89,5.543 15.89,5.338L15.89,0.689C15.89,0.501 15.957,0.34 16.091,0.206C16.226,0.069 16.385,0 16.57,0C16.758,0 16.919,0.069 17.053,0.206C17.187,0.34 17.255,0.501 17.255,0.689L17.255,4.83L18.54,4.83C18.713,4.83 18.863,4.892 18.989,5.015C19.115,5.138 19.178,5.286 19.178,5.46C19.178,5.631 19.115,5.779 18.989,5.905C18.863,6.028 18.713,6.09 18.54,6.09L16.641,6.09ZM20.979,6.166C20.792,6.166 20.63,6.098 20.496,5.964C20.365,5.827 20.299,5.664 20.299,5.477L20.299,0.731L21.664,0.731L21.664,5.477C21.664,5.664 21.597,5.827 21.462,5.964C21.328,6.098 21.167,6.166 20.979,6.166ZM19.648,1.331C19.474,1.331 19.324,1.27 19.198,1.147C19.075,1.023 19.014,0.876 19.014,0.706C19.014,0.532 19.075,0.384 19.198,0.26C19.324,0.137 19.474,0.076 19.648,0.076L22.306,0.076C22.48,0.076 22.628,0.137 22.751,0.26C22.877,0.384 22.941,0.532 22.941,0.706C22.941,0.876 22.877,1.023 22.751,1.147C22.628,1.27 22.48,1.331 22.306,1.331L19.648,1.331ZM24.553,6.09C24.346,6.09 24.168,6.016 24.019,5.867C23.874,5.719 23.801,5.543 23.801,5.338L23.801,0.823C23.801,0.619 23.874,0.444 24.019,0.298C24.168,0.15 24.346,0.076 24.553,0.076L26.59,0.076C26.763,0.076 26.912,0.137 27.035,0.26C27.161,0.384 27.224,0.531 27.224,0.701C27.224,0.872 27.161,1.019 27.035,1.142C26.912,1.266 26.763,1.327 26.59,1.327L25.158,1.327L25.158,4.838L26.657,4.838C26.831,4.838 26.979,4.9 27.102,5.023C27.225,5.146 27.287,5.293 27.287,5.464C27.287,5.635 27.225,5.782 27.102,5.905C26.979,6.028 26.831,6.09 26.657,6.09L24.553,6.09ZM24.637,3.595L24.637,2.444L26.3,2.444C26.46,2.444 26.595,2.5 26.707,2.612C26.822,2.724 26.88,2.86 26.88,3.02C26.88,3.177 26.822,3.312 26.707,3.427C26.595,3.539 26.46,3.595 26.3,3.595L24.637,3.595Z"
+ android:fillColor="#000"/>
+ <path
+ android:pathData="M30.101,5.346C29.923,5.346 29.768,5.282 29.637,5.154C29.509,5.023 29.445,4.867 29.445,4.686L29.445,1.742C29.445,1.561 29.509,1.406 29.637,1.278C29.768,1.147 29.923,1.082 30.101,1.082C30.28,1.082 30.433,1.147 30.561,1.278C30.689,1.406 30.753,1.561 30.753,1.742L30.753,4.686C30.753,4.867 30.689,5.023 30.561,5.154C30.433,5.282 30.28,5.346 30.101,5.346ZM28.677,3.858C28.499,3.858 28.345,3.795 28.217,3.67C28.089,3.542 28.025,3.39 28.025,3.214C28.025,3.038 28.089,2.887 28.217,2.762C28.345,2.634 28.499,2.57 28.677,2.57L31.525,2.57C31.704,2.57 31.857,2.634 31.985,2.762C32.113,2.887 32.177,3.038 32.177,3.214C32.177,3.39 32.113,3.542 31.985,3.67C31.857,3.795 31.704,3.858 31.525,3.858L28.677,3.858Z"
+ android:fillColor="#000"/>
+</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_4g_mobiledata_updated.xml b/packages/SettingsLib/res/drawable/ic_4g_mobiledata_updated.xml
new file mode 100644
index 0000000..562bcaf
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_4g_mobiledata_updated.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright (C) 2025 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="19dp"
+ android:height="13.31dp"
+ android:viewportWidth="14.88"
+ android:viewportHeight="10.42">
+ <path
+ android:pathData="M4.552,10.325C4.286,10.325 4.058,10.229 3.866,10.038C3.68,9.847 3.586,9.618 3.586,9.352L3.586,7.301L3.74,7.021L3.74,1.953L4.72,2.66L3.712,2.66L1.808,6.496L4.37,6.496L4.797,6.405L5.777,6.405C6.015,6.405 6.218,6.489 6.386,6.657C6.554,6.825 6.638,7.028 6.638,7.266C6.638,7.499 6.554,7.7 6.386,7.868C6.218,8.036 6.015,8.12 5.777,8.12L1.192,8.12C0.856,8.12 0.572,8.01 0.338,7.791C0.11,7.572 -0.005,7.299 -0.005,6.972C-0.005,6.813 0.016,6.699 0.058,6.629C0.1,6.554 0.142,6.48 0.184,6.405L3.124,0.763C3.222,0.576 3.374,0.413 3.579,0.273C3.789,0.133 4.013,0.063 4.251,0.063C4.606,0.063 4.905,0.191 5.147,0.448C5.39,0.7 5.511,1.006 5.511,1.365L5.511,9.352C5.511,9.618 5.416,9.847 5.224,10.038C5.038,10.229 4.814,10.325 4.552,10.325ZM11.303,10.416C10.179,10.411 9.28,10.031 8.608,9.275C7.941,8.514 7.607,7.406 7.607,5.95L7.607,4.417C7.607,2.975 7.948,1.878 8.629,1.127C9.311,0.371 10.223,-0.005 11.366,0C11.88,0 12.314,0.075 12.668,0.224C13.028,0.369 13.333,0.576 13.585,0.847C13.842,1.113 14.019,1.374 14.117,1.631C14.215,1.883 14.222,2.121 14.138,2.345C14.054,2.569 13.91,2.732 13.704,2.835C13.504,2.938 13.308,2.968 13.116,2.926C12.925,2.884 12.776,2.802 12.668,2.681C12.561,2.555 12.451,2.422 12.339,2.282C12.227,2.142 12.087,2.032 11.919,1.953C11.751,1.869 11.551,1.827 11.317,1.827C10.799,1.822 10.384,2.011 10.071,2.394C9.763,2.777 9.609,3.358 9.609,4.137L9.609,6.293C9.609,7.063 9.768,7.644 10.085,8.036C10.407,8.428 10.827,8.624 11.345,8.624C11.849,8.624 12.244,8.477 12.528,8.183C12.813,7.889 12.967,7.474 12.99,6.937L12.99,6.265L12.017,6.265C11.812,6.265 11.635,6.188 11.485,6.034C11.336,5.875 11.261,5.689 11.261,5.474C11.261,5.255 11.338,5.068 11.492,4.914C11.651,4.755 11.84,4.676 12.059,4.676L14.026,4.676C14.26,4.676 14.458,4.755 14.621,4.914C14.785,5.073 14.869,5.269 14.873,5.502L14.873,6.538C14.873,7.77 14.551,8.724 13.907,9.401C13.268,10.078 12.4,10.416 11.303,10.416Z"
+ android:fillColor="#000"/>
+</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_4g_plus_mobiledata_updated.xml b/packages/SettingsLib/res/drawable/ic_4g_plus_mobiledata_updated.xml
new file mode 100644
index 0000000..73e8994
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_4g_plus_mobiledata_updated.xml
@@ -0,0 +1,27 @@
+<!--
+ Copyright (C) 2025 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="23dp"
+ android:height="12.5dp"
+ android:viewportWidth="19.17"
+ android:viewportHeight="10.42">
+ <path
+ android:pathData="M4.552,10.325C4.286,10.325 4.058,10.229 3.866,10.038C3.68,9.847 3.586,9.618 3.586,9.352L3.586,7.301L3.74,7.021L3.74,1.953L4.72,2.66L3.712,2.66L1.808,6.496L4.37,6.496L4.797,6.405L5.777,6.405C6.015,6.405 6.218,6.489 6.386,6.657C6.554,6.825 6.638,7.028 6.638,7.266C6.638,7.499 6.554,7.7 6.386,7.868C6.218,8.036 6.015,8.12 5.777,8.12L1.192,8.12C0.856,8.12 0.572,8.01 0.338,7.791C0.11,7.572 -0.005,7.299 -0.005,6.972C-0.005,6.813 0.016,6.699 0.058,6.629C0.1,6.554 0.142,6.48 0.184,6.405L3.124,0.763C3.222,0.576 3.374,0.413 3.579,0.273C3.789,0.133 4.013,0.063 4.251,0.063C4.606,0.063 4.905,0.191 5.147,0.448C5.39,0.7 5.511,1.006 5.511,1.365L5.511,9.352C5.511,9.618 5.416,9.847 5.224,10.038C5.038,10.229 4.814,10.325 4.552,10.325ZM11.303,10.416C10.179,10.411 9.28,10.031 8.608,9.275C7.941,8.514 7.607,7.406 7.607,5.95L7.607,4.417C7.607,2.975 7.948,1.878 8.629,1.127C9.311,0.371 10.223,-0.005 11.366,0C11.88,0 12.314,0.075 12.668,0.224C13.028,0.369 13.333,0.576 13.585,0.847C13.842,1.113 14.019,1.374 14.117,1.631C14.215,1.883 14.222,2.121 14.138,2.345C14.054,2.569 13.91,2.732 13.704,2.835C13.504,2.938 13.308,2.968 13.116,2.926C12.925,2.884 12.776,2.802 12.668,2.681C12.561,2.555 12.451,2.422 12.339,2.282C12.227,2.142 12.087,2.032 11.919,1.953C11.751,1.869 11.551,1.827 11.317,1.827C10.799,1.822 10.384,2.011 10.071,2.394C9.763,2.777 9.609,3.358 9.609,4.137L9.609,6.293C9.609,7.063 9.768,7.644 10.085,8.036C10.407,8.428 10.827,8.624 11.345,8.624C11.849,8.624 12.244,8.477 12.528,8.183C12.813,7.889 12.967,7.474 12.99,6.937L12.99,6.265L12.017,6.265C11.812,6.265 11.635,6.188 11.485,6.034C11.336,5.875 11.261,5.689 11.261,5.474C11.261,5.255 11.338,5.068 11.492,4.914C11.651,4.755 11.84,4.676 12.059,4.676L14.026,4.676C14.26,4.676 14.458,4.755 14.621,4.914C14.785,5.073 14.869,5.269 14.873,5.502L14.873,6.538C14.873,7.77 14.551,8.724 13.907,9.401C13.268,10.078 12.4,10.416 11.303,10.416Z"
+ android:fillColor="#000"/>
+ <path
+ android:pathData="M17.086,4.476C16.907,4.476 16.752,4.412 16.622,4.284C16.494,4.153 16.43,3.997 16.43,3.816L16.43,0.872C16.43,0.691 16.494,0.536 16.622,0.408C16.752,0.277 16.907,0.212 17.086,0.212C17.264,0.212 17.418,0.277 17.546,0.408C17.674,0.536 17.738,0.691 17.738,0.872L17.738,3.816C17.738,3.997 17.674,4.153 17.546,4.284C17.418,4.412 17.264,4.476 17.086,4.476ZM15.662,2.988C15.483,2.988 15.33,2.925 15.202,2.8C15.074,2.672 15.01,2.52 15.01,2.344C15.01,2.168 15.074,2.017 15.202,1.892C15.33,1.764 15.483,1.7 15.662,1.7L18.51,1.7C18.688,1.7 18.842,1.764 18.97,1.892C19.098,2.017 19.162,2.168 19.162,2.344C19.162,2.52 19.098,2.672 18.97,2.8C18.842,2.925 18.688,2.988 18.51,2.988L15.662,2.988Z"
+ android:fillColor="#000"/>
+</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_5g_e_mobiledata_updated.xml b/packages/SettingsLib/res/drawable/ic_5g_e_mobiledata_updated.xml
new file mode 100644
index 0000000..c46da66
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_5g_e_mobiledata_updated.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright (C) 2025 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="22.0dp"
+ android:height="12.57dp"
+ android:viewportHeight="11.21"
+ android:viewportWidth="19.62">
+
+ <path
+ android:fillColor="#000"
+ android:pathData="M2.573,11.206C1.99,11.206 1.502,11.094 1.11,10.87C0.718,10.641 0.436,10.364 0.263,10.037C0.091,9.706 0.002,9.4 -0.003,9.12C-0.007,8.84 0.058,8.616 0.193,8.448C0.333,8.275 0.499,8.168 0.69,8.126C0.882,8.079 1.057,8.089 1.215,8.154C1.379,8.219 1.502,8.315 1.586,8.441C1.675,8.567 1.75,8.716 1.81,8.889C1.871,9.062 1.971,9.202 2.111,9.309C2.251,9.412 2.429,9.463 2.643,9.463C2.947,9.463 3.203,9.363 3.413,9.162C3.623,8.961 3.763,8.663 3.833,8.266L4.008,7.272C4.074,6.899 4.029,6.609 3.875,6.404C3.726,6.199 3.5,6.096 3.196,6.096C3,6.096 2.825,6.143 2.671,6.236C2.522,6.325 2.401,6.43 2.307,6.551C2.181,6.672 2.03,6.752 1.852,6.789C1.675,6.826 1.488,6.81 1.292,6.74C1.045,6.651 0.865,6.497 0.753,6.278C0.641,6.054 0.62,5.804 0.69,5.529L1.593,1.98C1.677,1.672 1.831,1.429 2.055,1.252C2.284,1.075 2.557,0.986 2.874,0.986L5.674,0.986C5.964,0.986 6.195,1.089 6.367,1.294C6.54,1.495 6.601,1.733 6.549,2.008C6.517,2.213 6.412,2.388 6.234,2.533C6.062,2.673 5.875,2.743 5.674,2.743L3.056,2.743L2.433,5.13L2.475,5.137C2.676,4.955 2.905,4.815 3.161,4.717C3.418,4.614 3.7,4.563 4.008,4.563C4.727,4.563 5.268,4.836 5.632,5.382C6.001,5.923 6.111,6.628 5.961,7.496L5.814,8.336C5.656,9.274 5.299,9.988 4.743,10.478C4.188,10.963 3.465,11.206 2.573,11.206ZM10.577,11.206C9.392,11.206 8.515,10.795 7.945,9.974C7.381,9.153 7.229,8.009 7.49,6.544L7.749,5.039C8.006,3.606 8.498,2.54 9.226,1.84C9.959,1.14 10.883,0.79 11.998,0.79C12.535,0.79 12.995,0.879 13.377,1.056C13.76,1.229 14.059,1.46 14.273,1.749C14.488,2.038 14.612,2.314 14.644,2.575C14.677,2.832 14.644,3.053 14.546,3.24C14.453,3.427 14.313,3.567 14.126,3.66C13.94,3.749 13.753,3.774 13.566,3.737C13.384,3.695 13.244,3.606 13.146,3.471C13.048,3.336 12.941,3.2 12.824,3.065C12.708,2.925 12.57,2.815 12.411,2.736C12.257,2.657 12.068,2.617 11.844,2.617C11.35,2.617 10.918,2.808 10.549,3.191C10.185,3.569 9.936,4.141 9.8,4.906L9.422,7.048C9.287,7.813 9.348,8.399 9.604,8.805C9.861,9.211 10.248,9.414 10.766,9.414C11.256,9.414 11.665,9.267 11.991,8.973C12.318,8.679 12.54,8.264 12.656,7.727L12.775,7.055L11.893,7.055C11.665,7.055 11.48,6.964 11.34,6.782C11.205,6.6 11.158,6.385 11.2,6.138C11.233,5.951 11.326,5.795 11.48,5.669C11.639,5.538 11.809,5.473 11.991,5.473L13.979,5.473C14.25,5.473 14.462,5.566 14.616,5.753C14.775,5.94 14.831,6.168 14.784,6.439L14.595,7.489C14.376,8.702 13.916,9.626 13.216,10.261C12.521,10.891 11.641,11.206 10.577,11.206ZM16.001,6.01C15.799,6.01 15.637,5.937 15.514,5.792C15.39,5.643 15.346,5.47 15.379,5.271L16.181,0.735C16.218,0.53 16.321,0.357 16.492,0.214C16.666,0.068 16.856,-0.004 17.063,-0.004L18.983,-0.004C19.187,-0.004 19.351,0.068 19.474,0.214C19.597,0.36 19.642,0.529 19.609,0.722C19.581,0.868 19.505,0.992 19.382,1.096C19.259,1.197 19.126,1.247 18.983,1.247L17.462,1.247L16.841,4.758L18.21,4.758C18.414,4.758 18.577,4.831 18.697,4.977C18.82,5.122 18.865,5.292 18.832,5.485C18.806,5.631 18.732,5.755 18.609,5.859C18.486,5.96 18.353,6.01 18.21,6.01L16.001,6.01ZM16.526,3.515L16.732,2.364L18.281,2.364C18.472,2.364 18.623,2.432 18.735,2.566C18.847,2.698 18.888,2.853 18.857,3.032C18.832,3.167 18.762,3.281 18.647,3.377C18.535,3.469 18.413,3.515 18.281,3.515L16.526,3.515Z" />
+</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_5g_mobiledata_updated.xml b/packages/SettingsLib/res/drawable/ic_5g_mobiledata_updated.xml
new file mode 100644
index 0000000..66787b0
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_5g_mobiledata_updated.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright (C) 2025 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="17dp"
+ android:height="12.28dp"
+ android:viewportWidth="14.42"
+ android:viewportHeight="10.42">
+ <path
+ android:pathData="M2.807,10.416C2.247,10.416 1.774,10.325 1.386,10.143C0.999,9.956 0.684,9.704 0.441,9.387C0.199,9.065 0.056,8.745 0.014,8.428C-0.028,8.111 0.014,7.859 0.14,7.672C0.271,7.485 0.439,7.366 0.644,7.315C0.85,7.259 1.036,7.266 1.204,7.336C1.372,7.406 1.494,7.506 1.568,7.637C1.643,7.763 1.727,7.912 1.82,8.085C1.914,8.253 2.03,8.393 2.17,8.505C2.315,8.617 2.504,8.673 2.737,8.673C3.055,8.673 3.309,8.57 3.5,8.365C3.696,8.16 3.794,7.849 3.794,7.434L3.794,6.461C3.794,6.083 3.701,5.796 3.514,5.6C3.332,5.399 3.092,5.299 2.793,5.299C2.593,5.299 2.427,5.341 2.296,5.425C2.166,5.509 2.054,5.605 1.96,5.712C1.858,5.819 1.715,5.901 1.533,5.957C1.351,6.008 1.148,6.001 0.924,5.936C0.682,5.861 0.49,5.714 0.35,5.495C0.215,5.271 0.159,5.035 0.182,4.788L0.455,1.281C0.483,0.987 0.614,0.733 0.847,0.518C1.081,0.303 1.347,0.196 1.645,0.196L4.515,0.196C4.758,0.196 4.966,0.282 5.138,0.455C5.316,0.628 5.404,0.833 5.404,1.071C5.404,1.314 5.316,1.521 5.138,1.694C4.966,1.867 4.758,1.953 4.515,1.953L2.044,1.953L1.841,4.34L1.897,4.354C2.07,4.172 2.285,4.03 2.541,3.927C2.803,3.824 3.094,3.773 3.416,3.773C4.126,3.773 4.697,4.02 5.131,4.515C5.565,5.005 5.782,5.677 5.782,6.531L5.782,7.378C5.782,8.33 5.516,9.074 4.984,9.611C4.452,10.148 3.727,10.416 2.807,10.416ZM10.853,10.416C9.729,10.411 8.83,10.031 8.158,9.275C7.491,8.514 7.157,7.406 7.157,5.95L7.157,4.417C7.157,2.975 7.498,1.878 8.179,1.127C8.861,0.371 9.773,-0.005 10.916,0C11.43,0 11.864,0.075 12.218,0.224C12.578,0.369 12.883,0.576 13.135,0.847C13.392,1.113 13.569,1.374 13.667,1.631C13.765,1.883 13.772,2.121 13.688,2.345C13.604,2.569 13.46,2.732 13.254,2.835C13.054,2.938 12.858,2.968 12.666,2.926C12.475,2.884 12.326,2.802 12.218,2.681C12.111,2.555 12.001,2.422 11.889,2.282C11.777,2.142 11.637,2.032 11.469,1.953C11.301,1.869 11.101,1.827 10.867,1.827C10.349,1.822 9.934,2.011 9.621,2.394C9.313,2.777 9.159,3.358 9.159,4.137L9.159,6.293C9.159,7.063 9.318,7.644 9.635,8.036C9.957,8.428 10.377,8.624 10.895,8.624C11.399,8.624 11.794,8.477 12.078,8.183C12.363,7.889 12.517,7.474 12.54,6.937L12.54,6.265L11.567,6.265C11.362,6.265 11.185,6.188 11.035,6.034C10.886,5.875 10.811,5.689 10.811,5.474C10.811,5.255 10.888,5.068 11.042,4.914C11.201,4.755 11.39,4.676 11.609,4.676L13.576,4.676C13.81,4.676 14.008,4.755 14.171,4.914C14.335,5.073 14.419,5.269 14.423,5.502L14.423,6.538C14.423,7.77 14.101,8.724 13.457,9.401C12.818,10.078 11.95,10.416 10.853,10.416Z"
+ android:fillColor="#000"/>
+</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_5g_plus_mobiledata_default_updated.xml b/packages/SettingsLib/res/drawable/ic_5g_plus_mobiledata_default_updated.xml
new file mode 100644
index 0000000..5ba3c98
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_5g_plus_mobiledata_default_updated.xml
@@ -0,0 +1,27 @@
+<!--
+ Copyright (C) 2025 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="22dp"
+ android:height="11.63dp"
+ android:viewportWidth="19.71"
+ android:viewportHeight="10.42">
+ <path
+ android:pathData="M2.807,10.416C2.247,10.416 1.774,10.325 1.386,10.143C0.999,9.956 0.684,9.704 0.441,9.387C0.199,9.065 0.056,8.745 0.014,8.428C-0.028,8.111 0.014,7.859 0.14,7.672C0.271,7.485 0.439,7.366 0.644,7.315C0.85,7.259 1.036,7.266 1.204,7.336C1.372,7.406 1.494,7.506 1.568,7.637C1.643,7.763 1.727,7.912 1.82,8.085C1.914,8.253 2.03,8.393 2.17,8.505C2.315,8.617 2.504,8.673 2.737,8.673C3.055,8.673 3.309,8.57 3.5,8.365C3.696,8.16 3.794,7.849 3.794,7.434L3.794,6.461C3.794,6.083 3.701,5.796 3.514,5.6C3.332,5.399 3.092,5.299 2.793,5.299C2.593,5.299 2.427,5.341 2.296,5.425C2.166,5.509 2.054,5.605 1.96,5.712C1.858,5.819 1.715,5.901 1.533,5.957C1.351,6.008 1.148,6.001 0.924,5.936C0.682,5.861 0.49,5.714 0.35,5.495C0.215,5.271 0.159,5.035 0.182,4.788L0.455,1.281C0.483,0.987 0.614,0.733 0.847,0.518C1.081,0.303 1.347,0.196 1.645,0.196L4.515,0.196C4.758,0.196 4.966,0.282 5.138,0.455C5.316,0.628 5.404,0.833 5.404,1.071C5.404,1.314 5.316,1.521 5.138,1.694C4.966,1.867 4.758,1.953 4.515,1.953L2.044,1.953L1.841,4.34L1.897,4.354C2.07,4.172 2.285,4.03 2.541,3.927C2.803,3.824 3.094,3.773 3.416,3.773C4.126,3.773 4.697,4.02 5.131,4.515C5.565,5.005 5.782,5.677 5.782,6.531L5.782,7.378C5.782,8.33 5.516,9.074 4.984,9.611C4.452,10.148 3.727,10.416 2.807,10.416ZM10.853,10.416C9.729,10.411 8.83,10.031 8.158,9.275C7.491,8.514 7.157,7.406 7.157,5.95L7.157,4.417C7.157,2.975 7.498,1.878 8.179,1.127C8.861,0.371 9.773,-0.005 10.916,0C11.43,0 11.864,0.075 12.218,0.224C12.578,0.369 12.883,0.576 13.135,0.847C13.392,1.113 13.569,1.374 13.667,1.631C13.765,1.883 13.772,2.121 13.688,2.345C13.604,2.569 13.46,2.732 13.254,2.835C13.054,2.938 12.858,2.968 12.666,2.926C12.475,2.884 12.326,2.802 12.218,2.681C12.111,2.555 12.001,2.422 11.889,2.282C11.777,2.142 11.637,2.032 11.469,1.953C11.301,1.869 11.101,1.827 10.867,1.827C10.349,1.822 9.934,2.011 9.621,2.394C9.313,2.777 9.159,3.358 9.159,4.137L9.159,6.293C9.159,7.063 9.318,7.644 9.635,8.036C9.957,8.428 10.377,8.624 10.895,8.624C11.399,8.624 11.794,8.477 12.078,8.183C12.363,7.889 12.517,7.474 12.54,6.937L12.54,6.265L11.567,6.265C11.362,6.265 11.185,6.188 11.035,6.034C10.886,5.875 10.811,5.689 10.811,5.474C10.811,5.255 10.888,5.068 11.042,4.914C11.201,4.755 11.39,4.676 11.609,4.676L13.576,4.676C13.81,4.676 14.008,4.755 14.171,4.914C14.335,5.073 14.419,5.269 14.423,5.502L14.423,6.538C14.423,7.77 14.101,8.724 13.457,9.401C12.818,10.078 11.95,10.416 10.853,10.416Z"
+ android:fillColor="#000"/>
+ <path
+ android:pathData="M17.636,4.476C17.457,4.476 17.302,4.412 17.172,4.284C17.044,4.153 16.98,3.997 16.98,3.816L16.98,0.872C16.98,0.691 17.044,0.536 17.172,0.408C17.302,0.277 17.457,0.212 17.636,0.212C17.814,0.212 17.968,0.277 18.096,0.408C18.224,0.536 18.288,0.691 18.288,0.872L18.288,3.816C18.288,3.997 18.224,4.153 18.096,4.284C17.968,4.412 17.814,4.476 17.636,4.476ZM16.212,2.988C16.033,2.988 15.88,2.925 15.752,2.8C15.624,2.672 15.56,2.52 15.56,2.344C15.56,2.168 15.624,2.017 15.752,1.892C15.88,1.764 16.033,1.7 16.212,1.7L19.06,1.7C19.238,1.7 19.392,1.764 19.52,1.892C19.648,2.017 19.712,2.168 19.712,2.344C19.712,2.52 19.648,2.672 19.52,2.8C19.392,2.925 19.238,2.988 19.06,2.988L16.212,2.988Z"
+ android:fillColor="#000"/>
+</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_5g_plus_mobiledata_updated.xml b/packages/SettingsLib/res/drawable/ic_5g_plus_mobiledata_updated.xml
new file mode 100644
index 0000000..5ba3c98
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_5g_plus_mobiledata_updated.xml
@@ -0,0 +1,27 @@
+<!--
+ Copyright (C) 2025 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="22dp"
+ android:height="11.63dp"
+ android:viewportWidth="19.71"
+ android:viewportHeight="10.42">
+ <path
+ android:pathData="M2.807,10.416C2.247,10.416 1.774,10.325 1.386,10.143C0.999,9.956 0.684,9.704 0.441,9.387C0.199,9.065 0.056,8.745 0.014,8.428C-0.028,8.111 0.014,7.859 0.14,7.672C0.271,7.485 0.439,7.366 0.644,7.315C0.85,7.259 1.036,7.266 1.204,7.336C1.372,7.406 1.494,7.506 1.568,7.637C1.643,7.763 1.727,7.912 1.82,8.085C1.914,8.253 2.03,8.393 2.17,8.505C2.315,8.617 2.504,8.673 2.737,8.673C3.055,8.673 3.309,8.57 3.5,8.365C3.696,8.16 3.794,7.849 3.794,7.434L3.794,6.461C3.794,6.083 3.701,5.796 3.514,5.6C3.332,5.399 3.092,5.299 2.793,5.299C2.593,5.299 2.427,5.341 2.296,5.425C2.166,5.509 2.054,5.605 1.96,5.712C1.858,5.819 1.715,5.901 1.533,5.957C1.351,6.008 1.148,6.001 0.924,5.936C0.682,5.861 0.49,5.714 0.35,5.495C0.215,5.271 0.159,5.035 0.182,4.788L0.455,1.281C0.483,0.987 0.614,0.733 0.847,0.518C1.081,0.303 1.347,0.196 1.645,0.196L4.515,0.196C4.758,0.196 4.966,0.282 5.138,0.455C5.316,0.628 5.404,0.833 5.404,1.071C5.404,1.314 5.316,1.521 5.138,1.694C4.966,1.867 4.758,1.953 4.515,1.953L2.044,1.953L1.841,4.34L1.897,4.354C2.07,4.172 2.285,4.03 2.541,3.927C2.803,3.824 3.094,3.773 3.416,3.773C4.126,3.773 4.697,4.02 5.131,4.515C5.565,5.005 5.782,5.677 5.782,6.531L5.782,7.378C5.782,8.33 5.516,9.074 4.984,9.611C4.452,10.148 3.727,10.416 2.807,10.416ZM10.853,10.416C9.729,10.411 8.83,10.031 8.158,9.275C7.491,8.514 7.157,7.406 7.157,5.95L7.157,4.417C7.157,2.975 7.498,1.878 8.179,1.127C8.861,0.371 9.773,-0.005 10.916,0C11.43,0 11.864,0.075 12.218,0.224C12.578,0.369 12.883,0.576 13.135,0.847C13.392,1.113 13.569,1.374 13.667,1.631C13.765,1.883 13.772,2.121 13.688,2.345C13.604,2.569 13.46,2.732 13.254,2.835C13.054,2.938 12.858,2.968 12.666,2.926C12.475,2.884 12.326,2.802 12.218,2.681C12.111,2.555 12.001,2.422 11.889,2.282C11.777,2.142 11.637,2.032 11.469,1.953C11.301,1.869 11.101,1.827 10.867,1.827C10.349,1.822 9.934,2.011 9.621,2.394C9.313,2.777 9.159,3.358 9.159,4.137L9.159,6.293C9.159,7.063 9.318,7.644 9.635,8.036C9.957,8.428 10.377,8.624 10.895,8.624C11.399,8.624 11.794,8.477 12.078,8.183C12.363,7.889 12.517,7.474 12.54,6.937L12.54,6.265L11.567,6.265C11.362,6.265 11.185,6.188 11.035,6.034C10.886,5.875 10.811,5.689 10.811,5.474C10.811,5.255 10.888,5.068 11.042,4.914C11.201,4.755 11.39,4.676 11.609,4.676L13.576,4.676C13.81,4.676 14.008,4.755 14.171,4.914C14.335,5.073 14.419,5.269 14.423,5.502L14.423,6.538C14.423,7.77 14.101,8.724 13.457,9.401C12.818,10.078 11.95,10.416 10.853,10.416Z"
+ android:fillColor="#000"/>
+ <path
+ android:pathData="M17.636,4.476C17.457,4.476 17.302,4.412 17.172,4.284C17.044,4.153 16.98,3.997 16.98,3.816L16.98,0.872C16.98,0.691 17.044,0.536 17.172,0.408C17.302,0.277 17.457,0.212 17.636,0.212C17.814,0.212 17.968,0.277 18.096,0.408C18.224,0.536 18.288,0.691 18.288,0.872L18.288,3.816C18.288,3.997 18.224,4.153 18.096,4.284C17.968,4.412 17.814,4.476 17.636,4.476ZM16.212,2.988C16.033,2.988 15.88,2.925 15.752,2.8C15.624,2.672 15.56,2.52 15.56,2.344C15.56,2.168 15.624,2.017 15.752,1.892C15.88,1.764 16.033,1.7 16.212,1.7L19.06,1.7C19.238,1.7 19.392,1.764 19.52,1.892C19.648,2.017 19.712,2.168 19.712,2.344C19.712,2.52 19.648,2.672 19.52,2.8C19.392,2.925 19.238,2.988 19.06,2.988L16.212,2.988Z"
+ android:fillColor="#000"/>
+</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_carrier_wifi_updated.xml b/packages/SettingsLib/res/drawable/ic_carrier_wifi_updated.xml
new file mode 100644
index 0000000..14db826
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_carrier_wifi_updated.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2025 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="19.0dp"
+ android:height="12.38dp"
+ android:viewportHeight="10.26"
+ android:viewportWidth="15.75">
+
+ <path
+ android:fillColor="#000"
+ android:pathData="M2.864,10.259C2.598,10.259 2.358,10.168 2.143,9.986C1.929,9.804 1.793,9.589 1.737,9.342L0.036,1.208C-0.043,0.877 0.013,0.594 0.204,0.361C0.4,0.128 0.657,0.011 0.974,0.011C1.208,0.011 1.418,0.093 1.604,0.256C1.791,0.419 1.908,0.611 1.954,0.83L2.885,5.828L3.039,6.92L3.088,6.92L3.249,5.828L4.278,0.851C4.325,0.622 4.446,0.424 4.642,0.256C4.843,0.088 5.065,0.004 5.307,0.004C5.55,0.004 5.769,0.088 5.965,0.256C6.166,0.424 6.292,0.625 6.343,0.858L7.358,5.814L7.526,6.913L7.575,6.913L7.729,5.814L8.653,0.781C8.695,0.571 8.805,0.391 8.982,0.242C9.16,0.093 9.356,0.018 9.57,0.018C9.874,0.018 10.114,0.128 10.291,0.347C10.473,0.566 10.529,0.828 10.459,1.131L8.765,9.342C8.709,9.594 8.574,9.811 8.359,9.993C8.145,10.17 7.902,10.259 7.631,10.259C7.37,10.259 7.132,10.17 6.917,9.993C6.703,9.811 6.57,9.594 6.518,9.342L5.44,4.19L5.279,3.133L5.23,3.133L5.069,4.183L3.977,9.342C3.926,9.589 3.793,9.804 3.578,9.986C3.364,10.168 3.126,10.259 2.864,10.259Z" />
+
+ <path
+ android:fillColor="#000"
+ android:pathData="M13.676,4.396C13.497,4.396 13.342,4.332 13.212,4.204C13.084,4.073 13.02,3.917 13.02,3.736L13.02,0.792C13.02,0.611 13.084,0.456 13.212,0.328C13.342,0.197 13.497,0.132 13.676,0.132C13.854,0.132 14.008,0.197 14.136,0.328C14.264,0.456 14.328,0.611 14.328,0.792L14.328,3.736C14.328,3.917 14.264,4.073 14.136,4.204C14.008,4.332 13.854,4.396 13.676,4.396ZM12.252,2.908C12.073,2.908 11.92,2.845 11.792,2.72C11.664,2.592 11.6,2.44 11.6,2.264C11.6,2.088 11.664,1.937 11.792,1.812C11.92,1.684 12.073,1.62 12.252,1.62L15.1,1.62C15.278,1.62 15.432,1.684 15.56,1.812C15.688,1.937 15.752,2.088 15.752,2.264C15.752,2.44 15.688,2.592 15.56,2.72C15.432,2.845 15.278,2.908 15.1,2.908L12.252,2.908Z" />
+
+</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_e_mobiledata_updated.xml b/packages/SettingsLib/res/drawable/ic_e_mobiledata_updated.xml
new file mode 100644
index 0000000..febcd87
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_e_mobiledata_updated.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright (C) 2025 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="17dp"
+ android:height="31.08dp"
+ android:viewportWidth="5.48"
+ android:viewportHeight="10.02">
+ <path
+ android:pathData="M1.081,10.02C0.787,10.02 0.533,9.913 0.318,9.698C0.104,9.483 -0.004,9.229 -0.004,8.935L-0.004,1.081C-0.004,0.787 0.104,0.533 0.318,0.318C0.533,0.103 0.787,-0.004 1.081,-0.004L4.455,-0.004C4.707,-0.004 4.922,0.087 5.099,0.269C5.281,0.446 5.372,0.659 5.372,0.906C5.372,1.153 5.281,1.368 5.099,1.55C4.922,1.727 4.707,1.816 4.455,1.816L1.963,1.816L1.963,8.2L4.56,8.2C4.812,8.2 5.027,8.291 5.204,8.473C5.386,8.65 5.477,8.863 5.477,9.11C5.477,9.357 5.386,9.572 5.204,9.754C5.027,9.931 4.812,10.02 4.56,10.02L1.081,10.02ZM1.186,5.736L1.186,4.042L3.951,4.042C4.185,4.042 4.385,4.126 4.553,4.294C4.721,4.457 4.805,4.656 4.805,4.889C4.805,5.118 4.721,5.316 4.553,5.484C4.385,5.652 4.185,5.736 3.951,5.736L1.186,5.736Z"
+ android:fillColor="#000"/>
+</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_g_mobiledata_updated.xml b/packages/SettingsLib/res/drawable/ic_g_mobiledata_updated.xml
new file mode 100644
index 0000000..d719f7a
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_g_mobiledata_updated.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright (C) 2025 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="17dp"
+ android:height="24.37dp"
+ android:viewportWidth="7.27"
+ android:viewportHeight="10.42">
+ <path
+ android:pathData="M3.696,10.416C2.571,10.411 1.673,10.031 1.001,9.275C0.333,8.514 -0,7.406 -0,5.95L-0,4.417C-0,2.975 0.34,1.878 1.022,1.127C1.703,0.371 2.615,-0.005 3.759,0C4.272,0 4.706,0.075 5.061,0.224C5.42,0.369 5.726,0.576 5.978,0.847C6.235,1.113 6.412,1.374 6.51,1.631C6.608,1.883 6.615,2.121 6.531,2.345C6.447,2.569 6.302,2.732 6.097,2.835C5.896,2.938 5.7,2.968 5.509,2.926C5.317,2.884 5.168,2.802 5.061,2.681C4.953,2.555 4.844,2.422 4.732,2.282C4.62,2.142 4.48,2.032 4.312,1.953C4.144,1.869 3.943,1.827 3.71,1.827C3.192,1.822 2.776,2.011 2.464,2.394C2.156,2.777 2.002,3.358 2.002,4.137L2.002,6.293C2.002,7.063 2.16,7.644 2.478,8.036C2.8,8.428 3.22,8.624 3.738,8.624C4.242,8.624 4.636,8.477 4.921,8.183C5.205,7.889 5.359,7.474 5.383,6.937L5.383,6.265L4.41,6.265C4.204,6.265 4.027,6.188 3.878,6.034C3.728,5.875 3.654,5.689 3.654,5.474C3.654,5.255 3.731,5.068 3.885,4.914C4.043,4.755 4.232,4.676 4.452,4.676L6.419,4.676C6.652,4.676 6.85,4.755 7.014,4.914C7.177,5.073 7.261,5.269 7.266,5.502L7.266,6.538C7.266,7.77 6.944,8.724 6.3,9.401C5.661,10.078 4.792,10.416 3.696,10.416Z"
+ android:fillColor="#000"/>
+</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_h_mobiledata_updated.xml b/packages/SettingsLib/res/drawable/ic_h_mobiledata_updated.xml
new file mode 100644
index 0000000..e60ff8cd
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_h_mobiledata_updated.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright (C) 2025 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="17dp"
+ android:height="26.68dp"
+ android:viewportWidth="6.53"
+ android:viewportHeight="10.25">
+ <path
+ android:pathData="M5.547,10.252C5.277,10.252 5.043,10.154 4.847,9.958C4.656,9.757 4.56,9.522 4.56,9.251L4.56,1.005C4.56,0.73 4.656,0.494 4.847,0.298C5.043,0.102 5.277,0.004 5.547,0.004C5.818,0.004 6.049,0.102 6.24,0.298C6.436,0.494 6.534,0.73 6.534,1.005L6.534,9.251C6.534,9.522 6.436,9.757 6.24,9.958C6.049,10.154 5.818,10.252 5.547,10.252ZM0.99,10.252C0.72,10.252 0.486,10.154 0.29,9.958C0.099,9.757 0.003,9.522 0.003,9.251L0.003,1.005C0.003,0.73 0.099,0.494 0.29,0.298C0.486,0.102 0.72,0.004 0.99,0.004C1.261,0.004 1.492,0.102 1.683,0.298C1.879,0.494 1.977,0.73 1.977,1.005L1.977,9.251C1.977,9.522 1.879,9.757 1.683,9.958C1.492,10.154 1.261,10.252 0.99,10.252ZM1.151,5.933L1.151,4.106L5.484,4.106L5.484,5.933L1.151,5.933Z"
+ android:fillColor="#000"/>
+</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_h_plus_mobiledata_updated.xml b/packages/SettingsLib/res/drawable/ic_h_plus_mobiledata_updated.xml
new file mode 100644
index 0000000..e02df56
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_h_plus_mobiledata_updated.xml
@@ -0,0 +1,27 @@
+<!--
+ Copyright (C) 2025 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="16dp"
+ android:height="13.52dp"
+ android:viewportWidth="12.13"
+ android:viewportHeight="10.25">
+ <path
+ android:pathData="M5.541,10.252C5.271,10.252 5.037,10.154 4.841,9.958C4.65,9.757 4.554,9.522 4.554,9.251L4.554,1.005C4.554,0.73 4.65,0.494 4.841,0.298C5.037,0.102 5.271,0.004 5.541,0.004C5.812,0.004 6.043,0.102 6.234,0.298C6.43,0.494 6.528,0.73 6.528,1.005L6.528,9.251C6.528,9.522 6.43,9.757 6.234,9.958C6.043,10.154 5.812,10.252 5.541,10.252ZM0.984,10.252C0.714,10.252 0.48,10.154 0.284,9.958C0.093,9.757 -0.003,9.522 -0.003,9.251L-0.003,1.005C-0.003,0.73 0.093,0.494 0.284,0.298C0.48,0.102 0.714,0.004 0.984,0.004C1.255,0.004 1.486,0.102 1.677,0.298C1.873,0.494 1.971,0.73 1.971,1.005L1.971,9.251C1.971,9.522 1.873,9.757 1.677,9.958C1.486,10.154 1.255,10.252 0.984,10.252ZM1.145,5.933L1.145,4.106L5.478,4.106L5.478,5.933L1.145,5.933Z"
+ android:fillColor="#000"/>
+ <path
+ android:pathData="M10.056,4.396C9.877,4.396 9.722,4.332 9.592,4.204C9.464,4.073 9.4,3.917 9.4,3.736L9.4,0.792C9.4,0.611 9.464,0.456 9.592,0.328C9.722,0.197 9.877,0.132 10.056,0.132C10.234,0.132 10.388,0.197 10.516,0.328C10.644,0.456 10.708,0.611 10.708,0.792L10.708,3.736C10.708,3.917 10.644,4.073 10.516,4.204C10.388,4.332 10.234,4.396 10.056,4.396ZM8.632,2.908C8.453,2.908 8.3,2.845 8.172,2.72C8.044,2.592 7.98,2.44 7.98,2.264C7.98,2.088 8.044,1.937 8.172,1.812C8.3,1.684 8.453,1.62 8.632,1.62L11.48,1.62C11.658,1.62 11.812,1.684 11.94,1.812C12.068,1.937 12.132,2.088 12.132,2.264C12.132,2.44 12.068,2.592 11.94,2.72C11.812,2.845 11.658,2.908 11.48,2.908L8.632,2.908Z"
+ android:fillColor="#000"/>
+</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_lte_mobiledata_updated.xml b/packages/SettingsLib/res/drawable/ic_lte_mobiledata_updated.xml
new file mode 100644
index 0000000..9d64439
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_lte_mobiledata_updated.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright (C) 2025 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="20dp"
+ android:height="11.92dp"
+ android:viewportWidth="17.2"
+ android:viewportHeight="10.25">
+ <path
+ android:pathData="M1.082,10.14C0.788,10.14 0.534,10.033 0.319,9.818C0.105,9.603 -0.003,9.349 -0.003,9.055L-0.003,1.005C-0.003,0.73 0.093,0.494 0.284,0.298C0.48,0.102 0.714,0.004 0.984,0.004C1.255,0.004 1.486,0.102 1.677,0.298C1.873,0.494 1.971,0.73 1.971,1.005L1.971,8.313L4.19,8.313C4.442,8.313 4.659,8.404 4.841,8.586C5.023,8.763 5.114,8.976 5.114,9.223C5.114,9.475 5.023,9.692 4.841,9.874C4.659,10.051 4.442,10.14 4.19,10.14L1.082,10.14ZM7.59,10.252C7.32,10.252 7.086,10.154 6.89,9.958C6.694,9.757 6.596,9.522 6.596,9.251L6.596,1.068L8.577,1.068L8.577,9.251C8.577,9.522 8.479,9.757 8.283,9.958C8.087,10.154 7.856,10.252 7.59,10.252ZM5.413,1.936C5.161,1.936 4.944,1.847 4.762,1.67C4.585,1.488 4.496,1.273 4.496,1.026C4.496,0.779 4.585,0.566 4.762,0.389C4.944,0.207 5.161,0.116 5.413,0.116L9.753,0.116C10.005,0.116 10.222,0.207 10.404,0.389C10.586,0.566 10.677,0.779 10.677,1.026C10.677,1.273 10.586,1.488 10.404,1.67C10.222,1.847 10.005,1.936 9.753,1.936L5.413,1.936ZM12.799,10.14C12.505,10.14 12.251,10.033 12.036,9.818C11.821,9.603 11.714,9.349 11.714,9.055L11.714,1.201C11.714,0.907 11.821,0.653 12.036,0.438C12.251,0.223 12.505,0.116 12.799,0.116L16.173,0.116C16.425,0.116 16.64,0.207 16.817,0.389C16.999,0.566 17.09,0.779 17.09,1.026C17.09,1.273 16.999,1.488 16.817,1.67C16.64,1.847 16.425,1.936 16.173,1.936L13.681,1.936L13.681,8.32L16.278,8.32C16.53,8.32 16.745,8.411 16.922,8.593C17.104,8.77 17.195,8.983 17.195,9.23C17.195,9.477 17.104,9.692 16.922,9.874C16.745,10.051 16.53,10.14 16.278,10.14L12.799,10.14ZM12.904,5.856L12.904,4.162L15.669,4.162C15.902,4.162 16.103,4.246 16.271,4.414C16.439,4.577 16.523,4.776 16.523,5.009C16.523,5.238 16.439,5.436 16.271,5.604C16.103,5.772 15.902,5.856 15.669,5.856L12.904,5.856Z"
+ android:fillColor="#000"/>
+</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_lte_plus_mobiledata_updated.xml b/packages/SettingsLib/res/drawable/ic_lte_plus_mobiledata_updated.xml
new file mode 100644
index 0000000..7075516
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_lte_plus_mobiledata_updated.xml
@@ -0,0 +1,27 @@
+<!--
+ Copyright (C) 2025 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="25dp"
+ android:height="11.85dp"
+ android:viewportWidth="21.63"
+ android:viewportHeight="10.25">
+ <path
+ android:pathData="M1.082,10.14C0.788,10.14 0.534,10.033 0.319,9.818C0.105,9.603 -0.003,9.349 -0.003,9.055L-0.003,1.005C-0.003,0.73 0.093,0.494 0.284,0.298C0.48,0.102 0.714,0.004 0.984,0.004C1.255,0.004 1.486,0.102 1.677,0.298C1.873,0.494 1.971,0.73 1.971,1.005L1.971,8.313L4.19,8.313C4.442,8.313 4.659,8.404 4.841,8.586C5.023,8.763 5.114,8.976 5.114,9.223C5.114,9.475 5.023,9.692 4.841,9.874C4.659,10.051 4.442,10.14 4.19,10.14L1.082,10.14ZM7.59,10.252C7.32,10.252 7.086,10.154 6.89,9.958C6.694,9.757 6.596,9.522 6.596,9.251L6.596,1.068L8.577,1.068L8.577,9.251C8.577,9.522 8.479,9.757 8.283,9.958C8.087,10.154 7.856,10.252 7.59,10.252ZM5.413,1.936C5.161,1.936 4.944,1.847 4.762,1.67C4.585,1.488 4.496,1.273 4.496,1.026C4.496,0.779 4.585,0.566 4.762,0.389C4.944,0.207 5.161,0.116 5.413,0.116L9.753,0.116C10.005,0.116 10.222,0.207 10.404,0.389C10.586,0.566 10.677,0.779 10.677,1.026C10.677,1.273 10.586,1.488 10.404,1.67C10.222,1.847 10.005,1.936 9.753,1.936L5.413,1.936ZM12.799,10.14C12.505,10.14 12.251,10.033 12.036,9.818C11.821,9.603 11.714,9.349 11.714,9.055L11.714,1.201C11.714,0.907 11.821,0.653 12.036,0.438C12.251,0.223 12.505,0.116 12.799,0.116L16.173,0.116C16.425,0.116 16.64,0.207 16.817,0.389C16.999,0.566 17.09,0.779 17.09,1.026C17.09,1.273 16.999,1.488 16.817,1.67C16.64,1.847 16.425,1.936 16.173,1.936L13.681,1.936L13.681,8.32L16.278,8.32C16.53,8.32 16.745,8.411 16.922,8.593C17.104,8.77 17.195,8.983 17.195,9.23C17.195,9.477 17.104,9.692 16.922,9.874C16.745,10.051 16.53,10.14 16.278,10.14L12.799,10.14ZM12.904,5.856L12.904,4.162L15.669,4.162C15.902,4.162 16.103,4.246 16.271,4.414C16.439,4.577 16.523,4.776 16.523,5.009C16.523,5.238 16.439,5.436 16.271,5.604C16.103,5.772 15.902,5.856 15.669,5.856L12.904,5.856Z"
+ android:fillColor="#000"/>
+ <path
+ android:pathData="M19.556,4.396C19.377,4.396 19.222,4.332 19.092,4.204C18.964,4.073 18.9,3.917 18.9,3.736L18.9,0.792C18.9,0.611 18.964,0.456 19.092,0.328C19.222,0.197 19.377,0.132 19.556,0.132C19.734,0.132 19.888,0.197 20.016,0.328C20.144,0.456 20.208,0.611 20.208,0.792L20.208,3.736C20.208,3.917 20.144,4.073 20.016,4.204C19.888,4.332 19.734,4.396 19.556,4.396ZM18.132,2.908C17.953,2.908 17.8,2.845 17.672,2.72C17.544,2.592 17.48,2.44 17.48,2.264C17.48,2.088 17.544,1.937 17.672,1.812C17.8,1.684 17.953,1.62 18.132,1.62L20.98,1.62C21.158,1.62 21.312,1.684 21.44,1.812C21.568,1.937 21.632,2.088 21.632,2.264C21.632,2.44 21.568,2.592 21.44,2.72C21.312,2.845 21.158,2.908 20.98,2.908L18.132,2.908Z"
+ android:fillColor="#000"/>
+</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_wifi_0.xml b/packages/SettingsLib/res/drawable/ic_wifi_0.xml
index 8ff6554..7f98457 100644
--- a/packages/SettingsLib/res/drawable/ic_wifi_0.xml
+++ b/packages/SettingsLib/res/drawable/ic_wifi_0.xml
@@ -1,5 +1,5 @@
<!--
- Copyright (C) 2023 The Android Open Source Project
+ Copyright (C) 2025 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -14,24 +14,24 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="18dp"
- android:height="13dp"
- android:viewportWidth="18.0"
- android:viewportHeight="13.0">
+ android:width="17.0dp"
+ android:height="12.58dp"
+ android:viewportHeight="12.0"
+ android:viewportWidth="16.21">
+
<path
- android:pathData="M0.523,3.314C0.32,3.502 0.32,3.819 0.516,4.015L1.223,4.722C1.418,4.917 1.734,4.916 1.938,4.73C5.936,1.09 12.066,1.09 16.064,4.73C16.268,4.916 16.584,4.917 16.779,4.722L17.486,4.015C17.682,3.819 17.682,3.502 17.479,3.314C12.698,-1.105 5.304,-1.105 0.523,3.314Z"
- android:fillAlpha="0.24"
- android:fillColor="#000"/>
+ android:fillAlpha="0.45"
+ android:fillColor="#000"
+ android:pathData="M12.659,7.45C13.199,6.91 13.149,6.01 12.479,5.64C11.179,4.92 9.689,4.51 8.109,4.51C6.529,4.51 5.029,4.92 3.739,5.64C3.069,6.01 3.019,6.91 3.559,7.45C3.999,7.89 4.699,7.94 5.259,7.66C6.119,7.24 7.089,7 8.109,7C9.129,7 10.099,7.24 10.959,7.66C11.519,7.94 12.219,7.89 12.659,7.45Z" />
+
<path
- android:pathData="M15.011,6.49C15.207,6.294 15.207,5.976 15.002,5.792C11.592,2.736 6.411,2.736 3,5.792C2.795,5.976 2.795,6.294 2.991,6.49L3.698,7.197C3.893,7.392 4.209,7.39 4.417,7.209C7.042,4.93 10.96,4.93 13.585,7.209C13.793,7.39 14.109,7.392 14.304,7.197L15.011,6.49Z"
- android:fillAlpha="0.24"
- android:fillColor="#000"/>
+ android:fillAlpha="0.45"
+ android:fillColor="#000"
+ android:pathData="M15.85,4.26C16.36,3.75 16.34,2.91 15.76,2.49C13.61,0.93 10.97,0 8.11,0C5.25,0 2.61,0.92 0.46,2.49C-0.12,2.91 -0.14,3.75 0.37,4.26C0.84,4.73 1.59,4.75 2.13,4.37C3.83,3.19 5.89,2.5 8.11,2.5C10.33,2.5 12.39,3.19 14.09,4.37C14.63,4.75 15.38,4.73 15.85,4.26Z" />
+
<path
- android:pathData="M5.465,8.964C5.27,8.769 5.269,8.45 5.481,8.273C7.515,6.576 10.487,6.576 12.521,8.273C12.733,8.45 12.732,8.769 12.537,8.964L11.83,9.672C11.634,9.867 11.319,9.863 11.099,9.698C9.859,8.767 8.143,8.767 6.904,9.698C6.683,9.863 6.368,9.867 6.173,9.672L5.465,8.964Z"
- android:fillAlpha="0.24"
- android:fillColor="#000"/>
- <path
- android:pathData="M10.062,11.439C10.257,11.244 10.259,10.92 10.022,10.779C9.395,10.407 8.608,10.407 7.98,10.779C7.743,10.92 7.745,11.244 7.94,11.439L8.647,12.146C8.843,12.342 9.159,12.342 9.355,12.146L10.062,11.439Z"
- android:fillAlpha="0.24"
- android:fillColor="#000"/>
+ android:fillAlpha="0.45"
+ android:fillColor="#000"
+ android:pathData="M8.109,12C8.938,12 9.609,11.328 9.609,10.5C9.609,9.672 8.938,9 8.109,9C7.281,9 6.609,9.672 6.609,10.5C6.609,11.328 7.281,12 8.109,12Z" />
+
</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_wifi_0_error.xml b/packages/SettingsLib/res/drawable/ic_wifi_0_error.xml
index db31b9d..3a9bba5 100644
--- a/packages/SettingsLib/res/drawable/ic_wifi_0_error.xml
+++ b/packages/SettingsLib/res/drawable/ic_wifi_0_error.xml
@@ -1,28 +1,52 @@
+<!--
+ Copyright (C) 2025 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="17dp"
- android:height="13dp"
- android:viewportWidth="17.0"
- android:viewportHeight="13.0">
+ android:width="21.0dp"
+ android:height="15.66dp"
+ android:viewportHeight="13.5"
+ android:viewportWidth="18.1">
+
+ <group>
+ <!-- clip-out the circle which will contain the exclamation point (below this group) -->
+ <clip-path android:pathData="
+ M0,0
+ H18.1
+ V13.5
+ H0
+ Z
+ M15.109,13.5C17.871,13.5 20.109,11.261 20.109,8.5C20.109,5.739 17.871,3.5 15.109,3.5C12.348,3.5 10.109,5.739 10.109,8.5C10.109,11.261 12.348,13.5 15.109,13.5Z" />
+
+ <path
+ android:fillAlpha="0.45"
+ android:fillColor="#000"
+ android:pathData="M8.109,12C8.938,12 9.609,11.328 9.609,10.5C9.609,9.672 8.938,9 8.109,9C7.281,9 6.609,9.672 6.609,10.5C6.609,11.328 7.281,12 8.109,12Z" />
+
+ <path
+ android:fillAlpha="0.45"
+ android:fillColor="#000"
+ android:pathData="M12.659,7.45C13.199,6.91 13.149,6.01 12.479,5.64C11.179,4.92 9.689,4.51 8.109,4.51C6.529,4.51 5.029,4.92 3.739,5.64C3.069,6.01 3.019,6.91 3.559,7.45C3.999,7.89 4.699,7.94 5.259,7.66C6.119,7.24 7.089,7 8.109,7C9.129,7 10.099,7.24 10.959,7.66C11.519,7.94 12.219,7.89 12.659,7.45Z" />
+
+ <path
+ android:fillAlpha="0.45"
+ android:fillColor="#000"
+ android:pathData="M15.85,4.26C16.36,3.75 16.34,2.91 15.76,2.49C13.61,0.93 10.97,0 8.11,0C5.25,0 2.61,0.92 0.46,2.49C-0.12,2.91 -0.14,3.75 0.37,4.26C0.84,4.73 1.59,4.75 2.13,4.37C3.83,3.19 5.89,2.5 8.11,2.5C10.33,2.5 12.39,3.19 14.09,4.37C14.63,4.75 15.38,4.73 15.85,4.26Z" />
+ </group>
+
<path
- android:pathData="M0.146,4.015C-0.05,3.819 -0.05,3.502 0.153,3.314C4.002,-0.244 9.545,-0.937 14.055,1.234C13.339,1.449 12.792,2.053 12.66,2.801C8.998,1.281 4.65,1.924 1.568,4.73C1.364,4.916 1.048,4.917 0.853,4.722L0.146,4.015Z"
- android:fillAlpha="0.3"
- android:fillColor="#000"/>
- <path
- android:pathData="M12.63,4.435C9.406,2.836 5.424,3.288 2.63,5.792C2.424,5.976 2.425,6.294 2.621,6.49L3.328,7.197C3.523,7.392 3.839,7.39 4.047,7.209C6.484,5.094 10.033,4.942 12.63,6.753V4.435Z"
- android:fillAlpha="0.3"
- android:fillColor="#000"/>
- <path
- android:pathData="M5.095,8.964C4.9,8.769 4.899,8.45 5.111,8.273C7.145,6.576 10.117,6.576 12.151,8.273C12.363,8.45 12.362,8.769 12.166,8.964L11.459,9.672C11.264,9.867 10.949,9.863 10.728,9.698C9.489,8.767 7.773,8.767 6.533,9.698C6.313,9.863 5.998,9.867 5.802,9.672L5.095,8.964Z"
- android:fillAlpha="0.3"
- android:fillColor="#000"/>
- <path
- android:pathData="M9.652,10.779C9.889,10.92 9.887,11.244 9.692,11.439L8.984,12.146C8.789,12.342 8.473,12.342 8.277,12.146L7.57,11.439C7.375,11.244 7.373,10.92 7.61,10.779C8.237,10.407 9.024,10.407 9.652,10.779Z"
- android:fillAlpha="0.3"
- android:fillColor="#000"/>
- <path
- android:pathData="M14.63,11.15C14.63,10.598 15.078,10.15 15.63,10.15C16.182,10.15 16.63,10.598 16.63,11.15C16.63,11.703 16.182,12.15 15.63,12.15C15.078,12.15 14.63,11.703 14.63,11.15Z"
- android:fillColor="#000"/>
- <path
- android:pathData="M14.63,3.15C14.63,2.874 14.854,2.65 15.13,2.65H16.13C16.406,2.65 16.63,2.874 16.63,3.15V8.15C16.63,8.427 16.406,8.65 16.13,8.65H15.13C14.854,8.65 14.63,8.427 14.63,8.15V3.15Z"
- android:fillColor="#000"/>
+ android:fillColor="#000"
+ android:pathData="M15.109,5C14.699,5 14.359,5.34 14.359,5.75L14.359,8.75C14.359,9.16 14.699,9.5 15.109,9.5C15.519,9.5 15.859,9.16 15.859,8.75L15.859,5.75C15.859,5.34 15.519,5 15.109,5ZM15.109,12C15.519,12 15.859,11.66 15.859,11.25C15.859,10.84 15.519,10.5 15.109,10.5C14.699,10.5 14.359,10.84 14.359,11.25C14.359,11.66 14.699,12 15.109,12Z" />
+
</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_wifi_1.xml b/packages/SettingsLib/res/drawable/ic_wifi_1.xml
index e170f1d..9c661f4 100644
--- a/packages/SettingsLib/res/drawable/ic_wifi_1.xml
+++ b/packages/SettingsLib/res/drawable/ic_wifi_1.xml
@@ -1,5 +1,5 @@
<!--
- Copyright (C) 2023 The Android Open Source Project
+ Copyright (C) 2025 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -14,23 +14,23 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="18dp"
- android:height="13dp"
- android:viewportWidth="18.0"
- android:viewportHeight="13.0">
+ android:width="17.0dp"
+ android:height="12.58dp"
+ android:viewportHeight="12.0"
+ android:viewportWidth="16.21">
+
<path
- android:pathData="M0.523,3.314C0.32,3.502 0.32,3.819 0.516,4.015L1.223,4.722C1.418,4.917 1.734,4.916 1.938,4.73C5.936,1.09 12.066,1.09 16.064,4.73C16.268,4.916 16.584,4.917 16.779,4.722L17.486,4.015C17.682,3.819 17.682,3.502 17.479,3.314C12.698,-1.105 5.304,-1.105 0.523,3.314Z"
- android:fillAlpha="0.24"
- android:fillColor="#000"/>
+ android:fillAlpha="0.45"
+ android:fillColor="#000"
+ android:pathData="M12.659,7.45C13.199,6.91 13.149,6.01 12.479,5.64C11.179,4.92 9.689,4.51 8.109,4.51C6.529,4.51 5.029,4.92 3.739,5.64C3.069,6.01 3.019,6.91 3.559,7.45C3.999,7.89 4.699,7.94 5.259,7.66C6.119,7.24 7.089,7 8.109,7C9.129,7 10.099,7.24 10.959,7.66C11.519,7.94 12.219,7.89 12.659,7.45Z" />
+
<path
- android:pathData="M15.011,6.49C15.207,6.294 15.207,5.976 15.002,5.792C11.592,2.736 6.411,2.736 3,5.792C2.795,5.976 2.795,6.294 2.991,6.49L3.698,7.197C3.893,7.392 4.209,7.39 4.417,7.209C7.042,4.93 10.96,4.93 13.585,7.209C13.793,7.39 14.109,7.392 14.304,7.197L15.011,6.49Z"
- android:fillAlpha="0.24"
- android:fillColor="#000"/>
+ android:fillAlpha="0.45"
+ android:fillColor="#000"
+ android:pathData="M15.85,4.26C16.36,3.75 16.34,2.91 15.76,2.49C13.61,0.93 10.97,0 8.11,0C5.25,0 2.61,0.92 0.46,2.49C-0.12,2.91 -0.14,3.75 0.37,4.26C0.84,4.73 1.59,4.75 2.13,4.37C3.83,3.19 5.89,2.5 8.11,2.5C10.33,2.5 12.39,3.19 14.09,4.37C14.63,4.75 15.38,4.73 15.85,4.26Z" />
+
<path
- android:pathData="M5.465,8.964C5.27,8.769 5.269,8.45 5.481,8.273C7.515,6.576 10.487,6.576 12.521,8.273C12.733,8.45 12.732,8.769 12.537,8.964L11.83,9.672C11.634,9.867 11.319,9.863 11.099,9.698C9.859,8.767 8.143,8.767 6.904,9.698C6.683,9.863 6.368,9.867 6.173,9.672L5.465,8.964Z"
- android:fillAlpha="0.24"
- android:fillColor="#000"/>
- <path
- android:pathData="M10.062,11.439C10.257,11.244 10.259,10.92 10.022,10.779C9.395,10.407 8.608,10.407 7.98,10.779C7.743,10.92 7.745,11.244 7.94,11.439L8.647,12.146C8.843,12.342 9.159,12.342 9.355,12.146L10.062,11.439Z"
- android:fillColor="#000"/>
+ android:fillColor="#000"
+ android:pathData="M8.109,12C8.938,12 9.609,11.328 9.609,10.5C9.609,9.672 8.938,9 8.109,9C7.281,9 6.609,9.672 6.609,10.5C6.609,11.328 7.281,12 8.109,12Z" />
+
</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_wifi_1_error.xml b/packages/SettingsLib/res/drawable/ic_wifi_1_error.xml
index a4d6a5c..32a69f5 100644
--- a/packages/SettingsLib/res/drawable/ic_wifi_1_error.xml
+++ b/packages/SettingsLib/res/drawable/ic_wifi_1_error.xml
@@ -1,27 +1,51 @@
+<!--
+ Copyright (C) 2025 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="17dp"
- android:height="13dp"
- android:viewportWidth="17.0"
- android:viewportHeight="13.0">
+ android:width="21.0dp"
+ android:height="15.66dp"
+ android:viewportHeight="13.5"
+ android:viewportWidth="18.1">
+
+ <group>
+ <!-- clip-out the circle which will contain the exclamation point (below this group) -->
+ <clip-path android:pathData="
+ M0,0
+ H18.1
+ V13.5
+ H0
+ Z
+ M15.109,13.5C17.871,13.5 20.109,11.261 20.109,8.5C20.109,5.739 17.871,3.5 15.109,3.5C12.348,3.5 10.109,5.739 10.109,8.5C10.109,11.261 12.348,13.5 15.109,13.5Z" />
+
+ <path
+ android:fillColor="#000"
+ android:pathData="M8.109,12C8.938,12 9.609,11.328 9.609,10.5C9.609,9.672 8.938,9 8.109,9C7.281,9 6.609,9.672 6.609,10.5C6.609,11.328 7.281,12 8.109,12Z" />
+
+ <path
+ android:fillAlpha="0.45"
+ android:fillColor="#000"
+ android:pathData="M12.659,7.45C13.199,6.91 13.149,6.01 12.479,5.64C11.179,4.92 9.689,4.51 8.109,4.51C6.529,4.51 5.029,4.92 3.739,5.64C3.069,6.01 3.019,6.91 3.559,7.45C3.999,7.89 4.699,7.94 5.259,7.66C6.119,7.24 7.089,7 8.109,7C9.129,7 10.099,7.24 10.959,7.66C11.519,7.94 12.219,7.89 12.659,7.45Z" />
+
+ <path
+ android:fillAlpha="0.45"
+ android:fillColor="#000"
+ android:pathData="M15.85,4.26C16.36,3.75 16.34,2.91 15.76,2.49C13.61,0.93 10.97,0 8.11,0C5.25,0 2.61,0.92 0.46,2.49C-0.12,2.91 -0.14,3.75 0.37,4.26C0.84,4.73 1.59,4.75 2.13,4.37C3.83,3.19 5.89,2.5 8.11,2.5C10.33,2.5 12.39,3.19 14.09,4.37C14.63,4.75 15.38,4.73 15.85,4.26Z" />
+ </group>
+
<path
- android:pathData="M0.146,4.015C-0.05,3.819 -0.05,3.502 0.153,3.314C4.002,-0.244 9.545,-0.937 14.055,1.234C13.339,1.449 12.792,2.053 12.66,2.801C8.998,1.281 4.65,1.924 1.568,4.73C1.364,4.916 1.048,4.917 0.853,4.722L0.146,4.015Z"
- android:fillAlpha="0.3"
- android:fillColor="#000"/>
- <path
- android:pathData="M12.63,4.435C9.406,2.836 5.424,3.288 2.63,5.792C2.424,5.976 2.425,6.294 2.621,6.49L3.328,7.197C3.523,7.392 3.839,7.39 4.047,7.209C6.484,5.094 10.033,4.942 12.63,6.753V4.435Z"
- android:fillAlpha="0.3"
- android:fillColor="#000"/>
- <path
- android:pathData="M5.095,8.964C4.9,8.769 4.899,8.45 5.111,8.273C7.145,6.576 10.117,6.576 12.151,8.273C12.363,8.45 12.362,8.769 12.166,8.964L11.459,9.672C11.264,9.867 10.949,9.863 10.728,9.698C9.489,8.767 7.773,8.767 6.533,9.698C6.313,9.863 5.998,9.867 5.802,9.672L5.095,8.964Z"
- android:fillAlpha="0.3"
- android:fillColor="#000"/>
- <path
- android:pathData="M9.652,10.779C9.889,10.92 9.887,11.244 9.692,11.439L8.984,12.146C8.789,12.342 8.473,12.342 8.277,12.146L7.57,11.439C7.375,11.244 7.373,10.92 7.61,10.779C8.237,10.407 9.024,10.407 9.652,10.779Z"
- android:fillColor="#000"/>
- <path
- android:pathData="M14.63,11.15C14.63,10.598 15.078,10.15 15.63,10.15C16.182,10.15 16.63,10.598 16.63,11.15C16.63,11.703 16.182,12.15 15.63,12.15C15.078,12.15 14.63,11.703 14.63,11.15Z"
- android:fillColor="#000"/>
- <path
- android:pathData="M14.63,3.15C14.63,2.874 14.854,2.65 15.13,2.65H16.13C16.406,2.65 16.63,2.874 16.63,3.15V8.15C16.63,8.427 16.406,8.65 16.13,8.65H15.13C14.854,8.65 14.63,8.427 14.63,8.15V3.15Z"
- android:fillColor="#000"/>
+ android:fillColor="#000"
+ android:pathData="M15.109,5C14.699,5 14.359,5.34 14.359,5.75L14.359,8.75C14.359,9.16 14.699,9.5 15.109,9.5C15.519,9.5 15.859,9.16 15.859,8.75L15.859,5.75C15.859,5.34 15.519,5 15.109,5ZM15.109,12C15.519,12 15.859,11.66 15.859,11.25C15.859,10.84 15.519,10.5 15.109,10.5C14.699,10.5 14.359,10.84 14.359,11.25C14.359,11.66 14.699,12 15.109,12Z" />
+
</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_wifi_2.xml b/packages/SettingsLib/res/drawable/ic_wifi_2.xml
index fc62267..02c14e1 100644
--- a/packages/SettingsLib/res/drawable/ic_wifi_2.xml
+++ b/packages/SettingsLib/res/drawable/ic_wifi_2.xml
@@ -1,5 +1,5 @@
<!--
- Copyright (C) 2023 The Android Open Source Project
+ Copyright (C) 2025 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -14,22 +14,22 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="18dp"
- android:height="13dp"
- android:viewportWidth="18.0"
- android:viewportHeight="13.0">
+ android:width="17.0dp"
+ android:height="12.58dp"
+ android:viewportHeight="12.0"
+ android:viewportWidth="16.21">
+
<path
- android:pathData="M0.523,3.314C0.32,3.502 0.32,3.819 0.516,4.015L1.223,4.722C1.418,4.917 1.734,4.916 1.938,4.73C5.936,1.09 12.066,1.09 16.064,4.73C16.268,4.916 16.584,4.917 16.779,4.722L17.486,4.015C17.682,3.819 17.682,3.502 17.479,3.314C12.698,-1.105 5.304,-1.105 0.523,3.314Z"
- android:fillAlpha="0.24"
- android:fillColor="#000"/>
+ android:fillColor="#000"
+ android:pathData="M12.659,7.45C13.199,6.91 13.149,6.01 12.479,5.64C11.179,4.92 9.689,4.51 8.109,4.51C6.529,4.51 5.029,4.92 3.739,5.64C3.069,6.01 3.019,6.91 3.559,7.45C3.999,7.89 4.699,7.94 5.259,7.66C6.119,7.24 7.089,7 8.109,7C9.129,7 10.099,7.24 10.959,7.66C11.519,7.94 12.219,7.89 12.659,7.45Z" />
+
<path
- android:pathData="M15.011,6.49C15.207,6.294 15.207,5.976 15.002,5.792C11.592,2.736 6.411,2.736 3,5.792C2.795,5.976 2.795,6.294 2.991,6.49L3.698,7.197C3.893,7.392 4.209,7.39 4.417,7.209C7.042,4.93 10.96,4.93 13.585,7.209C13.793,7.39 14.109,7.392 14.304,7.197L15.011,6.49Z"
- android:fillAlpha="0.24"
- android:fillColor="#000"/>
+ android:fillAlpha="0.45"
+ android:fillColor="#000"
+ android:pathData="M15.85,4.26C16.36,3.75 16.34,2.91 15.76,2.49C13.61,0.93 10.97,0 8.11,0C5.25,0 2.61,0.92 0.46,2.49C-0.12,2.91 -0.14,3.75 0.37,4.26C0.84,4.73 1.59,4.75 2.13,4.37C3.83,3.19 5.89,2.5 8.11,2.5C10.33,2.5 12.39,3.19 14.09,4.37C14.63,4.75 15.38,4.73 15.85,4.26Z" />
+
<path
- android:pathData="M5.465,8.964C5.27,8.769 5.269,8.45 5.481,8.273C7.515,6.576 10.487,6.576 12.521,8.273C12.733,8.45 12.732,8.769 12.537,8.964L11.83,9.672C11.634,9.867 11.319,9.863 11.099,9.698C9.859,8.767 8.143,8.767 6.904,9.698C6.683,9.863 6.368,9.867 6.173,9.672L5.465,8.964Z"
- android:fillColor="#000"/>
- <path
- android:pathData="M10.062,11.439C10.257,11.244 10.259,10.92 10.022,10.779C9.395,10.407 8.608,10.407 7.98,10.779C7.743,10.92 7.745,11.244 7.94,11.439L8.647,12.146C8.843,12.342 9.159,12.342 9.355,12.146L10.062,11.439Z"
- android:fillColor="#000"/>
+ android:fillColor="#000"
+ android:pathData="M8.109,12C8.938,12 9.609,11.328 9.609,10.5C9.609,9.672 8.938,9 8.109,9C7.281,9 6.609,9.672 6.609,10.5C6.609,11.328 7.281,12 8.109,12Z" />
+
</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_wifi_2_error.xml b/packages/SettingsLib/res/drawable/ic_wifi_2_error.xml
index 65f40ef..da0aa12 100644
--- a/packages/SettingsLib/res/drawable/ic_wifi_2_error.xml
+++ b/packages/SettingsLib/res/drawable/ic_wifi_2_error.xml
@@ -1,26 +1,50 @@
+<!--
+ Copyright (C) 2025 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="17dp"
- android:height="13dp"
- android:viewportWidth="17.0"
- android:viewportHeight="13.0">
+ android:width="21.0dp"
+ android:height="15.66dp"
+ android:viewportHeight="13.5"
+ android:viewportWidth="18.1">
+
+ <group>
+ <!-- clip-out the circle which will contain the exclamation point (below this group) -->
+ <clip-path android:pathData="
+ M0,0
+ H18.1
+ V13.5
+ H0
+ Z
+ M15.109,13.5C17.871,13.5 20.109,11.261 20.109,8.5C20.109,5.739 17.871,3.5 15.109,3.5C12.348,3.5 10.109,5.739 10.109,8.5C10.109,11.261 12.348,13.5 15.109,13.5Z" />
+
+ <path
+ android:fillColor="#000"
+ android:pathData="M8.109,12C8.938,12 9.609,11.328 9.609,10.5C9.609,9.672 8.938,9 8.109,9C7.281,9 6.609,9.672 6.609,10.5C6.609,11.328 7.281,12 8.109,12Z" />
+
+ <path
+ android:fillColor="#000"
+ android:pathData="M12.659,7.45C13.199,6.91 13.149,6.01 12.479,5.64C11.179,4.92 9.689,4.51 8.109,4.51C6.529,4.51 5.029,4.92 3.739,5.64C3.069,6.01 3.019,6.91 3.559,7.45C3.999,7.89 4.699,7.94 5.259,7.66C6.119,7.24 7.089,7 8.109,7C9.129,7 10.099,7.24 10.959,7.66C11.519,7.94 12.219,7.89 12.659,7.45Z" />
+
+ <path
+ android:fillAlpha="0.45"
+ android:fillColor="#000"
+ android:pathData="M15.85,4.26C16.36,3.75 16.34,2.91 15.76,2.49C13.61,0.93 10.97,0 8.11,0C5.25,0 2.61,0.92 0.46,2.49C-0.12,2.91 -0.14,3.75 0.37,4.26C0.84,4.73 1.59,4.75 2.13,4.37C3.83,3.19 5.89,2.5 8.11,2.5C10.33,2.5 12.39,3.19 14.09,4.37C14.63,4.75 15.38,4.73 15.85,4.26Z" />
+ </group>
+
<path
- android:pathData="M0.146,4.015C-0.05,3.819 -0.05,3.502 0.153,3.314C4.002,-0.244 9.545,-0.937 14.055,1.234C13.339,1.449 12.792,2.053 12.66,2.801C8.998,1.281 4.65,1.924 1.568,4.73C1.364,4.916 1.048,4.917 0.853,4.722L0.146,4.015Z"
- android:fillAlpha="0.3"
- android:fillColor="#000"/>
- <path
- android:pathData="M12.63,4.435C9.406,2.836 5.424,3.288 2.63,5.792C2.424,5.976 2.425,6.294 2.621,6.49L3.328,7.197C3.523,7.392 3.839,7.39 4.047,7.209C6.484,5.094 10.033,4.942 12.63,6.753V4.435Z"
- android:fillAlpha="0.3"
- android:fillColor="#000"/>
- <path
- android:pathData="M5.095,8.964C4.9,8.769 4.899,8.45 5.111,8.273C7.145,6.576 10.117,6.576 12.151,8.273C12.363,8.45 12.362,8.769 12.166,8.964L11.459,9.672C11.264,9.867 10.949,9.863 10.728,9.698C9.489,8.767 7.773,8.767 6.533,9.698C6.313,9.863 5.998,9.867 5.802,9.672L5.095,8.964Z"
- android:fillColor="#000"/>
- <path
- android:pathData="M9.652,10.779C9.889,10.92 9.887,11.244 9.692,11.439L8.984,12.146C8.789,12.342 8.473,12.342 8.277,12.146L7.57,11.439C7.375,11.244 7.373,10.92 7.61,10.779C8.237,10.407 9.024,10.407 9.652,10.779Z"
- android:fillColor="#000"/>
- <path
- android:pathData="M14.63,11.15C14.63,10.598 15.078,10.15 15.63,10.15C16.182,10.15 16.63,10.598 16.63,11.15C16.63,11.703 16.182,12.15 15.63,12.15C15.078,12.15 14.63,11.703 14.63,11.15Z"
- android:fillColor="#000"/>
- <path
- android:pathData="M14.63,3.15C14.63,2.874 14.854,2.65 15.13,2.65H16.13C16.406,2.65 16.63,2.874 16.63,3.15V8.15C16.63,8.427 16.406,8.65 16.13,8.65H15.13C14.854,8.65 14.63,8.427 14.63,8.15V3.15Z"
- android:fillColor="#000"/>
+ android:fillColor="#000"
+ android:pathData="M15.109,5C14.699,5 14.359,5.34 14.359,5.75L14.359,8.75C14.359,9.16 14.699,9.5 15.109,9.5C15.519,9.5 15.859,9.16 15.859,8.75L15.859,5.75C15.859,5.34 15.519,5 15.109,5ZM15.109,12C15.519,12 15.859,11.66 15.859,11.25C15.859,10.84 15.519,10.5 15.109,10.5C14.699,10.5 14.359,10.84 14.359,11.25C14.359,11.66 14.699,12 15.109,12Z" />
+
</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_wifi_3.xml b/packages/SettingsLib/res/drawable/ic_wifi_3.xml
index 9079daf..6b183af 100644
--- a/packages/SettingsLib/res/drawable/ic_wifi_3.xml
+++ b/packages/SettingsLib/res/drawable/ic_wifi_3.xml
@@ -1,5 +1,5 @@
<!--
- Copyright (C) 2023 The Android Open Source Project
+ Copyright (C) 2025 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -14,21 +14,21 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="18dp"
- android:height="13dp"
- android:viewportWidth="18.0"
- android:viewportHeight="13.0">
+ android:width="17.0dp"
+ android:height="12.58dp"
+ android:viewportHeight="12.0"
+ android:viewportWidth="16.21">
+
<path
- android:pathData="M0.523,3.314C0.32,3.502 0.32,3.819 0.516,4.015L1.223,4.722C1.418,4.917 1.734,4.916 1.938,4.73C5.936,1.09 12.066,1.09 16.064,4.73C16.268,4.916 16.584,4.917 16.779,4.722L17.486,4.015C17.682,3.819 17.682,3.502 17.479,3.314C12.698,-1.105 5.304,-1.105 0.523,3.314Z"
- android:fillAlpha="0.24"
- android:fillColor="#000"/>
+ android:fillColor="#000"
+ android:pathData="M12.659,7.45C13.199,6.91 13.149,6.01 12.479,5.64C11.179,4.92 9.689,4.51 8.109,4.51C6.529,4.51 5.029,4.92 3.739,5.64C3.069,6.01 3.019,6.91 3.559,7.45C3.999,7.89 4.699,7.94 5.259,7.66C6.119,7.24 7.089,7 8.109,7C9.129,7 10.099,7.24 10.959,7.66C11.519,7.94 12.219,7.89 12.659,7.45Z" />
+
<path
- android:pathData="M15.011,6.49C15.207,6.294 15.207,5.976 15.002,5.792C11.592,2.736 6.411,2.736 3,5.792C2.795,5.976 2.795,6.294 2.991,6.49L3.698,7.197C3.893,7.392 4.209,7.39 4.417,7.209C7.042,4.93 10.96,4.93 13.585,7.209C13.793,7.39 14.109,7.392 14.304,7.197L15.011,6.49Z"
- android:fillColor="#000"/>
+ android:fillColor="#000"
+ android:pathData="M15.85,4.26C16.36,3.75 16.34,2.91 15.76,2.49C13.61,0.93 10.97,0 8.11,0C5.25,0 2.61,0.92 0.46,2.49C-0.12,2.91 -0.14,3.75 0.37,4.26C0.84,4.73 1.59,4.75 2.13,4.37C3.83,3.19 5.89,2.5 8.11,2.5C10.33,2.5 12.39,3.19 14.09,4.37C14.63,4.75 15.38,4.73 15.85,4.26Z" />
+
<path
- android:pathData="M5.465,8.964C5.27,8.769 5.269,8.45 5.481,8.273C7.515,6.576 10.487,6.576 12.521,8.273C12.733,8.45 12.732,8.769 12.537,8.964L11.83,9.672C11.634,9.867 11.319,9.863 11.099,9.698C9.859,8.767 8.143,8.767 6.904,9.698C6.683,9.863 6.368,9.867 6.173,9.672L5.465,8.964Z"
- android:fillColor="#000"/>
- <path
- android:pathData="M10.062,11.439C10.257,11.244 10.259,10.92 10.022,10.779C9.395,10.407 8.608,10.407 7.98,10.779C7.743,10.92 7.745,11.244 7.94,11.439L8.647,12.146C8.843,12.342 9.159,12.342 9.355,12.146L10.062,11.439Z"
- android:fillColor="#000"/>
+ android:fillColor="#000"
+ android:pathData="M8.109,12C8.938,12 9.609,11.328 9.609,10.5C9.609,9.672 8.938,9 8.109,9C7.281,9 6.609,9.672 6.609,10.5C6.609,11.328 7.281,12 8.109,12Z" />
+
</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_wifi_3_error.xml b/packages/SettingsLib/res/drawable/ic_wifi_3_error.xml
index 940781b..c30affa 100644
--- a/packages/SettingsLib/res/drawable/ic_wifi_3_error.xml
+++ b/packages/SettingsLib/res/drawable/ic_wifi_3_error.xml
@@ -1,25 +1,49 @@
+<!--
+ Copyright (C) 2025 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="17dp"
- android:height="13dp"
- android:viewportWidth="17.0"
- android:viewportHeight="13.0">
+ android:width="21.0dp"
+ android:height="15.66dp"
+ android:viewportHeight="13.5"
+ android:viewportWidth="18.1">
+
+ <group>
+ <!-- clip-out the circle which will contain the exclamation point (below this group) -->
+ <clip-path android:pathData="
+ M0,0
+ H18.1
+ V13.5
+ H0
+ Z
+ M15.109,13.5C17.871,13.5 20.109,11.261 20.109,8.5C20.109,5.739 17.871,3.5 15.109,3.5C12.348,3.5 10.109,5.739 10.109,8.5C10.109,11.261 12.348,13.5 15.109,13.5Z" />
+
+ <path
+ android:fillColor="#000"
+ android:pathData="M8.109,12C8.938,12 9.609,11.328 9.609,10.5C9.609,9.672 8.938,9 8.109,9C7.281,9 6.609,9.672 6.609,10.5C6.609,11.328 7.281,12 8.109,12Z" />
+
+ <path
+ android:fillColor="#000"
+ android:pathData="M12.659,7.45C13.199,6.91 13.149,6.01 12.479,5.64C11.179,4.92 9.689,4.51 8.109,4.51C6.529,4.51 5.029,4.92 3.739,5.64C3.069,6.01 3.019,6.91 3.559,7.45C3.999,7.89 4.699,7.94 5.259,7.66C6.119,7.24 7.089,7 8.109,7C9.129,7 10.099,7.24 10.959,7.66C11.519,7.94 12.219,7.89 12.659,7.45Z" />
+
+ <path
+ android:fillColor="#000"
+ android:pathData="M15.85,4.26C16.36,3.75 16.34,2.91 15.76,2.49C13.61,0.93 10.97,0 8.11,0C5.25,0 2.61,0.92 0.46,2.49C-0.12,2.91 -0.14,3.75 0.37,4.26C0.84,4.73 1.59,4.75 2.13,4.37C3.83,3.19 5.89,2.5 8.11,2.5C10.33,2.5 12.39,3.19 14.09,4.37C14.63,4.75 15.38,4.73 15.85,4.26Z" />
+ </group>
+
<path
- android:pathData="M0.146,4.015C-0.05,3.819 -0.05,3.502 0.153,3.314C4.002,-0.244 9.545,-0.937 14.055,1.234C13.339,1.449 12.792,2.053 12.66,2.801C8.998,1.281 4.65,1.924 1.568,4.73C1.364,4.916 1.048,4.917 0.853,4.722L0.146,4.015Z"
- android:fillAlpha="0.3"
- android:fillColor="#000"/>
- <path
- android:pathData="M12.63,4.435C9.406,2.836 5.424,3.288 2.63,5.792C2.424,5.976 2.425,6.294 2.621,6.49L3.328,7.197C3.523,7.392 3.839,7.39 4.047,7.209C6.484,5.094 10.033,4.942 12.63,6.753V4.435Z"
- android:fillColor="#000"/>
- <path
- android:pathData="M5.095,8.964C4.9,8.769 4.899,8.45 5.111,8.273C7.145,6.576 10.117,6.576 12.151,8.273C12.363,8.45 12.362,8.769 12.166,8.964L11.459,9.672C11.264,9.867 10.949,9.863 10.728,9.698C9.489,8.767 7.773,8.767 6.533,9.698C6.313,9.863 5.998,9.867 5.802,9.672L5.095,8.964Z"
- android:fillColor="#000"/>
- <path
- android:pathData="M9.652,10.779C9.889,10.92 9.887,11.244 9.692,11.439L8.984,12.146C8.789,12.342 8.473,12.342 8.277,12.146L7.57,11.439C7.375,11.244 7.373,10.92 7.61,10.779C8.237,10.407 9.024,10.407 9.652,10.779Z"
- android:fillColor="#000"/>
- <path
- android:pathData="M14.63,11.15C14.63,10.598 15.078,10.15 15.63,10.15C16.182,10.15 16.63,10.598 16.63,11.15C16.63,11.703 16.182,12.15 15.63,12.15C15.078,12.15 14.63,11.703 14.63,11.15Z"
- android:fillColor="#000"/>
- <path
- android:pathData="M14.63,3.15C14.63,2.874 14.854,2.65 15.13,2.65H16.13C16.406,2.65 16.63,2.874 16.63,3.15V8.15C16.63,8.427 16.406,8.65 16.13,8.65H15.13C14.854,8.65 14.63,8.427 14.63,8.15V3.15Z"
- android:fillColor="#000"/>
+ android:fillColor="#000"
+ android:pathData="M15.109,5C14.699,5 14.359,5.34 14.359,5.75L14.359,8.75C14.359,9.16 14.699,9.5 15.109,9.5C15.519,9.5 15.859,9.16 15.859,8.75L15.859,5.75C15.859,5.34 15.519,5 15.109,5ZM15.109,12C15.519,12 15.859,11.66 15.859,11.25C15.859,10.84 15.519,10.5 15.109,10.5C14.699,10.5 14.359,10.84 14.359,11.25C14.359,11.66 14.699,12 15.109,12Z" />
+
</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_wifi_4.xml b/packages/SettingsLib/res/drawable/ic_wifi_4.xml
deleted file mode 100644
index 6185e4a..0000000
--- a/packages/SettingsLib/res/drawable/ic_wifi_4.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<!--
- Copyright (C) 2023 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="18dp"
- android:height="13dp"
- android:viewportWidth="18.0"
- android:viewportHeight="13.0">
- <path
- android:pathData="M0.523,3.314C0.32,3.502 0.32,3.819 0.516,4.015L1.223,4.722C1.418,4.917 1.734,4.916 1.938,4.73C5.936,1.09 12.066,1.09 16.064,4.73C16.268,4.916 16.584,4.917 16.779,4.722L17.486,4.015C17.682,3.819 17.682,3.502 17.479,3.314C12.698,-1.105 5.304,-1.105 0.523,3.314Z"
- android:fillColor="#000"/>
- <path
- android:pathData="M15.011,6.49C15.207,6.294 15.207,5.976 15.002,5.792C11.592,2.736 6.411,2.736 3,5.792C2.795,5.976 2.795,6.294 2.991,6.49L3.698,7.197C3.893,7.392 4.209,7.39 4.417,7.209C7.042,4.93 10.96,4.93 13.585,7.209C13.793,7.39 14.109,7.392 14.304,7.197L15.011,6.49Z"
- android:fillColor="#000"/>
- <path
- android:pathData="M5.465,8.964C5.27,8.769 5.269,8.45 5.481,8.273C7.515,6.576 10.487,6.576 12.521,8.273C12.733,8.45 12.732,8.769 12.537,8.964L11.83,9.672C11.634,9.867 11.319,9.863 11.099,9.698C9.859,8.767 8.143,8.767 6.904,9.698C6.683,9.863 6.368,9.867 6.173,9.672L5.465,8.964Z"
- android:fillColor="#000"/>
- <path
- android:pathData="M10.062,11.439C10.257,11.244 10.259,10.92 10.022,10.779C9.395,10.407 8.608,10.407 7.98,10.779C7.743,10.92 7.745,11.244 7.94,11.439L8.647,12.146C8.843,12.342 9.159,12.342 9.355,12.146L10.062,11.439Z"
- android:fillColor="#000"/>
-</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_wifi_4_error.xml b/packages/SettingsLib/res/drawable/ic_wifi_4_error.xml
deleted file mode 100644
index 715aaa0..0000000
--- a/packages/SettingsLib/res/drawable/ic_wifi_4_error.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="17dp"
- android:height="13dp"
- android:viewportWidth="17.0"
- android:viewportHeight="13.0">
- <path
- android:pathData="M0.146,4.015C-0.05,3.819 -0.05,3.502 0.153,3.314C4.002,-0.244 9.545,-0.937 14.055,1.234C13.339,1.449 12.792,2.053 12.66,2.801C8.998,1.281 4.65,1.924 1.568,4.73C1.364,4.916 1.048,4.917 0.853,4.722L0.146,4.015Z"
- android:fillColor="#000"/>
- <path
- android:pathData="M12.63,4.435C9.406,2.836 5.424,3.288 2.63,5.792C2.424,5.976 2.425,6.294 2.621,6.49L3.328,7.197C3.523,7.392 3.839,7.39 4.047,7.209C6.484,5.094 10.033,4.942 12.63,6.753V4.435Z"
- android:fillColor="#000"/>
- <path
- android:pathData="M5.095,8.964C4.9,8.769 4.899,8.45 5.111,8.273C7.145,6.576 10.117,6.576 12.151,8.273C12.363,8.45 12.362,8.769 12.166,8.964L11.459,9.672C11.264,9.867 10.949,9.863 10.728,9.698C9.489,8.767 7.773,8.767 6.533,9.698C6.313,9.863 5.998,9.867 5.802,9.672L5.095,8.964Z"
- android:fillColor="#000"/>
- <path
- android:pathData="M9.652,10.779C9.889,10.92 9.887,11.244 9.692,11.439L8.984,12.146C8.789,12.342 8.473,12.342 8.277,12.146L7.57,11.439C7.375,11.244 7.373,10.92 7.61,10.779C8.237,10.407 9.024,10.407 9.652,10.779Z"
- android:fillColor="#000"/>
- <path
- android:pathData="M14.63,11.15C14.63,10.598 15.078,10.15 15.63,10.15C16.182,10.15 16.63,10.598 16.63,11.15C16.63,11.703 16.182,12.15 15.63,12.15C15.078,12.15 14.63,11.703 14.63,11.15Z"
- android:fillColor="#000"/>
- <path
- android:pathData="M14.63,3.15C14.63,2.874 14.854,2.65 15.13,2.65H16.13C16.406,2.65 16.63,2.874 16.63,3.15V8.15C16.63,8.427 16.406,8.65 16.13,8.65H15.13C14.854,8.65 14.63,8.427 14.63,8.15V3.15Z"
- android:fillColor="#000"/>
-</vector>
diff --git a/packages/SettingsLib/res/values-af/arrays.xml b/packages/SettingsLib/res/values-af/arrays.xml
index c4ba7eb..89648d1 100644
--- a/packages/SettingsLib/res/values-af/arrays.xml
+++ b/packages/SettingsLib/res/values-af/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"Slegs toestelskerm (verstek)"</item>
+ <item msgid="9161645858025071955">"Eksterne skerm"</item>
+ <item msgid="23651860565814477">"Laaste interaksie met statusbalk"</item>
+ <item msgid="7521112827893653392">"Fokusgebaseer"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"Wys skakering net op toestelskerm"</item>
+ <item msgid="1955398604822147783">"Wys skakering op enkele eksterne skerm"</item>
+ <item msgid="391477482416751568">"Wys skakering op die skerm waarop die statusbalk die laaste interaksie gehad het"</item>
+ <item msgid="1746820128097981528">"Wys skakering op die laaste gefokusde skerm"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 3a7e452..dbc4e5a 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Kon nie omgewing opdateer nie"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktief (net media). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktiewe (net media). L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> battery"</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Gekoppel (steun oudiodeling). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery"</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Gekoppel (steun oudiodeling). L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> battery."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Gekoppel (steun oudiodeling). Links: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Gekoppel (steun oudiodeling). Regs: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Gekoppel (steun oudiodeling)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Aktief (net media)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Steun oudiodeling"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Aktief (net media), net linkerkant"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Aktief (net media), net regterkant"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Aktief (net media), linker- en regterkant"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Hardeware-versnelde lewering"</string>
<string name="media_category" msgid="8122076702526144053">"Media"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Monitering"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Strengmodus geaktiveer"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Flits skerm as apps lang bewerkings uitvoer op die hoofdraad"</string>
<string name="pointer_location" msgid="7516929526199520173">"Wyserligging"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView-implementering"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Stel WebView-implementering"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Hierdie keuse is nie meer geldig nie. Probeer weer."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Fotokleurmodus"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Gebruik sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Gedeaktiveer"</string>
diff --git a/packages/SettingsLib/res/values-am/arrays.xml b/packages/SettingsLib/res/values-am/arrays.xml
index a151f83..4ae2d99b 100644
--- a/packages/SettingsLib/res/values-am/arrays.xml
+++ b/packages/SettingsLib/res/values-am/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"የመሣሪያ ማሳያ ብቻ (ነባሪ)"</item>
+ <item msgid="9161645858025071955">"ውጫዊ ማሳያ"</item>
+ <item msgid="23651860565814477">"የቅርብ ጊዜ የሁኔታ አሞሌ ንክኪ"</item>
+ <item msgid="7521112827893653392">"ትኩረት ላይ የተመሠረተ"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"በመሣሪያ ማሳያ ላይ ብቻ ጥላ አሳይ"</item>
+ <item msgid="1955398604822147783">"በነጠላ ውጫዊ ማሳያ ላይ ጥላ አሳይ"</item>
+ <item msgid="391477482416751568">"ለመጨረሻ ጊዜ በሁኔታ አሞሌው መስተጋብር የተፈጠረበት ማሳያ ላይ ጥላ አሳይ"</item>
+ <item msgid="1746820128097981528">"ለመጨረሻ ጊዜ ትኩረት በተደረገበት ማሳያ ላይ ጥላ አሳይ"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index 25e9c5e..bfe6006 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"በዙሪያ ያሉትን ማዘመን አልተቻለም"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"ገቢር (ሚዲያ ብቻ)። <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ባትሪ።"</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"ገቢር (ሚዲያ ብቻ)። ግ፦ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>፣ ቀ፦ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> ባትሪ።"</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"ተገናኝቷል (የድምፅ ማጋራት ይደግፋል)፣ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ባትሪ።"</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"ተገናኝቷል (የድምፅ ማጋራት ይደግፋል) ግ፦ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>፣ ቀ፦ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> ባትሪ።"</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"ተገናኝቷል (የድምፅ ማጋራት ይደግፋል)። ግራ፦<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ባትሪ።"</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"ተገናኝቷል (የድምፅ ማጋራት ይደግፋል)። ቀኝ፦ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ባትሪ።"</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"ተገናኝቷል (የድምፅ ማጋራት ይደግፋል)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"ገቢር (ሚዲያ ብቻ)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"ድምፅ ማጋራትን ይደግፋል"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"ገቢር (ሚዲያ ብቻ)፣ ግራ ብቻ"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"ገቢር (ሚዲያ ብቻ) ቀኝ ብቻ"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"ገቢር (ሚዲያ ብቻ)፣ ግራ እና ቀኝ"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"የተፋጠነ የሃርድዌር አሰጣጥ"</string>
<string name="media_category" msgid="8122076702526144053">"ማህደረመረጃ"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"ቁጥጥር"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"ጥብቅ ሁነታ ነቅቷል"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"መተግበሪያዎች ረጅም ክንውኖች ወደ ዋና ክሮች ሲያካሂዱ ማያላይ ብልጭ አድርግ።"</string>
<string name="pointer_location" msgid="7516929526199520173">"የአመልካች ሥፍራ"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"የWebView ትግበራ"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"የWebView ትግበራን ያዘጋጁ"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"ይህ ምርጫ ከአሁን በኋላ የሚሰራ አይደለም። እንደገና ይሞክሩ።"</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"የስዕል ቀለም ሁነታ"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"sRGB ይጠቀሙ"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"ተሰናክሏል"</string>
diff --git a/packages/SettingsLib/res/values-ar/arrays.xml b/packages/SettingsLib/res/values-ar/arrays.xml
index ebdb0c7..e3c36b8 100644
--- a/packages/SettingsLib/res/values-ar/arrays.xml
+++ b/packages/SettingsLib/res/values-ar/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"شاشة الجهاز فقط (الإعداد التلقائي)"</item>
+ <item msgid="9161645858025071955">"الشاشة الخارجية"</item>
+ <item msgid="23651860565814477">"آخر لمسة على شريط الحالة"</item>
+ <item msgid="7521112827893653392">"على الشاشة التي يتم التركيز عليها"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"عرض الظل على شاشة الجهاز فقط"</item>
+ <item msgid="1955398604822147783">"عرض الظل على شاشة خارجية واحدة"</item>
+ <item msgid="391477482416751568">"عرض الظل على آخر شاشة تم التفاعل مع شريط الحالة فيها"</item>
+ <item msgid="1746820128097981528">"عرض الظل على آخر شاشة تم التركيز عليها"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 8956c44..64a021d 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"تعذَّر تعديل حالة الأصوات المحيطة"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"البلوتوث نشِط (للوسائط فقط). مستوى شحن البطارية: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"البلوتوث نشِط (للوسائط فقط)، مستوى الشحن في سماعة الرأس اليسرى: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>، مستوى الشحن في سماعة الرأس اليمنى: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>"</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"البلوتوث متصل (ميزة \"مشاركة الصوت\" متاحة). مستوى شحن البطارية: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"البلوتوث متصل (ميزة \"مشاركة الصوت\" متاحة). مستوى الشحن في سماعة الرأس اليسرى: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>، مستوى الشحن في سماعة الرأس اليمنى: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>"</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"البلوتوث متصل (ميزة \"مشاركة الصوت\" متاحة). مستوى الشحن في سماعة الرأس اليسرى: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"البلوتوث متصل (ميزة \"مشاركة الصوت\" متاحة). مستوى الشحن في سماعة الرأس اليمنى: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"البلوتوث متصل (ميزة \"مشاركة الصوت\" متاحة)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"البلوتوث مفعَّل (للوسائط فقط)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"تتوفّر ميزة \"مشاركة الصوت\""</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"السماعة اليسرى فقط مشغَّلة (للوسائط فقط)"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"السماعة اليمنى فقط مشغَّلة (للوسائط فقط)"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"السماعتان اليسرى واليمنى مشغَّلتان (للوسائط فقط)"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"عرض تسارع الأجهزة"</string>
<string name="media_category" msgid="8122076702526144053">"الوسائط"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"المراقبة"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"تفعيل الوضع المتشدد"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"وميض الشاشة عند إجراء التطبيقات عمليات طويلة في سلسلة المحادثات الرئيسية"</string>
<string name="pointer_location" msgid="7516929526199520173">"موقع المؤشر"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"تطبيق WebView"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"تعيين تطبيق WebView"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"لم يعد هذا الاختيار صالحًا. أعد المحاولة."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"نمط لون الصورة"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"استخدام sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"غير مفعّل"</string>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index bfacbb2..82ee7f3 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"আশ-পাশ আপডে’ট কৰিব পৰা নগ’ল"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"সক্ৰিয় হৈ আছে (কেৱল মিডিয়া)। <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> বেটাৰী।"</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"সক্ৰিয় হৈ আছে (কেৱল মিডিয়া)। বাওঁ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, সোঁ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> বেটাৰী।"</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"সংযুক্ত হৈ আছে (অডিঅ’ শ্বেয়াৰিং সমৰ্থন কৰে), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> বেটাৰী।"</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"সংযুক্ত হৈ আছে (অডিঅ’ শ্বেয়াৰিং সমৰ্থন কৰে), বাওঁ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, সোঁ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> বেটাৰী"</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"সংযুক্ত হৈ আছে (অডিঅ’ শ্বেয়াৰিং সমৰ্থন কৰে)। বাকী আছে: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> বেটাৰী।"</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"সংযুক্ত হৈ আছে (অডিঅ’ শ্বেয়াৰিং সমৰ্থন কৰে)। সোঁ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> বেটাৰী।"</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"সংযুক্ত হৈ আছে (অডিঅ’ শ্বেয়াৰিং সমৰ্থন কৰে)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"সক্ৰিয় হৈ আছে (কেৱল মিডিয়া)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"অডিঅ’ শ্বেয়াৰিং সমৰ্থন কৰে"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"সক্ৰিয় হৈ আছে (কেৱল মিডিয়া), কেৱল বাওঁ"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"সক্ৰিয় হৈ আছে (কেৱল মিডিয়া), কেৱল সোঁ"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"সক্ৰিয় হৈ আছে (কেৱল মিডিয়া), বাওঁ আৰু সোঁ"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"হাৰ্ডৱেৰৰদ্বাৰা ত্বৰিত ৰেণ্ডাৰিং"</string>
<string name="media_category" msgid="8122076702526144053">"মিডিয়া"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"নিৰীক্ষণ কৰি থকা হৈছে"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"কঠোৰ ম’ড সক্ষম কৰা হৈছে"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"যেতিয়া এপ্সমূহে মুখ্য থ্ৰেডত দীঘলীয়া কাৰ্যকলাপ চলায়, তেতিয়া স্ক্ৰীন ফ্লাশ্ব কৰক"</string>
<string name="pointer_location" msgid="7516929526199520173">"পইণ্টাৰৰ অৱস্থান"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"ৱেবভিউ প্ৰয়োগ"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"ৱেবভিউ প্ৰয়োগ ছেট কৰক"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"বাছনিটো এতিয়া আৰু মান্য় নহয়। আকৌ চেষ্টা কৰক।"</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"চিত্ৰৰ ৰং ম’ড"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"এছআৰজিবি ব্যৱহাৰ কৰক"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"নিষ্ক্ৰিয় হৈ আছে"</string>
diff --git a/packages/SettingsLib/res/values-az/arrays.xml b/packages/SettingsLib/res/values-az/arrays.xml
index 52cf498..3b02070 100644
--- a/packages/SettingsLib/res/values-az/arrays.xml
+++ b/packages/SettingsLib/res/values-az/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"Yalnız cihaz displeyi (defolt)"</item>
+ <item msgid="9161645858025071955">"Xarici displey"</item>
+ <item msgid="23651860565814477">"Ən son status paneli toxunuşu"</item>
+ <item msgid="7521112827893653392">"Fokus əsaslı"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"Kölgəni yalnız cihaz displeyində göstərin"</item>
+ <item msgid="1955398604822147783">"Tək xarici displeydə kölgə göstərilsin"</item>
+ <item msgid="391477482416751568">"Ən son status paneli ilə interaksiya edilmiş displeydə kölgə göstərilsin"</item>
+ <item msgid="1746820128097981528">"Son fokuslanmış displeydə kölgə göstərilsin"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index 9013fb5..aa93964 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Ətraf mühit güncəllənmədi"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktiv (yalnız media). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batareya."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktiv (yalnız media). Sol: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, Sağ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> batareya."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Qoşulub (audio paylaşma dəstəklənir). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batareya."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Qoşulub (audio paylaşma dəstəklənir). Sol: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, Sağ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> batareya."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Qoşulub (audio paylaşma dəstəklənir). Sol: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batareya."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Qoşulub (audio paylaşma dəstəklənir). Sağ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batareya."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Qoşulub (audio paylaşma dəstəklənir)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Aktiv (yalnız media)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Audio paylaşma dəstəklənir"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Aktiv (yalnız media), yalnız sol"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Aktiv (yalnız media), yalnız sağ"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Aktiv (yalnız media), sol və sağ"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Renderinq aparat sürətlənməsi"</string>
<string name="media_category" msgid="8122076702526144053">"Media"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Monitorinq"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Ciddi rejim"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Uzun əməliyyatlar ərzində ekran işıqlandırılsın"</string>
<string name="pointer_location" msgid="7516929526199520173">"Kursor yeri"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView servisi"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"WebView servisini ayarlayın"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Bu seçim artıq etibarlı deyil. Yenidən cəhd edin."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Şəkil rəng rejimi"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"sRGB istifadə edin"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Deaktiv"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 7a00b96..7f60500 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Ažuriranje okruženja nije uspelo"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktivno (samo za medije). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterije."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktivno (samo za medije). Levo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, desno: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> baterije."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Povezano (podržava deljenje zvuka), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterije."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Povezano (podržava deljenje zvuka), levo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, desno: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> baterije."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Povezano (podržava deljenje zvuka). Levo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterije"</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Povezano (podržava deljenje zvuka). Desno: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterije."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Povezano (podržava deljenje zvuka)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Aktivan (samo za medije)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Podržava deljenje zvuka"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Aktivan (samo za medije), samo levo"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Aktivan (samo za medije), samo desno"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Aktivan (samo za medije), levo i desno"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Hardverski ubrzano prikazivanje"</string>
<string name="media_category" msgid="8122076702526144053">"Mediji"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Nadgledanje"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Omogućen je strogi režim"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Ekran treperi kada aplikacije obavljaju duge operacije na glavnoj niti"</string>
<string name="pointer_location" msgid="7516929526199520173">"Lokacija pokazivača"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"Primena WebView-a"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Podesite primenu WebView-a"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Ovaj izbor više nije važeći. Probajte ponovo."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Režim boja slika"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Koristi sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Onemogućeno je"</string>
diff --git a/packages/SettingsLib/res/values-be/arrays.xml b/packages/SettingsLib/res/values-be/arrays.xml
index 48c3627..e33a71e 100644
--- a/packages/SettingsLib/res/values-be/arrays.xml
+++ b/packages/SettingsLib/res/values-be/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"Толькі дысплэй прылады (стандартна)"</item>
+ <item msgid="9161645858025071955">"Знешні дысплэй"</item>
+ <item msgid="23651860565814477">"Апошняе націсканне на панэль стану"</item>
+ <item msgid="7521112827893653392">"У залежнасці ад выкарыстання"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"Паказваць шчыток толькі на дысплэі прылады"</item>
+ <item msgid="1955398604822147783">"Паказваць шчыток апавяшчэнняў на адным знешнім дысплэі"</item>
+ <item msgid="391477482416751568">"Паказваць шчыток апавяшчэнняў на дысплэі, на якім адбывалася апошняе ўзаемадзеянне з панэллю стану"</item>
+ <item msgid="1746820128097981528">"Паказваць шчыток апавяшчэнняў на дысплэі, які выкарыстоўваўся апошнім"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 0ad8ac7..50de924 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Не ўдалося абнавіць стан навакольных гукаў"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Выкарыстоўваецца (толькі для мультымедыя). Зарад акумулятара: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Выкарыстоўваецца (толькі для мультымедыя). Зарад акумулятара: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> (левы навушнік), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> (правы навушнік)."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Падключана (падтрымліваецца абагульванне аўдыя). Зарад акумулятара: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Падключана (падтрымліваецца абагульванне аўдыя). Зарад акумулятара: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> (левы навушнік), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> (правы навушнік)."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Падключана (падтрымліваецца абагульванне аўдыя). Зарад акумулятара: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> (левы навушнік)."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Падключана (падтрымліваецца абагульванне аўдыя). Зарад акумулятара: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> (правы навушнік)."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Падключана (падтрымліваецца абагульванне аўдыя)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Выкарыстоўваецца (толькі для мультымедыя)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Падтрымліваецца абагульванне аўдыя"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Выкарыстоўваецца (толькі для мультымедыя), толькі левы навушнік"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Выкарыстоўваецца (толькі для мультымедыя), толькі правы навушнік"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Выкарыстоўваецца (толькі для мультымедыя), левы і правы навушнікі"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Апаратнае паскарэнне рэндэрынгу"</string>
<string name="media_category" msgid="8122076702526144053">"Медыя"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Маніторынг"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Уключаны строгі рэжым"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Падсвечваць экран падчас доўгіх аперацый"</string>
<string name="pointer_location" msgid="7516929526199520173">"Пазіцыя ўказальніка"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"Рэалізацыя WebView"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Наладзіць рэалізацыю WebView"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Гэты варыянт больш не даступны. Паспрабуйце яшчэ раз."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Каляровы рэжым выявы"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Выкарыстоўваць sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Выключана"</string>
diff --git a/packages/SettingsLib/res/values-bg/arrays.xml b/packages/SettingsLib/res/values-bg/arrays.xml
index 21dfa06..fabd7d9 100644
--- a/packages/SettingsLib/res/values-bg/arrays.xml
+++ b/packages/SettingsLib/res/values-bg/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"Само на екрана на устройството (по подразбиране)"</item>
+ <item msgid="9161645858025071955">"Външен екран"</item>
+ <item msgid="23651860565814477">"Последно докосване на лентата на състоянието"</item>
+ <item msgid="7521112827893653392">"Въз основа на фокуса"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"Показване на падащия панел само на екрана на устройството"</item>
+ <item msgid="1955398604822147783">"Показване на падащия панел на един външен екран"</item>
+ <item msgid="391477482416751568">"Показване на падащия панел на екрана, с чиято лента на състоянието е взаимодействано последно"</item>
+ <item msgid="1746820128097981528">"Показване на падащия панел на екрана, върху който последно е бил поставен фокусът"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 8a87e57..c3c1783 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Данните за околните звуци не бяха актуализирани"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Активно (само за мултимедия). Батерия – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Активно (само за мултимедия). Л: батерия – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, Д: батерия – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Свързано (поддържа споделяне на звука). Батерия – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Свързано (поддържа споделяне на звука). Л: батерия – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, Д: батерия – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Свързано (поддържа споделяне на звука). За ляво ухо. Батерия: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Свързано (поддържа споделяне на звука). За дясно ухо. Батерия: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Свързано (поддържа споделяне на звука)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Активно (само за мултимедия)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Поддържа споделяне на звука"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Активно (само за мултимедия), само лявата"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Активно (само за мултимедия), само дясната"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Активно (само за мултимедия), лявата и дясната"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Хардуерно ускорено изобразяване"</string>
<string name="media_category" msgid="8122076702526144053">"Мултимедия"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Наблюдение"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Активиран строг режим"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Примигване на екрана при дълги операции в главната нишка"</string>
<string name="pointer_location" msgid="7516929526199520173">"Mестопол. на показалеца"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"Внедряване на WebView"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Задаване на внедряването на WebView"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Този избор вече не е валиден. Опитайте отново."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Цветови режим за снимките"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Използване на sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Деактивирано"</string>
diff --git a/packages/SettingsLib/res/values-bn/arrays.xml b/packages/SettingsLib/res/values-bn/arrays.xml
index b27264d..27fe258 100644
--- a/packages/SettingsLib/res/values-bn/arrays.xml
+++ b/packages/SettingsLib/res/values-bn/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"শুধুমাত্র ডিভাইসের ডিসপ্লে (ডিফল্ট)"</item>
+ <item msgid="9161645858025071955">"এক্সটার্নাল ডিসপ্লে"</item>
+ <item msgid="23651860565814477">"লেটেস্ট স্ট্যাটাস বার টাচ"</item>
+ <item msgid="7521112827893653392">"ফোকাস-ভিত্তিক"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"শুধুমাত্র ডিভাইসের ডিসপ্লেতে শেড দেখুন"</item>
+ <item msgid="1955398604822147783">"কোনও একটি বাইরের ডিসপ্লেতে শেড দেখুন"</item>
+ <item msgid="391477482416751568">"সেই ডিসপ্লেতে শেড দেখুন যেখানে যার স্ট্যাটাস বারে শেষ বার ইন্টার্যাকশন করা হয়েছে"</item>
+ <item msgid="1746820128097981528">"সেই ডিসপ্লেতে শেড দেখুন যেখানে শেষবার ফোকাস করা হয়েছে"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 1e7c7a2..93b6521 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"সারাউন্ডিং আপডেট করা যায়নি"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"চালু আছে (শুধুমাত্র মিডিয়া)। <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ব্যাটারি।"</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"চালু আছে (শুধুমাত্র মিডিয়া), বাঁদিক: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, ডানদিক: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> ব্যাটারি।"</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"কানেক্ট করা আছে (অডিও শেয়ারিংয়ে কাজ করে), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ব্যাটারি।"</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"কানেক্ট করা আছে (অডিও শেয়ারিংয়ে কাজ করে), বাঁদিক: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, ডানদিক: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> ব্যাটারি।"</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"কানেক্ট করা আছে (অডিও শেয়ারিংয়ে কাজ করে)। বাঁদিক: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ব্যাটারি।"</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"কানেক্ট করা আছে (অডিও শেয়ারিংয়ে কাজ করে)। ডানদিকে: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ব্যাটারি।"</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"কানেক্ট করা আছে (অডিও শেয়ারিংয়ে কাজ করে)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"চালু আছে (শুধুমাত্র মিডিয়া)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"অডিও শেয়ারিংয়ে কাজ করে"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"চালু আছে (শুধুমাত্র মিডিয়া), শুধুমাত্র বাঁদিক"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"চালু আছে (শুধুমাত্র মিডিয়া), শুধুমাত্র ডানদিক"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"চালু আছে (শুধুমাত্র মিডিয়া), বাঁদিক ও ডানদিক"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"হার্ডওয়্যার দ্বারা চালিত রেন্ডারিং"</string>
<string name="media_category" msgid="8122076702526144053">"মিডিয়া"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"পর্যবেক্ষণে রাখা"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"স্ট্রিক্ট মোড চালু আছে"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"মুখ্য থ্রেডে অ্যাপগুলির দীর্ঘ কার্যকলাপের ক্ষেত্রে স্ক্রিন ফ্ল্যাশ করে"</string>
<string name="pointer_location" msgid="7516929526199520173">"পয়েন্টারের লোকেশন"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"ওয়েবভিউ প্রয়োগ"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"ওয়েবভিউ প্রয়োগ সেট করুন"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"এই পছন্দটি আর বৈধ নেই৷ আবার চেষ্টা করুন৷"</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"ছবি রঙ মোড"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"sRGB ব্যবহার করুন"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"অক্ষম হয়েছে"</string>
diff --git a/packages/SettingsLib/res/values-bs/arrays.xml b/packages/SettingsLib/res/values-bs/arrays.xml
index 44bbfaf..f8fc6ac 100644
--- a/packages/SettingsLib/res/values-bs/arrays.xml
+++ b/packages/SettingsLib/res/values-bs/arrays.xml
@@ -291,14 +291,14 @@
<string-array name="shade_display_awareness_entries">
<item msgid="816770658383209617">"Samo zaslon uređaja (zadano)"</item>
<item msgid="9161645858025071955">"Vanjski ekran"</item>
- <item msgid="23651860565814477">"Najnoviji dodir trake statusa"</item>
- <item msgid="7521112827893653392">"Na temelju fokusa"</item>
+ <item msgid="23651860565814477">"Posljednji dodir na statusnu traku"</item>
+ <item msgid="7521112827893653392">"Na osnovu fokusa"</item>
</string-array>
<string-array name="shade_display_awareness_summaries">
<item msgid="2964753205732912921">"Prikaži sjenu samo na ekranu uređaja"</item>
- <item msgid="1955398604822147783">"Prikaži sjenčanje na jednom vanjskom zaslonu"</item>
- <item msgid="391477482416751568">"Prikaži sjenčanje na zaslonu na kojem je posljednje stupljeno u interakciju s trakom statusa"</item>
- <item msgid="1746820128097981528">"Prikaži sjenčanje na posljednjem fokusiranom zaslonu"</item>
+ <item msgid="1955398604822147783">"Prikaži sjenu na jednom vanjskom ekranu"</item>
+ <item msgid="391477482416751568">"Prikaži sjenu na posljednjem ekranu na kojem se stupalo u interakciju sa statusnom trakom"</item>
+ <item msgid="1746820128097981528">"Prikaži sjenu na posljednjem fokusiranom ekranu"</item>
</string-array>
<string-array name="shade_display_awareness_values">
<item msgid="3055776101992426514">"default_display"</item>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index 756a326..abb0775 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Ažuriranje okruženja nije uspjelo"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktivno (samo za medijski sadržaj). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterije."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktivno (samo za medijski sadržaj). L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> baterije, D: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> baterije."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Povezano (podržava dijeljenje zvuka). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterije."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Povezano (podržava dijeljenje zvuka). L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> baterije, D: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> baterije."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Povezano (podržava dijeljenje zvuka). Lijevo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterije."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Povezano (podržava dijeljenje zvuka). Desno: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterije."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Povezano (podržava dijeljenje zvuka)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Aktivno (samo za medijski sadržaj)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Podržava dijeljenje zvuka"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Aktivno (samo za medijski sadržaj), samo lijevo"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Aktivno (samo za medijski sadržaj), samo desno"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Aktivno (samo za medijski sadržaj), lijevo i desno"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Hardverski ubrzano prikazivanje"</string>
<string name="media_category" msgid="8122076702526144053">"Mediji"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Praćenje"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Omogući strogi način rada"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Ekran bljeska kada aplikacije vrše duge operacije u glavnoj niti"</string>
<string name="pointer_location" msgid="7516929526199520173">"Lokacija pokazivača"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"Postavljanje WebViewa"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Podesi WebView"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Ovaj izbor više ne vrijedi. Pokušajte ponovo."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Način rada boja slika"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Koristi sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Onemogućeno"</string>
diff --git a/packages/SettingsLib/res/values-ca/arrays.xml b/packages/SettingsLib/res/values-ca/arrays.xml
index f19551c..8f1f630 100644
--- a/packages/SettingsLib/res/values-ca/arrays.xml
+++ b/packages/SettingsLib/res/values-ca/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"Només a la pantalla del dispositiu (opció predeterminada)"</item>
+ <item msgid="9161645858025071955">"Pantalla externa"</item>
+ <item msgid="23651860565814477">"Darrer toc a la barra d\'estat"</item>
+ <item msgid="7521112827893653392">"Basat en l\'enfocament"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"Mostra l\'ombra només a la pantalla del dispositiu"</item>
+ <item msgid="1955398604822147783">"Mostra l\'àrea en una sola pantalla externa"</item>
+ <item msgid="391477482416751568">"Mostra l\'àrea a la pantalla amb què s\'ha interaccionat per darrera vegada a la barra d\'estat"</item>
+ <item msgid="1746820128097981528">"Mostra l\'àrea a la darrera pantalla en què s\'hagi posat el focus"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 0548099..ed49307c 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"No s\'ha pogut actualitzar l\'entorn"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Actiu (només contingut multimèdia). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Actiu (només contingut multimèdia), E: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> de bateria, D: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> de bateria."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Connectat (admet compartició d\'àudio). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Connectat (admet compartició d\'àudio), E: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> de bateria, D: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> de bateria."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Connectat (admet compartició d\'àudio). Esquerre: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Connectat (admet compartició d\'àudio). Dret: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Connectat (admet compartició d\'àudio)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Actiu (només contingut multimèdia)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Admet compartició d\'àudio"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Actiu (només contingut multimèdia), només esquerre"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Actiu (només contingut multimèdia), només dret"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Actiu (només contingut multimèdia), esquerre i dret"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Renderització accelerada per maquinari"</string>
<string name="media_category" msgid="8122076702526144053">"Multimèdia"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Supervisió"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Mode estricte activat"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Il·lumina la pantalla quan les aplicacions facin operacions llargues al fil principal"</string>
<string name="pointer_location" msgid="7516929526199520173">"Ubicació del punter"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"Implementació de WebView"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Estableix implementació de WebView"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Aquesta opció ja no és vàlida. Torna-ho a provar."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Mode de color de la imatge"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Utilitza sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Desactivat"</string>
diff --git a/packages/SettingsLib/res/values-cs/arrays.xml b/packages/SettingsLib/res/values-cs/arrays.xml
index ad1cafd..152cd83 100644
--- a/packages/SettingsLib/res/values-cs/arrays.xml
+++ b/packages/SettingsLib/res/values-cs/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"Pouze zobrazení zařízení (výchozí)"</item>
+ <item msgid="9161645858025071955">"Externí displej"</item>
+ <item msgid="23651860565814477">"Poslední dotknutí se stavového řádku"</item>
+ <item msgid="7521112827893653392">"Výběr"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"Zobrazovat panel pouze na displeji zařízení"</item>
+ <item msgid="1955398604822147783">"Zobrazovat panel na jednom externím displeji"</item>
+ <item msgid="391477482416751568">"Zobrazovat panel na displeji, na kterém uživatel naposledy interagoval se stavovým řádkem"</item>
+ <item msgid="1746820128097981528">"Zobrazovat panel na displeji, který byl naposledy vybrán"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index a774a1d..7ea6e43 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Okolí se nepodařilo aktualizovat"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktivní (pouze média). Baterie: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktivní (pouze média), baterie: L <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, P <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Připojeno (podporuje sdílení zvuku), baterie: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Připojeno (podporuje sdílení zvuku), baterie: L <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, P <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Připojeno (podporuje sdílení zvuku). Levá strana: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterie"</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Připojeno (podporuje sdílení zvuku). Pravá strana: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterie."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Připojeno (podporuje sdílení zvuku)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Aktivní (pouze média)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Podporuje sdílení zvuku"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Aktivní (pouze média), pouze levé"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Aktivní (pouze média), pouze pravé"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Aktivní (pouze média), levé a pravé"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Hardwarově urychlené vykreslování"</string>
<string name="media_category" msgid="8122076702526144053">"Média"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Sledování"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Přísný režim aktivován"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Rozblikat obrazovku při dlouhých operacích hlavního vlákna"</string>
<string name="pointer_location" msgid="7516929526199520173">"Umístění ukazatele"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"Implementace WebView"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Nastavte implementaci WebView"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Tato volba již není platná. Zkuste to znovu."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Režim barev obrázku"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Použije se barevný prostor sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Vypnuto"</string>
diff --git a/packages/SettingsLib/res/values-da/arrays.xml b/packages/SettingsLib/res/values-da/arrays.xml
index ed45775..aff59c2 100644
--- a/packages/SettingsLib/res/values-da/arrays.xml
+++ b/packages/SettingsLib/res/values-da/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"Kun på enhedens skærm (standard)"</item>
+ <item msgid="9161645858025071955">"Ekstern skærm"</item>
+ <item msgid="23651860565814477">"Seneste tryk på statusbjælken"</item>
+ <item msgid="7521112827893653392">"Fokusbaseret"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"Vis kun skygge på enhedens skærm"</item>
+ <item msgid="1955398604822147783">"Vis skygge på en enkelt ekstern skærm"</item>
+ <item msgid="391477482416751568">"Vis skygge på den skærm, hvor der sidst blev interageret med statusbjælken"</item>
+ <item msgid="1746820128097981528">"Vis skygge på den skærm, der sidst var i fokus"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index d7aa9b1..4aad2a2 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Omgivelserne kunne ikke opdateres"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktiveret (kun for medier). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batteri."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktiveret (kun for medier), V: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, H: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> batteri."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Forbundet (understøtter lyddeling). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batteri."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Forbundet (understøtter lyddeling), V: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, H: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> batteri."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Forbundet (understøtter lyddeling). Venstre: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batteri."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Forbundet (understøtter lyddeling). Højre: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batteri."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Forbundet (understøtter lyddeling)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Aktiveret (kun for medier)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Understøtter lyddeling"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Aktiveret (kun for medier), kun venstre"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Aktiveret (kun for medier), kun højre"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Aktiveret (kun for medier), venstre og højre"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Hardware-accelereret gengivelse"</string>
<string name="media_category" msgid="8122076702526144053">"Medie"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Overvågning"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Striks tilstand aktiveret"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Blink med skærmen, når apps foretager handlinger på hovedtråd"</string>
<string name="pointer_location" msgid="7516929526199520173">"Markørens lokation"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView-implementering"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Konfigurer WebView-implementering"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Dette valg er ikke længere gyldigt. Prøv igen."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Farvetilstand for billeder"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Brug sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Deaktiveret"</string>
diff --git a/packages/SettingsLib/res/values-de/arrays.xml b/packages/SettingsLib/res/values-de/arrays.xml
index 924718a..6dc8754 100644
--- a/packages/SettingsLib/res/values-de/arrays.xml
+++ b/packages/SettingsLib/res/values-de/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"Nur Gerätedisplay (Standard)"</item>
+ <item msgid="9161645858025071955">"Externes Display"</item>
+ <item msgid="23651860565814477">"Letzte Berührung der Statusleiste"</item>
+ <item msgid="7521112827893653392">"Fokusbasiert"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"Leiste nur auf dem Display des Geräts anzeigen"</item>
+ <item msgid="1955398604822147783">"Leiste auf einem einzigen externen Display anzeigen"</item>
+ <item msgid="391477482416751568">"Leiste auf dem Display anzeigen, auf dem zuletzt mit der Statusleiste interagiert wurde"</item>
+ <item msgid="1746820128097981528">"Leiste auf dem zuletzt fokussierten Display anzeigen"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index 73268c5..55cae96 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Status der Umgebungsgeräusche konnte nicht aktualisiert werden"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktiv (nur Medien). Akku: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktiv (nur Medien). Akku links: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, Akku rechts: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Verbunden (unterstützt Audiofreigabe). Akku: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Verbunden (unterstützt Audiofreigabe). Akku links: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, Akku rechts: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Verbunden (unterstützt Audiofreigabe). Akku links: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Verbunden (unterstützt Audiofreigabe). Akku rechts: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Verbunden (unterstützt Audiofreigabe)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Aktiv (nur Medien)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Unterstützt Audiofreigabe"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Aktiv (nur Medien), nur links"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Aktiv (nur Medien), nur rechts"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Aktiv (nur Medien), links und rechts"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Hardwarebeschleunigtes Rendering"</string>
<string name="media_category" msgid="8122076702526144053">"Medien"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Monitoring"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Strikter Modus aktiviert"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Bei langen App-Vorgängen im Hauptthread blinkt Bildschirm"</string>
<string name="pointer_location" msgid="7516929526199520173">"Zeigerposition"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView-Implementierung"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"WebView-Implementierung festlegen"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Diese Auswahl ist nicht mehr gültig. Bitte versuche es noch einmal."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Farbmodus für Bilder"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"sRGB verwenden"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Deaktiviert"</string>
diff --git a/packages/SettingsLib/res/values-el/arrays.xml b/packages/SettingsLib/res/values-el/arrays.xml
index 41aefc0..33e2390 100644
--- a/packages/SettingsLib/res/values-el/arrays.xml
+++ b/packages/SettingsLib/res/values-el/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"Μόνο οθόνη συσκευής (Προεπιλογή)"</item>
+ <item msgid="9161645858025071955">"Εξωτερική οθόνη"</item>
+ <item msgid="23651860565814477">"Τελευταίο άγγιγμα της γραμμής κατάστασης"</item>
+ <item msgid="7521112827893653392">"Με εστίαση"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"Εμφάνιση σκίασης μόνο στην οθόνη συσκευής"</item>
+ <item msgid="1955398604822147783">"Εμφάνιση σκίασης σε εξωτερική οθόνη"</item>
+ <item msgid="391477482416751568">"Εμφάνιση σκίασης στην οθόνη στην οποία έγινε η τελευταία αλληλεπίδραση με τη γραμμή κατάστασης"</item>
+ <item msgid="1746820128097981528">"Εμφάνιση σκίασης στην τελευταία οθόνη με εστίαση"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index 209b782..6b6b7fb 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Δεν ήταν δυνατή η ενημέρωση των ήχων περιβάλλοντος"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Ενεργό (μόνο για μέσα). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> μπαταρία."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Ενεργό (μόνο για μέσα). Α: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, Δ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> μπαταρία."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Συνδεδεμένο (υποστηρίζει κοινή χρήση ήχου). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> μπαταρία."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Συνδεδεμένο (υποστηρίζει κοινή χρήση ήχου). Α: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, Δ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> μπαταρία."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Συνδεδεμένο (υποστηρίζει κοινή χρήση ήχου). Αριστερά: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> μπαταρία."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Συνδεδεμένο (υποστηρίζει κοινή χρήση ήχου). Δεξιά: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> μπαταρία."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Συνδεδεμένο (υποστηρίζει κοινή χρήση ήχου)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Ενεργό (μόνο για μέσα)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Υποστηρίζει κοινή χρήση ήχου"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Ενεργό (μόνο για μέσα), μόνο αριστερό"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Ενεργό (μόνο για μέσα), μόνο δεξί"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Ενεργό (μόνο για μέσα), αριστερό και δεξί"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Απόδοση με επιτάχυνση από υλικό εξοπλισμό"</string>
<string name="media_category" msgid="8122076702526144053">"Μέσα"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Παρακολούθηση"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Ενεργ. αυστηρής λειτουργ."</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Αναβ. οθόνη σε εκτέλεση μεγάλων λειτ.σε κύριο νήμα"</string>
<string name="pointer_location" msgid="7516929526199520173">"Θέση δείκτη"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"Υλοποίηση WebView"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Ορισμός υλοποίησης WebView"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Αυτή η επιλογή δεν είναι πια έγκυρη. Δοκιμάστε ξανά."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Λειτουργία χρώματος εικόνας"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Χρήση sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Απενεργοποιημένο"</string>
diff --git a/packages/SettingsLib/res/values-en-rAU/arrays.xml b/packages/SettingsLib/res/values-en-rAU/arrays.xml
index 6c7a7ff..b53ad98 100644
--- a/packages/SettingsLib/res/values-en-rAU/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rAU/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"Device display only (default)"</item>
+ <item msgid="9161645858025071955">"External display"</item>
+ <item msgid="23651860565814477">"Latest status bar touch"</item>
+ <item msgid="7521112827893653392">"Focus-based"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"Show shade on device display only"</item>
+ <item msgid="1955398604822147783">"Show shade on single external display"</item>
+ <item msgid="391477482416751568">"Show shade on display which last had its status bar interacted with"</item>
+ <item msgid="1746820128097981528">"Show shade on last focused display"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index d965c65..a811960 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Couldn\'t update surroundings"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Active (media only). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Active (media only). L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> battery."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Connected (supports audio sharing). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Connected (supports audio sharing). L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> battery."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Connected (supports audio sharing). Left: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Connected (supports audio sharing). Right: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Connected (supports audio sharing)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Active (media only)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Supports audio sharing"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Active (media only), left only"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Active (media only), right only"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Active (media only), left and right"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Hardware accelerated rendering"</string>
<string name="media_category" msgid="8122076702526144053">"Media"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Monitoring"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Strict mode enabled"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Flash screen when apps do long operations on main thread"</string>
<string name="pointer_location" msgid="7516929526199520173">"Pointer location"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView implementation"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Set WebView implementation"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"This choice is no longer valid. Try again."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Picture colour mode"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Use sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Disabled"</string>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index 748d7b1..a12b46c 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -113,13 +113,23 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Couldn’t update surroundings"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Active (media only). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Active (media only). L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> battery."</string>
+ <string name="bluetooth_guest_battery_level" msgid="2820003593899467676">"Guest device. <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
+ <string name="bluetooth_guest_battery_level_untethered" msgid="5404013822067644960">"Guest device. L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> battery."</string>
+ <string name="bluetooth_guest_media_only_battery_level" msgid="7928347900623812299">"Guest device (media only). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
+ <string name="bluetooth_guest_media_only_battery_level_untethered" msgid="4458143141394300892">"Guest device (media only). L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> battery."</string>
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Connected (supports audio sharing). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Connected (supports audio sharing). L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> battery."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Connected (supports audio sharing). Left: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Connected (supports audio sharing). Right: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Connected (supports audio sharing)"</string>
+ <string name="bluetooth_guest_battery_level_lea_support" msgid="8098327939585013928">"Guest device (supports audio sharing). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
+ <string name="bluetooth_guest_battery_level_untethered_lea_support" msgid="3701035025565668360">"Guest device (supports audio sharing). L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> battery."</string>
+ <string name="bluetooth_guest_no_battery_level_lea_support" msgid="2977038548753103470">"Guest device (supports audio sharing)"</string>
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Active (media only)"</string>
+ <string name="bluetooth_guest_no_battery_level" msgid="9122974160381136920">"Guest device"</string>
+ <string name="bluetooth_guest_media_only_no_battery_level" msgid="7666347601796705721">"Guest device (media only)"</string>
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Supports audio sharing"</string>
+ <string name="bluetooth_guest_saved_device_lea_support" msgid="5621291599518569876">"Guest device. Supports audio sharing"</string>
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Active (media only), left only"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Active (media only), right only"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Active (media only), left and right"</string>
@@ -376,6 +386,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Hardware accelerated rendering"</string>
<string name="media_category" msgid="8122076702526144053">"Media"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Monitoring"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Strict mode enabled"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Flash screen when apps do long operations on main thread"</string>
<string name="pointer_location" msgid="7516929526199520173">"Pointer location"</string>
@@ -470,6 +482,9 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView implementation"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Set WebView implementation"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"This choice is no longer valid. Try again."</string>
+ <string name="webview_launch_devtools_title" msgid="8009687433555367112">"WebView DevTools"</string>
+ <string name="webview_launch_devtools_no_package" msgid="3182544553665113721">"WebView package not found."</string>
+ <string name="webview_launch_devtools_no_activity" msgid="4066006313619617140">"Could not launch DevTools."</string>
<string name="picture_color_mode" msgid="1013807330552931903">"Picture color mode"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Use sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Disabled"</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/arrays.xml b/packages/SettingsLib/res/values-en-rGB/arrays.xml
index 6c7a7ff..b53ad98 100644
--- a/packages/SettingsLib/res/values-en-rGB/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rGB/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"Device display only (default)"</item>
+ <item msgid="9161645858025071955">"External display"</item>
+ <item msgid="23651860565814477">"Latest status bar touch"</item>
+ <item msgid="7521112827893653392">"Focus-based"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"Show shade on device display only"</item>
+ <item msgid="1955398604822147783">"Show shade on single external display"</item>
+ <item msgid="391477482416751568">"Show shade on display which last had its status bar interacted with"</item>
+ <item msgid="1746820128097981528">"Show shade on last focused display"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index d965c65..a811960 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Couldn\'t update surroundings"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Active (media only). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Active (media only). L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> battery."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Connected (supports audio sharing). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Connected (supports audio sharing). L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> battery."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Connected (supports audio sharing). Left: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Connected (supports audio sharing). Right: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Connected (supports audio sharing)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Active (media only)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Supports audio sharing"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Active (media only), left only"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Active (media only), right only"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Active (media only), left and right"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Hardware accelerated rendering"</string>
<string name="media_category" msgid="8122076702526144053">"Media"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Monitoring"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Strict mode enabled"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Flash screen when apps do long operations on main thread"</string>
<string name="pointer_location" msgid="7516929526199520173">"Pointer location"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView implementation"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Set WebView implementation"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"This choice is no longer valid. Try again."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Picture colour mode"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Use sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Disabled"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/arrays.xml b/packages/SettingsLib/res/values-en-rIN/arrays.xml
index 6c7a7ff..b53ad98 100644
--- a/packages/SettingsLib/res/values-en-rIN/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rIN/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"Device display only (default)"</item>
+ <item msgid="9161645858025071955">"External display"</item>
+ <item msgid="23651860565814477">"Latest status bar touch"</item>
+ <item msgid="7521112827893653392">"Focus-based"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"Show shade on device display only"</item>
+ <item msgid="1955398604822147783">"Show shade on single external display"</item>
+ <item msgid="391477482416751568">"Show shade on display which last had its status bar interacted with"</item>
+ <item msgid="1746820128097981528">"Show shade on last focused display"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index d965c65..a811960 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Couldn\'t update surroundings"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Active (media only). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Active (media only). L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> battery."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Connected (supports audio sharing). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Connected (supports audio sharing). L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> battery."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Connected (supports audio sharing). Left: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Connected (supports audio sharing). Right: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Connected (supports audio sharing)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Active (media only)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Supports audio sharing"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Active (media only), left only"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Active (media only), right only"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Active (media only), left and right"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Hardware accelerated rendering"</string>
<string name="media_category" msgid="8122076702526144053">"Media"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Monitoring"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Strict mode enabled"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Flash screen when apps do long operations on main thread"</string>
<string name="pointer_location" msgid="7516929526199520173">"Pointer location"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView implementation"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Set WebView implementation"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"This choice is no longer valid. Try again."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Picture colour mode"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Use sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Disabled"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/arrays.xml b/packages/SettingsLib/res/values-es-rUS/arrays.xml
index 5894975..2f1b14d 100644
--- a/packages/SettingsLib/res/values-es-rUS/arrays.xml
+++ b/packages/SettingsLib/res/values-es-rUS/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"Solo en la pantalla del dispositivo (predeterminado)"</item>
+ <item msgid="9161645858025071955">"Pantalla externa"</item>
+ <item msgid="23651860565814477">"Última interacción con la barra de estado"</item>
+ <item msgid="7521112827893653392">"Basado en el enfoque"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"Mostrar sobra solo en la pantalla del dispositivo"</item>
+ <item msgid="1955398604822147783">"Mostrar panel en una sola pantalla externa"</item>
+ <item msgid="391477482416751568">"Mostrar el panel de la última pantalla en la que se interactuó con su barra de estado"</item>
+ <item msgid="1746820128097981528">"Mostrar el panel en la última pantalla enfocada"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index acd6790..6c3c98a 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"No se pudo actualizar el sonido envolvente"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Activado (solo para contenido multimedia). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Activo (solo para contenido multimedia); I: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>; D: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> de batería."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Conectado (admite el uso compartido de audio); <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Conectado (admite el uso compartido de audio); I: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>; D: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> de batería."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Conectado (admite el uso compartido de audio). Izquierdo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Conectado (admite el uso compartido de audio). Derecho: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Conectado (admite el uso compartido de audio)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Activo (solo para contenido multimedia)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Admite el uso compartido de audio"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Activo (solo para contenido multimedia); solo izquierdo"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Activo (solo para contenido multimedia); solo derecho"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Activo (solo para contenido multimedia); izquierdo y derecho"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Renderización acelerada por hardware"</string>
<string name="media_category" msgid="8122076702526144053">"Multimedia"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Supervisión"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Modo estricto"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Parpadear si aplicaciones tardan en proceso principal"</string>
<string name="pointer_location" msgid="7516929526199520173">"Ubicación del puntero"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"Implementación de WebView"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Configurar la implementación de WebView"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Esta opción ya no es válida. Vuelve a intentarlo."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Modo de color de la imagen"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Usa sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Inhabilitado"</string>
diff --git a/packages/SettingsLib/res/values-es/arrays.xml b/packages/SettingsLib/res/values-es/arrays.xml
index 1e8c661..9031cc3 100644
--- a/packages/SettingsLib/res/values-es/arrays.xml
+++ b/packages/SettingsLib/res/values-es/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"Solo en la pantalla del dispositivo (predeterminado)"</item>
+ <item msgid="9161645858025071955">"Pantalla externa"</item>
+ <item msgid="23651860565814477">"Toque más reciente en la barra de estado"</item>
+ <item msgid="7521112827893653392">"Basado en el enfoque"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"Mostrar el panel solo en la pantalla del dispositivo"</item>
+ <item msgid="1955398604822147783">"Mostrar el panel en una sola pantalla externa"</item>
+ <item msgid="391477482416751568">"Mostrar el panel en la pantalla en la que se haya interactuado por última vez con la barra de estado"</item>
+ <item msgid="1746820128097981528">"Mostrar el panel en la última pantalla enfocada"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 00b987c..b91c9b4 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"No se han podido actualizar los alrededores"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Activo (solo multimedia). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Activo (solo multimedia). Izquierdo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> de batería. Derecho: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> de batería."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Conectado (permite compartir audio). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Conectado (admite Compartir audio). Izquierdo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> de batería. Derecho: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> de batería."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Conectado (admite Compartir audio). Izquierdo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Conectado (admite Compartir audio). Derecho: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Conectado (admite Compartir audio)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Activo (solo multimedia)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Permite compartir audio"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Activo (solo multimedia), solo el izquierdo"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Activo (solo multimedia), solo el derecho"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Activo (solo multimedia), izquierdo y derecho"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Renderización acelerada por hardware"</string>
<string name="media_category" msgid="8122076702526144053">"Multimedia"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Supervisión"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Modo Estricto habilitado"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Hace parpadear la pantalla si las aplicaciones tardan mucho en el subproceso principal"</string>
<string name="pointer_location" msgid="7516929526199520173">"Ubicación del puntero"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"Implementación de WebView"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Establecer implementación de WebView"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Esta opción ya no está disponible. Vuelve a intentarlo."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Modo de color de imagen"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Utiliza sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Inhabilitado"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index b442ed3..8c5d7fe 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Ümbritsevate helide seadeid ei saanud värskendada"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktiivne (ainult meedia). Aku <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktiivne (ainult meedia). Aku: V: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, P: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Ühendatud (toetab heli jagamist). Aku <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Ühendatud (toetab heli jagamist). Aku: V: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, P: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Ühendatud (toetab heli jagamist). Vasak: aku <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Ühendatud (toetab heli jagamist). Parem: aku <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Ühendatud (toetab heli jagamist)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Aktiivne (ainult meedia)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Toetab heli jagamist"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Aktiivne (ainult meedia), ainult vasak"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Aktiivne (ainult meedia), ainult parem"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Aktiivne (ainult meedia), vasak ja parem"</string>
@@ -129,7 +149,7 @@
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Sisendseade"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Juurdepääs internetile"</string>
<string name="bluetooth_profile_pbap" msgid="2103406516858653017">"Luba juurdepääs kontaktidele ja kõneajale"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="402819589201138227">"Teavet kasutatakse kõne teadaannete ja muu jaoks"</string>
+ <string name="bluetooth_profile_pbap_summary" msgid="402819589201138227">"Teavet kasutatakse kõne teadaannete ja muu jaoks."</string>
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Interneti-ühenduse jagamine"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Tekstsõnumid"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"Juurdepääs SIM-ile"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Riistvarakiirendusega renderdamine"</string>
<string name="media_category" msgid="8122076702526144053">"Meedia"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Jälgimine"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Range režiim on lubatud"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Ekraan vilgub, kui rakendused teevad pealõimes pikki toiminguid"</string>
<string name="pointer_location" msgid="7516929526199520173">"Kursori asukoht"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView\' rakendamine"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"WebView\' rakendamise seadistamine"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"See valik ei kehti enam. Proovige uuesti."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Pildi värvirežiim"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"sRGB kasutamine"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Keelatud"</string>
diff --git a/packages/SettingsLib/res/values-eu/arrays.xml b/packages/SettingsLib/res/values-eu/arrays.xml
index a1528c2..616b12f 100644
--- a/packages/SettingsLib/res/values-eu/arrays.xml
+++ b/packages/SettingsLib/res/values-eu/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"Gailuaren pantailan soilik (lehenetsia)"</item>
+ <item msgid="9161645858025071955">"Kanpoko pantailan"</item>
+ <item msgid="23651860565814477">"Egoera-barraren azken ukitzea"</item>
+ <item msgid="7521112827893653392">"Fokuaren arabera"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"Erakutsi itzalak gailuaren pantailan soilik"</item>
+ <item msgid="1955398604822147783">"Erakutsi itzala kanpoko pantaila bakar batean"</item>
+ <item msgid="391477482416751568">"Erakutsi itzala egoera-barran interakzio bat izan duen azken pantailan"</item>
+ <item msgid="1746820128097981528">"Erakutsi itzala fokuratutako azken pantailan"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 1c422b6..a1e4664 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Ezin izan da eguneratu ingurunea"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktibo (multimedia-edukia soilik). Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktibo (multimedia-edukia soilik). L aldearen bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>. R aldearen bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Konektatuta (audioa partekatzeko eginbidea onartzen du). Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Konektatuta (audioa partekatzeko eginbidea onartzen du). L aldearen bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>. R aldearen bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Konektatuta (audioa partekatzeko eginbidea onartzen du). Ezkerreko aldearen bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Konektatuta (audioa partekatzeko eginbidea onartzen du). Eskuineko aldearen bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Konektatuta (audioa partekatzeko eginbidea onartzen du)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Aktibo (multimedia-edukia soilik)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Audioa partekatzeko eginbidea onartzen du"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Aktibo (multimedia-edukia soilik); ezkerreko aldea soilik"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Aktibo (multimedia-edukia soilik); eskuineko aldea soilik"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Aktibo (multimedia-edukia soilik); ezkerreko eta eskuineko aldeak"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Hardware bidez azeleratutako errendatzea"</string>
<string name="media_category" msgid="8122076702526144053">"Multimedia-edukia"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Kontrola"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Modu zorrotza gaituta"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Distirarazi hari nagusian eragiketa luzeak egitean"</string>
<string name="pointer_location" msgid="7516929526199520173">"Erakuslearen kokapena"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView inplementazioa"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Ezarri WebView inplementazioa"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Jada ez dago erabilgarri aukera hori. Saiatu berriro."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Irudiaren kolore modua"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Erabili sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Desgaituta"</string>
diff --git a/packages/SettingsLib/res/values-fa/arrays.xml b/packages/SettingsLib/res/values-fa/arrays.xml
index d7face8..8421726 100644
--- a/packages/SettingsLib/res/values-fa/arrays.xml
+++ b/packages/SettingsLib/res/values-fa/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"۲"</item>
<item msgid="4779928470672877922">"۳"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"فقط نمایشگر دستگاه (پیشفرض)"</item>
+ <item msgid="9161645858025071955">"نمایشگر خارجی"</item>
+ <item msgid="23651860565814477">"آخرین لمس نوار وضعیت"</item>
+ <item msgid="7521112827893653392">"کانونیمحور"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"نمایش سایه فقط در نمایشگر دستگاه"</item>
+ <item msgid="1955398604822147783">"نمایش سایه در یک نمایشگر خارجی"</item>
+ <item msgid="391477482416751568">"نمایش سایه در نمایشگری که کاربر آخرین بار با نوار وضعیت آن تعامل داشته است"</item>
+ <item msgid="1746820128097981528">"نمایش سایه در آخرین نمایشگر کانونیشده"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"نمایشگر_پیشفرض"</item>
+ <item msgid="774789415968826925">"هر_نمایشگر_خارجی"</item>
+ <item msgid="7880769915418638436">"آخرین_لمس_نوار_وضعیت"</item>
+ <item msgid="4313165186636015195">"نمایشگر_کانونیشده"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index b1f76fb..c939180 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"پیرامون بهروز نشد"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"فعال (فقط رسانه). باتری: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"فعال (فقط رسانه). باتری چپ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>، باتری راست: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"متصل (از اشتراک صدا پشتیبانی میکند)، باتری: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"متصل (از اشتراک صدا پشتیبانی میکند)، باتری چپ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>، باتری راست: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"متصل (از اشتراک صدا پشتیبانی میکند). باتری چپ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"متصل (از اشتراک صدا پشتیبانی میکند). باتری راست: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"متصل (از اشتراک صدا پشتیبانی میکند)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"فعال (فقط رسانه)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"از اشتراک صدا پشتیبانی میکند"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"فعال (فقط رسانه)، فقط چپ"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"فعال (فقط رسانه)، فقط راست"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"فعال (فقط رسانه)، چپ و راست"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"پردازش سختافزاری سریع"</string>
<string name="media_category" msgid="8122076702526144053">"رسانه"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"نظارت"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"حالت شدید فعال شد"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"چشمک زدن صفحه هنگام انجام عملیات طولانی توسط برنامهها در رشته اصلی"</string>
<string name="pointer_location" msgid="7516929526199520173">"محل اشارهگر"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"اجرای وبنما"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"تنظیم اجرای وبنما"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"این انتخاب دیگر معتبر نیست. دوباره امتحان کنید."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"حالت رنگ عکس"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"استفاده از sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"غیر فعال"</string>
diff --git a/packages/SettingsLib/res/values-fi/arrays.xml b/packages/SettingsLib/res/values-fi/arrays.xml
index a10dfbe..9779c6a 100644
--- a/packages/SettingsLib/res/values-fi/arrays.xml
+++ b/packages/SettingsLib/res/values-fi/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"Vain laitteen näyttö (oletus)"</item>
+ <item msgid="9161645858025071955">"Ulkoinen näyttö"</item>
+ <item msgid="23651860565814477">"Viimeisin tilapalkin kosketus"</item>
+ <item msgid="7521112827893653392">"Kohdistusperustainen"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"Näytä ilmoitusalue vain laitteen näytöllä"</item>
+ <item msgid="1955398604822147783">"Näytä ilmoitusalue yhdellä ulkoisella näytöllä"</item>
+ <item msgid="391477482416751568">"Näytä ilmoitusalue näytöllä, jolla tilapalkkiin on viimeksi reagoitu"</item>
+ <item msgid="1746820128097981528">"Näytä ilmoitusalue viimeksi kohdistetulla näytöllä"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index b59aa30..d222882 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Ympäristön päivittäminen epäonnistui"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktiivinen (vain media). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> virtaa."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktiivinen (vain media). V: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, O: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> virtaa."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Yhdistetty (tukee audionjakoa). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> virtaa."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Yhdistetty (tukee audionjakoa). V: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> virtaa, O: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> virtaa."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Yhdistetty (tukee audionjakoa). Vasen: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> virtaa."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Yhdistetty (tukee audionjakoa). Oikea: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> virtaa."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Yhdistetty (tukee audionjakoa)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Aktiivinen (vain media)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Tukee audionjakoa"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Aktiivinen (vain media), vain vasen"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Aktiivinen (vain media), vain oikea"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Aktiivinen (vain media), vasen ja oikea"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Laitteistokiihdytetty hahmonnus"</string>
<string name="media_category" msgid="8122076702526144053">"Media"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Valvonta"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Tiukka tila käytössä"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Vilkuta näyttöä sovellusten tehdessä pitkiä toimia"</string>
<string name="pointer_location" msgid="7516929526199520173">"Osoittimen sijainti"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView-käyttöönotto"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Määritä WebView-käyttöönotto"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Tämä valinta ei ole enää saatavilla. Yritä uudestaan."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Kuvien värit"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Ota sRGB käyttöön"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Poistettu käytöstä"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/arrays.xml b/packages/SettingsLib/res/values-fr-rCA/arrays.xml
index 9eec65d..f5be655 100644
--- a/packages/SettingsLib/res/values-fr-rCA/arrays.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"Écran de l\'appareil seulement (par défaut)"</item>
+ <item msgid="9161645858025071955">"Écran externe"</item>
+ <item msgid="23651860565814477">"Dernière barre d\'état tactile"</item>
+ <item msgid="7521112827893653392">"Affichage mis en évidence"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"Afficher le volet sur l\'écran de l\'appareil seulement"</item>
+ <item msgid="1955398604822147783">"Afficher le volet sur un seul écran externe"</item>
+ <item msgid="391477482416751568">"Afficher le volet sur l\'écran avec lequel la barre d\'état a interagi en dernier"</item>
+ <item msgid="1746820128097981528">"Afficher le volet sur le dernier affichage mis en évidence"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 99ba8b0..b03e6cb 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Impossible de mettre à jour les sons de l\'environnement"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Actif (contenu multimédia uniquement). Pile à <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Actif (contenu multimédia uniquement). G. : pile à <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, D. : pile à <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Connecté (prise en charge du partage audio). Pile à <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Connecté (prise en charge du partage audio). G. : pile à <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, D. : pile à <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Connecté (prise en charge du partage audio). Gauche : pile à <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Connecté (prise en charge du partage audio). Droite : pile à <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Connecté (prise en charge du partage audio)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Actif (contenu multimédia uniquement)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Prise en charge du partage audio"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Actif (contenu multimédia uniquement), côté gauche seulement"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Actif (contenu multimédia uniquement), côté droit seulement"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Actif (contenu multimédia uniquement), côtés gauche et droit"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Accélération matérielle"</string>
<string name="media_category" msgid="8122076702526144053">"Médias"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Surveillance"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Mode Strict activé"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Afficher un cadre rouge si le fil principal reste occupé"</string>
<string name="pointer_location" msgid="7516929526199520173">"Emplacement du curseur"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"Mise en œuvre WebView"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Définir la mise en œuvre WebView"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Ce choix n\'est plus valide. Réessayez."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Mode couleur des images"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Utiliser sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Désactivé"</string>
diff --git a/packages/SettingsLib/res/values-fr/arrays.xml b/packages/SettingsLib/res/values-fr/arrays.xml
index 3787509..3cf68b2 100644
--- a/packages/SettingsLib/res/values-fr/arrays.xml
+++ b/packages/SettingsLib/res/values-fr/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"Écran de l\'appareil uniquement (par défaut)"</item>
+ <item msgid="9161645858025071955">"Écran externe"</item>
+ <item msgid="23651860565814477">"Dernière interaction avec la barre d\'état"</item>
+ <item msgid="7521112827893653392">"Basé sur la sélection"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"Afficher le volet sur l\'écran de l\'appareil uniquement"</item>
+ <item msgid="1955398604822147783">"Afficher le volet sur un seul écran externe"</item>
+ <item msgid="391477482416751568">"Afficher le volet sur l\'écran avec lequel la barre d\'état a été utilisée en dernier lieu"</item>
+ <item msgid="1746820128097981528">"Afficher le volet sur le dernier écran avec lequel l\'utilisateur a interagi"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index ba77d87..4440126 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Impossible de mettre à jour le mode Sons environnants"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Actif (multimédia uniquement). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batterie."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Actif (multimédia uniquement). Gauche : <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> de batterie, droit : <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> de batterie."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Connecté (compatible avec le partage audio). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batterie."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Connecté (compatible avec le partage audio). Gauche : <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> de batterie, droit : <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> de batterie."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Connecté (compatible avec le partage audio). Gauche : <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batterie."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Connecté (compatible avec le partage audio). Droit : <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batterie."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Connecté (compatible avec le partage audio)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Activé (multimédia uniquement)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Compatible avec le partage audio"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Activé (multimédia uniquement), gauche uniquement"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Activé (multimédia uniquement), droit uniquement"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Activé (multimédia uniquement), gauche et droit"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Rendu accéléré par le matériel"</string>
<string name="media_category" msgid="8122076702526144053">"Multimédia"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Suivi"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Mode Strict activé"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Faire clignoter l\'écran si le thread principal reste occupé"</string>
<string name="pointer_location" msgid="7516929526199520173">"Emplacement du curseur"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"Implémentation WebView"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Définir la mise en œuvre WebView"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Ce choix n\'est plus valide. Réessayez."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Mode de couleur des images"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Utiliser sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Désactivé"</string>
diff --git a/packages/SettingsLib/res/values-gl/arrays.xml b/packages/SettingsLib/res/values-gl/arrays.xml
index 9307ba7..76441f9 100644
--- a/packages/SettingsLib/res/values-gl/arrays.xml
+++ b/packages/SettingsLib/res/values-gl/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"Só pantalla do dispositivo (opción predeterminada)"</item>
+ <item msgid="9161645858025071955">"Pantalla externa"</item>
+ <item msgid="23651860565814477">"Último toque na barra de estado"</item>
+ <item msgid="7521112827893653392">"En función do enfoque"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"Mostrar panel despregable só na pantalla do dispositivo"</item>
+ <item msgid="1955398604822147783">"Mostrar panel despregable nunha única pantalla externa"</item>
+ <item msgid="391477482416751568">"Mostrar panel despregable na pantalla na que tivo lugar a última interacción coa barra de estado"</item>
+ <item msgid="1746820128097981528">"Mostrar panel despregable na última pantalla enfocada"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"pantalla_predeterminada"</item>
+ <item msgid="774789415968826925">"calquera_pantalla_externa"</item>
+ <item msgid="7880769915418638436">"último_toque_barra_estado"</item>
+ <item msgid="4313165186636015195">"pantalla_enfocada"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index 3d5a9bd..536b918 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Non se puido actualizar o ambiente"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Activo (só contido multimedia). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Activo (só contido multimedia). Esquerdo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> de batería. Dereito: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> de batería."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Conectado (compatible con audio compartido). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Conectado (compatible con audio compartido). Esquerdo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> de batería. Dereito: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> de batería."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Conectado (compatible con audio compartido). Esquerdo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Conectado (compatible con audio compartido). Dereito: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Conectado (compatible con audio compartido)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Activo (só contido multimedia)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Compatible con audio compartido"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Activo (só contido multimedia), só esquerdo"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Activo (só contido multimedia), só dereito"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Activo (só contido multimedia), esquerdo e dereito"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Procesamento acelerado mediante hardware"</string>
<string name="media_category" msgid="8122076702526144053">"Multimedia"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Supervisión"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Modo estrito activado"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"A pantalla ilumínase se as aplicacións tardan moito no proceso principal"</string>
<string name="pointer_location" msgid="7516929526199520173">"Localización do punteiro"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"Implementación de WebView"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Definir implementación de WebView"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Esta opción xa non é válida. Téntao de novo."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Modo de cor da imaxe"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Utiliza sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Desactivado"</string>
diff --git a/packages/SettingsLib/res/values-gu/arrays.xml b/packages/SettingsLib/res/values-gu/arrays.xml
index 6026663b..8d9ef2b 100644
--- a/packages/SettingsLib/res/values-gu/arrays.xml
+++ b/packages/SettingsLib/res/values-gu/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"માત્ર ડિવાઇસનું ડિસ્પ્લે (ડિફૉલ્ટ)"</item>
+ <item msgid="9161645858025071955">"બાહ્ય ડિસ્પ્લે"</item>
+ <item msgid="23651860565814477">"નવીનતમ સ્ટેટસ બાર ટચ"</item>
+ <item msgid="7521112827893653392">"ફોકસ-આધારિત"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"માત્ર ડિવાઇસના ડિસ્પ્લે પર શેડ બતાવો"</item>
+ <item msgid="1955398604822147783">"માત્ર એક જ બાહ્ય ડિસ્પ્લે પર શેડ બતાવો"</item>
+ <item msgid="391477482416751568">"તે ડિસ્પ્લે પર શેડ બતાવો જેની સાથે તેના સ્ટેટસ બારે છેલ્લે ક્રિયાપ્રતિક્રિયા કરી હતી"</item>
+ <item msgid="1746820128097981528">"છેલ્લે ફોકસ કરેલા ડિસ્પ્લે પર શેડ બતાવો"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index 57ecad8..1b4bad3 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"આસપાસના અવાજો અપડેટ કરી શક્યા નથી"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"સક્રિય (માત્ર મીડિયા માટે). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> બૅટરી."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"સક્રિય (માત્ર મીડિયા માટે). ડાબી બાજુ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, જમણી બાજુ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> બૅટરી."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"કનેક્ટેડ (ઑડિયો શેરિંગને સપોર્ટ કરે છે). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> બૅટરી."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"કનેક્ટેડ (ઑડિયો શેરિંગને સપોર્ટ કરે છે). ડાબી બાજુ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, જમણી બાજુ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> બૅટરી."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"કનેક્ટેડ (ઑડિયો શેરિંગને સપોર્ટ કરે છે). ડાબી બાજુ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> બૅટરી."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"કનેક્ટેડ (ઑડિયો શેરિંગને સપોર્ટ કરે છે). જમણી બાજુ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> બૅટરી."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"કનેક્ટેડ (ઑડિયો શેરિંગને સપોર્ટ કરે છે)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"સક્રિય છે (માત્ર મીડિયા માટે)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"ઑડિયો શેરિંગને સપોર્ટ કરે છે"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"સક્રિય છે (માત્ર મીડિયા માટે), માત્ર ડાબી બાજુ"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"સક્રિય છે (માત્ર મીડિયા માટે), માત્ર જમણી બાજુ"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"સક્રિય છે (માત્ર મીડિયા માટે), ડાબી અને જમણી બાજુ"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"હાર્ડવેર પ્રવેગક રેન્ડરિંગ"</string>
<string name="media_category" msgid="8122076702526144053">"મીડિયા"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"નિરિક્ષણ કરી રહ્યું છે"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"સ્ટ્રિક્ટ મોડ ચાલુ કરેલો છે"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"જ્યારે મુખ્ય થ્રેડ પર ઍપ લાંબી કામગીરીઓ કરે ત્યારે સ્ક્રીનને ફ્લેશ કરો"</string>
<string name="pointer_location" msgid="7516929526199520173">"પૉઇન્ટર લોકેશન"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView અમલીકરણ"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"WebView અમલીકરણ સેટ કરો"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"આ વિકલ્પ હવે માન્ય નથી. ફરી પ્રયાસ કરો."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"ચિત્ર રંગ મોડ"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"sRGB નો ઉપયોગ કરો"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"બંધ"</string>
diff --git a/packages/SettingsLib/res/values-hi/arrays.xml b/packages/SettingsLib/res/values-hi/arrays.xml
index 67de2ae..9c138d2 100644
--- a/packages/SettingsLib/res/values-hi/arrays.xml
+++ b/packages/SettingsLib/res/values-hi/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"सिर्फ़ डिवाइस का डिसप्ले (डिफ़ॉल्ट)"</item>
+ <item msgid="9161645858025071955">"बाहरी डिसप्ले पर"</item>
+ <item msgid="23651860565814477">"हाल ही में स्टेटस बार को टच किया गया"</item>
+ <item msgid="7521112827893653392">"फ़ोकस के हिसाब से"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"सिर्फ़ डिवाइस के डिसप्ले पर शेड दिखाएं"</item>
+ <item msgid="1955398604822147783">"किसी एक बाहरी डिसप्ले पर शेड दिखाएं"</item>
+ <item msgid="391477482416751568">"उस डिसप्ले पर शेड दिखाएं जिसकी स्टेटस बार के साथ पिछली बार इंटरैक्शन किया गया था"</item>
+ <item msgid="1746820128097981528">"उस डिसप्ले पर शेड दिखाएं जिस पर आखिरी बार फ़ोकस किया गया था"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index c1f4fe2..55d425f 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"वॉल्यूम को मैनेज करने की सेटिंग नहीं बदली जा सकी"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"चालू है (सिर्फ़ मीडिया के लिए). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> बैटरी."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"चालू है (सिर्फ़ मीडिया के लिए). बायां हेडसेट: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, दायां हेडसेट: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> बैटरी."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"कनेक्ट हो गया (ऑडियो शेयर करने की सुविधा काम करती है). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> बैटरी."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"कनेक्ट हो गया (ऑडियो शेयर करने की सुविधा काम करती है). बायां हेडसेट: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, दायां हेडसेट: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> बैटरी."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"कनेक्ट हो गया (ऑडियो शेयर करने की सुविधा काम करती है). बायां हेडसेट: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> बैटरी."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"कनेक्ट हो गया (ऑडियो शेयर करने की सुविधा काम करती है). दायां हेडसेट: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> बैटरी."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"कनेक्ट है (ऑडियो शेयर करने की सुविधा काम करती है)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"चालू है (सिर्फ़ मीडिया के लिए)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"ऑडियो शेयर करने की सुविधा काम करती है"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"चालू है (सिर्फ़ मीडिया के लिए), सिर्फ़ बाएं कान की मशीन"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"चालू है (सिर्फ़ मीडिया के लिए), सिर्फ़ दाएं कान की मशीन"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"चालू है (सिर्फ़ मीडिया के लिए), बाएं और दाएं कान की मशीन"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"हार्डवेयर ऐक्सेलरेटेड रेंडरिंग"</string>
<string name="media_category" msgid="8122076702526144053">"मीडिया"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"निगरानी"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"स्ट्रिक्ट मोड चालू रखें"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"थ्रेड पर लंबा प्रोसेस होने पर स्क्रीन फ़्लैश करें"</string>
<string name="pointer_location" msgid="7516929526199520173">"पॉइंटर की जगह"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"वेबव्यू लागू करें"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"वेबव्यू सेट करें"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"यह चुनाव अब मान्य नहीं है. दोबारा कोशिश करें."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"चित्र रंग मोड"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"sRGB का उपयोग करें"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"बंद"</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 131195e..97f2df6 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Ažuriranje okruženja nije uspjelo"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktivno (samo medijski sadržaji). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterije."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktivno (samo medijski sadržaji), L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, D: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> baterije."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Povezano (podržava zajedničko slušanje). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterije."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Povezano (podržava zajedničko slušanje), L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, D: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> baterije."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Povezano (podržava zajedničko slušanje). Lijeva strana: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterije"</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Povezano (podržava zajedničko slušanje). Desna strana: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterije."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Povezano (podržava zajedničko slušanje)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Aktivno (samo medijski sadržaji)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Podržava zajedničko slušanje"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Aktivno (samo medijski sadržaji), samo lijeva"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Aktivno (samo medijski sadržaji), samo desna"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Aktivno (samo medijski sadržaji), lijeva i desna"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Hardverski ubrzano renderiranje"</string>
<string name="media_category" msgid="8122076702526144053">"Mediji"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Nadzor"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Omogućen strogi način"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Zaslon bljeska kada operacije aplikacija u glavnoj niti dugo traju"</string>
<string name="pointer_location" msgid="7516929526199520173">"Mjesto pokazivača"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"Implementacija WebViewa"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Postavi implementaciju WebViewa"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Taj izbor više nije važeći. Pokušajte ponovo."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Način boje slike"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Upotrijebi sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Onemogućeno"</string>
diff --git a/packages/SettingsLib/res/values-hu/arrays.xml b/packages/SettingsLib/res/values-hu/arrays.xml
index d8d42f9..677b821 100644
--- a/packages/SettingsLib/res/values-hu/arrays.xml
+++ b/packages/SettingsLib/res/values-hu/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"Csak az eszköz kijelzője (alapértelmezett)"</item>
+ <item msgid="9161645858025071955">"Külső kijelző"</item>
+ <item msgid="23651860565814477">"Az állapotsor legutóbbi érintése"</item>
+ <item msgid="7521112827893653392">"Fókusz alapján"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"Felület megjelenítése csak az eszköz kijelzőjén"</item>
+ <item msgid="1955398604822147783">"Felület megjelenítése egyetlen külső kijelzőn"</item>
+ <item msgid="391477482416751568">"Felület megjelenítése azon a kijelzőn, amelyen utoljára végeztek műveletet az állapotsorral"</item>
+ <item msgid="1746820128097981528">"Felület megjelenítése az utoljára fókuszban lévő kijelzőn"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index fa32155..5e97cff 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Nem sikerült módosítani a környezetet"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktív (csak médiatartalom lejátszása esetén). Akkumulátor töltöttségi szintje: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktív (csak médiatartalom lejátszása esetén). Akkumulátorok töltöttségi szintje: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> (bal) és <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> (jobb)."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Csatlakoztatva (támogatja a hang megosztását). Akkumulátor töltöttségi szintje: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Csatlakoztatva (támogatja a hang megosztását). Akkumulátorok töltöttségi szintje: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> (bal) és <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> (jobb)."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Csatlakoztatva (támogatja a hang megosztását). Akkumulátor töltöttségi szintje: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> (bal)."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Csatlakoztatva (támogatja a hang megosztását). Akkumulátor töltöttségi szintje: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> (jobb)."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Csatlakoztatva (támogatja a hang megosztását)."</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Aktív (csak médiatartalom lejátszása)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Támogatja a hang megosztását"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Aktív (csak médiatartalom lejátszása), csak a bal"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Aktív (csak médiatartalom lejátszása), csak a jobb"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Aktív (csak médiatartalom lejátszása), bal és jobb"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Hardveres gyorsítású megjelenítés"</string>
<string name="media_category" msgid="8122076702526144053">"Média"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Figyelés"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Szigorú mód engedélyezve"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Képernyővillogás a fő szál hosszú műveleteinél"</string>
<string name="pointer_location" msgid="7516929526199520173">"Mutató helye"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView-megvalósítás"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"WebView-megvalósítás beállítása"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Ez a választás már nem érvényes. Próbálkozzon újra."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Kép színe mód"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"sRGB használata"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Letiltva"</string>
diff --git a/packages/SettingsLib/res/values-hy/arrays.xml b/packages/SettingsLib/res/values-hy/arrays.xml
index b2133fb..f71d1fc 100644
--- a/packages/SettingsLib/res/values-hy/arrays.xml
+++ b/packages/SettingsLib/res/values-hy/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"Միայն սարքի էկրանը (կանխադրված)"</item>
+ <item msgid="9161645858025071955">"Արտաքին էկրան"</item>
+ <item msgid="23651860565814477">"Կարգավիճակի գոտու հետ վերջին փոխազդումը"</item>
+ <item msgid="7521112827893653392">"Ֆոկուսի հիման վրա"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"Ցույց տալ երանգը միայն սարքի էկրանին"</item>
+ <item msgid="1955398604822147783">"Ցույց տալ երանգը մեկ արտաքին էկրանին"</item>
+ <item msgid="391477482416751568">"Ցույց տալ երանգն էկրանին, որի կարգավիճակի գոտու հետ վերջերս օգտատերը փոխազդել է"</item>
+ <item msgid="1746820128097981528">"Ցույց տալ երանգը վերջին ֆոկուսավորված էկրանին"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index fa87813..d342717 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Չհաջողվեց թարմացնել շրջակայքի կարգավիճակը"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Ակտիվ է (միայն մեդիա)։ Մարտկոցի լիցքը՝ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>։"</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Ակտիվ է (միայն մեդիա)։ Ձախ ականջակալի լիցքը՝ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, աջ ականջակալի լիցքը՝ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>։"</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Միացված է (աջակցում է աուդիոյի փոխանցում)։ Մարտկոցի լիցքը՝ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>։"</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Միացված է (աջակցում է աուդիոյի փոխանցում)։ Ձախ ականջակալի լիցքը՝ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, աջ ականջակալի լիցքը՝ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>։"</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Միացված է (աջակցում է աուդիոյի փոխանցում)։ Ձախ ականջակալի լիցքը՝ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>։"</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Միացված է (աջակցում է աուդիոյի փոխանցում)։ Աջ ականջակալի լիցքը՝ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>։"</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Միացված է (աջակցում է աուդիոյի փոխանցում)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Ակտիվ է (միայն մեդիա)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Աջակցում է աուդիոյի փոխանցում"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Ակտիվ է (միայն մեդիա), միայն ձախ"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Ակտիվ է (միայն մեդիա), միայն աջ"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Ակտիվ է (միայն մեդիա), աջ և ձախ"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Սարքաշարի արագացված նյութավորում"</string>
<string name="media_category" msgid="8122076702526144053">"Մեդիա"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Մշտադիտարկում"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Խիստ ռեժիմն ակտիվացված է"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Լուսավորել էկրանը` ծրագրի գլխավոր շղթայի վրա երկար աշխատելիս"</string>
<string name="pointer_location" msgid="7516929526199520173">"Նշորդի տեղադրությունը"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView ծառայություն"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Ընտրեք WebView-ի իրականացումը"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Այս ընտրանքն այլևս վավեր չէ: Փորձեք նորից:"</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Նկարի գունային ռեժիմ"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Օգտագործել sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Կասեցված է"</string>
diff --git a/packages/SettingsLib/res/values-in/arrays.xml b/packages/SettingsLib/res/values-in/arrays.xml
index fa2fa9e..a4bb2f4 100644
--- a/packages/SettingsLib/res/values-in/arrays.xml
+++ b/packages/SettingsLib/res/values-in/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"Hanya layar perangkat (Default)"</item>
+ <item msgid="9161645858025071955">"Layar eksternal"</item>
+ <item msgid="23651860565814477">"Sentuhan status bar terbaru"</item>
+ <item msgid="7521112827893653392">"Berbasis fokus"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"Tampilkan shade hanya di layar perangkat"</item>
+ <item msgid="1955398604822147783">"Tampilkan menu di satu layar eksternal"</item>
+ <item msgid="391477482416751568">"Tampilkan menu di layar yang terakhir kali berinteraksi dengan status bar-nya"</item>
+ <item msgid="1746820128097981528">"Tampilkan menu di layar yang terakhir difokuskan"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 1ff4b29..649ee0bb 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Tidak dapat memperbarui suara sekitar"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktif (hanya media). Baterai <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktif (hanya media). Baterai L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Terhubung (mendukung berbagi audio). Baterai <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Terhubung (mendukung berbagi audio). Baterai L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Terhubung (mendukung berbagi audio). Kiri: Baterai <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Terhubung (mendukung berbagi audio). Kanan: Baterai <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Terhubung (mendukung berbagi audio)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Aktif (hanya media)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Mendukung berbagi audio"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Aktif (hanya media), hanya kiri"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Aktif (hanya media), hanya kanan"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Aktif (hanya media), kiri dan kanan"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Render yang dipercepat hardware"</string>
<string name="media_category" msgid="8122076702526144053">"Media"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Pemantauan"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Mode ketat diaktifkan"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Buat layar berkedip saat aplikasi berlama-lama menjalankan operasi di thread utama"</string>
<string name="pointer_location" msgid="7516929526199520173">"Lokasi kursor"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"Penerapan WebView"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Setel penerapan WebView"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Pilihan ini tidak valid lagi. Coba lagi."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Mode warna gambar"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Gunakan sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Dinonaktifkan"</string>
@@ -634,7 +662,7 @@
<string name="user_add_profile_item_title" msgid="3111051717414643029">"Profil dibatasi"</string>
<string name="user_add_user_title" msgid="5457079143694924885">"Tambahkan pengguna baru?"</string>
<string name="user_add_user_message_long" msgid="1527434966294733380">"Anda dapat menggunakan perangkat ini bersama orang lain dengan membuat pengguna tambahan. Setiap pengguna memiliki ruang sendiri, yang dapat disesuaikan dengan aplikasi, wallpaper, dan lainnya. Pengguna juga dapat menyesuaikan setelan perangkat seperti Wi-Fi yang dapat memengaruhi semua pengguna lain.\n\nSaat Anda menambahkan pengguna baru, pengguna tersebut perlu menyiapkan ruangnya.\n\nPengguna mana pun dapat mengupdate aplikasi untuk semua pengguna lainnya. Layanan dan setelan aksesibilitas mungkin tidak ditransfer ke pengguna baru."</string>
- <string name="user_add_user_message_short" msgid="3295959985795716166">"Saat Anda menambahkan pengguna baru, orang tersebut harus menyiapkan ruangnya sendiri.\n\nPengguna mana pun dapat meng-update aplikasi untuk semua pengguna lain."</string>
+ <string name="user_add_user_message_short" msgid="3295959985795716166">"Saat Anda menambahkan pengguna baru, orang tersebut harus menyiapkan ruangnya sendiri.\n\nPengguna mana pun dapat mengupdate aplikasi untuk semua pengguna lain."</string>
<string name="user_grant_admin_title" msgid="5157031020083343984">"Jadikan pengguna ini sebagai admin?"</string>
<string name="user_grant_admin_message" msgid="1673791931033486709">"Admin memiliki hak istimewa khusus yang tidak dimiliki pengguna lain. Admin dapat mengelola semua pengguna, mengupdate atau mereset perangkat ini, mengubah setelan, melihat semua aplikasi terinstal, dan memberi atau mencabut hak istimewa admin untuk pengguna lain."</string>
<string name="user_grant_admin_button" msgid="5441486731331725756">"Jadikan admin"</string>
diff --git a/packages/SettingsLib/res/values-is/arrays.xml b/packages/SettingsLib/res/values-is/arrays.xml
index 851a7a49..27846cc 100644
--- a/packages/SettingsLib/res/values-is/arrays.xml
+++ b/packages/SettingsLib/res/values-is/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"Aðeins skjár tækis (sjálfgefið)"</item>
+ <item msgid="9161645858025071955">"Ytri skjár"</item>
+ <item msgid="23651860565814477">"Síðasta snerting stöðustiku"</item>
+ <item msgid="7521112827893653392">"Byggt á fókus"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"Aðeins skyggja skjá tækis"</item>
+ <item msgid="1955398604822147783">"Skyggja stakan ytri skjá"</item>
+ <item msgid="391477482416751568">"Skyggja skjá þar sem stöðustika var síðast notuð"</item>
+ <item msgid="1746820128097981528">"Skyggja síðasta skjá í fókus"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index 804ea63..d361157 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Ekki var hægt að uppfæra umhverfi"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Virkt (eingöngu margmiðlunarefni). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> rafhlöðuhleðsla."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Virkt (eingöngu margmiðlunarefni), V: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, H: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> rafhlöðuhleðsla."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Tengt (styður hljóðdeilingu), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> rafhlöðuhleðsla."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Tengt (styður hljóðdeilingu), V: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, H: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> rafhlöðuhleðsla."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Tengt (styður hljóðdeilingu). Vinstri: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> rafhlöðuhleðsla."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Tengt (styður hljóðdeilingu). Hægri: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> rafhlöðuhleðsla."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Tengt (styður hljóðdeilingu)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Virkt (eingöngu margmiðlunarefni)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Styður hljóðdeilingu"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Virkt (eingöngu margmiðlunarefni), eingöngu vinstri"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Virkt (eingöngu margmiðlunarefni), eingöngu hægri"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Virkt (eingöngu margmiðlunarefni), vinstri og hægri"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Myndþýðing með vélbúnaðarhröðun"</string>
<string name="media_category" msgid="8122076702526144053">"Margmiðlun"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Eftirlit"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Kveikt á strangri stillingu"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Blikka skjá ef forrit gera tímafreka hluti á aðalþræði"</string>
<string name="pointer_location" msgid="7516929526199520173">"Staðsetning bendils"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"Innleiðing WebView"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Stilla innleiðingu WebView"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Þetta val er ekki lengur gilt. Reyndu aftur."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Litastilling mynda"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Nota sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Óvirkt"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 09ec5cc..98e415b 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Impossibile aggiornare audio ambientale"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Attivo (solo contenuti multimediali). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> di batteria."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Attivo (solo contenuti multimediali). S: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> di batteria. D: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> di batteria."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Connesso (supporta la condivisione audio). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> di batteria."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Connesso (supporta la condivisione audio). S: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> di batteria. D: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> di batteria."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Connesso (supporta la condivisione audio). Sinistro: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> di batteria."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Connesso (supporta la condivisione audio). Destro: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> di batteria."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Connesso (supporta la condivisione audio)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Attivo (solo contenuti multimediali)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Supporta la condivisione audio"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Attivo (solo contenuti multimediali), solo sinistro"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Attivo (solo contenuti multimediali), solo destro"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Attivo (solo contenuti multimediali), sinistro e destro"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Rendering con accelerazione hardware"</string>
<string name="media_category" msgid="8122076702526144053">"Contenuti multimediali"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Monitoraggio"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Attiva StrictMode"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Fai lampeggiare lo schermo per operazioni lunghe sul thread principale"</string>
<string name="pointer_location" msgid="7516929526199520173">"Posizione puntatore"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"Implementazione di WebView"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Imposta l\'implementazione di WebView"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"La selezione non è più valida. Riprova."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Modalità colori immagini"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Usa sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Disattivato"</string>
diff --git a/packages/SettingsLib/res/values-iw/arrays.xml b/packages/SettingsLib/res/values-iw/arrays.xml
index 9d176c0..744e502 100644
--- a/packages/SettingsLib/res/values-iw/arrays.xml
+++ b/packages/SettingsLib/res/values-iw/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"מסך המכשיר בלבד (ברירת המחדל)"</item>
+ <item msgid="9161645858025071955">"מסך חיצוני"</item>
+ <item msgid="23651860565814477">"אינטראקציה אחרונה עם שורת הסטטוס"</item>
+ <item msgid="7521112827893653392">"לפי התמקדות"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"הצגת הצללה במסך המכשיר בלבד"</item>
+ <item msgid="1955398604822147783">"הצגת לוח ההתראות במסך חיצוני אחד"</item>
+ <item msgid="391477482416751568">"הצגת לוח ההתראות במסך שבו הייתה האינטראקציה האחרונה עם שורת הסטטוס"</item>
+ <item msgid="1746820128097981528">"הצגת לוח ההתראות במסך האחרון שבו המשתמש התמקד"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 361dd18..b341c4d 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"לא ניתן לעדכן את עוצמת הרעשים בסביבה"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"פעיל (מדיה בלבד). סוללה: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"פעיל (מדיה בלבד). סוללה בצד שמאל: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, סוללה בצד ימין: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"מחובר (תמיכה בשיתוף אודיו). סוללה: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"מחובר (תמיכה בשיתוף אודיו). סוללה בצד שמאל: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, סוללה בצד ימין: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"מחובר (תמיכה בשיתוף אודיו). סוללה בצד שמאל: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"מחובר (תמיכה בשיתוף אודיו). סוללה בצד ימין: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"מחובר (תמיכה בשיתוף אודיו)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"פעיל (מדיה בלבד)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"תמיכה בשיתוף אודיו"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"פעיל (מדיה בלבד), שמאל בלבד"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"פעיל (מדיה בלבד), ימין בלבד"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"פעיל (מדיה בלבד), שמאל וימין"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"עיבוד מואץ של חומרה"</string>
<string name="media_category" msgid="8122076702526144053">"מדיה"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"מעקב"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"מצב קפדני מופעל"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"המסך יהבהב כשאפליקציות יבצעו פעולות ארוכות ב-thread הראשי"</string>
<string name="pointer_location" msgid="7516929526199520173">"מיקום מצביע"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"יישום WebView"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"הגדרת יישום WebView"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"אפשרות זו כבר אינה תקפה. אפשר לנסות שוב."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"מצב צבע התמונה"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"שימוש ב-sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"מושבת"</string>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index 1170cd1..2e36d6a 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"周囲の音を更新できませんでした"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"有効(メディアのみ)。バッテリー残量 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>。"</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"有効(メディアのみ)。左: バッテリー残量 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>、右: バッテリー残量 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>。"</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"接続済み(音声の共有をサポート)。バッテリー残量 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>。"</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"接続済み(音声の共有をサポート)。左: バッテリー残量 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>、右: バッテリー残量 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>。"</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"接続済み(音声の共有をサポート)。左: バッテリー残量 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>。"</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"接続済み(音声の共有をサポート)。右: バッテリー残量 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>。"</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"接続済み(音声の共有をサポート)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"有効(メディアのみ)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"音声の共有をサポートしています"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"有効(メディアのみ)、左のみ"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"有効(メディアのみ)、右のみ"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"有効(メディアのみ)、左右"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"ハードウェアアクセラレーテッドレンダリング"</string>
<string name="media_category" msgid="8122076702526144053">"メディア"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"モニタリング"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"厳格モードを有効にする"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"メインスレッドの処理が長引く場合は画面を点滅させる"</string>
<string name="pointer_location" msgid="7516929526199520173">"ポインタの位置"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView の実装"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"WebView の実装の設定"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"この選択は無効になりました。もう一度お試しください。"</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"画像の色モード"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"sRGBを使用"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"無効"</string>
diff --git a/packages/SettingsLib/res/values-ka/arrays.xml b/packages/SettingsLib/res/values-ka/arrays.xml
index 8ee3338..3ecf9d8 100644
--- a/packages/SettingsLib/res/values-ka/arrays.xml
+++ b/packages/SettingsLib/res/values-ka/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"მხოლოდ მოწყობილობის ეკრანი (ნაგულისხმევი)"</item>
+ <item msgid="9161645858025071955">"გარე ეკრანი"</item>
+ <item msgid="23651860565814477">"სტატუსის ზოლის ბოლო შეხება"</item>
+ <item msgid="7521112827893653392">"ფოკუსის მიხედვით"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"ჩრდილის ჩვენება მხოლოდ მოწყობილობის ეკრანზე"</item>
+ <item msgid="1955398604822147783">"ჩრდილის ჩვენება ერთ გარე ეკრანზე"</item>
+ <item msgid="391477482416751568">"ეკრანზე ჩრდილის ჩვენება, რომლის სტატუსის ზოლთანაც მოხდა ბოლო ინტერაქცია"</item>
+ <item msgid="1746820128097981528">"ჩრდილის ჩვენება ბოლო ფოკუსირებულ ეკრანზე"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"ფოკუსირებული_ეკრანი"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index 6503795..e627b79 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"გარემოცვის განახლება ვერ მოხერხდა"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"აქტიური (მხოლოდ მედია). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>%% ბატარეა."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"აქტიური (მხოლოდ მედია), მარცხენა: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, მარჯვენა:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> ბატარეა."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"დაკავშირებული (აუდიოს გაზიარება მხარდაჭერილია). ბატარეა <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"დაკავშირებული (აუდიოს გაზიარება მხარდაჭერილია). მარცხენა: ბატარეა <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, მარჯვენა: ბატარეა <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>"</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"დაკავშირებული (აუდიოს გაზიარება მხარდაჭერილია). მარცხენა: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ბატარეა."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"დაკავშირებული (აუდიოს გაზიარება მხარდაჭერილია). მარჯვენა: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ბატარეა."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"დაკავშირებული (აუდიოს გაზიარება მხარდაჭერილია)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"აქტიური (მხოლოდ მედია)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"აუდიოს გაზიარება მხარდაჭერილია"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"აქტიური (მხოლოდ მედია), მხოლოდ მარცხენა"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"აქტიური (მხოლოდ მედია), მხოლოდ მარჯვენა"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"აქტიური (მხოლოდ მედია), მარცხენა და მარჯვენა"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"აპარატურით დაჩქარებული გამოსახულება"</string>
<string name="media_category" msgid="8122076702526144053">"მედია"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"მონიტორინგი"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"მკაცრი რეჟიმი ჩართულია"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"ეკრანის აციმციმება, როცა აპები ახორციელებენ ხანგრძლივ ოპერაციებს მთავარ ნაკადზე"</string>
<string name="pointer_location" msgid="7516929526199520173">"მაჩვენებლის მდებარეობა"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView რეალიზაცია"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"WebView რეალიზაციის დაყენება"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"თქვენი არჩევანი აღარ მოქმედებს. ცადეთ ხელახლა."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"გამოსახულების ფერების რეჟიმი"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"sRGB-ს გამოყენება"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"გამორთულია"</string>
diff --git a/packages/SettingsLib/res/values-kk/arrays.xml b/packages/SettingsLib/res/values-kk/arrays.xml
index 6aa5f2b..e2510a7 100644
--- a/packages/SettingsLib/res/values-kk/arrays.xml
+++ b/packages/SettingsLib/res/values-kk/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"Тек құрылғы дисплейі (әдепкі)"</item>
+ <item msgid="9161645858025071955">"Сыртқы дисплей"</item>
+ <item msgid="23651860565814477">"Соңғы күй жолағын түрту"</item>
+ <item msgid="7521112827893653392">"Назарға негізделген"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"Құрылғы дисплейінде ғана реңк көрсету"</item>
+ <item msgid="1955398604822147783">"Жалғыз сыртқы дисплейде көлеңкені көрсету"</item>
+ <item msgid="391477482416751568">"Күй жолағы соңғы рет қолданылған дисплейде көлеңкені көрсету"</item>
+ <item msgid="1746820128097981528">"Соңғы рет назарда болған дисплейде көлеңкені көрсету"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index 9082a56..a85e624 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Айналаны жаңарту мүмкін болмады."</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Істеп тұр (тек мультимедиа). Батарея зарядының деңгейі – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Істеп тұр (тек мультимедиа). Сол жақ: батарея зарядының деңгейі — <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>. Оң жақ: батарея зарядының деңгейі — <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Жалғанып тұр (аудио бөлісу мүмкіндігі бар). Батарея зарядының деңгейі – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Қосылды (аудио бөлісуге мүмкіндік береді). Сол жақ: батарея зарядының деңгейі — <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>. Оң жақ: батарея зарядының деңгейі — <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Қосылды (аудио бөлісуге мүмкіндік береді). Сол жақ: батарея зарядының деңгейі – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Қосылды (аудио бөлісуге мүмкіндік береді). Оң жақ: батарея зарядының деңгейі – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Жалғанды (аудио бөлісу мүмкіндігі бар)."</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Істеп тұр (тек мультимедиа)."</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Аудио бөлісуге мүмкіндік береді."</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Тек сол жақ істеп тұр (мультимедиа ғана)."</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Тек оң жақ істеп тұр (мультимедиа ғана)."</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Сол және оң жақ істеп тұр (мультимедиа ғана)."</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Бейнелеуді аппаратпен жеделдету"</string>
<string name="media_category" msgid="8122076702526144053">"Mультимeдиа"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Бақылау"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Қатаң режим қосылған"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Қолданбалар ұзақ операцияларды орындағанда экранды жыпылықтату"</string>
<string name="pointer_location" msgid="7516929526199520173">"Меңзер орны"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView қызметі"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"WebView ендіруін орнату"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Бұл таңдау енді жарамды емес. Әрекетті қайталаңыз."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Сурет түс режимі"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"sRGB пайдалану"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Өшірулі"</string>
diff --git a/packages/SettingsLib/res/values-km/arrays.xml b/packages/SettingsLib/res/values-km/arrays.xml
index e9a21e8..07e64a5 100644
--- a/packages/SettingsLib/res/values-km/arrays.xml
+++ b/packages/SettingsLib/res/values-km/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"ផ្ទាំងអេក្រង់ឧបករណ៍តែប៉ុណ្ណោះ (លំនាំដើម)"</item>
+ <item msgid="9161645858025071955">"ផ្ទាំងអេក្រង់ខាងក្រៅ"</item>
+ <item msgid="23651860565814477">"ការចុចរបារស្ថានភាពចុងក្រោយបំផុត"</item>
+ <item msgid="7521112827893653392">"ផ្អែកលើការផ្ដោត"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"បង្ហាញផ្ទាំងនៅលើផ្ទាំងអេក្រង់ឧបករណ៍តែប៉ុណ្ណោះ"</item>
+ <item msgid="1955398604822147783">"បង្ហាញផ្ទាំងនៅលើផ្ទាំងអេក្រង់ខាងក្រៅតែមួយ"</item>
+ <item msgid="391477482416751568">"បង្ហាញផ្ទាំងនៅលើផ្ទាំងអេក្រង់ដែលមានការធ្វើអន្តរកម្មចុងក្រោយលើរបារស្ថានភាពរបស់វា"</item>
+ <item msgid="1746820128097981528">"បង្ហាញផ្ទាំងនៅលើផ្ទាំងអេក្រង់ដែលបានផ្ដោតចុងក្រោយ"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index 3cc214e..d2d5893 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"មិនអាចប្ដូរមជ្ឈដ្ឋានជុំវិញបានទេ"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"សកម្ម (តែមេឌៀប៉ុណ្ណោះ)។ ថ្ម <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>។"</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"សកម្ម (តែមេឌៀប៉ុណ្ណោះ)។ ឆ្វេង៖ ថ្ម <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> ស្ដាំ៖ ថ្ម <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>។"</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"បានភ្ជាប់ (អាចប្រើការស្ដាប់សំឡេងរួមគ្នា)។ ថ្ម <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>។"</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"បានភ្ជាប់ (អាចប្រើការស្ដាប់សំឡេងរួមគ្នា)។ ឆ្វេង៖ ថ្ម <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> ស្ដាំ៖ ថ្ម <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>។"</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"បានភ្ជាប់ (អាចប្រើការស្ដាប់សំឡេងរួមគ្នា)។ ឆ្វេង៖ ថ្ម <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>។"</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"បានភ្ជាប់ (អាចប្រើការស្ដាប់សំឡេងរួមគ្នា)។ ស្ដាំ៖ ថ្ម <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>។"</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"បានភ្ជាប់ (អាចប្រើការស្ដាប់សំឡេងរួមគ្នា)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"សកម្ម (តែមេឌៀប៉ុណ្ណោះ)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"អាចប្រើការស្ដាប់សំឡេងរួមគ្នា"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"សកម្ម (តែមេឌៀប៉ុណ្ណោះ) តែខាងឆ្វេងប៉ុណ្ណោះ"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"សកម្ម (តែមេឌៀប៉ុណ្ណោះ) តែខាងស្ដាំប៉ុណ្ណោះ"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"សកម្ម (តែមេឌៀប៉ុណ្ណោះ) ឆ្វេង និងស្ដាំ"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"ការបំប្លែងដែលពន្លឿនដោយប្រើហាតវែរ"</string>
<string name="media_category" msgid="8122076702526144053">"មេឌៀ"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"តាមដាន"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"បានបើកមុខងារតឹងរ៉ឹង"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"បញ្ចេញពន្លឺអេក្រង់ពេលកម្មវិធីធ្វើប្រតិបត្តិការយូរលើសែស្រឡាយមេ"</string>
<string name="pointer_location" msgid="7516929526199520173">"ទីតាំងទ្រនិច"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"ការអនុវត្ត WebView"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"កំណត់ការប្រតិបត្តិ WebView"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"ជម្រើសនេះលែងមានសុពលភាពទៀតហើយ ព្យាយាមម្តងទៀត"</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"របៀបនៃពណ៌រូបភាព"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"ប្រើ sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"បានបិទ"</string>
diff --git a/packages/SettingsLib/res/values-kn/arrays.xml b/packages/SettingsLib/res/values-kn/arrays.xml
index dc9c7e0..de2269a 100644
--- a/packages/SettingsLib/res/values-kn/arrays.xml
+++ b/packages/SettingsLib/res/values-kn/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"ಸಾಧನದ ಡಿಸ್ಪ್ಲೇ ಮಾತ್ರ (ಡೀಫಾಲ್ಟ್)"</item>
+ <item msgid="9161645858025071955">"ಬಾಹ್ಯ ಡಿಸ್ಪ್ಲೇ"</item>
+ <item msgid="23651860565814477">"ಇತ್ತೀಚಿನ ಸ್ಥಿತಿ ಪಟ್ಟಿಯ ಸ್ಪರ್ಶ"</item>
+ <item msgid="7521112827893653392">"ಫೋಕಸ್-ಆಧಾರಿತ"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"ಸಾಧನದ ಡಿಸ್ಪ್ಲೇನಲ್ಲಿ ಮಾತ್ರ ಶೇಡ್ ತೋರಿಸಿ"</item>
+ <item msgid="1955398604822147783">"ಒಂದೇ ಬಾಹ್ಯ ಡಿಸ್ಪ್ಲೇನಲ್ಲಿ ಶೇಡ್ ಅನ್ನು ತೋರಿಸಿ"</item>
+ <item msgid="391477482416751568">"ಸ್ಥಿತಿ ಪಟ್ಟಿಯಲ್ಲಿ ಕೊನೆಯದಾಗಿ ಸಂವಹನ ನಡೆಸಿದ ಶೇಡ್ ಅನ್ನು ಡಿಸ್ಪ್ಲೇ ಮೇಲೆ ತೋರಿಸಿ"</item>
+ <item msgid="1746820128097981528">"ಕೊನೆಯ ಕೇಂದ್ರೀಕೃತ ಡಿಸ್ಪ್ಲೇನಲ್ಲಿ ಶೇಡ್ ಅನ್ನು ತೋರಿಸಿ"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index d2b2176..87f2cdf 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"ಆ್ಯಂಬಿಯೆಂಟ್ ಸ್ಥಿತಿಯನ್ನು ಅಪ್ಡೇಟ್ ಮಾಡಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"ಸಕ್ರಿಯವಾಗಿದೆ (ಮೀಡಿಯಾ ಮಾತ್ರ). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ಬ್ಯಾಟರಿ ಮಟ್ಟ."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"ಸಕ್ರಿಯವಾಗಿದೆ (ಮೀಡಿಯಾ ಮಾತ್ರ). ಎಡ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, ಬಲ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> ಬ್ಯಾಟರಿ ಮಟ್ಟ."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"ಕನೆಕ್ಟ್ ಆಗಿದೆ (ಆಡಿಯೋ ಹಂಚಿಕೊಳ್ಳುವಿಕೆಯನ್ನು ಬೆಂಬಲಿಸುತ್ತದೆ). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ಬ್ಯಾಟರಿ ಮಟ್ಟ."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"ಕನೆಕ್ಟ್ ಆಗಿದೆ (ಆಡಿಯೋ ಹಂಚಿಕೊಳ್ಳುವಿಕೆಯನ್ನು ಬೆಂಬಲಿಸುತ್ತದೆ). ಎಡ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, ಬಲ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> ಬ್ಯಾಟರಿ ಮಟ್ಟ."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"ಕನೆಕ್ಟ್ ಆಗಿದೆ (ಆಡಿಯೋ ಹಂಚಿಕೊಳ್ಳುವಿಕೆಯನ್ನು ಬೆಂಬಲಿಸುತ್ತದೆ). ಎಡ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ಬ್ಯಾಟರಿ ಮಟ್ಟ."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"ಕನೆಕ್ಟ್ ಆಗಿದೆ (ಆಡಿಯೋ ಹಂಚಿಕೊಳ್ಳುವಿಕೆಯನ್ನು ಬೆಂಬಲಿಸುತ್ತದೆ). ಬಲ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ಬ್ಯಾಟರಿ ಮಟ್ಟ."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"ಕನೆಕ್ಟ್ ಆಗಿದೆ (ಆಡಿಯೋ ಹಂಚಿಕೊಳ್ಳುವಿಕೆಯನ್ನು ಬೆಂಬಲಿಸುತ್ತದೆ)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"ಸಕ್ರಿಯವಾಗಿದೆ (ಮೀಡಿಯಾ ಮಾತ್ರ)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"ಆಡಿಯೋ ಹಂಚಿಕೊಳ್ಳುವಿಕೆಯನ್ನು ಬೆಂಬಲಿಸುತ್ತದೆ"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"ಸಕ್ರಿಯವಾಗಿದೆ (ಮೀಡಿಯಾ ಮಾತ್ರ), ಎಡ ಭಾಗದ ಮಾತ್ರ"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"ಸಕ್ರಿಯವಾಗಿದೆ (ಮೀಡಿಯಾ ಮಾತ್ರ), ಬಲ ಭಾಗದ ಮಾತ್ರ"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"ಸಕ್ರಿಯವಾಗಿದೆ (ಮೀಡಿಯಾ ಮಾತ್ರ), ಎಡ ಮತ್ತು ಬಲ ಭಾಗದ"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"ಹಾರ್ಡ್ವೇರ್ ವೇಗವರ್ಧಿತ ರೆಂಡರಿಂಗ್"</string>
<string name="media_category" msgid="8122076702526144053">"ಮಾಧ್ಯಮ"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"ಪರಿವೀಕ್ಷಣೆ ಮಾಡುವಿಕೆ"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"ಸ್ಟ್ರಿಕ್ಟ್ ಮೋಡ್ ಸಕ್ರಿಯ"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"ಅಪ್ಲಿಕೇಶನ್ಗಳು ಮುಖ್ಯ ಥ್ರೆಡ್ನಲ್ಲಿ ದೀರ್ಘ ಕಾರ್ಯಾಚರಣೆ ನಿರ್ವಹಿಸಿದಾಗ ಪರದೆಯನ್ನು ಫ್ಲ್ಯಾಶ್ ಮಾಡು"</string>
<string name="pointer_location" msgid="7516929526199520173">"ಪಾಯಿಂಟರ್ ಸ್ಥಳ"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView ಹೊಂದಿಸಿ"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"WebView ಅನುಷ್ಠಾನಗೊಳಿಸುವಿಕೆಯನ್ನು ಸೆಟ್ ಮಾಡಿ"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"ಈ ಆಯ್ಕೆಯು ಇನ್ನು ಮುಂದೆ ಮಾನ್ಯವಾಗಿರುವುದಿಲ್ಲ. ಮತ್ತೊಮ್ಮೆ ಪ್ರಯತ್ನಿಸಿ."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"ಚಿತ್ರ ಬಣ್ಣದ ಮೋಡ್"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"sRGB ಬಳಸಿ"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
diff --git a/packages/SettingsLib/res/values-ko/arrays.xml b/packages/SettingsLib/res/values-ko/arrays.xml
index 1477497..3cc5af0 100644
--- a/packages/SettingsLib/res/values-ko/arrays.xml
+++ b/packages/SettingsLib/res/values-ko/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"기기 디스플레이만(기본값)"</item>
+ <item msgid="9161645858025071955">"외부 디스플레이"</item>
+ <item msgid="23651860565814477">"최근 상태 표시줄 터치"</item>
+ <item msgid="7521112827893653392">"포커스 기반"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"기기 디스플레이에만 음영 표시"</item>
+ <item msgid="1955398604822147783">"단일 외부 디스플레이에 음영 표시"</item>
+ <item msgid="391477482416751568">"마지막으로 상호작용한 상태 표시줄이 있는 디스플레이에 음영 표시"</item>
+ <item msgid="1746820128097981528">"마지막으로 포커스된 디스플레이에 음영 표시"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index bece637..669d8ef 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"주변 소리를 업데이트할 수 없음"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"사용 중입니다(미디어 전용). 배터리는 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>입니다."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"사용 중입니다(미디어 전용). 배터리는 왼쪽 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, 오른쪽 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>입니다."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"연결되었습니다(오디오 공유 지원). 배터리는 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>입니다."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"연결되었습니다(오디오 공유 지원). 배터리는 왼쪽 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, 오른쪽 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>입니다."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"연결되었습니다(오디오 공유 지원). 왼쪽 배터리는 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>입니다."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"연결되었습니다(오디오 공유 지원). 오른쪽 배터리는 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>입니다."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"연결됨(오디오 공유 지원)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"사용 중(미디어 전용)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"오디오 공유 지원"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"사용 중(미디어 전용), 왼쪽만"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"사용 중(미디어 전용), 오른쪽만"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"사용 중(미디어 전용), 왼쪽 및 오른쪽"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"하드웨어 가속 렌더링"</string>
<string name="media_category" msgid="8122076702526144053">"미디어"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"모니터링"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"엄격 모드 사용"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"앱이 기본 스레드에서 오래 작업하면 화면 깜박이기"</string>
<string name="pointer_location" msgid="7516929526199520173">"포인터 위치"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView 구현"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"WebView 구현 설정"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"선택이 더 이상 유효하지 않습니다. 다시 시도하세요."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"사진 색상 모드"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"sRGB 사용"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"사용 중지됨"</string>
diff --git a/packages/SettingsLib/res/values-ky/arrays.xml b/packages/SettingsLib/res/values-ky/arrays.xml
index 54d9ecd..5e40443 100644
--- a/packages/SettingsLib/res/values-ky/arrays.xml
+++ b/packages/SettingsLib/res/values-ky/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"Түзмөктүн экраны гана (демейки)"</item>
+ <item msgid="9161645858025071955">"Тышкы экран"</item>
+ <item msgid="23651860565814477">"Абал тилкесине акыркы жолу тийүү"</item>
+ <item msgid="7521112827893653392">"Акыркы аракетке негизделген"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"Көлөкөнү түзмөктүн экранында гана көрсөтүү"</item>
+ <item msgid="1955398604822147783">"Көлөкөнү бир тышкы экранда көрсөтүү"</item>
+ <item msgid="391477482416751568">"Көлөкөнү колдонуучу абал тилкеси менен акыркы жолу аракеттешкен экранда көрсөтүү"</item>
+ <item msgid="1746820128097981528">"Көлөкөнү акыркы активдүү экранда көрсөтүү"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index b6baf38..c69325b 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Айланадагы абал жаңыртылган жок"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Жигердүү (медиа үчүн гана). Батарея: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Жигердүү (медиа үчүн гана). Батарея: L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Туташып турат (чогуу уксаңыз болот). Батарея: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Туташып турат (чогуу уксаңыз болот). Батарея: L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Туташып турат (чогуу уксаңыз болот). Сол кулак – батареянын деңгээли: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Туташып турат (чогуу уксаңыз болот). Оң кулак – батареянын деңгээли: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Туташып турат (чогуу уксаңыз болот)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Активдүү (медиа үчүн гана)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Чогуу уксаңыз болот"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Активдүү (медиа үчүн гана), сол кулакчын гана"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Активдүү (медиа үчүн гана), оң кулакчын гана"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Активдүү (медиа үчүн гана), сол жана оң кулакчын"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Визуалдаштырууну аппарат менен ылдамдатуу"</string>
<string name="media_category" msgid="8122076702526144053">"Медиа"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Мониторинг"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Катаал режим иштетилди"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Узак операцияларда экран күйүп-өчүп турат"</string>
<string name="pointer_location" msgid="7516929526199520173">"Көрсөткүчтүн турган жери"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView кызматы"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"WebView аткарылышын коюу"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Тандалган нерсе жараксыз болуп калган. Кайталап көрүңүз."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Сүрөт түсү режими"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"sRGB колдонуңуз"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Өчүк"</string>
diff --git a/packages/SettingsLib/res/values-lo/arrays.xml b/packages/SettingsLib/res/values-lo/arrays.xml
index ccf645b..cf0a783 100644
--- a/packages/SettingsLib/res/values-lo/arrays.xml
+++ b/packages/SettingsLib/res/values-lo/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"ຈໍສະແດງຜົນຂອງອຸປະກອນເທົ່ານັ້ນ (ຄ່າເລີ່ມຕົ້ນ)"</item>
+ <item msgid="9161645858025071955">"ຈໍສະແດງຜົນພາຍນອກ"</item>
+ <item msgid="23651860565814477">"ການສຳຜັດແຖບສະຖານະຫຼ້າສຸດ"</item>
+ <item msgid="7521112827893653392">"ອີງຕາມການໂຟກັສ"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"ສະແດງເສດສີໃນຈໍສະແດງຜົນຂອງອຸປະກອນເທົ່ານັ້ນ"</item>
+ <item msgid="1955398604822147783">"ສະແດງເສດສີໃນຈໍສະແດງຜົນພາຍນອກເຄື່ອງດຽວ"</item>
+ <item msgid="391477482416751568">"ສະແດງເສດສີໃນຈໍສະແດງຜົນທີ່ມີການໂຕ້ຕອບກັບແຖບສະຖານະຫຼ້າສຸດ"</item>
+ <item msgid="1746820128097981528">"ສະແດງເສດສີໃນຈໍສະແດງຜົນທີ່ໂຟກັສຫຼ້າສຸດ"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index 3046b4f..d1f1344 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"ບໍ່ສາມາດອັບເດດສຽງແວດລ້ອມໄດ້"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"ນຳໃຊ້ຢູ່ (ມີເດຍເທົ່ານັ້ນ). ແບັດເຕີຣີ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"ນຳໃຊ້ຢູ່ (ມີເດຍເທົ່ານັ້ນ). ຊ: ແບັດເຕີຣີ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, ຂ: ແບັດເຕີຣີ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"ເຊື່ອມຕໍ່ແລ້ວ (ຮອງຮັບການແບ່ງປັນສຽງ). ແບັດເຕີຣີ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"ເຊື່ອມຕໍ່ແລ້ວ (ຮອງຮັບການແບ່ງປັນສຽງ). ຊ: ແບັດເຕີຣີ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, ຂ: ແບັດເຕີຣີ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"ເຊື່ອມຕໍ່ແລ້ວ (ຮອງຮັບການແບ່ງປັນສຽງ). ຊ້າຍ: ແບັດເຕີຣີ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"ເຊື່ອມຕໍ່ແລ້ວ (ຮອງຮັບການແບ່ງປັນສຽງ). ຂວາ: ແບັດເຕີຣີ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"ເຊື່ອມຕໍ່ແລ້ວ (ຮອງຮັບການແບ່ງປັນສຽງ)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"ນຳໃຊ້ຢູ່ (ມີເດຍເທົ່ານັ້ນ)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"ຮອງຮັບການແບ່ງປັນສຽງ"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"ນຳໃຊ້ຢູ່ (ມີເດຍເທົ່ານັ້ນ), ຊ້າຍເທົ່ານັ້ນ"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"ນຳໃຊ້ຢູ່ (ມີເດຍເທົ່ານັ້ນ), ຂວາເທົ່ານັ້ນ"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"ນຳໃຊ້ຢູ່ (ມີເດຍເທົ່ານັ້ນ), ຊ້າຍ ແລະ ຂວາ"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"ການສະແດງຜົນໂດຍໃຊ້ຮາດແວຊ່ວຍ"</string>
<string name="media_category" msgid="8122076702526144053">"ມີເດຍ"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"ກຳລັງກວດສອບ"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"ເປີດໃຊ້ໂໝດເຄັ່ງຄັດ"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"ກະພິບໜ້າຈໍເມື່ອມີແອັບເຮັດວຽກດົນເກີນໄປໃນເທຣດຫຼັກ"</string>
<string name="pointer_location" msgid="7516929526199520173">"ຕຳແໜ່ງໂຕຊີ້"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"ການຈັດຕັ້ງປະຕິບັດ WebView"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"ຕັ້ງການຈັດຕັ້ງປະຕິບັດ WebView"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"ບໍ່ສາມາດໃຊ້ການເລືອກນີ້ໄດ້ອີກຕໍ່ໄປແລ້ວ. ກະລຸນາລອງໃໝ່."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"ໂໝດສີຮູບ"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"ໃຊ້ sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"ປິດນຳໃຊ້ແລ້ວ"</string>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index f81caa8..7f94010 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Nepavyko atnaujinti aplinkos"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktyvus (tik medija). Akumuliatorius lygis: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktyvus (tik medija), akumuliatoriaus lygis kairėje: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, dešinėje: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Prijungta (palaikomas garso įrašų bendrinimas). Akumuliatoriaus lygis: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Prijungta (palaikomas garso įrašų bendrinimas), akumuliatoriaus lygis kairėje: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, dešinėje: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Prijungta (palaikomas garso įrašų bendrinimas). Akumuliatoriaus lygis kairėje: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Prijungta (palaikomas garso įrašų bendrinimas). Akumuliatoriaus lygis dešinėje: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Prijungta (palaikomas garso įrašų bendrinimas)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Aktyvus (tik medija)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Palaikomas garso įrašų bendrinimas"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Aktyvus (tik medija), tik kairė"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Aktyvus (tik medija), tik dešinė"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Aktyvus (tik medija), kairė ir dešinė"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Aparatinės įrangos paspartintas pateikimas"</string>
<string name="media_category" msgid="8122076702526144053">"Medija"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Stebėjimas"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Įgal. griežtas režimas"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Ekr. blyksės, kai pr. atl. ilgus proc. pgr. gijoje"</string>
<string name="pointer_location" msgid="7516929526199520173">"Žymiklio vieta"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"„WebView“ diegimas"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"„WebView“ diegimo nustatymas"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Šios parinkties nebegalima pasirinkti. Bandykite dar kartą."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Nuotraukos spalvos režimas"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Naudoti sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Išjungtas"</string>
diff --git a/packages/SettingsLib/res/values-lv/arrays.xml b/packages/SettingsLib/res/values-lv/arrays.xml
index 6d293be..da4ae31f 100644
--- a/packages/SettingsLib/res/values-lv/arrays.xml
+++ b/packages/SettingsLib/res/values-lv/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"Tikai ierīces displejs (noklusējums)"</item>
+ <item msgid="9161645858025071955">"Ārējais displejs"</item>
+ <item msgid="23651860565814477">"Pēdējais pieskāriens statusa joslai"</item>
+ <item msgid="7521112827893653392">"Saskaņā ar fokusu"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"Rādīt ēnu tikai ierīces displejā"</item>
+ <item msgid="1955398604822147783">"Rādīt ēnu vienā ārējā displejā"</item>
+ <item msgid="391477482416751568">"Rādīt ēnu tajā displejā, kura statusa joslā pēdējoreiz tika veikta darbība"</item>
+ <item msgid="1746820128097981528">"Rādīt ēnu pēdējā fokusētajā displejā"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index 987857b..50a56d4 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Nevarēja atjaunināt apkārtnes skaņas"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktīvs (tikai multividei). Akumulatora uzlādes līmenis: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktīvs (tikai multividei). Akumulatora uzlādes līmenis kreisajā austiņā: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, labajā austiņā: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Izveidots savienojums (atbalsta audio kopīgošanu). Akumulatora uzlādes līmenis: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Izveidots savienojums (atbalsta audio kopīgošanu). Akumulatora uzlādes līmenis kreisajā austiņā: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, labajā austiņā: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Izveidots savienojums (atbalsta audio kopīgošanu). Akumulatora uzlādes līmenis kreisajā austiņā: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Izveidots savienojums (atbalsta audio kopīgošanu). Akumulatora uzlādes līmenis labajā austiņā: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Izveidots savienojums (atbalsta audio kopīgošanu)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Aktīvs (tikai multividei)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Atbalsta audio kopīgošanu"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Aktīvs (tikai multivide), tikai kreisās puses aparāts"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Aktīvs (tikai multivide), tikai labās puses aparāts"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Aktīvs (tikai multivide), kreisās un labās puses aparāts"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Aparatūras paātrinātā atveidošana"</string>
<string name="media_category" msgid="8122076702526144053">"Multivide"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Pārraudzība"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Precīzais rež. ir iespēj."</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Zibsnīt ekrānu, ja liet. ilgi darbojas galv. pav."</string>
<string name="pointer_location" msgid="7516929526199520173">"Rādītāja atrašanās vieta"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView ieviešana"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Iestatīt WebView ieviešanu"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Šī iespēja vairs nav derīga. Mēģiniet vēlreiz."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Attēla krāsu režīms"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Izmantot sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Atspējota"</string>
diff --git a/packages/SettingsLib/res/values-mk/arrays.xml b/packages/SettingsLib/res/values-mk/arrays.xml
index 0490f28..4dce6bc 100644
--- a/packages/SettingsLib/res/values-mk/arrays.xml
+++ b/packages/SettingsLib/res/values-mk/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"Само на екранот на уредот (стандардно)"</item>
+ <item msgid="9161645858025071955">"Надворешен екран"</item>
+ <item msgid="23651860565814477">"Последен допир на статусната лента"</item>
+ <item msgid="7521112827893653392">"Засновано на фокус"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"Прикажувај сенка само на екранот на уредот"</item>
+ <item msgid="1955398604822147783">"Прикажувај сенка на еден надворешен екран"</item>
+ <item msgid="391477482416751568">"Прикажувај сенка на екранот што последен имал интеракција со статусната лента"</item>
+ <item msgid="1746820128097981528">"Прикажувај сенка на последниот фокусиран екран"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"стандарден_екран"</item>
+ <item msgid="774789415968826925">"кој_било_надворешен_екран"</item>
+ <item msgid="7880769915418638436">"последен_допир_на_статусната_лента"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index fa65437..e86a6ce 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Не можеше да се ажурира опкружувањето"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Активно (само аудиовизуелни содржини). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> батерија."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Активно (само аудиовизуелни содржини). Л: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> батерија, Д: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> батерија."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Поврзано (поддржува споделување аудио). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> батерија."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Поврзано (поддржува споделување аудио). Л: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> батерија, Д: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> батерија."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Поврзано (поддржува споделување аудио). Лево: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> батерија."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Поврзано (поддржува споделување аудио). Десно: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> батерија."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Поврзано (поддржува споделување аудио)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Активно (само аудиовизуелни содржини)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Поддржува споделување аудио"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Активно (само аудиовизуелни содржини), само лево"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Активно (само аудиовизуелни содржини), само десно"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Активно (само аудиовизуелни содржини), лево и десно"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Хардверско забрзување"</string>
<string name="media_category" msgid="8122076702526144053">"Аудиовизуелни содржини"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Следење"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Овозможен е строг режим"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Трепкај со екранот при долги операции на главна нишка"</string>
<string name="pointer_location" msgid="7516929526199520173">"Локација на покажувач"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"Примена на WebView"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Поставете воведување WebView"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Овој избор веќе не важи. Обидете се повторно."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Режим на боја на слика"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Користи sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Оневозможено"</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index 3e59d9f..f7ab232 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"സറൗണ്ടിംഗ്സ് അപ്ഡേറ്റ് ചെയ്യാനായില്ല"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"സജീവം (മീഡിയ മാത്രം). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ബാറ്ററി."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"സജീവം (മീഡിയ മാത്രം). ഇടതുവശത്ത്: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> ബാറ്ററി, വലതുവശത്ത്: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> ബാറ്ററി."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"കണക്റ്റ് ചെയ്തു (ഓഡിയോ പങ്കിടൽ പിന്തുണയ്ക്കുന്നു). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ബാറ്ററി."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"കണക്റ്റ് ചെയ്തു (ഓഡിയോ പങ്കിടൽ പിന്തുണയ്ക്കുന്നു). ഇടതുവശത്ത്: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> ബാറ്ററി, വലതുവശത്ത്: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> ബാറ്ററി."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"കണക്റ്റ് ചെയ്തു (ഓഡിയോ പങ്കിടൽ പിന്തുണയ്ക്കുന്നു). ഇടത് വശത്ത്: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ബാറ്ററി."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"കണക്റ്റ് ചെയ്തു (ഓഡിയോ പങ്കിടൽ പിന്തുണയ്ക്കുന്നു). വലത് വശത്ത്: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ബാറ്ററി."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"കണക്റ്റ് ചെയ്തു (ഓഡിയോ പങ്കിടൽ പിന്തുണയ്ക്കുന്നു)."</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"സജീവം (മീഡിയ മാത്രം)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"ഓഡിയോ പങ്കിടൽ പിന്തുണയ്ക്കുന്നു"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"സജീവം (മീഡിയ മാത്രം), ഇടതുവശത്ത് മാത്രം"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"സജീവം (മീഡിയ മാത്രം), വലതുവശത്ത് മാത്രം"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"സജീവം (മീഡിയ മാത്രം), ഇടതുവശത്തെയും വലതുവശത്തെയും"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"ഹാർഡ്വെയർ ത്വരിതപ്പെടുത്തിയ റെൻഡറിംഗ്"</string>
<string name="media_category" msgid="8122076702526144053">"മീഡിയ"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"മോണിറ്ററിംഗ്"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"ഫോഴ്സ്മോഡ് സജീവമാക്കി"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"പ്രധാന ത്രെഡിൽ ആപ്പുകൾ ദൈർഘ്യമേറിയ പ്രവർത്തനങ്ങൾ നടത്തുമ്പോൾ സ്ക്രീൻ ഫ്ലാഷ് ചെയ്യുക"</string>
<string name="pointer_location" msgid="7516929526199520173">"പോയിന്റർ ലൊക്കേഷൻ"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView നടപ്പാക്കൽ"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"WebView നടപ്പാക്കൽ സജ്ജമാക്കുക"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"ഈ തിരഞ്ഞെടുപ്പിന് തുടർന്നങ്ങോട്ട് സാധുതയില്ല. വീണ്ടും ശ്രമിക്കുക."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"ചിത്ര വർണ്ണ മോഡ്"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"sRGB ഉപയോഗിക്കുക"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"പ്രവർത്തനരഹിതമാക്കി"</string>
diff --git a/packages/SettingsLib/res/values-mn/arrays.xml b/packages/SettingsLib/res/values-mn/arrays.xml
index ca103af..121371d 100644
--- a/packages/SettingsLib/res/values-mn/arrays.xml
+++ b/packages/SettingsLib/res/values-mn/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"Зөвхөн төхөөрөмжийн дэлгэц (өгөгдмөл)"</item>
+ <item msgid="9161645858025071955">"Гаднын дэлгэц"</item>
+ <item msgid="23651860565814477">"Статус самбарын сүүлийн үеийн хүрэлт"</item>
+ <item msgid="7521112827893653392">"Төвлөрөлд тулгуурласан"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"Зөвхөн төхөөрөмж дээрх дэлгэцэд сүүдрийг харуулах"</item>
+ <item msgid="1955398604822147783">"Нэг гаднын дэлгэц дээр сүүдэр харуулах"</item>
+ <item msgid="391477482416751568">"Статус самбартай нь сүүлд харилцан үйлдэл хийсэн дэлгэц дээр сүүдэр харуулах"</item>
+ <item msgid="1746820128097981528">"Сүүлд төвлөрсөн дэлгэц дээр сүүдэр харуулах"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index e8e9e0c..4dc754e 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Орчин тойрныг шинэчилж чадсангүй"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Идэвхтэй (зөвхөн медиа). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> батарей."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Идэвхтэй (зөвхөн медиа). З: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, Б: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> батарей."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Холбогдсон (аудио хуваалцахыг дэмждэг). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> батарей."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Холбогдсон (аудио хуваалцахыг дэмждэг). З: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, Б: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> батарей."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Холбогдсон (аудио хуваалцахыг дэмждэг). Зүүн: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> батарей."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Холбогдсон (аудио хуваалцахыг дэмждэг). Баруун: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> батарей."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Холбогдсон (аудио хуваалцахыг дэмждэг)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Идэвхтэй (зөвхөн медиа)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Аудио хуваалцахыг дэмждэг"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Идэвхтэй (зөвхөн медиа), зөвхөн зүүн"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Идэвхтэй (зөвхөн медиа), зөвхөн баруун"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Идэвхтэй (зөвхөн медиа), зүүн болон баруун"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Техник хангамжийн хурдасгасан үзүүлэлт"</string>
<string name="media_category" msgid="8122076702526144053">"Медиа"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Мониторинг"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Хатуу горимыг идэвхжүүлсэн"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Аппууд үндсэн хэлхээс дээр удаан хугацаанд үйлдлүүд хийх үед дэлгэцийг анивчуулах"</string>
<string name="pointer_location" msgid="7516929526199520173">"Чиглүүлэгчийн байршил"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView хэрэгжилт"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"WebView хэрэгжилтийг тохируулах"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Энэ сонголт хүчингүй байна. Дахин оролдоно уу."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"\"Зургийн өнгө\" горим"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"sRGB-г ашиглах"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Идэвхгүй болсон"</string>
diff --git a/packages/SettingsLib/res/values-mr/arrays.xml b/packages/SettingsLib/res/values-mr/arrays.xml
index 1437a2c..eba95ae 100644
--- a/packages/SettingsLib/res/values-mr/arrays.xml
+++ b/packages/SettingsLib/res/values-mr/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"फक्त डिव्हाइस डिस्प्ले (डीफॉल्ट)"</item>
+ <item msgid="9161645858025071955">"बाह्य डिस्प्ले"</item>
+ <item msgid="23651860565814477">"नवीनतम स्टेटस बार स्पर्श"</item>
+ <item msgid="7521112827893653392">"फोकसवर आधारित"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"फक्त डिव्हाइस डिस्प्लेवर शेड दाखवा"</item>
+ <item msgid="1955398604822147783">"एकल बाह्य डिस्प्लेवर शेड दाखवा"</item>
+ <item msgid="391477482416751568">"त्याच्या स्टेटस बारशी शेवटचा संवाद साधला आहे अशा डिस्प्लेवर शेड दाखवा"</item>
+ <item msgid="1746820128097981528">"शेवटच्या फोकस केलेल्या डिस्प्लेवर शेड दाखवा"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index f1f5cab..eef39c4 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"जवळपासचे आवाज अपडेट करता आले नाहीत"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"अॅक्टिव्ह आहे (फक्त मीडिया). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> बॅटरी."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"ॲक्टिव्ह आहे (फक्त मीडिया). डावीकडे: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> बॅटरी, उजवीकडे: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> बॅटरी."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"कनेक्ट केले आहे (ऑडिओ शेअरिंगला सपोर्ट करते). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> बॅटरी."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"कनेक्ट केले आहे (ऑडिओ शेअरिंगला सपोर्ट करते). डावीकडे: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, उजवीकडे: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> बॅटरी."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"कनेक्ट केले आहे (ऑडिओ शेअरिंगला सपोर्ट करते). डावीकडे: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> बॅटरी."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"कनेक्ट केले आहे (ऑडिओ शेअरिंगला सपोर्ट करते). उजवीकडे: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> बॅटरी."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"कनेक्ट केले आहे (ऑडिओ शेअरिंगला सपोर्ट करते)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"अॅक्टिव्ह आहे (फक्त मीडिया)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"ऑडिओ शेअरिंगला सपोर्ट करते"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"अॅक्टिव्ह आहे (फक्त मीडिया), फक्त डावे"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"अॅक्टिव्ह आहे (फक्त मीडिया), फक्त उजवे"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"अॅक्टिव्ह आहे (फक्त मीडिया), डावे आणि उजवे"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"हार्डवेअर अॅक्सिलरेटेड रेंडरिंग"</string>
<string name="media_category" msgid="8122076702526144053">"मीडिया"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"परीक्षण"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"कठोर मोड सुरू"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"मुख्य थ्रेडवर अॅप्स मोठी कार्ये करतात तेव्हा स्क्रीन फ्लॅश करा"</string>
<string name="pointer_location" msgid="7516929526199520173">"पॉइंटर स्थान"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"वेबदृश्य अंमलबजावणी"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"वेबदृश्य अंमलबजावणी सेट करा"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"ही निवड यापुढे वैध असणार नाही. पुन्हा प्रयत्न करा."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"चित्र रंग मोड"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"sRGB वापरा"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"बंद केले"</string>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index 412100c..ca4649c 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Tidak dapat mengemaskinikan persekitaran"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktif (media sahaja). Bateri <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktif (media sahaja), L: Bateri <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: Bateri <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Disambungkan (menyokong perkongsian audio). Bateri <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Disambungkan (menyokong perkongsian audio). L: Bateri <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: Bateri <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Disambungkan (menyokong perkongsian audio). Kiri: Bateri <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Disambungkan (menyokong perkongsian audio). Kanan: Bateri <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Disambungkan (menyokong perkongsian audio)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Aktif (media sahaja)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Menyokong perkongsian audio"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Aktif (media sahaja), kiri sahaja"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Aktif (media sahaja), kanan sahaja"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Aktif (media sahaja), kiri dan kanan"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Pemaparan dipercepat perkakasan"</string>
<string name="media_category" msgid="8122076702526144053">"Media"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Memantau"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Mod tegas didayakan"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Kelip skrin apabila apl beroperasi lama pada urutan utama"</string>
<string name="pointer_location" msgid="7516929526199520173">"Lokasi penuding"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"Pelaksanaan WebView"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Tetapkan pelaksanaan WebView"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Pilihan ini tidak lagi sah. Cuba lagi."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Mod warna gambar"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Gunakan sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Dilumpuhkan"</string>
diff --git a/packages/SettingsLib/res/values-my/arrays.xml b/packages/SettingsLib/res/values-my/arrays.xml
index aef22b2..91ce12a 100644
--- a/packages/SettingsLib/res/values-my/arrays.xml
+++ b/packages/SettingsLib/res/values-my/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"စက်ဖန်သားပြင် သီးသန့် (မူရင်း)"</item>
+ <item msgid="9161645858025071955">"ပြင်ပဖန်သားပြင်"</item>
+ <item msgid="23651860565814477">"နောက်ဆုံး အခြေအနေပြဘား တို့ထိမှု"</item>
+ <item msgid="7521112827893653392">"ပြသမှုအခြေပြု"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"စက်ဖန်သားပြင်တွင်သာ အရိပ်ပြပါ"</item>
+ <item msgid="1955398604822147783">"ပြင်ပဖန်သားပြင်တစ်ခုတွင် အရိပ်ကိုပြပါ"</item>
+ <item msgid="391477482416751568">"အခြေအနေပြဘား နောက်ဆုံးပြန်လှန်တုံ့ပြန်ထားသော ဖန်သားပြင်တွင် အရိပ်ကိုပြပါ"</item>
+ <item msgid="1746820128097981528">"နောက်ဆုံးပြထားသော ဖန်သားပြင်တွင် အရိပ်ကိုပြပါ"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"မူရင်းဖန်သားပြင်"</item>
+ <item msgid="774789415968826925">"မည်သည့်ပြင်ပဖန်သားပြင်မဆို"</item>
+ <item msgid="7880769915418638436">"အခြေအနေပြဘား နောက်ဆုံးထိတွေ့မှု"</item>
+ <item msgid="4313165186636015195">"ပြသထားသောဖန်သားပြင်"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index cf493cf..1225e4c 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"ဝန်းကျင်အသံ အပ်ဒိတ်လုပ်၍ မရလိုက်ပါ"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"အသုံးပြုနေသည် (မီဒီယာသီးသန့်)။ ဘက်ထရီ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>။"</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"အသုံးပြုနေသည် (မီဒီယာသီးသန့်)။ ဘက်ထရီ L- <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>၊ R- <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>။"</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"ချိတ်ဆက်ထားသည် (အော်ဒီယို မျှဝေခြင်း ပံ့ပိုးသည်)။ ဘက်ထရီ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>။"</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"ချိတ်ဆက်ထားသည် (အော်ဒီယို မျှဝေခြင်း ပံ့ပိုးသည်)။ ဘက်ထရီ L- <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>၊ R- <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>။"</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"ချိတ်ဆက်ထားသည် (အော်ဒီယို မျှဝေခြင်း ပံ့ပိုးသည်)။ ဘယ်- ဘက်ထရီ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>။"</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"ချိတ်ဆက်ထားသည် (အော်ဒီယို မျှဝေခြင်း ပံ့ပိုးသည်)။ ညာ- ဘက်ထရီ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>။"</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"ချိတ်ဆက်ထားသည် (အော်ဒီယို မျှဝေခြင်း ပံ့ပိုးသည်)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"သုံးနေသည် (မီဒီယာသီးသန့်)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"အော်ဒီယို မျှဝေခြင်း ပံ့ပိုးသည်"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"သုံးနေသည် (မီဒီယာသီးသန့်)၊ ဘယ်သီးသန့်"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"သုံးနေသည် (မီဒီယာသီးသန့်)၊ ညာသီးသန့်"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"သုံးနေသည် (မီဒီယာသီးသန့်)၊ ဘယ်နှင့် ညာ"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"ဟာ့ဒ်ဝဲ အရှိန်မြှင့် ပုံဖော်ခြင်း"</string>
<string name="media_category" msgid="8122076702526144053">"မီဒီယာ"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"စောင့်ကြည့်စစ်ဆေးခြင်း"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"တင်းကြပ်သောစနစ် ဖွင့်ရန်"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"အက်ပ်လုပ်ဆောင်မှု ရှည်ကြာလျှင် စကရင်ပြန်စသည်"</string>
<string name="pointer_location" msgid="7516929526199520173">"မြား၏တည်နေရာ"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView အကောင်အထည်ဖော်မှု"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"WebView အကောင်အထည်ဖော်မှု သတ်မှတ်ပါ"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"ဤရွေးချယ်မှု မှန်ကန်မှု မရှိတော့ပါ။ ထပ်စမ်းကြည့်ပါ။"</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"ဓာတ်ပုံအရောင်မုဒ်"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"sRGB ကို အသုံးပြုပါ"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"ပိတ်ထားသည်"</string>
diff --git a/packages/SettingsLib/res/values-nb/arrays.xml b/packages/SettingsLib/res/values-nb/arrays.xml
index 88f193c..c0106c4 100644
--- a/packages/SettingsLib/res/values-nb/arrays.xml
+++ b/packages/SettingsLib/res/values-nb/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"Bare enhetsskjermen (standard)"</item>
+ <item msgid="9161645858025071955">"Ekstern skjerm"</item>
+ <item msgid="23651860565814477">"Siste trykk på statusfeltet"</item>
+ <item msgid="7521112827893653392">"Fokusbasert"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"Vis skyggen bare på enhetsskjermen"</item>
+ <item msgid="1955398604822147783">"Vis skyggen på én ekstern skjerm"</item>
+ <item msgid="391477482416751568">"Vis skyggen på skjermen hvor det ble trykket på statusfeltet sist"</item>
+ <item msgid="1746820128097981528">"Vis skyggen på den sist fokuserte skjermen"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"Standardskjerm"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index 045318a..7c9b10f 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Kunne ikke oppdatere omgivelsene"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktiv (bare medieinnhold) <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batteri."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktiv (bare medieinnhold). V: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> batteri, H: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> batteri."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Tilkoblet (støtter lyddeling). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batteri."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Tilkoblet (støtter lyddeling). V: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> batteri, H: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> batteri."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Tilkoblet (støtter lyddeling). Venstre: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batteri."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Tilkoblet (støtter lyddeling). Høyre: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batteri."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Tilkoblet (støtter lyddeling)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Aktiv (bare medieinnhold)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Støtter lyddeling"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Aktiv (bare medieinnhold), bare venstre"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Aktiv (bare medieinnhold), bare høyre"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Aktiv (bare medieinnhold), høyre og venstre"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Maskinvareakselerert gjengivelse"</string>
<string name="media_category" msgid="8122076702526144053">"Medier"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Overvåking"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Slå på streng modus"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Skjermblink ved lange apphandlinger på hovedtråd"</string>
<string name="pointer_location" msgid="7516929526199520173">"Pekerplassering"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView-implementering"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Angi WebView-implementering"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Dette valget er ikke gyldig lenger. Prøv på nytt."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Fargemodus for bilder"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Bruk sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Slått av"</string>
diff --git a/packages/SettingsLib/res/values-ne/arrays.xml b/packages/SettingsLib/res/values-ne/arrays.xml
index 1989994..23d6343 100644
--- a/packages/SettingsLib/res/values-ne/arrays.xml
+++ b/packages/SettingsLib/res/values-ne/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"२"</item>
<item msgid="4779928470672877922">"३"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"डिभाइसको डिस्प्ले मात्र (डिफल्ट)"</item>
+ <item msgid="9161645858025071955">"बाह्य डिस्प्ले"</item>
+ <item msgid="23651860565814477">"पछिल्लो पटक स्ट्याटस बारमा टच गरिएको"</item>
+ <item msgid="7521112827893653392">"फोकसमा आधारित"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"यो सेड डिभाइसकै डिस्प्लेमा मात्र देखाउनुहोस्"</item>
+ <item msgid="1955398604822147783">"एउटा बाह्य डिस्प्लेमा सेड देखाउनुहोस्"</item>
+ <item msgid="391477482416751568">"पछिल्लो पटक जुन डिस्प्लेको स्ट्याटस बारमा टच गरिएको थियो सो डिस्प्लेमा सेड देखाउनुहोस्"</item>
+ <item msgid="1746820128097981528">"पछिल्लो पटक फोकस गरिएको डिस्प्लेमा सेड देखाउनुहोस्"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index d637a4b..e2e7a8f 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"वरपरका आवाजसम्बन्धी सेटिङ अपडेट गर्न सकिएन"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"सक्रिय छ (मिडिया मात्र)। <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ब्याट्री।"</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"सक्रिय छ (मिडिया मात्र)। बायाँ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, दायाँ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> ब्याट्री।"</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"कनेक्ट गरिएको छ (अडियो सेयर गर्न मिल्छ)। <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ब्याट्री।"</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"कनेक्ट गरिएको छ (अडियो सेयर गर्न मिल्छ)। बायाँ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, दायाँ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> ब्याट्री।"</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"कनेक्ट गरिएको छ (अडियो सेयर गर्न मिल्छ)। बायाँ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ब्याट्री।"</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"कनेक्ट गरिएको छ (अडियो सेयर गर्न मिल्छ)। दायाँ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ब्याट्री।"</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"कनेक्ट गरिएको छ (अडियो सेयर गर्न मिल्छ)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"सक्रिय छ (मिडिया मात्र)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"अडियो सेयर गर्न मिल्छ"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"सक्रिय छ (मिडिया मात्र), बायाँ मात्र"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"सक्रिय छ (मिडिया मात्र), दायाँ मात्र"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"सक्रिय छ (मिडिया मात्र), बायाँ र दायाँ"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"हार्डवेयरले बढाएको रेन्डरिङ"</string>
<string name="media_category" msgid="8122076702526144053">"मिडिया"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"अनुगमन गरिँदै छ"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"स्ट्रिक्ट मोड अन गर्नुहोस्"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"एपले मुख्य थ्रेडमा लामा गतिविधि गर्दा स्क्रिन फ्ल्यास गर्नुहोस्"</string>
<string name="pointer_location" msgid="7516929526199520173">"पोइन्टरको स्थान"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView कार्यान्वयन"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"WebView कार्यान्वयन सेट गर्नुहोस्"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"यो छनोट अब मान्य छैन। फेरि प्रयास गर्नुहोस्।"</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"चित्र रङ्ग मोड"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"sRGB प्रयोग गर्नुहोस्"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"अफ गरिएको छ"</string>
@@ -657,8 +685,8 @@
<string name="add_guest_failed" msgid="8074548434469843443">"नयाँ अतिथि बनाउन सकिएन"</string>
<string name="user_nickname" msgid="262624187455825083">"उपनाम"</string>
<string name="edit_user_info_message" msgid="6677556031419002895">"यो डिभाइस प्रयोग गर्ने सबै जना तपाईंले छनौट गर्ने नाम र फोटो देख्न सक्ने छन्।"</string>
- <string name="user_add_user" msgid="7876449291500212468">"प्रयोगकर्ता कनेक्ट गर्नुहोस्"</string>
- <string name="guest_new_guest" msgid="3482026122932643557">"अतिथि कनेक्ट गर्नुहोस्"</string>
+ <string name="user_add_user" msgid="7876449291500212468">"प्रयोगकर्ता थप्नुहोस्"</string>
+ <string name="guest_new_guest" msgid="3482026122932643557">"अतिथि थप्नुहोस्"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"अथिति हटाउनुहोस्"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"अतिथि सत्र रिसेट गर्नुहोस्"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"अतिथिका रूपमा ब्राउज गर्ने सेसन रिसेट गर्ने हो?"</string>
diff --git a/packages/SettingsLib/res/values-nl/arrays.xml b/packages/SettingsLib/res/values-nl/arrays.xml
index 12c9551..669326a 100644
--- a/packages/SettingsLib/res/values-nl/arrays.xml
+++ b/packages/SettingsLib/res/values-nl/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"Alleen apparaatscherm (standaard)"</item>
+ <item msgid="9161645858025071955">"Extern scherm"</item>
+ <item msgid="23651860565814477">"Laatste aanraking van statusbalk"</item>
+ <item msgid="7521112827893653392">"Op focus gebaseerd"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"Alleen paneel tonen op apparaatscherm"</item>
+ <item msgid="1955398604822147783">"Venster tonen op één extern scherm"</item>
+ <item msgid="391477482416751568">"Venster tonen op scherm waarop de laatst interactie met de statusbalk was"</item>
+ <item msgid="1746820128097981528">"Venster tonen op laatste gefocuste scherm"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 481479e..6dfcc7b 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Kan omgeving niet updaten"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Actief (alleen media). Batterijniveau <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Actief (alleen media), L: batterijniveau <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: batterijniveau <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Verbonden (ondersteunt audio delen), batterijniveau <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Verbonden (ondersteunt audio delen), L: batterijniveau <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: batterijniveau <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Verbonden (ondersteunt audio delen). Links: batterijniveau <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Verbonden (ondersteunt audio delen). Rechts: batterijniveau <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Verbonden (ondersteunt audio delen)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Actief (alleen media)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Ondersteunt audio delen"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Actief (alleen media), alleen links"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Actief (alleen media), alleen rechts"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Actief (alleen media), links en rechts"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Rendering met hardwareversnelling"</string>
<string name="media_category" msgid="8122076702526144053">"Media"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Controle"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Strikte modus staat aan"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Knipperend scherm bij lange bewerkingen door apps"</string>
<string name="pointer_location" msgid="7516929526199520173">"Cursorlocatie"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView-implementatie"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"WebView-implementatie instellen"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Deze keuze is niet meer geldig. Probeer het opnieuw."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Kleurenmodus voor afbeeldingen"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"sRGB gebruiken"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Uitgezet"</string>
diff --git a/packages/SettingsLib/res/values-or/arrays.xml b/packages/SettingsLib/res/values-or/arrays.xml
index 9782303..3b906c4 100644
--- a/packages/SettingsLib/res/values-or/arrays.xml
+++ b/packages/SettingsLib/res/values-or/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"କେବଳ ଡିଭାଇସ ଡିସପ୍ଲେ (ଡିଫଲ୍ଟ)"</item>
+ <item msgid="9161645858025071955">"ଏକ୍ସଟର୍ନଲ ଡିସପ୍ଲେ"</item>
+ <item msgid="23651860565814477">"ନବୀନତମ ଷ୍ଟାଟସ ବାର ଟଚ"</item>
+ <item msgid="7521112827893653392">"ଫୋକସ-ଆଧାରିତ"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"କେବଳ ଡିଭାଇସରେ ଡିସପ୍ଲେ ସେଡ ଦେଖାନ୍ତୁ"</item>
+ <item msgid="1955398604822147783">"ସିଙ୍ଗଲ ଏକ୍ସଟର୍ନଲ ଡିସପ୍ଲେରେ ସେଡ ଦେଖାନ୍ତୁ"</item>
+ <item msgid="391477482416751568">"ଡିସପ୍ଲେରେ ଏପରି ସେଡ ଦେଖାନ୍ତୁ ଯାହା ସହିତ ଏହାର ଷ୍ଟାଟସ ବାର ଶେଷ ଥର ପାଇଁ ଇଣ୍ଟରାକ୍ଟ ହୋଇଛି"</item>
+ <item msgid="1746820128097981528">"ଫୋକସ କରାଯାଇଥିବା ଗତ ଡିସପ୍ଲେରେ ସେଡ ଦେଖାନ୍ତୁ"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index bcde4e9..44c819c 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"ପରିପାର୍ଶ୍ୱକୁ ଅପଡେଟ କରାଯାଇପାରିଲା ନାହିଁ"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"ସକ୍ରିୟ (କେବଳ ମିଡିଆ)। <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ବେଟେରୀ।"</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"ସକ୍ରିୟ (କେବଳ ମିଡିଆ)। ବାମ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, ଡାହାଣ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> ବେଟେରୀ।"</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"କନେକ୍ଟ କରାଯାଇଛି (ଅଡିଓ ସେୟାରିଂକୁ ସପୋର୍ଟ କରେ)। <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ବେଟେରୀ।"</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"କନେକ୍ଟ କରାଯାଇଛି (ଅଡିଓ ସେୟାରିଂକୁ ସମର୍ଥନ କରେ)। ବାମ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, ଡାହାଣ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> ବେଟେରୀ।"</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"କନେକ୍ଟ କରାଯାଇଛି (ଅଡିଓ ସେୟାରିଂକୁ ସମର୍ଥନ କରେ)। ବାମ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ବେଟେରୀ।"</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"କନେକ୍ଟ କରାଯାଇଛି (ଅଡିଓ ସେୟାରିଂକୁ ସପୋର୍ଟ କରେ)। ଡାହାଣ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ବେଟେରୀ।"</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"କନେକ୍ଟ କରାଯାଇଛି (ଅଡିଓ ସେୟାରିଂକୁ ସମର୍ଥନ କରେ)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"ସକ୍ରିୟ (କେବଳ ମିଡିଆ)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"ଅଡିଓ ସେୟାରିଂକୁ ସପୋର୍ଟ କରେ"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"ସକ୍ରିୟ (କେବଳ ମିଡିଆ), କେବଳ ବାମ"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"ସକ୍ରିୟ (କେବଳ ମିଡିଆ), କେବଳ ଡାହାଣ"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"ସକ୍ରିୟ (କେବଳ ମିଡିଆ), ବାମ ଏବଂ ଡାହାଣ"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"ହାର୍ଡୱେର୍ ଆକ୍ସଲରେଟେଡ୍ ରେଣ୍ଡରିଙ୍ଗ"</string>
<string name="media_category" msgid="8122076702526144053">"ମିଡିଆ"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"ମନିଟରିଙ୍ଗ"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"କଡ଼ା ମୋଡ୍ ସକ୍ଷମ କରାଯାଇଛି"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"ମୁଖ୍ୟ ଥ୍ରେଡ୍ରେ ଆପ୍ ଦୀର୍ଘ ସମୟ କାର୍ଯ୍ୟ କଲେ ସ୍କ୍ରୀନ୍ ଫ୍ଲାଶ୍ କରନ୍ତୁ"</string>
<string name="pointer_location" msgid="7516929526199520173">"ପଏଣ୍ଟର୍ ଲୋକେସନ୍"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"ୱେବ୍ଭ୍ୟୁ ପ୍ରୟୋଗ"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"WebView କାର୍ଯ୍ୟକାରିତାକୁ ସେଟ୍ କରନ୍ତୁ"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"ଏହି ପସନ୍ଦ ଆଉ ମାନ୍ୟ ନାହିଁ। ପୁଣିଥରେ ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"ପିକ୍ଚର୍ ରଙ୍ଗ ମୋଡ୍"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"sRGB ବ୍ୟବହାର କରନ୍ତୁ"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"ଅକ୍ଷମ ହୋଇଛି"</string>
diff --git a/packages/SettingsLib/res/values-pa/arrays.xml b/packages/SettingsLib/res/values-pa/arrays.xml
index afb85ca..115214f 100644
--- a/packages/SettingsLib/res/values-pa/arrays.xml
+++ b/packages/SettingsLib/res/values-pa/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"ਸਿਰਫ਼ ਡੀਵਾਈਸ ਦੀ ਡਿਸਪਲੇ (ਪੂਰਵ-ਨਿਰਧਾਰਿਤ)"</item>
+ <item msgid="9161645858025071955">"ਬਾਹਰੀ ਡਿਸਪਲੇ"</item>
+ <item msgid="23651860565814477">"ਨਵੀਨਤਮ ਸਥਿਤੀ ਪੱਟੀ ਸਪਰਸ਼"</item>
+ <item msgid="7521112827893653392">"ਫੋਕਸ-ਆਧਾਰਿਤ"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"ਸਿਰਫ਼ ਡੀਵਾਈਸ ਦੀ ਡਿਸਪਲੇ \'ਤੇ ਸ਼ੇਡ ਦਿਖਾਓ"</item>
+ <item msgid="1955398604822147783">"ਇਕਹਿਰੇ ਬਾਹਰੀ ਡਿਸਪਲੇ \'ਤੇ ਸ਼ੇਡ ਦਿਖਾਓ"</item>
+ <item msgid="391477482416751568">"ਉਸ ਡਿਸਪਲੇ \'ਤੇ ਸ਼ੇਡ ਦਿਖਾਓ ਜਿਸ ਦੀ ਸਥਿਤੀ ਪੱਟੀ ਨਾਲ ਅਖੀਰ ਵਾਰ ਅੰਤਰਕਿਰਿਆ ਕੀਤੀ ਗਈ ਸੀ"</item>
+ <item msgid="1746820128097981528">"ਆਖਰੀ ਵਾਰ ਫੋਕਸ ਕੀਤੇ ਗਏ ਡਿਸਪਲੇ \'ਤੇ ਸ਼ੇਡ ਦਿਖਾਓ"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index 821c84e..731c195 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"ਆਲੇ-ਦੁਆਲੇ ਨੂੰ ਅੱਪਡੇਟ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"ਕਿਰਿਆਸ਼ੀਲ (ਸਿਰਫ਼ ਮੀਡੀਆ)। <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ਬੈਟਰੀ।"</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"ਕਿਰਿਆਸ਼ੀਲ (ਸਿਰਫ਼ ਮੀਡੀਆ)। ਖੱਬੇ ਪਾਸੇ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, ਸੱਜੇ ਪਾਸੇ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> ਬੈਟਰੀ।"</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"ਕਨੈਕਟ ਕੀਤਾ (ਆਡੀਓ ਸਾਂਝਾਕਰਨ ਦਾ ਸਮਰਥਨ ਕਰਦਾ ਹੈ)। <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ਬੈਟਰੀ।"</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"ਕਨੈਕਟ ਕੀਤਾ (ਆਡੀਓ ਸਾਂਝਾਕਰਨ ਦਾ ਸਮਰਥਨ ਕਰਦਾ ਹੈ)। ਖੱਬੇ ਪਾਸੇ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, ਸੱਜੇ ਪਾਸੇ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> ਬੈਟਰੀ।"</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"ਕਨੈਕਟ ਕੀਤਾ (ਆਡੀਓ ਸਾਂਝਾਕਰਨ ਦਾ ਸਮਰਥਨ ਕਰਦਾ ਹੈ)। ਖੱਬੇ ਪਾਸੇ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ਬੈਟਰੀ।"</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"ਕਨੈਕਟ ਕੀਤਾ (ਆਡੀਓ ਸਾਂਝਾਕਰਨ ਦਾ ਸਮਰਥਨ ਕਰਦਾ ਹੈ)। ਸੱਜੇ ਪਾਸੇ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ਬੈਟਰੀ।"</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"ਕਨੈਕਟ ਕੀਤਾ (ਆਡੀਓ ਸਾਂਝਾਕਰਨ ਦਾ ਸਮਰਥਨ ਕਰਦਾ ਹੈ)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"ਕਿਰਿਆਸ਼ੀਲ (ਸਿਰਫ਼ ਮੀਡੀਆ)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"ਆਡੀਓ ਸਾਂਝਾਕਰਨ ਦਾ ਸਮਰਥਨ ਕਰਦਾ ਹੈ"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"ਕਿਰਿਆਸ਼ੀਲ (ਸਿਰਫ਼ ਮੀਡੀਆ), ਸਿਰਫ਼ ਖੱਬਾ"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"ਕਿਰਿਆਸ਼ੀਲ (ਸਿਰਫ਼ ਮੀਡੀਆ), ਸਿਰਫ਼ ਸੱਜਾ"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"ਕਿਰਿਆਸ਼ੀਲ (ਸਿਰਫ਼ ਮੀਡੀਆ), ਖੱਬਾ ਅਤੇ ਸੱਜਾ"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"ਹਾਰਡਵੇਅਰ ਐਕਸੈੱਲਰੇਟਿਡ ਰੈਂਡਰਿੰਗ"</string>
<string name="media_category" msgid="8122076702526144053">"ਮੀਡੀਆ"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"ਨਿਰੀਖਣ ਕਰਨਾ"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"ਸਟ੍ਰਿਕਟ ਮੋਡ ਚਾਲੂ ਹੈ"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"ਐਪਾਂ ਵੱਲੋਂ ਮੁੱਖ ਥ੍ਰੈੱਡ \'ਤੇ ਲੰਬੀਆਂ ਕਾਰਵਾਈਆਂ ਕਰਨ \'ਤੇ ਸਕ੍ਰੀਨ ਫਲੈਸ਼ ਕਰੋ"</string>
<string name="pointer_location" msgid="7516929526199520173">"ਪੁਆਇੰਟਰ ਟਿਕਾਣਾ"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView ਅਮਲੀਕਰਨ"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"WebView ਅਮਲੀਕਰਨ ਸੈੱਟ ਕਰੋ"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"ਇਹ ਚੋਣ ਹੁਣ ਵੈਧ ਨਹੀਂ ਹੈ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"ਤਸਵੀਰ ਰੰਗ ਮੋਡ"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"sRGB ਵਰਤੋਂ ਕਰੋ"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"ਬੰਦ ਹੈ"</string>
diff --git a/packages/SettingsLib/res/values-pl/arrays.xml b/packages/SettingsLib/res/values-pl/arrays.xml
index 59791c0..6daf1b2 100644
--- a/packages/SettingsLib/res/values-pl/arrays.xml
+++ b/packages/SettingsLib/res/values-pl/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"Tylko wyświetlanie na urządzeniu (domyślnie)"</item>
+ <item msgid="9161645858025071955">"Wyświetlacz zewnętrzny"</item>
+ <item msgid="23651860565814477">"Ostatnie dotknięcie paska stanu"</item>
+ <item msgid="7521112827893653392">"Na podstawie aktywnego wyświetlacza"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"Pokaż cień tylko na wyświetlaczu urządzenia"</item>
+ <item msgid="1955398604822147783">"Pokazuj cień na pojedynczym wyświetlaczu zewnętrznym"</item>
+ <item msgid="391477482416751568">"Pokazuj cień na wyświetlaczu, na którym ostatnio nastąpiła interakcja z paskiem stanu"</item>
+ <item msgid="1746820128097981528">"Pokazuj cień na ostatnim aktywnym wyświetlaczu"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index 9f6eb4c..b9adae2 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Nie udało się zaktualizować otoczenia"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktywne (tylko multimedia). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> naładowania baterii."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktywne (tylko multimedia), lewa: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, prawa: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> naładowania baterii."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Połączone (obsługa udostępniania dźwięku), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> naładowania baterii."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Połączone (obsługa udostępniania dźwięku), lewa: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, prawa: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> naładowania baterii."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Połączone (obsługa udostępniania dźwięku). Lewa: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> naładowania baterii."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Połączone (obsługa udostępniania dźwięku). Prawa: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> naładowania baterii."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Połączone (obsługa udostępniania dźwięku)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Aktywne (tylko multimedia)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Obsługa udostępniania dźwięku"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Aktywne (tylko multimedia), tylko lewa"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Aktywne (tylko multimedia), tylko prawa"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Aktywne (tylko multimedia), lewa i prawa"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Sprzętowa akceleracja renderowania"</string>
<string name="media_category" msgid="8122076702526144053">"Multimedia"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Monitorowanie"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Tryb ścisły włączony"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Miganie ekranu podczas długich operacji w wątku głównym"</string>
<string name="pointer_location" msgid="7516929526199520173">"Lokalizacja wskaźnika"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"Implementacja WebView"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Ustaw implementację WebView"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Ta opcja nie jest już obsługiwana. Spróbuj ponownie."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Tryb kolorów obrazu"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Użyj sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Wyłączone"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index 72f25be..5b3bb06 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Não foi possível atualizar o som ambiente"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Ativo (apenas mídia). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Ativo (apenas mídia). Lado esquerdo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> de bateria. Lado direito: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> de bateria."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Conectado (aceita compartilhamento de áudio). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Conectado (aceita compartilhamento de áudio). Lado esquerdo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> de bateria. Lado direito: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> de bateria."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Conectado (aceita compartilhamento de áudio). Lado esquerdo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Conectado (aceita compartilhamento de áudio). Lado direito: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Conectado (aceita compartilhamento de áudio)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Ativo (apenas mídia)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Com suporte ao compartilhamento de áudio"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Ativo (apenas mídia), apenas esquerdo"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Ativo (apenas mídia), somente direito"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Ativo (apenas mídia), esquerdo e direito"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Renderização acelerada por hardware"</string>
<string name="media_category" msgid="8122076702526144053">"Mídia"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Monitoramento"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Modo restrito ativado"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Piscar tela se apps demorarem no processo principal"</string>
<string name="pointer_location" msgid="7516929526199520173">"Localização do cursor"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"Implementação do WebView"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Configurar implementação do WebView"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Esta opção não é mais válida. Tente novamente."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Modo de cor da imagem"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Usar sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Desativado"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index d09caad..e6b343a 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Não foi possível atualizar o ambiente"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Ativo (apenas para multimédia). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Ativo (apenas para multimédia). E: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> de bateria. D: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> de bateria."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Ligado (suporta partilha de áudio). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Ligado (suporta partilha de áudio). E: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> de bateria. D: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> de bateria."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Ligado (suporta a partilha de áudio). Esquerdo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Ligado (suporta a partilha de áudio). Direito: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Ligado (suporta a partilha de áudio)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Ativo (apenas para multimédia)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Suporta partilha de áudio"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Ativo (apenas para multimédia), apenas esquerdo"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Ativo (apenas para multimédia), apenas direito"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Ativo (apenas para multimédia), esquerdo e direito"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Conversão acelerada de hardware"</string>
<string name="media_category" msgid="8122076702526144053">"Multimédia"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Monitorização"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Modo rigoroso ativado"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Piscar ecrã se app fazem oper. prolong. no tópico princ."</string>
<string name="pointer_location" msgid="7516929526199520173">"Localização do ponteiro"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"Implementação WebView"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Definir implementação WebView"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Esta opção já não é válida. Tente novamente."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Modo de cor da imagem"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Usar sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Desativado"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 72f25be..5b3bb06 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Não foi possível atualizar o som ambiente"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Ativo (apenas mídia). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Ativo (apenas mídia). Lado esquerdo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> de bateria. Lado direito: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> de bateria."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Conectado (aceita compartilhamento de áudio). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Conectado (aceita compartilhamento de áudio). Lado esquerdo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> de bateria. Lado direito: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> de bateria."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Conectado (aceita compartilhamento de áudio). Lado esquerdo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Conectado (aceita compartilhamento de áudio). Lado direito: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Conectado (aceita compartilhamento de áudio)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Ativo (apenas mídia)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Com suporte ao compartilhamento de áudio"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Ativo (apenas mídia), apenas esquerdo"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Ativo (apenas mídia), somente direito"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Ativo (apenas mídia), esquerdo e direito"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Renderização acelerada por hardware"</string>
<string name="media_category" msgid="8122076702526144053">"Mídia"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Monitoramento"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Modo restrito ativado"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Piscar tela se apps demorarem no processo principal"</string>
<string name="pointer_location" msgid="7516929526199520173">"Localização do cursor"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"Implementação do WebView"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Configurar implementação do WebView"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Esta opção não é mais válida. Tente novamente."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Modo de cor da imagem"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Usar sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Desativado"</string>
diff --git a/packages/SettingsLib/res/values-ro/arrays.xml b/packages/SettingsLib/res/values-ro/arrays.xml
index 8bfeb70..edaf788 100644
--- a/packages/SettingsLib/res/values-ro/arrays.xml
+++ b/packages/SettingsLib/res/values-ro/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"Numai pe ecranul dispozitivului (prestabilit)"</item>
+ <item msgid="9161645858025071955">"Ecran extern"</item>
+ <item msgid="23651860565814477">"Cea mai recentă atingere a barei de stare"</item>
+ <item msgid="7521112827893653392">"În funcție de focalizare"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"Afișează umbra doar pe ecranul dispozitivului"</item>
+ <item msgid="1955398604822147783">"Afișează umbra pe un singur ecran extern"</item>
+ <item msgid="391477482416751568">"Afișează umbra pe ecranul pe care s-a interacționat ultima dată cu bara de stare"</item>
+ <item msgid="1746820128097981528">"Afișează umbra pe ultimul ecran focalizat"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index 26fdce8..13c9032 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Nu s-a putut actualiza zona din jur"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Activ (numai pentru conținut media). Nivelul bateriei <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Activ (numai pentru conținut media): nivelul bateriei din stânga: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, nivelul bateriei din dreapta: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>"</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Conectat (acceptă permiterea accesului la audio). Nivelul bateriei: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Conectat (acceptă permiterea accesului la audio), nivelul bateriei din stânga: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, nivelul bateriei din dreapta: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>"</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Conectat (acceptă permiterea accesului la audio). Nivelul bateriei din stânga: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Conectat (acceptă permiterea accesului la audio). Nivelul bateriei din dreapta: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Conectat (acceptă permiterea accesului la audio)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Activ (numai pentru conținut media)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Acceptă permiterea accesului la audio"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Activ (numai pentru conținut media), numai stânga"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Activ (numai pentru conținut media), numai dreapta"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Activ (numai pentru conținut media), stânga și dreapta"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Redare accelerată hardware"</string>
<string name="media_category" msgid="8122076702526144053">"Media"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Monitorizare"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Modul Strict activat"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Iluminare intermitentă la operații lungi pe firul principal"</string>
<string name="pointer_location" msgid="7516929526199520173">"Locația indicatorului"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"Implementare WebView"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Setează implementarea WebView"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Această opțiune nu mai este validă. Încearcă din nou."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Modul de culori pentru imagini"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Folosește sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Dezactivat"</string>
diff --git a/packages/SettingsLib/res/values-ru/arrays.xml b/packages/SettingsLib/res/values-ru/arrays.xml
index 52b2549..a31168e 100644
--- a/packages/SettingsLib/res/values-ru/arrays.xml
+++ b/packages/SettingsLib/res/values-ru/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"Только экран устройства (по умолчанию)"</item>
+ <item msgid="9161645858025071955">"Внешний дисплей"</item>
+ <item msgid="23651860565814477">"Последнее нажатие на строку состояния"</item>
+ <item msgid="7521112827893653392">"Последняя активность"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"Показывать тень только на экране устройства"</item>
+ <item msgid="1955398604822147783">"Показывать панель уведомлений на единственном внешнем дисплее"</item>
+ <item msgid="391477482416751568">"Показывать панель уведомлений на дисплее, со строкой состояния которого пользователь взаимодействовал в последний раз"</item>
+ <item msgid="1746820128097981528">"Показывать панель уведомлений на дисплее, на который пользователь перешел в последний раз"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index bf92e20..831623d 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Не удалось отрегулировать окружающие звуки."</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Используется (только для медиа), заряд: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Используется (только для медиа), заряд: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> (Л), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> (П)."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Подключено (поддерживается отправка аудио), заряд: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Подключено (поддерживается отправка аудио), заряд: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> (Л), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> (П)."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Подключено (поддерживается отправка аудио), заряд: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> (Л)."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Подключено (поддерживается отправка аудио), заряд: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> (П)."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Подключено (поддерживается отправка аудио)."</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Используется (только для медиа)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Поддерживается отправка аудио"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Используется (только для медиа), только левый"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Используется (только для медиа), правый наушник"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Используется (только для медиа), левый и правый наушники"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Аппаратное ускорение отрисовки"</string>
<string name="media_category" msgid="8122076702526144053">"Мультимедиа"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Мониторинг"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Строгий режим"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Подсвечивать экран во время длительных операций"</string>
<string name="pointer_location" msgid="7516929526199520173">"Место касания"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"Сервис WebView"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Настройки сервиса WebView"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Вариант недействителен. Повторите попытку."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Цветовой режим"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Использовать sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Отключено"</string>
diff --git a/packages/SettingsLib/res/values-si/arrays.xml b/packages/SettingsLib/res/values-si/arrays.xml
index 66f1ba7..f9e9ae1 100644
--- a/packages/SettingsLib/res/values-si/arrays.xml
+++ b/packages/SettingsLib/res/values-si/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"උපාංග සංදර්ශකය පමණි (පෙරනිමි)"</item>
+ <item msgid="9161645858025071955">"බාහිර සංදර්ශකය"</item>
+ <item msgid="23651860565814477">"නවතම තත්ත්ව තීරු ස්පර්ශය"</item>
+ <item msgid="7521112827893653392">"නාභිගත කිරීම-පාදක"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"උපාංග සංදර්ශකයේ පමණක් සෙවන පෙන්වන්න"</item>
+ <item msgid="1955398604822147783">"තනි බාහිර සංදර්ශකය මත වැස්ම පෙන්වන්න"</item>
+ <item msgid="391477482416751568">"තත්ත්ව තීරුව අවසන් වරට අන්තර්ක්රියා කළ වැස්ම දර්ශනයේ පෙන්වන්න."</item>
+ <item msgid="1746820128097981528">"අවසන් වරට නාභිගත කළ සංදර්ශකයේ වැස්ම පෙන්වන්න"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"නාභිගත කළ_සංදර්ශකය"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index 94e1ed4..dcfb914 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"වටපිටාව යාවත්කාලීන කළ නොහැකි විය"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"ක්රියාත්මකයි (මාධ්ය පමණයි). බැටරිය <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"ක්රියාත්මකයි (මාධ්ය පමණයි), බැටරිය ව: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, ද: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"සම්බන්ධයි (ශ්රව්ය බෙදා ගැනීමට සහය දක්වයි). බැටරිය <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"සම්බන්ධයි (ශ්රව්ය බෙදා ගැනීමට සහය දක්වයි). බැටරිය ව: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, ද: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"සම්බන්ධයි (ශ්රව්ය බෙදා ගැනීමට සහය දක්වයි). වම: බැටරිය <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"සම්බන්ධයි (ශ්රව්ය බෙදා ගැනීමට සහය දක්වයි). දකුණ: බැටරිය <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"සම්බන්ධයි (ශ්රව්ය බෙදා ගැනීමට සහය දක්වයි)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"සක්රිය (මාධ්ය පමණි)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"ශ්රව්ය බෙදා ගැනීම සහය දක්වයි"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"සක්රිය (මාධ්ය පමණි), වම පමණි"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"සක්රිය (මාධ්ය පමණි), දකුණ පමණි"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"සක්රිය (මාධ්ය පමණි), වම සහ දකුණ"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"දෘඩාංග වේගය වැඩි කළ පිරිනැමීම"</string>
<string name="media_category" msgid="8122076702526144053">"මාධ්ය"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"නිරීක්ෂණය"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"තදබල ආකාරය සබල කිරීම"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"මූලික පොටේ යෙදුම්, දිගු මෙහෙයුම් කරන විට තිරය ෆ්ලෑෂ් කරන්න"</string>
<string name="pointer_location" msgid="7516929526199520173">"සූචක පිහිටීම"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView ක්රියාත්මක කිරීම"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"WebView ක්රියාත්මක කිරීම සකසන්න"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"මෙම තෝරා ගැනීම තව දුරටත් වලංගු නැත. නැවත උත්සාහ කරන්න."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"පින්තූර වර්ණ ප්රකාරය"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"sRGB භාවිතා කරන්න"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"අබලයි"</string>
diff --git a/packages/SettingsLib/res/values-sk/arrays.xml b/packages/SettingsLib/res/values-sk/arrays.xml
index f8363cd..2d39d3a 100644
--- a/packages/SettingsLib/res/values-sk/arrays.xml
+++ b/packages/SettingsLib/res/values-sk/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"Iba obrazovka zariadenia (predvolené)"</item>
+ <item msgid="9161645858025071955">"Externá obrazovka"</item>
+ <item msgid="23651860565814477">"Posledné klepnutie na stavový riadok"</item>
+ <item msgid="7521112827893653392">"Na základe označenia"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"Zobraziť panel iba na obrazovke zariadenia"</item>
+ <item msgid="1955398604822147783">"Zobraziť panel na jednej externej obrazovke"</item>
+ <item msgid="391477482416751568">"Zobraziť panel na obrazovke, na ktorej došlo naposledy k interakcii so stavovým riadkom"</item>
+ <item msgid="1746820128097981528">"Zobraziť panel na poslednej označenej obrazovke"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index 6170ac5..86e8274 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Okolie sa nepodarilo aktualizovať"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktívne (iba médiá). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batérie."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktívne (iba médiá). Ľ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> batérie, P: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> batérie."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Pripojené (podporuje zdieľanie zvuku). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batérie."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Pripojené (podporuje zdieľanie zvuku). Ľ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, P: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> batérie."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Pripojené (podporuje zdieľanie zvuku). Ľavá strana: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batérie."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Pripojené (podporuje zdieľanie zvuku). Pravá strana: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batérie."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Pripojené (podporuje zdieľanie zvuku)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Aktívne (iba médiá)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Podporuje zdieľanie zvuku"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Aktívne (iba médiá), iba ľavá strana"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Aktívne (iba médiá), iba pravá strana"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Aktívne (iba médiá), ľavá aj pravá strana"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Hardvérom zrýchlené vykresľovanie"</string>
<string name="media_category" msgid="8122076702526144053">"Médiá"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Monitorovanie"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Povoliť prísny režim"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Blikať pri dlhých operáciách hlavného vlákna"</string>
<string name="pointer_location" msgid="7516929526199520173">"Umiestnenie kurzora"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"Implementácia WebView"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Nastaviť implementáciu WebView"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Táto voľba už nie je platná. Skúste to znova."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Farebný režim obrázka"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Použije sa sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Vypnuté"</string>
diff --git a/packages/SettingsLib/res/values-sl/arrays.xml b/packages/SettingsLib/res/values-sl/arrays.xml
index 2a128ef..498224a 100644
--- a/packages/SettingsLib/res/values-sl/arrays.xml
+++ b/packages/SettingsLib/res/values-sl/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"Prikaz samo v napravi (privzeto)"</item>
+ <item msgid="9161645858025071955">"Zunanji zaslon"</item>
+ <item msgid="23651860565814477">"Zadnji dotik vrstice stanja"</item>
+ <item msgid="7521112827893653392">"Na podlagi fokusa"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"Prikaz podokna samo na zaslonu naprave"</item>
+ <item msgid="1955398604822147783">"Prikaz podokna na enem zunanjem zaslonu"</item>
+ <item msgid="391477482416751568">"Prikaz podokna na zaslonu, na katerem je bila izvedena zadnja interakcija z vrstico stanja"</item>
+ <item msgid="1746820128097981528">"Prikaz podokna na zadnjem zaslonu s fokusom"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index 39b61d9..28ae8e1 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Okolice ni bilo mogoče posodobiti"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktivno (samo predstavnost). Baterija: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktivno (samo predstavnost), baterija – L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, D: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Povezano (podpira deljenje zvoka), baterija: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Povezano (podpira deljenje zvoka), baterija – L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, D: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Povezano (podpira deljenje zvoka). Levo – baterija: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Povezano (podpira deljenje zvoka). Desno – baterija: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Povezano (podpira deljenje zvoka)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Aktivno (samo predstavnost)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Podpira deljenje zvoka"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Aktivno (samo predstavnost), samo levo"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Aktivno (samo predstavnost), samo desno"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Aktivno (samo predstavnost), levo in desno"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Upodabljanje s strojnim pospeševanjem"</string>
<string name="media_category" msgid="8122076702526144053">"Predstavnost"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Spremljanje"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Strog način je omogočen"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Osveži zaslon pri dolgih postopkih v glavni niti."</string>
<string name="pointer_location" msgid="7516929526199520173">"Mesto kazalca"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"Izvedba spletnega pogleda"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Nastavitev izvedbe spletnega pogleda"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Ta izbira ni več veljavna. Poskusite znova."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Način barv slike"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Uporaba sRGB-ja"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Onemogočeno"</string>
diff --git a/packages/SettingsLib/res/values-sq/arrays.xml b/packages/SettingsLib/res/values-sq/arrays.xml
index 3b0994a..98429ce 100644
--- a/packages/SettingsLib/res/values-sq/arrays.xml
+++ b/packages/SettingsLib/res/values-sq/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"Vetëm ekrani i pajisjes (parazgjedhja)"</item>
+ <item msgid="9161645858025071955">"Ekrani i jashtëm"</item>
+ <item msgid="23651860565814477">"Prekja e fundit e shiritit të statusit"</item>
+ <item msgid="7521112827893653392">"Bazuar te fokusi"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"Shfaq hijen vetëm në ekranin e pajisjes"</item>
+ <item msgid="1955398604822147783">"Shfaq panelin në një ekran të vetëm të jashtëm"</item>
+ <item msgid="391477482416751568">"Shfaq panelin në ekranin me shiritin e statusit të të cilit është ndërvepruar së fundi"</item>
+ <item msgid="1746820128097981528">"Shfaq panelin në ekranin e fokusuar së fundi"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index 2d2c02b..4e6ec9f 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Ambienti rrethues nuk mund të përditësohej"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktiv (vetëm për media). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> bateri."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktiv (vetëm për media). Majtas: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> bateri, djathtas: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> bateri."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Lidhur (mbështet ndarjen e audios). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> bateri."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Lidhur (mbështet ndarjen e audios). Majtas: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> bateri, djathtas: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> bateri."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Lidhur (mbështet ndarjen e audios). Majtas: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> bateri."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Lidhur (mbështet ndarjen e audios). Djathtas: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> bateri."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Lidhur (mbështet ndarjen e audios)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Aktiv (vetëm për media)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Mbështet ndarjen e audios"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Aktiv (vetëm për media), vetëm majtas"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Aktiv (vetëm për media), vetëm djathtas"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Aktiv (vetëm për media), majtas dhe djathtas"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Interpretimi i përshpejtuar i harduerit"</string>
<string name="media_category" msgid="8122076702526144053">"Media"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Monitorimi"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Aktivizo modalitetin e rreptë"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Ndriço ekranin kur aplikacionet kryejnë operacione të gjata teksa bashkëveprojnë"</string>
<string name="pointer_location" msgid="7516929526199520173">"Vendndodhja e treguesit"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"Zbatimi i WebView"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Cakto zbatimin e WebView"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Kjo zgjedhje nuk është më e vlefshme. Provo përsëri."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Modalitti i ngjyrave të figurës"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Përdor sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Çaktivizuar"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index c053094..96924b9 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Ажурирање окружења није успело"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Активно (само за медије). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> батерије."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Активно (само за медије). Лево: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, десно: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> батерије."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Повезано (подржава дељење звука), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> батерије."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Повезано (подржава дељење звука), лево: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, десно: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> батерије."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Повезано (подржава дељење звука). Лево: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> батерије"</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Повезано (подржава дељење звука). Десно: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> батерије."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Повезано (подржава дељење звука)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Активан (само за медије)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Подржава дељење звука"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Активан (само за медије), само лево"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Активан (само за медије), само десно"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Активан (само за медије), лево и десно"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Хардверски убрзано приказивање"</string>
<string name="media_category" msgid="8122076702526144053">"Медији"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Надгледање"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Омогућен је строги режим"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Екран трепери када апликације обављају дуге операције на главној нити"</string>
<string name="pointer_location" msgid="7516929526199520173">"Локација показивача"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"Примена WebView-а"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Подесите примену WebView-а"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Овај избор више није важећи. Пробајте поново."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Режим боја слика"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Користи sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Онемогућено је"</string>
diff --git a/packages/SettingsLib/res/values-sv/arrays.xml b/packages/SettingsLib/res/values-sv/arrays.xml
index 8a77fdd..1a8c9d8 100644
--- a/packages/SettingsLib/res/values-sv/arrays.xml
+++ b/packages/SettingsLib/res/values-sv/arrays.xml
@@ -295,7 +295,7 @@
<item msgid="7521112827893653392">"Fokusbaserad"</item>
</string-array>
<string-array name="shade_display_awareness_summaries">
- <item msgid="2964753205732912921">"Visa endast skugga på enhetens skärm"</item>
+ <item msgid="2964753205732912921">"Visa panelen endast på enhetens skärm"</item>
<item msgid="1955398604822147783">"Visa skugga på en enda extern skärm"</item>
<item msgid="391477482416751568">"Visa skugga på skärmen där statusfältet senast interagerades med"</item>
<item msgid="1746820128097981528">"Visa skugga på skärmen som sist var i fokus"</item>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index e0897cb..3c7aff6 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Det gick inte att uppdatera omgivningsläget"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktiv (endast media). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batteri."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktiv (endast media). V: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, H: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> batteri."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Ansluten (ljuddelning stöds). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batteri."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Ansluten (ljuddelning stöds). V: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, H: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> batteri."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Ansluten (ljuddelning stöds). Vänster: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batteri."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Ansluten (ljuddelning stöds). Höger: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batteri."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Ansluten (ljuddelning stöds)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Aktiv (endast media)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Ljuddelning stöds"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Aktiv (endast media), endast vänster"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Aktiv (endast media), endast höger"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Aktiv (endast media), vänster och höger"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Hårdvaruaccelererad rendering"</string>
<string name="media_category" msgid="8122076702526144053">"Media"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Övervakning"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Strikt läge aktiverat"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Tänd skärm när app gör omfattande åtgärd på huvudtråd"</string>
<string name="pointer_location" msgid="7516929526199520173">"Pekarens plats"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView-implementering"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Ange WebView-implementering"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Det här alternativet är inte längre giltigt. Försök igen."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Färgläge för bilder"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Använd sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Inaktiverad"</string>
diff --git a/packages/SettingsLib/res/values-sw/arrays.xml b/packages/SettingsLib/res/values-sw/arrays.xml
index 652c358..2ec6256 100644
--- a/packages/SettingsLib/res/values-sw/arrays.xml
+++ b/packages/SettingsLib/res/values-sw/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"Kwenye skrini ya kifaa pekee (Chaguomsingi)"</item>
+ <item msgid="9161645858025071955">"Skrini ya nje"</item>
+ <item msgid="23651860565814477">"Matumizi ya hivi majuzi zaidi ya sehemu ya arifa"</item>
+ <item msgid="7521112827893653392">"Inayoangaziwa"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"Onyesha kiwango kwenye skrini ya kifaa pekee"</item>
+ <item msgid="1955398604822147783">"Onyesha kiwango kwenye skrini moja ya nje"</item>
+ <item msgid="391477482416751568">"Onyesha kiwango kwenye skrini ambayo sehemu yake ya arifa ilitumiwa hivi majuzi"</item>
+ <item msgid="1746820128097981528">"Onyesha kiwango kwenye skrini iliyoangaziwa mwisho kabisa"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index f12597f..4f520b4 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Imeshindwa kusasisha mazingira"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Inatumika (maudhui pekee). Chaji ya betri imefika <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Inatumika (maudhui pekee), Kushoto: chaji ya betri imefika <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, Kulia: chaji ya betri imefika <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Imeunganishwa (inaweza kutumia kipengele cha kusikiliza pamoja). Chaji imefika <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Imeunganishwa (inaweza kutumia kipengele cha kusikiliza pamoja). Kushoto: chaji ya betri imefika <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, Kulia: chaji ya betri imefika <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Imeunganishwa (inaweza kutumia kipengele cha kusikiliza pamoja). Kushoto: chaji ya betri imefika <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Imeunganishwa (inaweza kutumia kipengele cha kusikiliza pamoja). Kulia: chaji ya betri imefika <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Imeunganishwa (inaweza kusikiliza pamoja)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Inatumika (maudhui pekee)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Inaweza kutumia kipengele cha kusikiliza pamoja"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Inatumika (maudhui pekee), kushoto pekee"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Inatumika (maudhui pekee), kulia pekee"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Inatumika (maudhui pekee), kushoto na kulia"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Utekelezaji wa maunzi ulioharakishwa"</string>
<string name="media_category" msgid="8122076702526144053">"Maudhui"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Ufuatiliaji"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Hali makinifu imewashwa"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Fanya skrini imemeteke programu zinapoendeleza shughuli ndefu kwenye skrini kuu"</string>
<string name="pointer_location" msgid="7516929526199520173">"Mahali pa kiashiria"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"Utekelezaji wa WebView"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Weka utekelezaji wa WebView"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Chaguo hili halipo tena. Jaribu tena."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Hali ya rangi ya picha"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Tumia sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Imezimwa"</string>
diff --git a/packages/SettingsLib/res/values-ta/arrays.xml b/packages/SettingsLib/res/values-ta/arrays.xml
index 503cd8f..f42e476 100644
--- a/packages/SettingsLib/res/values-ta/arrays.xml
+++ b/packages/SettingsLib/res/values-ta/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"சாதனக் காட்சி மட்டும் (இயல்பு)"</item>
+ <item msgid="9161645858025071955">"வெளிப்புறக் காட்சி"</item>
+ <item msgid="23651860565814477">"சமீபத்திய நிலைப் பட்டித் தொடுகை"</item>
+ <item msgid="7521112827893653392">"ஃபோகஸ் அடிப்படையிலானது"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"சாதனக் காட்சியில் மட்டும் ஷேடைக் காட்டும்"</item>
+ <item msgid="1955398604822147783">"ஒற்றை வெளிப்புறக் காட்சியில் ஷேடைக் காட்டும்"</item>
+ <item msgid="391477482416751568">"கடைசியாக நிலைப் பட்டி தொடர்புகொண்ட ஷேடைக் காட்சியில் காட்டும்"</item>
+ <item msgid="1746820128097981528">"கடைசியாக ஃபோகஸ் செய்யப்பட்ட காட்சியில் ஷேடைக் காட்டும்"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 1bd2c34..aa34584 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"சுற்றுப்புறங்களைப் புதுப்பிக்க முடியவில்லை"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"செயலிலுள்ளது (மீடியா மட்டும்). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> பேட்டரி."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"செயலிலுள்ளது (மீடியா மட்டும்). இடது பேட்டரி: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, வலது பேட்டரி: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"இணைக்கப்பட்டுள்ளது (ஆடியோ பகிர்வை ஆதரிக்கிறது). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> பேட்டரி."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"இணைக்கப்பட்டுள்ளது (ஆடியோ பகிர்வை ஆதரிக்கிறது). இடது பேட்டரி: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, வலது பேட்டரி: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"இணைக்கப்பட்டுள்ளது (ஆடியோ பகிர்வை ஆதரிக்கிறது). இடது: - <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> பேட்டரி."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"இணைக்கப்பட்டுள்ளது (ஆடியோ பகிர்வை ஆதரிக்கிறது). வலது: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> பேட்டரி."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"இணைக்கப்பட்டுள்ளது (ஆடியோ பகிர்வை ஆதரிக்கிறது)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"செயலிலுள்ளது (மீடியா மட்டும்)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"ஆடியோ பகிர்வை ஆதரிக்கிறது"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"செயலிலுள்ளது (மீடியா மட்டும்), இடதுபுறம் மட்டும்"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"செயலிலுள்ளது (மீடியா மட்டும்), வலதுபுறம் மட்டும்"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"செயலிலுள்ளது (மீடியா மட்டும்), இடதுபுறம் மற்றும் வலதுபுறம்"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"வன்பொருள் முடுக்கத்துடன் கூடிய காட்சியாக்கம்"</string>
<string name="media_category" msgid="8122076702526144053">"மீடியா"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"கண்காணித்தல்"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"நிலையான பயன்முறை இயக்கப்பட்டது"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"முக்கியத் தொடரிழையில் நீண்ட நேரம் செயல்படும்போது திரையைக் காட்சிப்படுத்தும்"</string>
<string name="pointer_location" msgid="7516929526199520173">"குறிப்பான் இடம்"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView செயல்படுத்தல்"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"WebView செயல்படுத்தலை அமை"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"இனி இந்தத் தேர்வைப் பயன்படுத்த முடியாது. மீண்டும் முயலவும்."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"படத்தின் வண்ணப் பயன்முறை"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"sRGBஐப் பயன்படுத்தும்"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"முடக்கப்பட்டது"</string>
diff --git a/packages/SettingsLib/res/values-te/arrays.xml b/packages/SettingsLib/res/values-te/arrays.xml
index f72e4cd..a4e50d0 100644
--- a/packages/SettingsLib/res/values-te/arrays.xml
+++ b/packages/SettingsLib/res/values-te/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"పరికర డిస్ప్లేలో మాత్రమే (ఆటోమేటిక్ సెట్టింగ్)"</item>
+ <item msgid="9161645858025071955">"ఎక్స్టర్నల్ డిస్ప్లే"</item>
+ <item msgid="23651860565814477">"తాకి ఉపయోగించగల లేటెస్ట్ స్టేటస్ బార్"</item>
+ <item msgid="7521112827893653392">"యాక్టివ్గా ఉన్నవి"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"షేడ్ను పరికర డిస్ప్లేలో మాత్రమే చూపండి"</item>
+ <item msgid="1955398604822147783">"ఒక ఎక్స్టర్నల్ డిస్ప్లేలో షేడ్ను చూపండి"</item>
+ <item msgid="391477482416751568">"స్టేటస్ బార్తో చివరిగా ఇంటరాక్ట్ అయిన షేడ్ను డిస్ప్లేలో చూపండి"</item>
+ <item msgid="1746820128097981528">"చివరగా యాక్టివ్గా ఉన్న డిస్ప్లేలో షేడ్ను చూపండి"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index 010344f..cded034 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"పరిసరాలను అప్డేట్ చేయడం సాధ్యం కాలేదు"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"యాక్టివ్ (మీడియా మాత్రమే). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> బ్యాటరీ."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"యాక్టివ్ (మీడియా మాత్రమే). ఎడమ వైపు: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> బ్యాటరీ, కుడివైపు: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> బ్యాటరీ."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"కనెక్ట్ చేయబడింది (ఆడియో షేరింగ్కు సపోర్ట్ చేస్తుంది). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> బ్యాటరీ."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"కనెక్ట్ చేయబడింది (ఆడియో షేరింగ్కు సపోర్ట్ చేస్తుంది). ఎడమ వైపు: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> బ్యాటరీ, కుడివైపు: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> బ్యాటరీ."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"కనెక్ట్ చేయబడింది (ఆడియో షేరింగ్కు సపోర్ట్ చేస్తుంది). ఎడమ వైపు: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> బ్యాటరీ."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"కనెక్ట్ అయింది (ఆడియో షేరింగ్కు సపోర్ట్ చేస్తుంది). కుడివైపు: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> బ్యాటరీ."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"కనెక్ట్ చేయబడింది (ఆడియో షేరింగ్కు సపోర్ట్ చేస్తుంది)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"యాక్టివ్ (మీడియా మాత్రమే)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"ఆడియో షేరింగ్కు సపోర్ట్ చేస్తుంది"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"యాక్టివ్ (మీడియా మాత్రమే), ఎడమ వైపు మాత్రమే"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"యాక్టివ్ (మీడియా మాత్రమే), కుడివైపు మాత్రమే"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"యాక్టివ్ (మీడియా మాత్రమే), ఎడమ, కుడివైపు మాత్రమే"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"హార్డ్వేర్ యాగ్జిలరేషన్ ఆధారిత రెండరింగ్"</string>
<string name="media_category" msgid="8122076702526144053">"మీడియా"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"పర్యవేక్షణ"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"స్ట్రిక్ట్ మోడ్ ఎనేబుల్డ్"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"యాప్లు ప్రధాన థ్రెడ్లో సుదీర్ఘ చర్యలు చేసేటప్పుడు స్క్రీన్ను ఫ్లాష్ చేయండి"</string>
<string name="pointer_location" msgid="7516929526199520173">"పాయింటర్ లొకేషన్"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"వెబ్ వీక్షణ అమలు"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"వెబ్ వీక్షణ అమలుని సెట్ చేయండి"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"ఈ ఎంపిక ఇప్పుడు లేదు. మళ్లీ ట్రై చేయండి."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"చిత్రం రంగు మోడ్"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"sRGB ఉపయోగిస్తుంది"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"డిజేబుల్ చేయబడింది"</string>
diff --git a/packages/SettingsLib/res/values-th/arrays.xml b/packages/SettingsLib/res/values-th/arrays.xml
index adb274d..ad0f6bc 100644
--- a/packages/SettingsLib/res/values-th/arrays.xml
+++ b/packages/SettingsLib/res/values-th/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"จอแสดงผลของอุปกรณ์เท่านั้น (ค่าเริ่มต้น)"</item>
+ <item msgid="9161645858025071955">"จอแสดงผลภายนอก"</item>
+ <item msgid="23651860565814477">"การแตะแถบสถานะล่าสุด"</item>
+ <item msgid="7521112827893653392">"Focus-based"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"แสดงเฉดสีในจอแสดงผลของอุปกรณ์เท่านั้น"</item>
+ <item msgid="1955398604822147783">"แสดงเฉดสีในจอแสดงผลภายนอกเครื่องเดียว"</item>
+ <item msgid="391477482416751568">"แสดงเฉดสีในจอแสดงผลที่มีการโต้ตอบกับแถบสถานะล่าสุด"</item>
+ <item msgid="1746820128097981528">"แสดงเฉดสีในจอแสดงผลที่โฟกัสล่าสุด"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 9b4d408..eaf256d 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"อัปเดตเสียงแวดล้อมไม่ได้"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"ใช้งานอยู่ (สื่อเท่านั้น) แบตเตอรี่ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"ใช้งานอยู่ (สื่อเท่านั้น) แบตเตอรี่ข้างซ้าย: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, ข้างขวา: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>"</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"เชื่อมต่อแล้ว (รองรับการแชร์เสียง) แบตเตอรี่ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"เชื่อมต่อแล้ว (รองรับการแชร์เสียง) แบตเตอรี่ข้างซ้าย: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, ข้างขวา: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>"</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"เชื่อมต่อแล้ว (รองรับการแชร์เสียง) ซ้าย: แบตเตอรี่ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"เชื่อมต่อแล้ว (รองรับการแชร์เสียง) ขวา: แบตเตอรี่ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"เชื่อมต่อแล้ว (รองรับการแชร์เสียง)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"ใช้งานอยู่ (สื่อเท่านั้น)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"รองรับการแชร์เสียง"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"ใช้งานอยู่ (สื่อเท่านั้น), ซ้ายเท่านั้น"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"ใช้งานอยู่ (สื่อเท่านั้น), ขวาเท่านั้น"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"ใช้งานอยู่ (สื่อเท่านั้น), ซ้ายและขวา"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"การแสดงผลที่มีการเร่งด้วยฮาร์ดแวร์"</string>
<string name="media_category" msgid="8122076702526144053">"สื่อ"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"การตรวจสอบ"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"เปิดใช้งานโหมดเข้มงวด"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"กะพริบหน้าจอเมื่อแอปทำงานในเทรดหลักนาน"</string>
<string name="pointer_location" msgid="7516929526199520173">"ตำแหน่งของตัวชี้"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"การใช้งาน WebView"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"ตั้งค่าการใช้งาน WebView"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"ตัวเลือกนี้ใช้ไม่ได้อีกต่อไป โปรดลองอีกครั้ง"</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"โหมดสีของรูปภาพ"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"ใช้ sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"ปิดใช้"</string>
diff --git a/packages/SettingsLib/res/values-tl/arrays.xml b/packages/SettingsLib/res/values-tl/arrays.xml
index 0153375a..b1dd61a 100644
--- a/packages/SettingsLib/res/values-tl/arrays.xml
+++ b/packages/SettingsLib/res/values-tl/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"Display ng device lang (Default)"</item>
+ <item msgid="9161645858025071955">"External na display"</item>
+ <item msgid="23651860565814477">"Pinakahuling pagpindot sa status bar"</item>
+ <item msgid="7521112827893653392">"Focus-based"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"Ipakita ang shade sa display ng device lang"</item>
+ <item msgid="1955398604822147783">"Ipakita ang shade sa isang external na display"</item>
+ <item msgid="391477482416751568">"Ipakita ang shade sa display kung saan may kamakailang nakipag-ugnayan sa status bar nito"</item>
+ <item msgid="1746820128097981528">"Ipakita ang shade sa pinakahuling na-focus na display"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 4cd2f5f..b6d8d19 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Hindi ma-update ang paligid"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktibo (media lang). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterya."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktibo (media lang). L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> baterya."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Nakakonekta (sinusuportahan ang pag-share ng audio), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterya."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Nakakonekta (sinusuportahan ang pag-share ng audio). L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> baterya."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Nakakonekta (sinusuportahan ang pag-share ng audio). Kaliwa: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterya."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Nakakonekta (sinusuportahan ang pag-share ng audio). Kanan: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterya."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Nakakonekta (sinusuportahan ang pag-share ng audio)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Aktibo (media lang)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Sinusuportahan ang pag-share ng audio"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Aktibo (media lang), kaliwa lang"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Aktibo (media lang), kanan lang"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Aktibo (media lang), kaliwa at kanan"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Pag-render na pinapabilis ng hardware"</string>
<string name="media_category" msgid="8122076702526144053">"Media"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Pagsubaybay"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Enabled ang strict mode"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"I-flash ang screen pag may long ops ang app sa main thread"</string>
<string name="pointer_location" msgid="7516929526199520173">"Lokasyon ng pointer"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"Pagpapatupad sa WebView"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Itakda ang pagpapatupad sa WebView"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Wala nang bisa ang napiling ito. Subukang muli."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Mode ng kulay ng larawan"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Gamitin ang sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Naka-disable"</string>
diff --git a/packages/SettingsLib/res/values-tr/arrays.xml b/packages/SettingsLib/res/values-tr/arrays.xml
index 6fbbb12..04697f2 100644
--- a/packages/SettingsLib/res/values-tr/arrays.xml
+++ b/packages/SettingsLib/res/values-tr/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"Yalnızca cihaz ekranı (Varsayılan)"</item>
+ <item msgid="9161645858025071955">"Harici ekran"</item>
+ <item msgid="23651860565814477">"Durum çubuğuyla yapılan en son etkileşim"</item>
+ <item msgid="7521112827893653392">"Odaklanmaya dayalı"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"Gölgeyi yalnızca cihaz ekranında göster"</item>
+ <item msgid="1955398604822147783">"Gölgeyi tek bir harici ekranda göster"</item>
+ <item msgid="391477482416751568">"Gölgeyi, durum çubuğuyla en son etkileşim yapılan ekranda göster"</item>
+ <item msgid="1746820128097981528">"Gölgeyi en son odaklanılan ekranda göster"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index c993223..c4cbaf6 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Çevredeki sesler güncellenemedi"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Etkin (yalnızca medya). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> pil seviyesi."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Etkin (yalnızca medya). Sol: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, Sağ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> pil seviyesi."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Bağlı (ses paylaşımını destekler). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> pil seviyesi."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Bağlı (ses paylaşımını destekler). Sol: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, Sağ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> pil seviyesi."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Bağlı (ses paylaşımını destekler). Sol: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> pil seviyesi."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Bağlı (ses paylaşımını destekler). Sağ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> pil seviyesi."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Bağlı (ses paylaşımını destekler)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Etkin (yalnızca medya)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Ses paylaşımını destekler"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Etkin (yalnızca medya), yalnızca sol"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Etkin (yalnızca medya), yalnızca sağ"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Etkin (yalnızca medya), sol ve sağ"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Donanım hızlandırmalı oluşturma"</string>
<string name="media_category" msgid="8122076702526144053">"Medya"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"İzleme"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Yüksek düzey modu etkin"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Uygulamalar ana iş parçacığında uzun işlem yaparken ekranı yanıp söndür"</string>
<string name="pointer_location" msgid="7516929526199520173">"İşaretçi konumu"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"Web Görünümü kullanımı"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Web Görünümü kullanımını ayarla"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Bu seçenek artık geçerli değil. Tekrar deneyin."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Resim renk modu"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"sRGB\'yi kullan"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Devre dışı"</string>
diff --git a/packages/SettingsLib/res/values-uk/arrays.xml b/packages/SettingsLib/res/values-uk/arrays.xml
index a371c9c..569d6f3 100644
--- a/packages/SettingsLib/res/values-uk/arrays.xml
+++ b/packages/SettingsLib/res/values-uk/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"Лише екран пристрою (за умовчанням)"</item>
+ <item msgid="9161645858025071955">"Зовнішній дисплей"</item>
+ <item msgid="23651860565814477">"Останнє натискання рядка стану"</item>
+ <item msgid="7521112827893653392">"На основі фокусування"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"Показувати панель лише на екрані пристрою"</item>
+ <item msgid="1955398604822147783">"Показувати панель на одному зовнішньому дисплеї"</item>
+ <item msgid="391477482416751568">"Показувати панель на дисплеї, де відбулася остання взаємодія з рядком стану"</item>
+ <item msgid="1746820128097981528">"Показувати панель на останньому активному дисплеї"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index fd1ade6..ecff572 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Не вдалось оновити стан оточення"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Активне з’єднання (лише для мультимедіа). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> заряду акумулятора."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Активне з’єднання (лише для мультимедіа). Рівень заряду: лівий <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, правий: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Підключено (підтримує надсилання аудіо). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> заряду акумулятора."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Підключено (підтримує надсилання аудіо). Лівий: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, правий: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> заряду акумулятора."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Підключено (підтримує надсилання аудіо). Лівий: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> заряду акумулятора."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Підключено (підтримує надсилання аудіо). Правий: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> заряду акумулятора."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Підключено (підтримує надсилання аудіо)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Активно (лише для мультимедіа)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Підтримує надсилання аудіо"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Активно (лише для мультимедіа); лише лівий"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Активно (лише для мультимедіа); лише правий"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Активно (лише для мультимедіа); лівий і правий"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Апаратне прискорення"</string>
<string name="media_category" msgid="8122076702526144053">"Медіа"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Моніторинг"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Строгий режим увімкнено"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Підсвічувати екран під час довгострокових операцій"</string>
<string name="pointer_location" msgid="7516929526199520173">"Розташування курсора"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"Застосування WebView"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Налаштувати застосування WebView"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Ця опція більше не дійсна. Повторіть спробу."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Режим кольору"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Використовувати sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Вимкнено"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index 13ffeb1..3407114 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"اطراف کو اپ ڈیٹ نہیں کیا جا سکا"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"فعال (صرف میڈیا)۔ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> بیٹری۔"</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"فعال (صرف میڈیا)۔ L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>، R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> بیٹری۔"</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"منسلک ہے (آڈیو کے اشتراک کو سپورٹ کرتا ہے)۔ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> بیٹری۔"</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"منسلک ہے (آڈیو کے اشتراک کو سپورٹ کرتا ہے)۔ L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>، R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> بیٹری۔"</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"منسلک ہے (آڈیو کے اشتراک کو سپورٹ کرتا ہے)۔ بائيں: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> بیٹری۔"</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"منسلک ہے (آڈیو کے اشتراک کو سپورٹ کرتا ہے)۔ دائيں: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> بیٹری۔"</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"منسلک ہے (آڈیو کے اشتراک کو سپورٹ کرتا ہے)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"فعال (صرف میڈیا)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"آڈیو کے اشتراک کو سپورٹ کرتا ہے"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"فعال (صرف میڈیا)، صرف بائیں"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"فعال (صرف میڈیا)، صرف دائیں"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"فعال (صرف میڈیا)، بائیں اور دائیں"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"ہارڈ ویئر کے ذریعے تیز کردہ رینڈرنگ"</string>
<string name="media_category" msgid="8122076702526144053">"میڈیا"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"مانیٹر کرنا"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"سخت وضع فعال ہے"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"ایپس کے اصل تھریڈ پر طویل اعمال انجام دیتے وقت اسکرین کو فلیش کریں"</string>
<string name="pointer_location" msgid="7516929526199520173">"پوائنٹر مقام"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView کا نفاذ"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"WebView کا نفاذ سیٹ کریں"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"یہ انتخاب اب درست نہیں رہا۔ دوبارہ کوشش کریں۔"</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"تصویری رنگ موڈ"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"sRGB استعمال کریں"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"غیر فعال"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 04bd7fcc..bff7993 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Atrof-muhit yangilanmadi"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Faol (faqat media uchun) Quvvat: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Faol (faqat media uchun), quvvat: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> (L), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> (R)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Ulangan (audio yuborish mumkin), quvvat: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Ulangan (audio yuborish mumkin), quvvat: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> (L), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> (R)"</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Ulangan (audio yuborish mumkin). Quvvat: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> (chap)."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Ulangan (audio yuborish mumkin). Quvvat: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> (oʻng)."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Ulangan (audio yuborish mumkin)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Faol (faqat media uchun)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Audio yuborishi mumkin"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Faol (faqat media uchun), faqat chap"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Faol (faqat media uchun), faqat oʻng"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Faol (faqat media uchun), chap va oʻng"</string>
@@ -250,11 +270,11 @@
<string name="enable_adb" msgid="8072776357237289039">"USB orqali nosozliklarni aniqlash"</string>
<string name="enable_adb_summary" msgid="3711526030096574316">"USB orqali kompyuterga ulanganda tuzatish rejimi yoqilsin"</string>
<string name="clear_adb_keys" msgid="3010148733140369917">"USB orqali nosozliklarni tuzatishni taqiqlash"</string>
- <string name="enable_adb_wireless" msgid="6973226350963971018">"Wi-Fi orqali debagging"</string>
+ <string name="enable_adb_wireless" msgid="6973226350963971018">"Wi-Fi orqali debaging"</string>
<string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Wi‑Fi tarmoqqa ulanganda nosozliklarni aniqlash rejimi"</string>
<string name="adb_wireless_error" msgid="721958772149779856">"Xato"</string>
- <string name="adb_wireless_settings" msgid="2295017847215680229">"Wi-Fi orqali debagging"</string>
- <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Mavjud qurilmalarni koʻrish va ulardan foydalanish uchun Wi-Fi orqali debagging funksiyasini yoqing"</string>
+ <string name="adb_wireless_settings" msgid="2295017847215680229">"Wi-Fi orqali debaging"</string>
+ <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Mavjud qurilmalarni koʻrish va ulardan foydalanish uchun Wi-Fi orqali debaging funksiyasini yoqing"</string>
<string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Qurilmani QR kod orqali ulash"</string>
<string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"QR kod skaneri yordamida yangi qurilmalarni ulang"</string>
<string name="adb_pair_method_code_title" msgid="1122590300445142904">"Qurilmani ulanish kodi orqali ulash"</string>
@@ -345,8 +365,8 @@
<string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Modem rejimida apparatli tezlatishdan foydalanish (mavjud bo‘lsa)."</string>
<string name="adb_warning_title" msgid="7708653449506485728">"USB orqali nosozliklarni tuzatishga ruxsat berilsinmi?"</string>
<string name="adb_warning_message" msgid="8145270656419669221">"USB orqali nosozliklarni aniqlash faqat dasturlash maqsadlarida yoqiladi. Undan maʼlumotlarni qurilmangiz va kompyuter o‘rtasida ko‘chirish, ilovalarni xabarnomasiz o‘rnatish va jurnal maʼlumotlarini o‘qish uchun foydalaniladi."</string>
- <string name="adbwifi_warning_title" msgid="727104571653031865">"Wi-Fi orqali debagging uchun ruxsat berilsinmi?"</string>
- <string name="adbwifi_warning_message" msgid="8005936574322702388">"Wi-Fi orqali debagging faqat dasturlash maqsadlarida yoqiladi. Undan maʼlumotlarni qurilmangiz va kompyuter oʻrtasida koʻchirish, ilovalarni bildirishnomasiz oʻrnatish va jurnal maʼlumotlarini oʻqish uchun foydalaniladi."</string>
+ <string name="adbwifi_warning_title" msgid="727104571653031865">"Wi-Fi orqali debaging uchun ruxsat berilsinmi?"</string>
+ <string name="adbwifi_warning_message" msgid="8005936574322702388">"Wi-Fi orqali debaging faqat dasturlash maqsadlarida yoqiladi. Undan maʼlumotlarni qurilmangiz va kompyuter oʻrtasida koʻchirish, ilovalarni bildirishnomasiz oʻrnatish va jurnal maʼlumotlarini oʻqish uchun foydalaniladi."</string>
<string name="adb_keys_warning_message" msgid="2968555274488101220">"USB orqali nosozliklarni tuzatishga berilgan ruxsat siz hisobingizga kirgan barcha kompyuterlar uchun bekor qilinsinmi?"</string>
<string name="dev_settings_warning_title" msgid="8251234890169074553">"Dasturlash sozlamalariga ruxsat berilsinmi?"</string>
<string name="dev_settings_warning_message" msgid="37741686486073668">"Bu sozlamalar faqat dasturlash maqsadlariga mo‘ljallangan. Shuning uchun, ular qurilmangizga va undagi ilovalariga shikast yetkazib, noto‘g‘ri ishlashiga sabab bo‘lishi mumkin."</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Vizualizatsiyani apparatli tezlatish"</string>
<string name="media_category" msgid="8122076702526144053">"Multimedia"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Monitoring"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Qat’iy rejim yoqilgan"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Uzun amallar vaqtida ekranni miltillatish"</string>
<string name="pointer_location" msgid="7516929526199520173">"Kursor joylashuvi"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView ta’minotchisi"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"WebView ta’minotchisini sozlash"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Bu variant endi yaroqsiz. Qaytadan urining."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Rang rejimi"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"sRGB ranglaridan foydalanish"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Oʻchiq"</string>
diff --git a/packages/SettingsLib/res/values-vi/arrays.xml b/packages/SettingsLib/res/values-vi/arrays.xml
index 8e4cf53..daddccc 100644
--- a/packages/SettingsLib/res/values-vi/arrays.xml
+++ b/packages/SettingsLib/res/values-vi/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"Chỉ hiển thị trên thiết bị (Mặc định)"</item>
+ <item msgid="9161645858025071955">"Màn hình ngoài"</item>
+ <item msgid="23651860565814477">"Lần gần đây nhất chạm vào thanh trạng thái"</item>
+ <item msgid="7521112827893653392">"Theo tiêu điểm"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"Chỉ hiện ngăn thông báo trên màn hình thiết bị"</item>
+ <item msgid="1955398604822147783">"Hiện ngăn trên một màn hình ngoài"</item>
+ <item msgid="391477482416751568">"Hiện ngăn trên màn hình mà gần đây nhất người dùng đã tương tác với thanh trạng thái của màn hình đó"</item>
+ <item msgid="1746820128097981528">"Hiện ngăn trên màn hình mà gần đây nhất người dùng đã đặt tiêu điểm"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 2763c01..cb0a875a 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Không cập nhật được âm lượng xung quanh"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Đang hoạt động (chỉ phát nội dung đa phương tiện). Còn <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> pin."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Đang hoạt động (chỉ phát nội dung đa phương tiện). Bên trái: Còn <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> pin. Bên phải: Còn <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> pin."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Đã kết nối (có hỗ trợ tính năng chia sẻ âm thanh). Còn <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> pin."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Đã kết nối (có hỗ trợ tính năng chia sẻ âm thanh). Bên trái: Còn <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> pin. Bên phải: Còn <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> pin."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Đã kết nối (có hỗ trợ tính năng chia sẻ âm thanh). Bên trái: Còn <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> pin."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Đã kết nối (có hỗ trợ tính năng chia sẻ âm thanh). Bên phải: Còn <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> pin."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Đã kết nối (có hỗ trợ tính năng chia sẻ âm thanh)."</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Đang hoạt động (chỉ phát nội dung đa phương tiện)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Hỗ trợ tính năng chia sẻ âm thanh"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Đang hoạt động (chỉ phát nội dung đa phương tiện), chỉ dùng tai nghe bên trái"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Đang hoạt động (chỉ phát nội dung đa phương tiện), chỉ dùng tai nghe bên phải"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Đang hoạt động (chỉ phát nội dung đa phương tiện), đang dùng cả tai nghe bên trái và phải"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Kết xuất có tăng tốc phần cứng"</string>
<string name="media_category" msgid="8122076702526144053">"Phương tiện"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Giám sát"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Luôn bật chế độ nghiêm ngặt"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Màn hình nháy khi ứng dụng thực hiện các hoạt động dài trên luồng chính"</string>
<string name="pointer_location" msgid="7516929526199520173">"Vị trí con trỏ"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"Triển khai WebView"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Đặt triển khai WebView"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Lựa chọn này không còn hợp lệ nữa. Hãy thử lại."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Chế độ màu của ảnh"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Sử dụng sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Đã tắt"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/arrays.xml b/packages/SettingsLib/res/values-zh-rCN/arrays.xml
index 5c82865..204bccf 100644
--- a/packages/SettingsLib/res/values-zh-rCN/arrays.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"仅设备显示屏(默认)"</item>
+ <item msgid="9161645858025071955">"外接显示屏"</item>
+ <item msgid="23651860565814477">"最近一次触摸状态栏"</item>
+ <item msgid="7521112827893653392">"基于焦点"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"仅在设备显示屏上显示通知栏"</item>
+ <item msgid="1955398604822147783">"在单个外接显示屏上显示通知栏"</item>
+ <item msgid="391477482416751568">"在上次与状态栏互动的显示屏上显示通知栏"</item>
+ <item msgid="1746820128097981528">"在最近一次获得焦点的显示屏上显示通知栏"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 934c525..f13f7d9 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"无法更新周围声音"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"使用中(仅限媒体)。电池电量为 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>。"</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"使用中(仅限媒体)。左侧电池电量为 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>,右侧电池电量为 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>。"</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"已连接(支持音频分享)。电池电量为 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>。"</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"已连接(支持音频分享)。左侧电池电量为 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>,右侧电池电量为 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>。"</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"已连接(支持音频分享)。左侧电池电量为 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>。"</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"已连接(支持音频分享)。右侧电池电量为 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>。"</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"已连接(支持音频分享)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"使用中(仅限媒体)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"支持音频分享"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"使用中(仅限媒体),仅左侧"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"使用中(仅限媒体),仅右侧"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"使用中(仅限媒体),左侧和右侧"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"硬件加速渲染"</string>
<string name="media_category" msgid="8122076702526144053">"媒体"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"监控"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"启用严格模式"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"应用在主线程上执行长时间操作时闪烁屏幕"</string>
<string name="pointer_location" msgid="7516929526199520173">"指针位置"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView 实现"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"设置 WebView 实现"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"此选项已失效,请重试。"</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"图片颜色模式"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"使用 sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"已停用"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/arrays.xml b/packages/SettingsLib/res/values-zh-rHK/arrays.xml
index 2e06059..f70b02d 100644
--- a/packages/SettingsLib/res/values-zh-rHK/arrays.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"只限裝置顯示屏 (預設)"</item>
+ <item msgid="9161645858025071955">"外部顯示屏"</item>
+ <item msgid="23651860565814477">"最近一次觸碰狀態列"</item>
+ <item msgid="7521112827893653392">"突顯"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"只在裝置顯示屏上顯示陰影"</item>
+ <item msgid="1955398604822147783">"在單一外接螢幕顯示通知欄"</item>
+ <item msgid="391477482416751568">"在上次使用狀態列的螢幕上顯示通知欄"</item>
+ <item msgid="1746820128097981528">"在最新使用的螢幕顯示通知欄"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index 037f531..14976e0 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"無法更新環境聲音"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"啟用 (只限媒體)。<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> 電量。"</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"啟用 (只限媒體),左側:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> 電量,右側:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> 電量。"</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"已連線 (支援音訊分享功能),<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> 電量。"</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"已連線 (支援音訊分享功能),左側:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> 電量,右側:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> 電量。"</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"已連線 (支援音訊分享功能)。左側:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> 電量。"</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"已連線 (支援音訊分享功能)。右側:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> 電量。"</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"已連線 (支援音訊分享功能)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"啟用 (只限媒體)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"支援音訊分享功能"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"左側啟用 (只限媒體)"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"右側啟用 (只限媒體)"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"右側同時啟用 (只限媒體)"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"硬件加速轉譯"</string>
<string name="media_category" msgid="8122076702526144053">"媒體"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"監控"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"嚴格模式已啟用"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"當應用程式在主執行緒中進行長時間作業時,讓螢幕閃爍"</string>
<string name="pointer_location" msgid="7516929526199520173">"指標位置"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView 設置"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"設定 WebView 設置"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"此選擇已失效,請再試一次。"</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"相片顏色模式"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"使用 sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"已停用"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/arrays.xml b/packages/SettingsLib/res/values-zh-rTW/arrays.xml
index 5b48ad4..6ac8ff5 100644
--- a/packages/SettingsLib/res/values-zh-rTW/arrays.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"僅裝置螢幕 (預設)"</item>
+ <item msgid="9161645858025071955">"外接螢幕"</item>
+ <item msgid="23651860565814477">"最近一次觸碰狀態列"</item>
+ <item msgid="7521112827893653392">"使用中的螢幕"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"只在裝置螢幕顯示通知欄"</item>
+ <item msgid="1955398604822147783">"在單一外接螢幕顯示通知欄"</item>
+ <item msgid="391477482416751568">"在上次使用狀態列的螢幕上顯示通知欄"</item>
+ <item msgid="1746820128097981528">"在最新使用的螢幕顯示通知欄"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"預設螢幕"</item>
+ <item msgid="774789415968826925">"任何外接螢幕"</item>
+ <item msgid="7880769915418638436">"最新觸控狀態列"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index 0ef65e6..b65cb4f 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"無法更新環境狀態"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"已啟用 (僅限媒體)。電量:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>。"</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"已啟用 (僅限媒體)。左側電量:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>,右側電量:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>。"</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"已連線 (支援音訊分享)。電量:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>。"</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"已連線 (支援音訊分享)。左側電量:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>,右側電量:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>。"</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"已連線 (支援音訊分享)。左側電量:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>。"</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"已連線 (支援音訊分享)。右側電量:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>。"</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"已連線 (支援音訊分享)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"啟用 (僅限媒體)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"支援音訊分享"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"左側啟用 (僅限媒體)"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"右側啟用 (僅限媒體)"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"左右側同時啟用 (僅限媒體)"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"硬體加速轉譯"</string>
<string name="media_category" msgid="8122076702526144053">"媒體"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"監控"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"嚴格模式已啟用"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"當應用程式在主執行緒中進行長時間作業時,讓螢幕閃爍"</string>
<string name="pointer_location" msgid="7516929526199520173">"指標位置"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView 實作"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"設定 WebView 實作"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"這個選項已失效,請再試一次。"</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"螢幕色彩模式"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"使用 sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"已停用"</string>
diff --git a/packages/SettingsLib/res/values-zu/arrays.xml b/packages/SettingsLib/res/values-zu/arrays.xml
index 1a61f8b..25f9592 100644
--- a/packages/SettingsLib/res/values-zu/arrays.xml
+++ b/packages/SettingsLib/res/values-zu/arrays.xml
@@ -288,10 +288,22 @@
<item msgid="3753634915787796632">"2"</item>
<item msgid="4779928470672877922">"3"</item>
</string-array>
- <!-- no translation found for shade_display_awareness_entries:2 (23651860565814477) -->
- <!-- no translation found for shade_display_awareness_entries:3 (7521112827893653392) -->
- <!-- no translation found for shade_display_awareness_summaries:1 (1955398604822147783) -->
- <!-- no translation found for shade_display_awareness_summaries:2 (391477482416751568) -->
- <!-- no translation found for shade_display_awareness_summaries:3 (1746820128097981528) -->
- <!-- no translation found for shade_display_awareness_values:3 (4313165186636015195) -->
+ <string-array name="shade_display_awareness_entries">
+ <item msgid="816770658383209617">"Ukuboniswa kwedivayisi kuphela (Okuzenzakalelayo)"</item>
+ <item msgid="9161645858025071955">"Ukubonisa Kwangaphandle"</item>
+ <item msgid="23651860565814477">"Thinta ibha yesimo yamuva"</item>
+ <item msgid="7521112827893653392">"Kusekelwe ekugxileni"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_summaries">
+ <item msgid="2964753205732912921">"Bonisa umthunzi esibonisini sedivayisi kuphela"</item>
+ <item msgid="1955398604822147783">"Bonisa umthunzi esibonisini esisodwa sangaphandle"</item>
+ <item msgid="391477482416751568">"Bonisa umthunzi esibonisini kokudlule ebesinesimo sebha okuxhunyanwe naso"</item>
+ <item msgid="1746820128097981528">"Bonisa umthunzi esibonisini sokugcina okugxilwe kuso"</item>
+ </string-array>
+ <string-array name="shade_display_awareness_values">
+ <item msgid="3055776101992426514">"default_display"</item>
+ <item msgid="774789415968826925">"any_external_display"</item>
+ <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+ <item msgid="4313165186636015195">"focused_display"</item>
+ </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index de62628..859c153 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -113,13 +113,33 @@
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Ayikwazanga ukubuyekeza izindawo ezizungezile"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Iyasebenza (imidiya kuphela). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ibhethri."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Iyasebenza (imidiya kuphela). L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> ibhethri."</string>
+ <!-- no translation found for bluetooth_guest_battery_level (2820003593899467676) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered (5404013822067644960) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level (7928347900623812299) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_battery_level_untethered (4458143141394300892) -->
+ <skip />
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Ixhunyiwe (isekela ukwabelana ngokuqoshiwe). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ibhethri."</string>
<string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Ixhunyiwe (isekela ukwabelana ngokuqoshiwe). L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> ibhethri."</string>
<string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Ixhunyiwe (isekela ukwabelana ngokuqoshiwe). Kwesokudla: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ibhethri."</string>
<string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Ixhunyiwe (isekela ukwabelana ngokuqoshiwe). Kwesokudla: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ibhethri."</string>
<string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Ixhunyiwe (isekela ukwabelana ngokuqoshiwe)"</string>
+ <!-- no translation found for bluetooth_guest_battery_level_lea_support (8098327939585013928) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_battery_level_untethered_lea_support (3701035025565668360) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_no_battery_level_lea_support (2977038548753103470) -->
+ <skip />
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Kuyasebenza (imidiya kuphela)"</string>
+ <!-- no translation found for bluetooth_guest_no_battery_level (9122974160381136920) -->
+ <skip />
+ <!-- no translation found for bluetooth_guest_media_only_no_battery_level (7666347601796705721) -->
+ <skip />
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Isekela ukwabelana ngokuqoshiwe"</string>
+ <!-- no translation found for bluetooth_guest_saved_device_lea_support (5621291599518569876) -->
+ <skip />
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Iyasebenza (imidiya kuphela), ngakwesokunxele kuphela"</string>
<string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Kuyasebenza (imidiya kuphela), ngakwesokudla kuphela"</string>
<string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Kuyasebenza (imidiya kuphela), ngakwesokunxele nakwesokudla"</string>
@@ -376,6 +396,8 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Ukunikezelwa okusheshisiwe kwezingxenyekazi zekhompyutha"</string>
<string name="media_category" msgid="8122076702526144053">"Imidiya"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Ukwengamela"</string>
+ <!-- no translation found for window_management_category (2015535427098365170) -->
+ <skip />
<string name="strict_mode" msgid="889864762140862437">"Imodi eqinile ivumelwe"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Ukuphazimisa isikrini uma izinhlelo zokusebenza ziyenza umsebenzi ngesikhathi eside kuchungechunge olukhulu"</string>
<string name="pointer_location" msgid="7516929526199520173">"Isikhombi sendawo"</string>
@@ -470,6 +492,12 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"Ukufakwa ke-WebView"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Sesba ukufakwa kwe-WebView"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Lokhu kukhetha akusavumelekile. Zama futhi."</string>
+ <!-- no translation found for webview_launch_devtools_title (8009687433555367112) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_package (3182544553665113721) -->
+ <skip />
+ <!-- no translation found for webview_launch_devtools_no_activity (4066006313619617140) -->
+ <skip />
<string name="picture_color_mode" msgid="1013807330552931903">"Imodi yombala wesithombe"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"Sebenzisa i-sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Kukhutshaziwe"</string>
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 4b0400f..91ec836 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -889,6 +889,9 @@
<!-- Preference category for monitoring debugging development settings. [CHAR LIMIT=25] -->
<string name="debug_monitoring_category">Monitoring</string>
+ <!-- Preference category to alter window management settings, [CHAR LIMIT=50] -->
+ <string name="window_management_category">Window Management</string>
+
<!-- UI debug setting: always enable strict mode? [CHAR LIMIT=25] -->
<string name="strict_mode">Strict mode enabled</string>
<!-- UI debug setting: show strict mode summary [CHAR LIMIT=50] -->
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
index 4110d53..ba72709 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
@@ -585,7 +585,8 @@
legacy, true);
} catch (RemoteException ignored) {
}
- } catch (NameNotFoundException | IOException e) {
+ } catch (
+ IllegalArgumentException | NameNotFoundException | IOException e) {
Log.w(TAG, "Failed to query stats: " + e);
try {
mBackgroundHandler.mStatsObserver.onGetStatsCompleted(
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
index a00484a..522a436 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
@@ -555,22 +555,17 @@
* connected 2) is Hearing Aid or LE Audio OR 3) connected profile matches currentAudioProfile
*
* @param cachedDevice the CachedBluetoothDevice
- * @param audioManager audio manager to get the current audio profile
+ * @param isOngoingCall get the current audio profile based on if in phone call
* @return if the device is AvailableMediaBluetoothDevice
*/
@WorkerThread
public static boolean isAvailableMediaBluetoothDevice(
- CachedBluetoothDevice cachedDevice, AudioManager audioManager) {
- int audioMode = audioManager.getMode();
+ CachedBluetoothDevice cachedDevice, boolean isOngoingCall) {
int currentAudioProfile;
- if (audioMode == AudioManager.MODE_RINGTONE
- || audioMode == AudioManager.MODE_IN_CALL
- || audioMode == AudioManager.MODE_IN_COMMUNICATION) {
- // in phone call
+ if (isOngoingCall) {
currentAudioProfile = BluetoothProfile.HEADSET;
} else {
- // without phone call
currentAudioProfile = BluetoothProfile.A2DP;
}
@@ -859,22 +854,17 @@
* currentAudioProfile
*
* @param cachedDevice the CachedBluetoothDevice
- * @param audioManager audio manager to get the current audio profile
+ * @param isOngoingCall get the current audio profile based on if in phone call
* @return if the device is AvailableMediaBluetoothDevice
*/
@WorkerThread
public static boolean isConnectedBluetoothDevice(
- CachedBluetoothDevice cachedDevice, AudioManager audioManager) {
- int audioMode = audioManager.getMode();
+ CachedBluetoothDevice cachedDevice, boolean isOngoingCall) {
int currentAudioProfile;
- if (audioMode == AudioManager.MODE_RINGTONE
- || audioMode == AudioManager.MODE_IN_CALL
- || audioMode == AudioManager.MODE_IN_COMMUNICATION) {
- // in phone call
+ if (isOngoingCall) {
currentAudioProfile = BluetoothProfile.HEADSET;
} else {
- // without phone call
currentAudioProfile = BluetoothProfile.A2DP;
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index 97a345e..bb96041 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -1988,6 +1988,17 @@
}
/**
+ * @return {@code true} if {@code cachedBluetoothDevice} has member which is LeAudio device
+ */
+ public boolean hasConnectedLeAudioMemberDevice() {
+ LeAudioProfile leAudio = mProfileManager.getLeAudioProfile();
+ return leAudio != null && getMemberDevice().stream().anyMatch(
+ cachedDevice -> cachedDevice != null && cachedDevice.getDevice() != null
+ && leAudio.getConnectionStatus(cachedDevice.getDevice())
+ == BluetoothProfile.STATE_CONNECTED);
+ }
+
+ /**
* @return {@code true} if {@code cachedBluetoothDevice} supports broadcast assistant profile
*/
public boolean isConnectedLeAudioBroadcastAssistantDevice() {
diff --git a/packages/SettingsLib/src/com/android/settingslib/display/DisplayDensityUtils.java b/packages/SettingsLib/src/com/android/settingslib/display/DisplayDensityUtils.java
index 58e9355..985599c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/display/DisplayDensityUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/display/DisplayDensityUtils.java
@@ -57,7 +57,7 @@
* Summaries for scales smaller than "default" in order of smallest to
* largest.
*/
- private static final int[] SUMMARIES_SMALLER = new int[] {
+ private static final int[] SUMMARIES_SMALLER = new int[]{
R.string.screen_zoom_summary_small
};
@@ -65,7 +65,7 @@
* Summaries for scales larger than "default" in order of smallest to
* largest.
*/
- private static final int[] SUMMARIES_LARGER = new int[] {
+ private static final int[] SUMMARIES_LARGER = new int[]{
R.string.screen_zoom_summary_large,
R.string.screen_zoom_summary_very_large,
R.string.screen_zoom_summary_extremely_large,
@@ -108,7 +108,8 @@
* Creates an instance that stores the density values for the smallest display that satisfies
* the predicate. It is enough to store the values for one display because the same density
* should be set to all the displays that satisfy the predicate.
- * @param context The context
+ *
+ * @param context The context
* @param predicate Determines what displays the density should be set for. The default display
* must satisfy this predicate.
*/
@@ -127,14 +128,10 @@
mCurrentIndex = -1;
return;
}
- if (!mPredicate.test(defaultDisplayInfo)) {
- throw new IllegalArgumentException(
- "Predicate must not filter out the default display.");
- }
- int idOfSmallestDisplay = Display.DEFAULT_DISPLAY;
- int minDimensionPx = Math.min(defaultDisplayInfo.logicalWidth,
- defaultDisplayInfo.logicalHeight);
+ int idOfSmallestDisplay = Display.INVALID_DISPLAY;
+ int minDimensionPx = Integer.MAX_VALUE;
+ DisplayInfo smallestDisplayInfo = null;
for (Display display : mDisplayManager.getDisplays(
DisplayManager.DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED)) {
DisplayInfo info = new DisplayInfo();
@@ -149,9 +146,19 @@
if (minDimension < minDimensionPx) {
minDimensionPx = minDimension;
idOfSmallestDisplay = display.getDisplayId();
+ smallestDisplayInfo = info;
}
}
+ if (smallestDisplayInfo == null) {
+ Log.w(LOG_TAG, "No display satisfies the predicate");
+ mEntries = null;
+ mValues = null;
+ mDefaultDensity = 0;
+ mCurrentIndex = -1;
+ return;
+ }
+
final int defaultDensity =
DisplayDensityUtils.getDefaultDensityForDisplay(idOfSmallestDisplay);
if (defaultDensity <= 0) {
@@ -165,7 +172,12 @@
final Resources res = context.getResources();
- final int currentDensity = defaultDisplayInfo.logicalDensityDpi;
+ int currentDensity;
+ if (mPredicate.test(defaultDisplayInfo)) {
+ currentDensity = defaultDisplayInfo.logicalDensityDpi;
+ } else {
+ currentDensity = smallestDisplayInfo.logicalDensityDpi;
+ }
int currentDensityIndex = -1;
// Compute number of "larger" and "smaller" scales for this display.
@@ -266,16 +278,16 @@
* Returns the default density for the specified display.
*
* @param displayId the identifier of the display
- * @return the default density of the specified display, or {@code -1} if
- * the display does not exist or the density could not be obtained
+ * @return the default density of the specified display, or {@code -1} if the display does not
+ * exist or the density could not be obtained
*/
private static int getDefaultDensityForDisplay(int displayId) {
- try {
- final IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
- return wm.getInitialDisplayDensity(displayId);
- } catch (RemoteException exc) {
- return -1;
- }
+ try {
+ final IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
+ return wm.getInitialDisplayDensity(displayId);
+ } catch (RemoteException exc) {
+ return -1;
+ }
}
/**
diff --git a/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java b/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java
index 51259e2f..e7887ed 100644
--- a/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java
+++ b/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java
@@ -295,9 +295,9 @@
@WhenToDream
public int getWhenToDreamSetting() {
return isActivatedOnDock() && isActivatedOnSleep() ? WHILE_CHARGING_OR_DOCKED
- : isActivatedOnDock() ? WHILE_DOCKED
- : isActivatedOnPostured() ? WHILE_POSTURED
- : isActivatedOnSleep() ? WHILE_CHARGING
+ : isActivatedOnSleep() ? WHILE_CHARGING
+ : isActivatedOnDock() ? WHILE_DOCKED
+ : isActivatedOnPostured() ? WHILE_POSTURED
: NEVER;
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/mobile/TelephonyIcons.java b/packages/SettingsLib/src/com/android/settingslib/mobile/TelephonyIcons.java
index 094567c..9ca4623 100644
--- a/packages/SettingsLib/src/com/android/settingslib/mobile/TelephonyIcons.java
+++ b/packages/SettingsLib/src/com/android/settingslib/mobile/TelephonyIcons.java
@@ -18,6 +18,7 @@
import com.android.settingslib.R;
import com.android.settingslib.SignalIcon.MobileIconGroup;
+import com.android.settingslib.flags.Flags;
import java.util.HashMap;
import java.util.Map;
@@ -29,22 +30,47 @@
//***** Data connection icons
public static final int FLIGHT_MODE_ICON = R.drawable.stat_sys_airplane_mode;
- public static final int ICON_LTE = R.drawable.ic_lte_mobiledata;
- public static final int ICON_LTE_PLUS = R.drawable.ic_lte_plus_mobiledata;
- public static final int ICON_G = R.drawable.ic_g_mobiledata;
- public static final int ICON_E = R.drawable.ic_e_mobiledata;
- public static final int ICON_H = R.drawable.ic_h_mobiledata;
- public static final int ICON_H_PLUS = R.drawable.ic_h_plus_mobiledata;
- public static final int ICON_3G = R.drawable.ic_3g_mobiledata;
- public static final int ICON_4G = R.drawable.ic_4g_mobiledata;
- public static final int ICON_4G_PLUS = R.drawable.ic_4g_plus_mobiledata;
- public static final int ICON_4G_LTE = R.drawable.ic_4g_lte_mobiledata;
- public static final int ICON_4G_LTE_PLUS = R.drawable.ic_4g_lte_plus_mobiledata;
- public static final int ICON_5G_E = R.drawable.ic_5g_e_mobiledata;
- public static final int ICON_1X = R.drawable.ic_1x_mobiledata;
- public static final int ICON_5G = R.drawable.ic_5g_mobiledata;
- public static final int ICON_5G_PLUS = R.drawable.ic_5g_plus_mobiledata;
- public static final int ICON_CWF = R.drawable.ic_carrier_wifi;
+ public static final int ICON_LTE =
+ flagged(R.drawable.ic_lte_mobiledata, R.drawable.ic_lte_mobiledata_updated);
+ public static final int ICON_LTE_PLUS =
+ flagged(R.drawable.ic_lte_plus_mobiledata, R.drawable.ic_lte_plus_mobiledata_updated);
+ public static final int ICON_G =
+ flagged(R.drawable.ic_g_mobiledata, R.drawable.ic_g_mobiledata_updated);
+ public static final int ICON_E =
+ flagged(R.drawable.ic_e_mobiledata, R.drawable.ic_e_mobiledata_updated);
+ public static final int ICON_H =
+ flagged(R.drawable.ic_h_mobiledata, R.drawable.ic_h_mobiledata_updated);
+ public static final int ICON_H_PLUS =
+ flagged(R.drawable.ic_h_plus_mobiledata, R.drawable.ic_h_plus_mobiledata_updated);
+ public static final int ICON_3G =
+ flagged(R.drawable.ic_3g_mobiledata, R.drawable.ic_3g_mobiledata_updated);
+ public static final int ICON_4G =
+ flagged(R.drawable.ic_4g_mobiledata, R.drawable.ic_4g_mobiledata_updated);
+ public static final int ICON_4G_PLUS =
+ flagged(R.drawable.ic_4g_plus_mobiledata, R.drawable.ic_4g_plus_mobiledata_updated);
+ public static final int ICON_4G_LTE =
+ flagged(R.drawable.ic_4g_lte_mobiledata, R.drawable.ic_4g_lte_mobiledata_updated);
+ public static final int ICON_4G_LTE_PLUS =
+ flagged(R.drawable.ic_4g_lte_plus_mobiledata,
+ R.drawable.ic_4g_lte_plus_mobiledata_updated);
+ public static final int ICON_5G_E =
+ flagged(R.drawable.ic_5g_e_mobiledata, R.drawable.ic_5g_e_mobiledata_updated);
+ public static final int ICON_1X =
+ flagged(R.drawable.ic_1x_mobiledata, R.drawable.ic_1x_mobiledata_updated);
+ public static final int ICON_5G =
+ flagged(R.drawable.ic_5g_mobiledata, R.drawable.ic_5g_mobiledata_updated);
+ public static final int ICON_5G_PLUS =
+ flagged(R.drawable.ic_5g_plus_mobiledata, R.drawable.ic_5g_plus_mobiledata_updated);
+ public static final int ICON_CWF =
+ flagged(R.drawable.ic_carrier_wifi, R.drawable.ic_carrier_wifi_updated);
+
+ /** Make it slightly more obvious which resource we are using */
+ private static int flagged(int oldIcon, int newIcon) {
+ if (Flags.newStatusBarIcons()) {
+ return newIcon;
+ }
+ return oldIcon;
+ }
public static final MobileIconGroup CARRIER_NETWORK_CHANGE = new MobileIconGroup(
"CARRIER_NETWORK_CHANGE",
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.kt b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.kt
index c71b19c..88bccc9 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.kt
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.kt
@@ -119,12 +119,16 @@
private fun getIconsBasedOnFlag(): IntArray {
return if (newStatusBarIcons()) {
+ // TODO(b/396664075):
+ // The new wifi icons only define a range of [0, 3]. Since this array is indexed on
+ // level, we can simulate the range squash by mapping both level 3 to drawn-level 2,
+ // and level 4 to drawn-level 3
intArrayOf(
R.drawable.ic_wifi_0,
R.drawable.ic_wifi_1,
R.drawable.ic_wifi_2,
+ R.drawable.ic_wifi_2,
R.drawable.ic_wifi_3,
- R.drawable.ic_wifi_4
)
} else {
intArrayOf(
@@ -141,12 +145,13 @@
private fun getErrorIconsBasedOnFlag(): IntArray {
return if (newStatusBarIcons()) {
+ // See above note, new wifi icons only have 3 bars, so levels 2 and 3 are the same
intArrayOf(
R.drawable.ic_wifi_0_error,
R.drawable.ic_wifi_1_error,
R.drawable.ic_wifi_2_error,
+ R.drawable.ic_wifi_2_error,
R.drawable.ic_wifi_3_error,
- R.drawable.ic_wifi_4_error
)
} else {
intArrayOf(
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/display/DisplayDensityUtilsTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/display/DisplayDensityUtilsTest.java
index bba278a..73cf28f 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/display/DisplayDensityUtilsTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/display/DisplayDensityUtilsTest.java
@@ -88,8 +88,8 @@
@Test
public void createDisplayDensityUtil_onlyDefaultDisplay() throws RemoteException {
- var info = createDisplayInfoForDisplay(Display.DEFAULT_DISPLAY, Display.TYPE_INTERNAL, 2560,
- 1600, 320);
+ var info = createDisplayInfoForDisplay(
+ Display.DEFAULT_DISPLAY, Display.TYPE_INTERNAL, 2560, 1600, 320);
var display = new Display(mDisplayManagerGlobal, info.displayId, info,
(DisplayAdjustments) null);
doReturn(new Display[]{display}).when(mDisplayManager).getDisplays(any());
@@ -126,6 +126,33 @@
assertThat(mDisplayDensityUtils.getValues()).isEqualTo(new int[]{330, 390, 426, 462, 500});
}
+ @Test
+ public void createDisplayDensityUtil_forExternalDisplay() throws RemoteException {
+ // Default display
+ var defaultDisplayInfo = createDisplayInfoForDisplay(Display.DEFAULT_DISPLAY,
+ Display.TYPE_INTERNAL, 2000, 2000, 390);
+ var defaultDisplay = new Display(mDisplayManagerGlobal, defaultDisplayInfo.displayId,
+ defaultDisplayInfo,
+ (DisplayAdjustments) null);
+ doReturn(defaultDisplay).when(mDisplayManager).getDisplay(defaultDisplayInfo.displayId);
+
+ // Create external display
+ var externalDisplayInfo = createDisplayInfoForDisplay(/* displayId= */ 2,
+ Display.TYPE_EXTERNAL, 1920, 1080, 85);
+ var externalDisplay = new Display(mDisplayManagerGlobal, externalDisplayInfo.displayId,
+ externalDisplayInfo,
+ (DisplayAdjustments) null);
+
+ doReturn(new Display[]{externalDisplay, defaultDisplay}).when(mDisplayManager).getDisplays(
+ any());
+ doReturn(externalDisplay).when(mDisplayManager).getDisplay(externalDisplayInfo.displayId);
+
+ mDisplayDensityUtils = new DisplayDensityUtils(mContext,
+ (info) -> info.displayId == externalDisplayInfo.displayId);
+
+ assertThat(mDisplayDensityUtils.getValues()).isEqualTo(new int[]{72, 85, 94, 102, 112});
+ }
+
private DisplayInfo createDisplayInfoForDisplay(int displayId, int displayType,
int width, int height, int density) throws RemoteException {
var displayInfo = new DisplayInfo();
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothUtilsTest.java
index 7c46db9..ebe6128 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothUtilsTest.java
@@ -87,7 +87,6 @@
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private BluetoothDevice mBluetoothDevice;
- @Mock private AudioManager mAudioManager;
@Mock private PackageManager mPackageManager;
@Mock private LeAudioProfile mA2dpProfile;
@Mock private LeAudioProfile mLeAudioProfile;
@@ -446,13 +445,12 @@
assertThat(
BluetoothUtils.isAvailableMediaBluetoothDevice(
- mCachedBluetoothDevice, mAudioManager))
+ mCachedBluetoothDevice, /* isOngoingCall= */ false))
.isTrue();
}
@Test
public void isAvailableMediaBluetoothDevice_isHeadset_isConnectedA2dpDevice_returnFalse() {
- when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_RINGTONE);
when(mCachedBluetoothDevice.isConnectedA2dpDevice()).thenReturn(true);
when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
@@ -460,13 +458,12 @@
assertThat(
BluetoothUtils.isAvailableMediaBluetoothDevice(
- mCachedBluetoothDevice, mAudioManager))
+ mCachedBluetoothDevice, /* isOngoingCall= */ true))
.isFalse();
}
@Test
public void isAvailableMediaBluetoothDevice_isA2dp_isConnectedA2dpDevice_returnTrue() {
- when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_NORMAL);
when(mCachedBluetoothDevice.isConnectedA2dpDevice()).thenReturn(true);
when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
@@ -474,13 +471,12 @@
assertThat(
BluetoothUtils.isAvailableMediaBluetoothDevice(
- mCachedBluetoothDevice, mAudioManager))
+ mCachedBluetoothDevice, /* isOngoingCall= */ false))
.isTrue();
}
@Test
public void isAvailableMediaBluetoothDevice_isHeadset_isConnectedHfpDevice_returnTrue() {
- when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_RINGTONE);
when(mCachedBluetoothDevice.isConnectedHfpDevice()).thenReturn(true);
when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
@@ -488,7 +484,7 @@
assertThat(
BluetoothUtils.isAvailableMediaBluetoothDevice(
- mCachedBluetoothDevice, mAudioManager))
+ mCachedBluetoothDevice, /* isOngoingCall= */ true))
.isTrue();
}
@@ -499,56 +495,52 @@
when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
when(mBluetoothDevice.isConnected()).thenReturn(true);
- assertThat(BluetoothUtils.isConnectedBluetoothDevice(mCachedBluetoothDevice, mAudioManager))
- .isFalse();
+ assertThat(BluetoothUtils.isConnectedBluetoothDevice(
+ mCachedBluetoothDevice, /* isOngoingCall= */ false)).isFalse();
}
@Test
public void isConnectedBluetoothDevice_isHeadset_isConnectedA2dpDevice_returnTrue() {
- when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_RINGTONE);
when(mCachedBluetoothDevice.isConnectedA2dpDevice()).thenReturn(true);
when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
when(mBluetoothDevice.isConnected()).thenReturn(true);
- assertThat(BluetoothUtils.isConnectedBluetoothDevice(mCachedBluetoothDevice, mAudioManager))
- .isTrue();
+ assertThat(BluetoothUtils.isConnectedBluetoothDevice(
+ mCachedBluetoothDevice, /* isOngoingCall= */ true)).isTrue();
}
@Test
public void isConnectedBluetoothDevice_isA2dp_isConnectedA2dpDevice_returnFalse() {
- when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_NORMAL);
when(mCachedBluetoothDevice.isConnectedA2dpDevice()).thenReturn(true);
when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
when(mBluetoothDevice.isConnected()).thenReturn(true);
- assertThat(BluetoothUtils.isConnectedBluetoothDevice(mCachedBluetoothDevice, mAudioManager))
- .isFalse();
+ assertThat(BluetoothUtils.isConnectedBluetoothDevice(
+ mCachedBluetoothDevice, /* isOngoingCall= */ false)).isFalse();
}
@Test
public void isConnectedBluetoothDevice_isHeadset_isConnectedHfpDevice_returnFalse() {
- when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_RINGTONE);
when(mCachedBluetoothDevice.isConnectedHfpDevice()).thenReturn(true);
when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
when(mBluetoothDevice.isConnected()).thenReturn(true);
- assertThat(BluetoothUtils.isConnectedBluetoothDevice(mCachedBluetoothDevice, mAudioManager))
- .isFalse();
+ assertThat(BluetoothUtils.isConnectedBluetoothDevice(
+ mCachedBluetoothDevice, /* isOngoingCall= */ true)).isFalse();
}
@Test
public void isConnectedBluetoothDevice_isNotConnected_returnFalse() {
- when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_RINGTONE);
when(mCachedBluetoothDevice.isConnectedA2dpDevice()).thenReturn(true);
when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
when(mBluetoothDevice.isConnected()).thenReturn(false);
- assertThat(BluetoothUtils.isConnectedBluetoothDevice(mCachedBluetoothDevice, mAudioManager))
- .isFalse();
+ assertThat(BluetoothUtils.isConnectedBluetoothDevice(
+ mCachedBluetoothDevice, /* isOngoingCall= */ true)).isFalse();
}
@Test
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/dream/DreamBackendTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/dream/DreamBackendTest.java
index 00ae96c..c21eb0c 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/dream/DreamBackendTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/dream/DreamBackendTest.java
@@ -16,6 +16,8 @@
package com.android.settingslib.dream;
+import static android.service.dreams.Flags.FLAG_ALLOW_DREAM_WHEN_POSTURED;
+
import static com.android.settingslib.dream.DreamBackend.COMPLICATION_TYPE_DATE;
import static com.android.settingslib.dream.DreamBackend.COMPLICATION_TYPE_HOME_CONTROLS;
import static com.android.settingslib.dream.DreamBackend.COMPLICATION_TYPE_TIME;
@@ -28,6 +30,7 @@
import android.content.ContentResolver;
import android.content.Context;
import android.content.res.Resources;
+import android.platform.test.annotations.EnableFlags;
import android.provider.Settings;
import org.junit.After;
@@ -173,6 +176,58 @@
.containsExactlyElementsIn(enabledComplications);
}
+ @Test
+ @EnableFlags(FLAG_ALLOW_DREAM_WHEN_POSTURED)
+ public void testChargingAndPosturedBothEnabled() {
+ Settings.Secure.putInt(
+ mContext.getContentResolver(),
+ Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP,
+ 1
+ );
+ Settings.Secure.putInt(
+ mContext.getContentResolver(),
+ Settings.Secure.SCREENSAVER_ACTIVATE_ON_POSTURED,
+ 1
+ );
+
+ assertThat(mBackend.getWhenToDreamSetting()).isEqualTo(DreamBackend.WHILE_CHARGING);
+ }
+
+ @Test
+ public void testChargingAndDockedBothEnabled() {
+ Settings.Secure.putInt(
+ mContext.getContentResolver(),
+ Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP,
+ 1
+ );
+ Settings.Secure.putInt(
+ mContext.getContentResolver(),
+ Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK,
+ 1
+ );
+
+ assertThat(mBackend.getWhenToDreamSetting()).isEqualTo(
+ DreamBackend.WHILE_CHARGING_OR_DOCKED);
+ }
+
+ @Test
+ @EnableFlags(FLAG_ALLOW_DREAM_WHEN_POSTURED)
+ public void testPosturedAndDockedBothEnabled() {
+ Settings.Secure.putInt(
+ mContext.getContentResolver(),
+ Settings.Secure.SCREENSAVER_ACTIVATE_ON_POSTURED,
+ 1
+ );
+ Settings.Secure.putInt(
+ mContext.getContentResolver(),
+ Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK,
+ 1
+ );
+
+ assertThat(mBackend.getWhenToDreamSetting()).isEqualTo(
+ DreamBackend.WHILE_DOCKED);
+ }
+
private void setControlsEnabledOnLockscreen(boolean enabled) {
Settings.Secure.putInt(
mContext.getContentResolver(),
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 9505977..f03a5fb 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -1696,6 +1696,7 @@
proto.write(SettingProto.DEFAULT_VALUE, setting.getDefaultValue());
proto.write(SettingProto.DEFAULT_FROM_SYSTEM, setting.isDefaultFromSystem());
}
+ proto.write(SettingProto.PRESERVED_IN_RESTORE, setting.isValuePreservedInRestore());
proto.end(settingsToken);
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 7c588b3..8e3aa65 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -988,6 +988,11 @@
if (setting.getTag() != null) {
pw.print(" tag:"); pw.print(setting.getTag());
}
+ // The majority of settings are preserved in restore, so we're just dumping those that
+ // are not (to save space).
+ if (!setting.isValuePreservedInRestore()) {
+ pw.println(" notPreservedInRestore");
+ }
pw.println();
}
}
diff --git a/packages/SoundPicker/res/values-fr/strings.xml b/packages/SoundPicker/res/values-fr/strings.xml
index 9452e70..bfcbc67 100644
--- a/packages/SoundPicker/res/values-fr/strings.xml
+++ b/packages/SoundPicker/res/values-fr/strings.xml
@@ -18,7 +18,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="ringtone_default" msgid="798836092118824500">"Sonnerie par défaut"</string>
<string name="notification_sound_default" msgid="8133121186242636840">"Son de notification par défaut"</string>
- <string name="alarm_sound_default" msgid="4787646764557462649">"Son de l\'alarme par défaut"</string>
+ <string name="alarm_sound_default" msgid="4787646764557462649">"Son par défaut de l\'alarme"</string>
<string name="add_ringtone_text" msgid="6642389991738337529">"Ajouter une sonnerie"</string>
<string name="add_alarm_text" msgid="3545497316166999225">"Ajouter une alarme"</string>
<string name="add_notification_text" msgid="4431129543300614788">"Ajouter une notification"</string>
diff --git a/packages/SoundPicker/res/values-mr/strings.xml b/packages/SoundPicker/res/values-mr/strings.xml
index 3ddb991..39c7c4b 100644
--- a/packages/SoundPicker/res/values-mr/strings.xml
+++ b/packages/SoundPicker/res/values-mr/strings.xml
@@ -17,7 +17,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="ringtone_default" msgid="798836092118824500">"डीफॉल्ट रिंगटोन"</string>
- <string name="notification_sound_default" msgid="8133121186242636840">"डीफॉल्ट सूचना आवाज"</string>
+ <string name="notification_sound_default" msgid="8133121186242636840">"डीफॉल्ट नोटिफिकेशन आवाज"</string>
<string name="alarm_sound_default" msgid="4787646764557462649">"डीफॉल्ट अलार्म आवाज"</string>
<string name="add_ringtone_text" msgid="6642389991738337529">"रिंगटोन जोडा"</string>
<string name="add_alarm_text" msgid="3545497316166999225">"अलार्म जोडा"</string>
diff --git a/packages/SystemUI/OWNERS b/packages/SystemUI/OWNERS
index 236654d..f5c0233 100644
--- a/packages/SystemUI/OWNERS
+++ b/packages/SystemUI/OWNERS
@@ -8,7 +8,6 @@
acul@google.com
adamcohen@google.com
aioana@google.com
-alexchau@google.com
alexflo@google.com
andonian@google.com
amiko@google.com
@@ -91,10 +90,8 @@
rgl@google.com
roosa@google.com
saff@google.com
-samcackett@google.com
santie@google.com
shanh@google.com
-silvajordan@google.com
snoeberger@google.com
spdonghao@google.com
steell@google.com
@@ -106,7 +103,6 @@
tracyzhou@google.com
tsuji@google.com
twickham@google.com
-uwaisashraf@google.com
vadimt@google.com
valiiftime@google.com
vanjan@google.com
@@ -121,3 +117,11 @@
yurilin@google.com
yuzhechen@google.com
zakcohen@google.com
+
+# Overview eng team
+alexchau@google.com
+samcackett@google.com
+silvajordan@google.com
+uwaisashraf@google.com
+vinayjoglekar@google.com
+willosborn@google.com
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index 0ccb20c..eb5b22f 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -974,6 +974,26 @@
}
flag {
+ name: "use_notif_inflation_thread_for_footer"
+ namespace: "systemui"
+ description: "use the @NotifInflation thread for FooterView and EmptyShadeView inflation"
+ bug: "375320642"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
+ name: "use_notif_inflation_thread_for_row"
+ namespace: "systemui"
+ description: "use the @NotifInflation thread for ExpandableNotificationRow inflation"
+ bug: "375320642"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "notify_power_manager_user_activity_background"
namespace: "systemui"
description: "Decide whether to notify the user activity to power manager in the background thread."
@@ -1350,6 +1370,16 @@
}
flag {
+ name: "media_controls_a11y_colors"
+ namespace: "systemui"
+ description: "Color scheme updates for improved a11y"
+ bug: "378848399"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "output_switcher_redesign"
namespace: "systemui"
description: "Enables visual update for Media Output Switcher"
@@ -1895,6 +1925,13 @@
}
flag {
+ name: "physical_notification_movement"
+ namespace: "systemui"
+ description: "Make notifications use physics based animations for movement"
+ bug: "393581344"
+}
+
+flag {
name: "glanceable_hub_direct_edit_mode"
namespace: "systemui"
description: "Invokes edit mode directly from long press in glanceable hub"
@@ -1977,6 +2014,16 @@
}
flag {
+ name: "hardware_color_styles"
+ namespace: "systemui"
+ description: "Enables loading initial colors based ion hardware color"
+ bug: "347286986"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "shade_launch_accessibility"
namespace: "systemui"
description: "Intercept accessibility focus events for the Shade during launch animations to avoid stray TalkBack events."
@@ -2026,3 +2073,13 @@
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "skip_hide_sensitive_notif_animation"
+ namespace: "systemui"
+ description: "Skip hide sensitive notification animation when the showing layout is not changed."
+ bug: "390624334"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
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 65cd3c7..444389f 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewTransitionAnimatorController.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewTransitionAnimatorController.kt
@@ -36,6 +36,7 @@
import android.widget.FrameLayout
import com.android.internal.jank.Cuj.CujType
import com.android.internal.jank.InteractionJankMonitor
+import com.android.systemui.Flags
import java.util.LinkedList
import kotlin.math.min
import kotlin.math.roundToInt
@@ -58,7 +59,7 @@
@JvmOverloads
constructor(
/** The view that will be ghosted and from which the background will be extracted. */
- private val ghostedView: View,
+ transitioningView: View,
/** The [CujType] associated to this launch animation. */
private val launchCujType: Int? = null,
@@ -75,11 +76,24 @@
private val isEphemeral: Boolean = false,
private var interactionJankMonitor: InteractionJankMonitor =
InteractionJankMonitor.getInstance(),
+
+ /** [ViewTransitionRegistry] to store the mapping of transitioning view and its token */
+ private val transitionRegistry: IViewTransitionRegistry? =
+ if (Flags.decoupleViewControllerInAnimlib()) {
+ ViewTransitionRegistry.instance
+ } else {
+ null
+ }
) : ActivityTransitionAnimator.Controller {
override val isLaunching: Boolean = true
/** The container to which we will add the ghost view and expanding background. */
- override var transitionContainer = ghostedView.rootView as ViewGroup
+ override var transitionContainer: ViewGroup
+ get() = ghostedView.rootView as ViewGroup
+ set(_) {
+ // empty, should never be set to avoid memory leak
+ }
+
private val transitionContainerOverlay: ViewGroupOverlay
get() = transitionContainer.overlay
@@ -138,9 +152,33 @@
}
}
+ /** [ViewTransitionToken] to be used for storing transitioning view in [transitionRegistry] */
+ private val transitionToken =
+ if (Flags.decoupleViewControllerInAnimlib()) {
+ ViewTransitionToken(transitioningView::class.java)
+ } else {
+ null
+ }
+
+ /** The view that will be ghosted and from which the background will be extracted */
+ private val ghostedView: View
+ get() =
+ if (Flags.decoupleViewControllerInAnimlib()) {
+ transitionRegistry?.getView(transitionToken!!)
+ } else {
+ _ghostedView
+ }!!
+
+ private val _ghostedView =
+ if (Flags.decoupleViewControllerInAnimlib()) {
+ null
+ } else {
+ transitioningView
+ }
+
init {
// Make sure the View we launch from implements LaunchableView to avoid visibility issues.
- if (ghostedView !is LaunchableView) {
+ if (transitioningView !is LaunchableView) {
throw IllegalArgumentException(
"A GhostedViewLaunchAnimatorController was created from a View that does not " +
"implement LaunchableView. This can lead to subtle bugs where the visibility " +
@@ -148,6 +186,10 @@
)
}
+ if (Flags.decoupleViewControllerInAnimlib()) {
+ transitionRegistry?.register(transitionToken!!, transitioningView)
+ }
+
/** Find the first view with a background in [view] and its children. */
fun findBackground(view: View): Drawable? {
if (view.background != null) {
@@ -184,6 +226,7 @@
if (TransitionAnimator.returnAnimationsEnabled()) {
ghostedView.removeOnAttachStateChangeListener(detachListener)
}
+ transitionToken?.let { token -> transitionRegistry?.unregister(token) }
}
/**
@@ -237,7 +280,7 @@
val insets = backgroundInsets
val boundCorrections: Rect =
if (ghostedView is LaunchableView) {
- ghostedView.getPaddingForLaunchAnimation()
+ (ghostedView as LaunchableView).getPaddingForLaunchAnimation()
} else {
Rect()
}
@@ -387,8 +430,8 @@
if (ghostedView is LaunchableView) {
// Restore the ghosted view visibility.
- ghostedView.setShouldBlockVisibilityChanges(false)
- ghostedView.onActivityLaunchAnimationEnd()
+ (ghostedView as LaunchableView).setShouldBlockVisibilityChanges(false)
+ (ghostedView as LaunchableView).onActivityLaunchAnimationEnd()
} else {
// Make the ghosted view visible. We ensure that the view is considered VISIBLE by
// accessibility by first making it INVISIBLE then VISIBLE (see b/204944038#comment17
@@ -398,7 +441,7 @@
ghostedView.invalidate()
}
- if (isEphemeral) {
+ if (isEphemeral || Flags.decoupleViewControllerInAnimlib()) {
onDispose()
}
}
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/IViewTransitionRegistry.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/IViewTransitionRegistry.kt
new file mode 100644
index 0000000..af3ca87
--- /dev/null
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/IViewTransitionRegistry.kt
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2025 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.animation
+
+import android.view.View
+
+/** Represents a Registry for holding a transitioning view mapped to a token */
+interface IViewTransitionRegistry {
+
+ /**
+ * Registers the transitioning [view] mapped to a [token]
+ *
+ * @param token The token corresponding to the transitioning view
+ * @param view The view undergoing transition
+ */
+ fun register(token: ViewTransitionToken, view: View)
+
+ /**
+ * Unregisters the transitioned view from its corresponding [token]
+ *
+ * @param token The token corresponding to the transitioning view
+ */
+ fun unregister(token: ViewTransitionToken)
+
+ /**
+ * Extracts a transitioning view from registry using its corresponding [token]
+ *
+ * @param token The token corresponding to the transitioning view
+ */
+ fun getView(token: ViewTransitionToken): View?
+
+ /**
+ * Return token mapped to the [view], if it is present in the registry
+ *
+ * @param view the transitioning view whose token we are requesting
+ * @return token associated with the [view] if present, else null
+ */
+ fun getViewToken(view: View): ViewTransitionToken?
+
+ /** Event call to run on registry update (on both [register] and [unregister]) */
+ fun onRegistryUpdate()
+}
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt
index b9f9bc7..5b073e4 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt
@@ -27,9 +27,8 @@
import android.text.Layout
import android.util.Log
import android.util.LruCache
-
-private const val DEFAULT_ANIMATION_DURATION: Long = 300
-private const val TYPEFACE_CACHE_MAX_ENTRIES = 5
+import androidx.annotation.VisibleForTesting
+import com.android.app.animation.Interpolators
typealias GlyphCallback = (TextAnimator.PositionedGlyph, Float) -> Unit
@@ -76,6 +75,10 @@
cache.put(fvar, it)
}
}
+
+ companion object {
+ private const val TYPEFACE_CACHE_MAX_ENTRIES = 5
+ }
}
/**
@@ -108,25 +111,12 @@
private val typefaceCache: TypefaceVariantCache,
private val invalidateCallback: () -> Unit = {},
) {
- // Following two members are for mutable for testing purposes.
- public var textInterpolator = TextInterpolator(layout, typefaceCache)
- public var animator =
- ValueAnimator.ofFloat(1f).apply {
- duration = DEFAULT_ANIMATION_DURATION
- addUpdateListener {
- textInterpolator.progress = it.animatedValue as Float
- textInterpolator.linearProgress =
- it.currentPlayTime.toFloat() / it.duration.toFloat()
- invalidateCallback()
- }
- addListener(
- object : AnimatorListenerAdapter() {
- override fun onAnimationEnd(animation: Animator) = textInterpolator.rebase()
+ @VisibleForTesting var textInterpolator = TextInterpolator(layout, typefaceCache)
+ @VisibleForTesting var createAnimator: () -> ValueAnimator = { ValueAnimator.ofFloat(1f) }
- override fun onAnimationCancel(animation: Animator) = textInterpolator.rebase()
- }
- )
- }
+ var animator: ValueAnimator? = null
+
+ val fontVariationUtils = FontVariationUtils()
sealed class PositionedGlyph {
/** Mutable X coordinate of the glyph position relative from drawing offset. */
@@ -165,8 +155,6 @@
protected set
}
- private val fontVariationUtils = FontVariationUtils()
-
fun updateLayout(layout: Layout, textSize: Float = -1f) {
textInterpolator.layout = layout
@@ -178,9 +166,8 @@
}
}
- fun isRunning(): Boolean {
- return animator.isRunning
- }
+ val isRunning: Boolean
+ get() = animator?.isRunning ?: false
/**
* GlyphFilter applied just before drawing to canvas for tweaking positions and text size.
@@ -237,110 +224,110 @@
fun draw(c: Canvas) = textInterpolator.draw(c)
- /**
- * Set text style with animation.
- *
- * ```
- * By passing -1 to weight, the view preserve the current weight.
- * By passing -1 to textSize, the view preserve the current text size.
- * By passing -1 to duration, the default text animation, 1000ms, is used.
- * By passing false to animate, the text will be updated without animation.
- * ```
- *
- * @param fvar an optional text fontVariationSettings.
- * @param textSize an optional font size.
- * @param colors an optional colors array that must be the same size as numLines passed to the
- * TextInterpolator
- * @param strokeWidth an optional paint stroke width
- * @param animate an optional boolean indicating true for showing style transition as animation,
- * false for immediate style transition. True by default.
- * @param duration an optional animation duration in milliseconds. This is ignored if animate is
- * false.
- * @param interpolator an optional time interpolator. If null is passed, last set interpolator
- * will be used. This is ignored if animate is false.
- */
- fun setTextStyle(
- fvar: String? = "",
- textSize: Float = -1f,
- color: Int? = null,
- strokeWidth: Float = -1f,
- animate: Boolean = true,
- duration: Long = -1L,
- interpolator: TimeInterpolator? = null,
- delay: Long = 0,
- onAnimationEnd: Runnable? = null,
+ /** Style spec to use when rendering the font */
+ data class Style(
+ val fVar: String? = null,
+ val textSize: Float? = null,
+ val color: Int? = null,
+ val strokeWidth: Float? = null,
) {
- setTextStyleInternal(
- fvar,
- textSize,
- color,
- strokeWidth,
- animate,
- duration,
- interpolator,
- delay,
- onAnimationEnd,
- updateLayoutOnFailure = true,
- )
+ fun withUpdatedFVar(
+ fontVariationUtils: FontVariationUtils,
+ weight: Int = -1,
+ width: Int = -1,
+ opticalSize: Int = -1,
+ roundness: Int = -1,
+ ): Style {
+ return this.copy(
+ fVar =
+ fontVariationUtils.updateFontVariation(
+ weight = weight,
+ width = width,
+ opticalSize = opticalSize,
+ roundness = roundness,
+ )
+ )
+ }
+ }
+
+ /** Animation Spec for use when style changes should be animated */
+ data class Animation(
+ val animate: Boolean = true,
+ val startDelay: Long = 0,
+ val duration: Long = DEFAULT_ANIMATION_DURATION,
+ val interpolator: TimeInterpolator = Interpolators.LINEAR,
+ val onAnimationEnd: Runnable? = null,
+ ) {
+ fun configureAnimator(animator: Animator) {
+ animator.startDelay = startDelay
+ animator.duration = duration
+ animator.interpolator = interpolator
+ if (onAnimationEnd != null) {
+ animator.addListener(
+ object : AnimatorListenerAdapter() {
+ override fun onAnimationEnd(animation: Animator) {
+ onAnimationEnd.run()
+ }
+ }
+ )
+ }
+ }
+
+ companion object {
+ val DISABLED = Animation(animate = false)
+ }
+ }
+
+ /** Sets the text style, optionally with animation */
+ fun setTextStyle(style: Style, animation: Animation = Animation.DISABLED) {
+ animator?.cancel()
+ setTextStyleInternal(style, rebase = animation.animate)
+
+ if (animation.animate) {
+ animator = buildAnimator(animation).apply { start() }
+ } else {
+ textInterpolator.progress = 1f
+ textInterpolator.rebase()
+ invalidateCallback()
+ }
+ }
+
+ /** Builds a ValueAnimator from the specified animation parameters */
+ private fun buildAnimator(animation: Animation): ValueAnimator {
+ return createAnimator().apply {
+ duration = DEFAULT_ANIMATION_DURATION
+ animation.configureAnimator(this)
+
+ addUpdateListener {
+ textInterpolator.progress = it.animatedValue as Float
+ textInterpolator.linearProgress = it.currentPlayTime / it.duration.toFloat()
+ invalidateCallback()
+ }
+
+ addListener(
+ object : AnimatorListenerAdapter() {
+ override fun onAnimationEnd(animator: Animator) = textInterpolator.rebase()
+
+ override fun onAnimationCancel(animator: Animator) = textInterpolator.rebase()
+ }
+ )
+ }
}
private fun setTextStyleInternal(
- fvar: String?,
- textSize: Float,
- color: Int?,
- strokeWidth: Float,
- animate: Boolean,
- duration: Long,
- interpolator: TimeInterpolator?,
- delay: Long,
- onAnimationEnd: Runnable?,
- updateLayoutOnFailure: Boolean,
+ style: Style,
+ rebase: Boolean,
+ updateLayoutOnFailure: Boolean = true,
) {
try {
- if (animate) {
- animator.cancel()
- textInterpolator.rebase()
- }
-
- if (textSize >= 0) {
- textInterpolator.targetPaint.textSize = textSize
- }
- if (!fvar.isNullOrBlank()) {
- textInterpolator.targetPaint.typeface = typefaceCache.getTypefaceForVariant(fvar)
- }
- if (color != null) {
- textInterpolator.targetPaint.color = color
- }
- if (strokeWidth >= 0F) {
- textInterpolator.targetPaint.strokeWidth = strokeWidth
+ if (rebase) textInterpolator.rebase()
+ style.color?.let { textInterpolator.targetPaint.color = it }
+ style.textSize?.let { textInterpolator.targetPaint.textSize = it }
+ style.strokeWidth?.let { textInterpolator.targetPaint.strokeWidth = it }
+ style.fVar?.let {
+ textInterpolator.targetPaint.typeface = typefaceCache.getTypefaceForVariant(it)
}
textInterpolator.onTargetPaintModified()
-
- if (animate) {
- animator.startDelay = delay
- animator.duration = if (duration == -1L) DEFAULT_ANIMATION_DURATION else duration
- interpolator?.let { animator.interpolator = it }
- if (onAnimationEnd != null) {
- animator.addListener(
- object : AnimatorListenerAdapter() {
- override fun onAnimationEnd(animation: Animator) {
- onAnimationEnd.run()
- animator.removeListener(this)
- }
-
- override fun onAnimationCancel(animation: Animator) {
- animator.removeListener(this)
- }
- }
- )
- }
- animator.start()
- } else {
- // No animation is requested, thus set base and target state to the same state.
- textInterpolator.progress = 1f
- textInterpolator.rebase()
- invalidateCallback()
- }
} catch (ex: IllegalArgumentException) {
if (updateLayoutOnFailure) {
Log.e(
@@ -351,81 +338,15 @@
)
updateLayout(textInterpolator.layout)
- setTextStyleInternal(
- fvar,
- textSize,
- color,
- strokeWidth,
- animate,
- duration,
- interpolator,
- delay,
- onAnimationEnd,
- updateLayoutOnFailure = false,
- )
+ setTextStyleInternal(style, rebase, updateLayoutOnFailure = false)
} else {
throw ex
}
}
}
- /**
- * Set text style with animation. Similar as
- *
- * ```
- * fun setTextStyle(
- * fvar: String? = "",
- * textSize: Float = -1f,
- * color: Int? = null,
- * strokeWidth: Float = -1f,
- * animate: Boolean = true,
- * duration: Long = -1L,
- * interpolator: TimeInterpolator? = null,
- * delay: Long = 0,
- * onAnimationEnd: Runnable? = null
- * )
- * ```
- *
- * @param weight an optional style value for `wght` in fontVariationSettings.
- * @param width an optional style value for `wdth` in fontVariationSettings.
- * @param opticalSize an optional style value for `opsz` in fontVariationSettings.
- * @param roundness an optional style value for `ROND` in fontVariationSettings.
- */
- fun setTextStyle(
- weight: Int = -1,
- width: Int = -1,
- opticalSize: Int = -1,
- roundness: Int = -1,
- textSize: Float = -1f,
- color: Int? = null,
- strokeWidth: Float = -1f,
- animate: Boolean = true,
- duration: Long = -1L,
- interpolator: TimeInterpolator? = null,
- delay: Long = 0,
- onAnimationEnd: Runnable? = null,
- ) {
- setTextStyleInternal(
- fvar =
- fontVariationUtils.updateFontVariation(
- weight = weight,
- width = width,
- opticalSize = opticalSize,
- roundness = roundness,
- ),
- textSize = textSize,
- color = color,
- strokeWidth = strokeWidth,
- animate = animate,
- duration = duration,
- interpolator = interpolator,
- delay = delay,
- onAnimationEnd = onAnimationEnd,
- updateLayoutOnFailure = true,
- )
- }
-
companion object {
private val TAG = TextAnimator::class.simpleName!!
+ const val DEFAULT_ANIMATION_DURATION = 300L
}
}
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ViewTransitionRegistry.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ViewTransitionRegistry.kt
index 58c2a1c..86c7f76 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ViewTransitionRegistry.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ViewTransitionRegistry.kt
@@ -24,14 +24,14 @@
* A registry to temporarily store the view being transitioned into a Dialog (using
* [DialogTransitionAnimator]) or an Activity (using [ActivityTransitionAnimator])
*/
-class ViewTransitionRegistry {
+class ViewTransitionRegistry : IViewTransitionRegistry {
/**
* A map of a unique token to a WeakReference of the View being transitioned. WeakReference
* ensures that Views are garbage collected whenever they become eligible and avoid any
* memory leaks
*/
- private val registry by lazy { mutableMapOf<ViewTransitionToken, WeakReference<View>>() }
+ private val registry by lazy { mutableMapOf<ViewTransitionToken, WeakReference<View>>() }
/**
* A [View.OnAttachStateChangeListener] to be attached to all views stored in the registry to
@@ -45,8 +45,7 @@
}
override fun onViewDetachedFromWindow(view: View) {
- (view.getTag(R.id.tag_view_transition_token)
- as? ViewTransitionToken)?.let { token -> unregister(token) }
+ getViewToken(view)?.let { token -> unregister(token) }
}
}
}
@@ -57,12 +56,12 @@
* @param token unique token associated with the transitioning view
* @param view view undergoing transitions
*/
- fun register(token: ViewTransitionToken, view: View) {
+ override fun register(token: ViewTransitionToken, view: View) {
// token embedded as a view tag enables to use a single listener for all views
view.setTag(R.id.tag_view_transition_token, token)
view.addOnAttachStateChangeListener(listener)
registry[token] = WeakReference(view)
- emitCountForTrace()
+ onRegistryUpdate()
}
/**
@@ -70,30 +69,51 @@
*
* @param token unique token associated with the transitioning view
*/
- fun unregister(token: ViewTransitionToken) {
+ override fun unregister(token: ViewTransitionToken) {
registry.remove(token)?.let {
it.get()?.let { view ->
view.removeOnAttachStateChangeListener(listener)
view.setTag(R.id.tag_view_transition_token, null)
}
it.clear()
+ onRegistryUpdate()
}
- emitCountForTrace()
}
/**
* Access a view from registry using unique "token" associated with it
* WARNING - this returns a StrongReference to the View stored in the registry
*/
- fun getView(token: ViewTransitionToken): View? {
+ override fun getView(token: ViewTransitionToken): View? {
return registry[token]?.get()
}
/**
+ * Return token mapped to the [view], if it is present in the registry
+ *
+ * @param view the transitioning view whose token we are requesting
+ * @return token associated with the [view] if present, else null
+ */
+ override fun getViewToken(view: View): ViewTransitionToken? {
+ return (view.getTag(R.id.tag_view_transition_token) as? ViewTransitionToken)?.let { token ->
+ getView(token)?.let { token }
+ }
+ }
+
+ /** Event call to run on registry update (on both [register] and [unregister]) */
+ override fun onRegistryUpdate() {
+ emitCountForTrace()
+ }
+
+ /**
* Utility function to emit number of non-null views in the registry whenever the registry is
* updated (via [register] or [unregister])
*/
private fun emitCountForTrace() {
Trace.setCounter("transition_registry_view_count", registry.count().toLong())
}
+
+ companion object {
+ val instance by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { ViewTransitionRegistry() }
+ }
}
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ViewTransitionToken.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ViewTransitionToken.kt
index c211a8e..e011df0 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ViewTransitionToken.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ViewTransitionToken.kt
@@ -16,17 +16,19 @@
package com.android.systemui.animation
+import java.util.UUID
+
/**
* A token uniquely mapped to a View in [ViewTransitionRegistry]. This token is guaranteed to be
* unique as timestamp is appended to the token string
*
- * @constructor creates an instance of [ViewTransitionToken] with token as "timestamp" or
- * "ClassName_timestamp"
+ * @constructor creates an instance of [ViewTransitionToken] with token as "UUID" or
+ * "ClassName_UUID"
*
* @property token String value of a unique token
*/
@JvmInline
value class ViewTransitionToken private constructor(val token: String) {
- constructor() : this(token = System.currentTimeMillis().toString())
- constructor(clazz: Class<*>) : this(token = clazz.simpleName + "_${System.currentTimeMillis()}")
+ constructor() : this(token = UUID.randomUUID().toString())
+ constructor(clazz: Class<*>) : this(token = clazz.simpleName + "_${UUID.randomUUID()}")
}
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/animation/Expandable.kt b/packages/SystemUI/compose/core/src/com/android/compose/animation/Expandable.kt
index ae75e6c..8739919 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/animation/Expandable.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/animation/Expandable.kt
@@ -31,15 +31,13 @@
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.requiredSize
import androidx.compose.foundation.shape.RoundedCornerShape
-import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.contentColorFor
import androidx.compose.material3.minimumInteractiveComponentSize
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.DisposableEffect
-import androidx.compose.runtime.State
-import androidx.compose.runtime.derivedStateOf
+import androidx.compose.runtime.Stable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.movableContentOf
import androidx.compose.runtime.mutableStateOf
@@ -63,9 +61,17 @@
import androidx.compose.ui.graphics.drawscope.ContentDrawScope
import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.graphics.drawscope.scale
+import androidx.compose.ui.graphics.drawscope.translate
+import androidx.compose.ui.graphics.layer.GraphicsLayer
+import androidx.compose.ui.graphics.layer.drawLayer
+import androidx.compose.ui.graphics.rememberGraphicsLayer
import androidx.compose.ui.layout.boundsInRoot
import androidx.compose.ui.layout.findRootCoordinates
+import androidx.compose.ui.layout.layout
import androidx.compose.ui.layout.onGloballyPositioned
+import androidx.compose.ui.layout.onPlaced
+import androidx.compose.ui.node.DrawModifierNode
+import androidx.compose.ui.node.ModifierNodeElement
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.Density
@@ -76,6 +82,8 @@
import androidx.lifecycle.setViewTreeViewModelStoreOwner
import androidx.savedstate.findViewTreeSavedStateRegistryOwner
import androidx.savedstate.setViewTreeSavedStateRegistryOwner
+import com.android.compose.modifiers.thenIf
+import com.android.compose.ui.graphics.FullScreenComposeViewInOverlay
import com.android.systemui.animation.Expandable
import com.android.systemui.animation.TransitionAnimator
import kotlin.math.max
@@ -123,6 +131,9 @@
borderStroke: BorderStroke? = null,
onClick: ((Expandable) -> Unit)? = null,
interactionSource: MutableInteractionSource? = null,
+ // TODO(b/285250939): Default this to true then remove once the Compose QS expandables have
+ // proven that the new implementation is robust.
+ useModifierBasedImplementation: Boolean = false,
content: @Composable (Expandable) -> Unit,
) {
Expandable(
@@ -130,6 +141,7 @@
modifier,
onClick,
interactionSource,
+ useModifierBasedImplementation,
content,
)
}
@@ -158,16 +170,26 @@
* @sample com.android.systemui.compose.gallery.ActivityLaunchScreen
* @sample com.android.systemui.compose.gallery.DialogLaunchScreen
*/
-@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun Expandable(
controller: ExpandableController,
modifier: Modifier = Modifier,
onClick: ((Expandable) -> Unit)? = null,
interactionSource: MutableInteractionSource? = null,
+ // TODO(b/285250939): Default this to true then remove once the Compose QS expandables have
+ // proven that the new implementation is robust.
+ useModifierBasedImplementation: Boolean = false,
content: @Composable (Expandable) -> Unit,
) {
val controller = controller as ExpandableControllerImpl
+
+ if (useModifierBasedImplementation) {
+ Box(modifier.expandable(controller, onClick, interactionSource)) {
+ WrappedContent(controller.expandable, controller.contentColor, content)
+ }
+ return
+ }
+
val color = controller.color
val contentColor = controller.contentColor
val shape = controller.shape
@@ -175,21 +197,7 @@
val wrappedContent =
remember(content) {
movableContentOf { expandable: Expandable ->
- CompositionLocalProvider(LocalContentColor provides contentColor) {
- // We make sure that the content itself (wrapped by the background) is at least
- // 40.dp, which is the same as the M3 buttons. This applies even if onClick is
- // null, to make it easier to write expandables that are sometimes clickable and
- // sometimes not. There shouldn't be any Expandable smaller than 40dp because if
- // the expandable is not clickable directly, then something in its content
- // should be (and with a size >= 40dp).
- val minSize = 40.dp
- Box(
- Modifier.defaultMinSize(minWidth = minSize, minHeight = minSize),
- contentAlignment = Alignment.Center,
- ) {
- content(expandable)
- }
- }
+ WrappedContent(expandable, contentColor, content)
}
}
@@ -209,11 +217,7 @@
// Make sure we don't read animatorState directly here to avoid recomposition every time the
// state changes (i.e. every frame of the animation).
- val isAnimating by remember {
- derivedStateOf {
- controller.animatorState.value != null && controller.overlay.value != null
- }
- }
+ val isAnimating = controller.isAnimating
// If this expandable is expanded when it's being directly clicked on, let's ensure that it has
// the minimum interactive size followed by all M3 components (48.dp).
@@ -237,58 +241,36 @@
// animating.
AnimatedContentInOverlay(
color,
- controller.boundsInComposeViewRoot.value.size,
- controller.animatorState,
- controller.overlay.value
+ controller.boundsInComposeViewRoot.size,
+ controller.overlay
?: error("AnimatedContentInOverlay shouldn't be composed with null overlay."),
controller,
wrappedContent,
controller.composeViewRoot,
- { controller.currentComposeViewInOverlay.value = it },
+ { controller.currentComposeViewInOverlay = it },
controller.density,
)
}
- controller.isDialogShowing.value -> {
+ controller.isDialogShowing -> {
Box(
modifier
.updateExpandableSize()
.then(minInteractiveSizeModifier)
.drawWithContent { /* Don't draw anything when the dialog is shown. */ }
- .onGloballyPositioned {
- controller.boundsInComposeViewRoot.value = it.boundsInRoot()
- }
+ .onGloballyPositioned { controller.boundsInComposeViewRoot = it.boundsInRoot() }
) {
wrappedContent(controller.expandable)
}
}
else -> {
- val clickModifier =
- if (onClick != null) {
- if (interactionSource != null) {
- // If the caller provided an interaction source, then that means that they
- // will draw the click indication themselves.
- Modifier.clickable(interactionSource, indication = null) {
- onClick(controller.expandable)
- }
- } else {
- // If no interaction source is provided, we draw the default indication (a
- // ripple) and make sure it's clipped by the expandable shape.
- Modifier.clip(shape).clickable { onClick(controller.expandable) }
- }
- } else {
- Modifier
- }
-
Box(
modifier
.updateExpandableSize()
.then(minInteractiveSizeModifier)
- .then(clickModifier)
+ .then(clickModifier(controller, onClick, interactionSource))
.background(color, shape)
.border(controller)
- .onGloballyPositioned {
- controller.boundsInComposeViewRoot.value = it.boundsInRoot()
- }
+ .onGloballyPositioned { controller.boundsInComposeViewRoot = it.boundsInRoot() }
) {
wrappedContent(controller.expandable)
}
@@ -296,12 +278,182 @@
}
}
+@Composable
+private fun WrappedContent(
+ expandable: Expandable,
+ contentColor: Color,
+ content: @Composable (Expandable) -> Unit,
+) {
+ CompositionLocalProvider(LocalContentColor provides contentColor) {
+ // We make sure that the content itself (wrapped by the background) is at least 40.dp, which
+ // is the same as the M3 buttons. This applies even if onClick is null, to make it easier to
+ // write expandables that are sometimes clickable and sometimes not. There shouldn't be any
+ // Expandable smaller than 40dp because if the expandable is not clickable directly, then
+ // something in its content should be (and with a size >= 40dp).
+ val minSize = 40.dp
+ Box(
+ Modifier.defaultMinSize(minWidth = minSize, minHeight = minSize),
+ contentAlignment = Alignment.Center,
+ ) {
+ content(expandable)
+ }
+ }
+}
+
+@Composable
+@Stable
+private fun Modifier.expandable(
+ controller: ExpandableController,
+ onClick: ((Expandable) -> Unit)? = null,
+ interactionSource: MutableInteractionSource? = null,
+): Modifier {
+ val controller = controller as ExpandableControllerImpl
+
+ val isAnimating = controller.isAnimating
+ val drawInOverlayModifier =
+ if (isAnimating) {
+ val graphicsLayer = rememberGraphicsLayer()
+
+ FullScreenComposeViewInOverlay { view ->
+ Modifier.then(DrawExpandableInOverlayElement(view, controller, graphicsLayer))
+ }
+
+ Modifier.drawWithContent { graphicsLayer.record { this@drawWithContent.drawContent() } }
+ } else {
+ null
+ }
+
+ return this.thenIf(onClick != null) { Modifier.minimumInteractiveComponentSize() }
+ .thenIf(!isAnimating) {
+ Modifier.border(controller)
+ .then(clickModifier(controller, onClick, interactionSource))
+ .background(controller.color, controller.shape)
+ }
+ .thenIf(drawInOverlayModifier != null) { drawInOverlayModifier!! }
+ .onPlaced { controller.boundsInComposeViewRoot = it.boundsInRoot() }
+ .thenIf(!isAnimating && controller.isDialogShowing) {
+ Modifier.layout { measurable, constraints ->
+ measurable.measure(constraints).run {
+ layout(width, height) { /* Do not place/draw. */ }
+ }
+ }
+ }
+}
+
+private data class DrawExpandableInOverlayElement(
+ private val overlayComposeView: ComposeView,
+ private val controller: ExpandableControllerImpl,
+ private val contentGraphicsLayer: GraphicsLayer,
+) : ModifierNodeElement<DrawExpandableInOverlayNode>() {
+ override fun create(): DrawExpandableInOverlayNode {
+ return DrawExpandableInOverlayNode(overlayComposeView, controller, contentGraphicsLayer)
+ }
+
+ override fun update(node: DrawExpandableInOverlayNode) {
+ node.update(overlayComposeView, controller, contentGraphicsLayer)
+ }
+}
+
+private class DrawExpandableInOverlayNode(
+ composeView: ComposeView,
+ controller: ExpandableControllerImpl,
+ private var contentGraphicsLayer: GraphicsLayer,
+) : Modifier.Node(), DrawModifierNode {
+ private var controller = controller
+ set(value) {
+ resetCurrentNodeInOverlay()
+ field = value
+ setCurrentNodeInOverlay()
+ }
+
+ private var composeViewLocationOnScreen = composeView.locationOnScreen
+
+ fun update(
+ composeView: ComposeView,
+ controller: ExpandableControllerImpl,
+ contentGraphicsLayer: GraphicsLayer,
+ ) {
+ this.controller = controller
+ this.composeViewLocationOnScreen = composeView.locationOnScreen
+ this.contentGraphicsLayer = contentGraphicsLayer
+ }
+
+ override fun onAttach() {
+ setCurrentNodeInOverlay()
+ }
+
+ override fun onDetach() {
+ resetCurrentNodeInOverlay()
+ }
+
+ private fun setCurrentNodeInOverlay() {
+ controller.currentNodeInOverlay = this
+ }
+
+ private fun resetCurrentNodeInOverlay() {
+ if (controller.currentNodeInOverlay == this) {
+ controller.currentNodeInOverlay = null
+ }
+ }
+
+ override fun ContentDrawScope.draw() {
+ val state = controller.animatorState ?: return
+ val topOffset = state.top.toFloat() - composeViewLocationOnScreen[1]
+ val leftOffset = state.left.toFloat() - composeViewLocationOnScreen[0]
+
+ translate(top = topOffset, left = leftOffset) {
+ // Background.
+ this@draw.drawBackground(
+ state,
+ controller.color,
+ controller.borderStroke,
+ size = Size(state.width.toFloat(), state.height.toFloat()),
+ )
+
+ // Content, scaled & centered w.r.t. the animated state bounds.
+ val contentSize = controller.boundsInComposeViewRoot.size
+ val contentWidth = contentSize.width
+ val contentHeight = contentSize.height
+ val scale = min(state.width / contentWidth, state.height / contentHeight)
+ scale(scale, pivot = Offset(state.width / 2f, state.height / 2f)) {
+ translate(
+ left = (state.width - contentWidth) / 2f,
+ top = (state.height - contentHeight) / 2f,
+ ) {
+ drawLayer(contentGraphicsLayer)
+ }
+ }
+ }
+ }
+}
+
+private fun clickModifier(
+ controller: ExpandableControllerImpl,
+ onClick: ((Expandable) -> Unit)?,
+ interactionSource: MutableInteractionSource?,
+): Modifier {
+ if (onClick == null) {
+ return Modifier
+ }
+
+ if (interactionSource != null) {
+ // If the caller provided an interaction source, then that means that they will draw the
+ // click indication themselves.
+ return Modifier.clickable(interactionSource, indication = null) {
+ onClick(controller.expandable)
+ }
+ }
+
+ // If no interaction source is provided, we draw the default indication (a ripple) and make sure
+ // it's clipped by the expandable shape.
+ return Modifier.clip(controller.shape).clickable { onClick(controller.expandable) }
+}
+
/** Draw [content] in [overlay] while respecting its screen position given by [animatorState]. */
@Composable
private fun AnimatedContentInOverlay(
color: Color,
sizeInOriginalLayout: Size,
- animatorState: State<TransitionAnimator.State?>,
overlay: ViewGroupOverlay,
controller: ExpandableControllerImpl,
content: @Composable (Expandable) -> Unit,
@@ -324,7 +476,7 @@
// so that its content is laid out exactly the same way.
.requiredSize(with(density) { sizeInOriginalLayout.toDpSize() })
.drawWithContent {
- val animatorState = animatorState.value ?: return@drawWithContent
+ val animatorState = controller.animatorState ?: return@drawWithContent
// Scale the content with the background while keeping its aspect ratio.
val widthRatio =
@@ -348,7 +500,8 @@
setContent {
Box(
Modifier.fillMaxSize().drawWithContent {
- val animatorState = animatorState.value ?: return@drawWithContent
+ val animatorState =
+ controller.animatorState ?: return@drawWithContent
if (!animatorState.visible) {
return@drawWithContent
}
@@ -385,7 +538,7 @@
overlay.add(composeViewInOverlay)
val startState =
- animatorState.value
+ controller.animatorState
?: throw IllegalStateException(
"AnimatedContentInOverlay shouldn't be composed with null animatorState."
)
@@ -444,6 +597,7 @@
animatorState: TransitionAnimator.State,
color: Color,
border: BorderStroke?,
+ size: Size = this.size,
) {
val topRadius = animatorState.topCornerRadius
val bottomRadius = animatorState.bottomCornerRadius
@@ -452,7 +606,7 @@
val cornerRadius = CornerRadius(topRadius)
// Draw the background.
- drawRoundRect(color, cornerRadius = cornerRadius)
+ drawRoundRect(color, cornerRadius = cornerRadius, size = size)
// Draw the border.
if (border != null) {
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/animation/ExpandableController.kt b/packages/SystemUI/compose/core/src/com/android/compose/animation/ExpandableController.kt
index c5d2802..a03c896 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/animation/ExpandableController.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/animation/ExpandableController.kt
@@ -25,16 +25,21 @@
import androidx.compose.material3.contentColorFor
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
-import androidx.compose.runtime.MutableState
+import androidx.compose.runtime.Stable
import androidx.compose.runtime.State
+import androidx.compose.runtime.derivedStateOf
+import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Outline
import androidx.compose.ui.graphics.Shape
+import androidx.compose.ui.node.DrawModifierNode
+import androidx.compose.ui.node.invalidateDraw
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.platform.LocalView
@@ -49,10 +54,14 @@
import kotlin.math.roundToInt
/** A controller that can control animated launches from an [Expandable]. */
+@Stable
interface ExpandableController {
/** The [Expandable] controlled by this controller. */
val expandable: Expandable
+ /** Whether this controller is currently animating a launch. */
+ val isAnimating: Boolean
+
/** Called when the [Expandable] stop being included in the composition. */
fun onDispose()
}
@@ -73,24 +82,9 @@
val density = LocalDensity.current
val layoutDirection = LocalLayoutDirection.current
- // The current animation state, if we are currently animating a dialog or activity.
- val animatorState = remember { mutableStateOf<TransitionAnimator.State?>(null) }
-
- // Whether a dialog controlled by this ExpandableController is currently showing.
- val isDialogShowing = remember { mutableStateOf(false) }
-
- // The overlay in which we should animate the launch.
- val overlay = remember { mutableStateOf<ViewGroupOverlay?>(null) }
-
- // The current [ComposeView] being animated in the [overlay], if any.
- val currentComposeViewInOverlay = remember { mutableStateOf<View?>(null) }
-
- // The bounds in [composeViewRoot] of the expandable controlled by this controller.
- val boundsInComposeViewRoot = remember { mutableStateOf(Rect.Zero) }
-
// Whether this composable is still composed. We only do the dialog exit animation if this is
// true.
- val isComposed = remember { mutableStateOf(true) }
+ var isComposed by remember { mutableStateOf(true) }
val controller =
remember(
@@ -109,19 +103,14 @@
borderStroke,
composeViewRoot,
density,
- animatorState,
- isDialogShowing,
- overlay,
- currentComposeViewInOverlay,
- boundsInComposeViewRoot,
layoutDirection,
- isComposed,
+ { isComposed },
)
}
DisposableEffect(Unit) {
onDispose {
- isComposed.value = false
+ isComposed = false
if (TransitionAnimator.returnAnimationsEnabled()) {
controller.onDispose()
}
@@ -138,17 +127,35 @@
internal val borderStroke: BorderStroke?,
internal val composeViewRoot: View,
internal val density: Density,
- internal val animatorState: MutableState<TransitionAnimator.State?>,
- internal val isDialogShowing: MutableState<Boolean>,
- internal val overlay: MutableState<ViewGroupOverlay?>,
- internal val currentComposeViewInOverlay: MutableState<View?>,
- internal val boundsInComposeViewRoot: MutableState<Rect>,
private val layoutDirection: LayoutDirection,
- private val isComposed: State<Boolean>,
+ private val isComposed: () -> Boolean,
) : ExpandableController {
+ /** The current animation state, if we are currently animating a dialog or activity. */
+ var animatorState by mutableStateOf<TransitionAnimator.State?>(null)
+ private set
+
+ /** Whether a dialog controlled by this ExpandableController is currently showing. */
+ var isDialogShowing by mutableStateOf(false)
+ private set
+
+ /** The overlay in which we should animate the launch. */
+ var overlay by mutableStateOf<ViewGroupOverlay?>(null)
+ private set
+
+ /** The current [ComposeView] being animated in the [overlay], if any. */
+ var currentComposeViewInOverlay by mutableStateOf<View?>(null)
+
+ /** The bounds in [composeViewRoot] of the expandable controlled by this controller. */
+ var boundsInComposeViewRoot by mutableStateOf(Rect.Zero)
+
/** The [ActivityTransitionAnimator.Controller] to be cleaned up [onDispose]. */
private var activityControllerForDisposal: ActivityTransitionAnimator.Controller? = null
+ /**
+ * The current [DrawModifierNode] in the overlay, drawing the expandable during a transition.
+ */
+ internal var currentNodeInOverlay: DrawModifierNode? = null
+
override val expandable: Expandable =
object : Expandable {
override fun activityTransitionController(
@@ -158,7 +165,7 @@
returnCujType: Int?,
isEphemeral: Boolean,
): ActivityTransitionAnimator.Controller? {
- if (!isComposed.value) {
+ if (!isComposed()) {
return null
}
@@ -174,7 +181,7 @@
override fun dialogTransitionController(
cuj: DialogCuj?
): DialogTransitionAnimator.Controller? {
- if (!isComposed.value) {
+ if (!isComposed()) {
return null
}
@@ -182,6 +189,8 @@
}
}
+ override val isAnimating: Boolean by derivedStateOf { animatorState != null && overlay != null }
+
override fun onDispose() {
activityControllerForDisposal?.onDispose()
activityControllerForDisposal = null
@@ -204,7 +213,11 @@
override val isLaunching: Boolean = true
override fun onTransitionAnimationEnd(isExpandingFullyAbove: Boolean) {
- animatorState.value = null
+ animatorState = null
+
+ // Force invalidate the drawing done in the overlay whenever the animation state
+ // changes.
+ currentNodeInOverlay?.invalidateDraw()
}
override fun onTransitionAnimationProgress(
@@ -214,7 +227,7 @@
) {
// We copy state given that it's always the same object that is mutated by
// ActivityTransitionAnimator.
- animatorState.value =
+ animatorState =
TransitionAnimator.State(
state.top,
state.bottom,
@@ -227,13 +240,15 @@
// Force measure and layout the ComposeView in the overlay whenever the animation
// state changes.
- currentComposeViewInOverlay.value?.let {
- measureAndLayoutComposeViewInOverlay(it, state)
- }
+ currentComposeViewInOverlay?.let { measureAndLayoutComposeViewInOverlay(it, state) }
+
+ // Force invalidate the drawing done in the overlay whenever the animation state
+ // changes.
+ currentNodeInOverlay?.invalidateDraw()
}
override fun createAnimatorState(): TransitionAnimator.State {
- val boundsInRoot = boundsInComposeViewRoot.value
+ val boundsInRoot = boundsInComposeViewRoot
val outline =
shape.createOutline(
Size(boundsInRoot.width, boundsInRoot.height),
@@ -285,7 +300,7 @@
private fun rootLocationOnScreen(): Offset {
composeViewRoot.getLocationOnScreen(rootLocationOnScreen)
- val boundsInRoot = boundsInComposeViewRoot.value
+ val boundsInRoot = boundsInComposeViewRoot
val x = rootLocationOnScreen[0] + boundsInRoot.left
val y = rootLocationOnScreen[1] + boundsInRoot.top
return Offset(x, y)
@@ -319,14 +334,14 @@
override fun onTransitionAnimationStart(isExpandingFullyAbove: Boolean) {
delegate.onTransitionAnimationStart(isExpandingFullyAbove)
- overlay.value = transitionContainer.overlay as ViewGroupOverlay
+ overlay = transitionContainer.overlay as ViewGroupOverlay
cujType?.let { InteractionJankMonitor.getInstance().begin(composeViewRoot, it) }
}
override fun onTransitionAnimationEnd(isExpandingFullyAbove: Boolean) {
cujType?.let { InteractionJankMonitor.getInstance().end(it) }
delegate.onTransitionAnimationEnd(isExpandingFullyAbove)
- overlay.value = null
+ overlay = null
}
}
}
@@ -339,14 +354,14 @@
override fun startDrawingInOverlayOf(viewGroup: ViewGroup) {
val newOverlay = viewGroup.overlay as ViewGroupOverlay
- if (newOverlay != overlay.value) {
- overlay.value = newOverlay
+ if (newOverlay != overlay) {
+ overlay = newOverlay
}
}
override fun stopDrawingInOverlay() {
- if (overlay.value != null) {
- overlay.value = null
+ if (overlay != null) {
+ overlay = null
}
}
@@ -357,7 +372,7 @@
delegate.onTransitionAnimationEnd(isExpandingFullyAbove)
// Make sure we don't draw this expandable when the dialog is showing.
- isDialogShowing.value = true
+ isDialogShowing = true
}
}
}
@@ -367,16 +382,17 @@
return object : TransitionAnimator.Controller by delegate {
override fun onTransitionAnimationEnd(isExpandingFullyAbove: Boolean) {
delegate.onTransitionAnimationEnd(isExpandingFullyAbove)
- isDialogShowing.value = false
+ isDialogShowing = false
}
}
}
- override fun shouldAnimateExit(): Boolean =
- isComposed.value && composeViewRoot.isAttachedToWindow && composeViewRoot.isShown
+ override fun shouldAnimateExit(): Boolean {
+ return isComposed() && composeViewRoot.isAttachedToWindow && composeViewRoot.isShown
+ }
override fun onExitAnimationCancelled() {
- isDialogShowing.value = false
+ isDialogShowing = false
}
override fun jankConfigurationBuilder(): InteractionJankMonitor.Configuration.Builder? {
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/ui/graphics/DrawInOverlay.kt b/packages/SystemUI/compose/core/src/com/android/compose/ui/graphics/DrawInOverlay.kt
index f5c3a83..089da4b 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/ui/graphics/DrawInOverlay.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/ui/graphics/DrawInOverlay.kt
@@ -42,13 +42,19 @@
@Composable
fun Modifier.drawInOverlay(): Modifier {
val containerState = remember { ContainerState() }
+ FullScreenComposeViewInOverlay { Modifier.container(containerState) }
+ return this.drawInContainer(containerState, enabled = { true })
+}
+
+@Composable
+internal fun FullScreenComposeViewInOverlay(modifier: (ComposeView) -> Modifier = { Modifier }) {
val context = LocalContext.current
val localView = LocalView.current
val compositionContext = rememberCompositionContext()
val displayMetrics = context.resources.displayMetrics
val displaySize = IntSize(displayMetrics.widthPixels, displayMetrics.heightPixels)
- DisposableEffect(containerState, context, localView, compositionContext, displaySize) {
+ DisposableEffect(context, localView, compositionContext, displaySize) {
val overlay = localView.rootView.overlay as ViewGroupOverlay
val view =
ComposeView(context).apply {
@@ -59,7 +65,8 @@
setViewTreeViewModelStoreOwner(localView.findViewTreeViewModelStoreOwner())
setViewTreeSavedStateRegistryOwner(localView.findViewTreeSavedStateRegistryOwner())
- setContent { Box(Modifier.fillMaxSize().container(containerState)) }
+ val view = this
+ setContent { Box(modifier(view).fillMaxSize()) }
}
overlay.add(view)
@@ -74,6 +81,4 @@
onDispose { overlay.remove(view) }
}
-
- return this.drawInContainer(containerState, enabled = { true })
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt
index 2f38dc2..fad8ae7 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt
@@ -24,7 +24,6 @@
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.ui.Modifier
-import androidx.compose.ui.platform.testTag
import com.android.compose.animation.scene.ContentScope
import com.android.compose.animation.scene.ElementKey
import com.android.compose.animation.scene.UserAction
@@ -103,8 +102,6 @@
viewModel,
dialogFactory,
Modifier.element(Bouncer.Elements.Content)
- // TODO(b/393516240): Use the same sysuiResTag() as views instead.
- .testTag(Bouncer.Elements.Content.testTag)
.overscroll(verticalOverscrollEffect)
.sysuiResTag(Bouncer.TestTags.Root)
.fillMaxSize(),
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 0b17a3f..9b76f15 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
@@ -42,6 +42,7 @@
import com.android.compose.animation.scene.SceneKey
import com.android.compose.animation.scene.SceneTransitionLayout
import com.android.compose.animation.scene.Swipe
+import com.android.compose.animation.scene.UserActionResult
import com.android.compose.animation.scene.observableTransitionState
import com.android.compose.animation.scene.rememberMutableSceneTransitionLayoutState
import com.android.compose.animation.scene.transitions
@@ -87,10 +88,26 @@
spec = tween(durationMillis = TransitionDuration.TO_GLANCEABLE_HUB_DURATION_MS)
fade(AllElements)
}
+ to(CommunalScenes.Communal, key = CommunalTransitionKeys.Swipe) {
+ spec = tween(durationMillis = TransitionDuration.TO_GLANCEABLE_HUB_DURATION_MS)
+ translate(Communal.Elements.Grid, Edge.End)
+ timestampRange(startMillis = 167, endMillis = 334) { fade(AllElements) }
+ }
to(CommunalScenes.Blank) {
spec = tween(durationMillis = TO_GONE_DURATION.toInt(DurationUnit.MILLISECONDS))
fade(AllElements)
}
+ to(CommunalScenes.Blank, key = CommunalTransitionKeys.Swipe) {
+ spec = tween(durationMillis = TransitionDuration.TO_GLANCEABLE_HUB_DURATION_MS)
+ translate(Communal.Elements.Grid, Edge.End)
+ timestampRange(endMillis = 167) {
+ fade(Communal.Elements.Grid)
+ fade(Communal.Elements.IndicationArea)
+ fade(Communal.Elements.LockIcon)
+ fade(Communal.Elements.StatusBar)
+ }
+ timestampRange(startMillis = 167, endMillis = 334) { fade(Communal.Elements.Scrim) }
+ }
}
val sceneTransitions = transitions {
@@ -165,6 +182,7 @@
viewModel.communalBackground.collectAsStateWithLifecycle(
initialValue = CommunalBackgroundType.ANIMATED
)
+ val swipeToHubEnabled by viewModel.swipeToHubEnabled.collectAsStateWithLifecycle()
val state: MutableSceneTransitionLayoutState =
rememberMutableSceneTransitionLayoutState(
initialScene = currentSceneKey,
@@ -200,15 +218,27 @@
scene(
CommunalScenes.Blank,
userActions =
- if (viewModel.swipeToHubEnabled())
- mapOf(Swipe.Start(fromSource = Edge.End) to CommunalScenes.Communal)
- else emptyMap(),
+ if (swipeToHubEnabled) {
+ mapOf(
+ Swipe.Start(fromSource = Edge.End) to
+ UserActionResult(CommunalScenes.Communal, CommunalTransitionKeys.Swipe)
+ )
+ } else {
+ emptyMap()
+ },
) {
// This scene shows nothing only allowing for transitions to the communal scene.
Box(modifier = Modifier.fillMaxSize())
}
- scene(CommunalScenes.Communal, userActions = mapOf(Swipe.End to CommunalScenes.Blank)) {
+ scene(
+ CommunalScenes.Communal,
+ userActions =
+ mapOf(
+ Swipe.End to
+ UserActionResult(CommunalScenes.Blank, CommunalTransitionKeys.Swipe)
+ ),
+ ) {
CommunalScene(
backgroundType = backgroundType,
colors = colors,
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt
index aa07370..5e61af6 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt
@@ -19,7 +19,6 @@
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
-import androidx.compose.ui.platform.testTag
import com.android.compose.animation.scene.ContentScope
import com.android.compose.animation.scene.UserAction
import com.android.compose.animation.scene.UserActionResult
@@ -56,11 +55,7 @@
@Composable
override fun ContentScope.Content(modifier: Modifier) {
- LockscreenScene(
- lockscreenContent = lockscreenContent,
- // TODO(b/393516240): Use the same sysuiResTag() as views instead.
- modifier = modifier.testTag(key.rootElementKey.testTag),
- )
+ LockscreenScene(lockscreenContent = lockscreenContent, modifier = modifier)
}
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationsShadeOverlay.kt b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationsShadeOverlay.kt
index 64f3cb1..297995b 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationsShadeOverlay.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationsShadeOverlay.kt
@@ -23,7 +23,7 @@
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import androidx.compose.ui.layout.layoutId
+import androidx.compose.ui.platform.LocalResources
import androidx.compose.ui.res.dimensionResource
import com.android.compose.animation.scene.ContentScope
import com.android.compose.animation.scene.ElementKey
@@ -34,6 +34,13 @@
import com.android.systemui.keyguard.ui.composable.section.DefaultClockSection
import com.android.systemui.keyguard.ui.viewmodel.KeyguardClockViewModel
import com.android.systemui.lifecycle.rememberViewModel
+import com.android.systemui.media.controls.ui.composable.MediaCarousel
+import com.android.systemui.media.controls.ui.composable.isLandscape
+import com.android.systemui.media.controls.ui.controller.MediaCarouselController
+import com.android.systemui.media.controls.ui.view.MediaHost
+import com.android.systemui.media.controls.ui.view.MediaHostState.Companion.COLLAPSED
+import com.android.systemui.media.controls.ui.view.MediaHostState.Companion.EXPANDED
+import com.android.systemui.media.dagger.MediaModule.QUICK_QS_PANEL
import com.android.systemui.notifications.ui.viewmodel.NotificationsShadeOverlayActionsViewModel
import com.android.systemui.notifications.ui.viewmodel.NotificationsShadeOverlayContentViewModel
import com.android.systemui.res.R
@@ -42,10 +49,11 @@
import com.android.systemui.scene.ui.composable.Overlay
import com.android.systemui.shade.ui.composable.OverlayShade
import com.android.systemui.shade.ui.composable.OverlayShadeHeader
-import com.android.systemui.shade.ui.composable.SingleShadeMeasurePolicy
import com.android.systemui.statusbar.notification.stack.ui.view.NotificationScrollView
+import com.android.systemui.util.Utils
import dagger.Lazy
import javax.inject.Inject
+import javax.inject.Named
import kotlinx.coroutines.flow.Flow
@SysUISingleton
@@ -58,6 +66,8 @@
private val stackScrollView: Lazy<NotificationScrollView>,
private val clockSection: DefaultClockSection,
private val keyguardClockViewModel: KeyguardClockViewModel,
+ private val mediaCarouselController: MediaCarouselController,
+ @Named(QUICK_QS_PANEL) private val mediaHost: Lazy<MediaHost>,
) : Overlay {
override val key = Overlays.NotificationsShade
@@ -84,6 +94,11 @@
viewModel.notificationsPlaceholderViewModelFactory.create()
}
+ val usingCollapsedLandscapeMedia =
+ Utils.useCollapsedMediaInLandscape(LocalResources.current)
+ mediaHost.get().expansion =
+ if (usingCollapsedLandscapeMedia && isLandscape()) COLLAPSED else EXPANDED
+
OverlayShade(
panelElement = NotificationsShade.Elements.Panel,
alignmentOnWideScreens = Alignment.TopStart,
@@ -96,9 +111,7 @@
}
OverlayShadeHeader(
viewModel = headerViewModel,
- modifier =
- Modifier.element(NotificationsShade.Elements.StatusBar)
- .layoutId(SingleShadeMeasurePolicy.LayoutId.ShadeHeader),
+ modifier = Modifier.element(NotificationsShade.Elements.StatusBar),
)
},
) {
@@ -116,6 +129,19 @@
}
}
+ MediaCarousel(
+ isVisible = viewModel.showMedia,
+ mediaHost = mediaHost.get(),
+ carouselController = mediaCarouselController,
+ usingCollapsedLandscapeMedia = usingCollapsedLandscapeMedia,
+ modifier =
+ Modifier.padding(
+ top = notificationStackPadding,
+ start = notificationStackPadding,
+ end = notificationStackPadding,
+ ),
+ )
+
NotificationScrollingStack(
shadeSession = shadeSession,
stackScrollView = stackScrollView.get(),
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 f0d3f3e..9c85c96 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
@@ -80,6 +80,7 @@
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.common.ui.compose.Icon
import com.android.systemui.compose.modifiers.sysuiResTag
+import com.android.systemui.qs.flags.QSComposeFragment
import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsButtonViewModel
import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsForegroundServicesButtonViewModel
import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsSecurityButtonViewModel
@@ -218,11 +219,24 @@
Spacer(Modifier.weight(1f))
}
- security?.let { SecurityButton(it, Modifier.weight(1f)) }
- foregroundServices?.let { ForegroundServicesButton(it) }
- userSwitcher?.let { IconButton(it, Modifier.sysuiResTag("multi_user_switch")) }
- IconButton(viewModel.settings, Modifier.sysuiResTag("settings_button_container"))
- power?.let { IconButton(it, Modifier.sysuiResTag("pm_lite")) }
+ val useModifierBasedExpandable = remember { QSComposeFragment.isEnabled }
+ security?.let { SecurityButton(it, useModifierBasedExpandable, Modifier.weight(1f)) }
+ foregroundServices?.let { ForegroundServicesButton(it, useModifierBasedExpandable) }
+ userSwitcher?.let {
+ IconButton(
+ it,
+ useModifierBasedExpandable,
+ Modifier.sysuiResTag("multi_user_switch"),
+ )
+ }
+ IconButton(
+ viewModel.settings,
+ useModifierBasedExpandable,
+ Modifier.sysuiResTag("settings_button_container"),
+ )
+ power?.let {
+ IconButton(it, useModifierBasedExpandable, Modifier.sysuiResTag("pm_lite"))
+ }
}
}
}
@@ -231,6 +245,7 @@
@Composable
private fun SecurityButton(
model: FooterActionsSecurityButtonViewModel,
+ useModifierBasedExpandable: Boolean,
modifier: Modifier = Modifier,
) {
val onClick: ((Expandable) -> Unit)? =
@@ -239,13 +254,21 @@
{ expandable -> onClick(context, expandable) }
}
- TextButton(model.icon, model.text, showNewDot = false, onClick = onClick, modifier)
+ TextButton(
+ model.icon,
+ model.text,
+ showNewDot = false,
+ onClick = onClick,
+ useModifierBasedExpandable,
+ modifier,
+ )
}
/** The foreground services button. */
@Composable
private fun RowScope.ForegroundServicesButton(
- model: FooterActionsForegroundServicesButtonViewModel
+ model: FooterActionsForegroundServicesButtonViewModel,
+ useModifierBasedExpandable: Boolean,
) {
if (model.displayText) {
TextButton(
@@ -253,6 +276,7 @@
model.text,
showNewDot = model.hasNewChanges,
onClick = model.onClick,
+ useModifierBasedExpandable,
Modifier.weight(1f),
)
} else {
@@ -261,13 +285,18 @@
contentDescription = model.text,
showNewDot = model.hasNewChanges,
onClick = model.onClick,
+ useModifierBasedExpandable,
)
}
}
/** A button with an icon. */
@Composable
-fun IconButton(model: FooterActionsButtonViewModel, modifier: Modifier = Modifier) {
+fun IconButton(
+ model: FooterActionsButtonViewModel,
+ useModifierBasedExpandable: Boolean,
+ modifier: Modifier = Modifier,
+) {
Expandable(
color = colorAttr(model.backgroundColor),
shape = CircleShape,
@@ -277,6 +306,7 @@
color = MaterialTheme.colorScheme.secondary,
CornerSize(percent = 50),
),
+ useModifierBasedImplementation = useModifierBasedExpandable,
) {
val tint = model.iconTint?.let { Color(it) } ?: Color.Unspecified
Icon(model.icon, tint = tint, modifier = Modifier.size(20.dp))
@@ -290,6 +320,7 @@
contentDescription: String,
showNewDot: Boolean,
onClick: (Expandable) -> Unit,
+ useModifierBasedExpandable: Boolean,
modifier: Modifier = Modifier,
) {
// By default Expandable will show a ripple above its content when clicked, and clip the content
@@ -309,6 +340,7 @@
color = MaterialTheme.colorScheme.secondary,
CornerSize(percent = 50),
),
+ useModifierBasedImplementation = useModifierBasedExpandable,
) {
Box(Modifier.size(40.dp)) {
Box(
@@ -355,6 +387,7 @@
text: String,
showNewDot: Boolean,
onClick: ((Expandable) -> Unit)?,
+ useModifierBasedExpandable: Boolean,
modifier: Modifier = Modifier,
) {
Expandable(
@@ -367,12 +400,17 @@
.padding(horizontal = 4.dp)
.borderOnFocus(color = MaterialTheme.colorScheme.secondary, CornerSize(50)),
onClick = onClick,
+ useModifierBasedImplementation = useModifierBasedExpandable,
) {
Row(
Modifier.padding(horizontal = dimensionResource(R.dimen.qs_footer_padding)),
verticalAlignment = Alignment.CenterVertically,
) {
- Icon(icon, Modifier.padding(end = 12.dp).size(20.dp))
+ Icon(
+ icon,
+ Modifier.padding(end = 12.dp).size(20.dp),
+ colorAttr(R.attr.onShadeInactiveVariant),
+ )
Text(
text,
@@ -381,6 +419,7 @@
// TODO(b/242040009): Remove this letter spacing. We should only use the M3 text
// styles without modifying them.
letterSpacing = 0.01.em,
+ color = colorAttr(R.attr.onShadeInactiveVariant),
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
@@ -394,6 +433,7 @@
painterResource(com.android.internal.R.drawable.ic_chevron_end),
contentDescription = null,
Modifier.padding(start = 8.dp).size(20.dp),
+ colorAttr(R.attr.onShadeInactiveVariant),
)
}
}
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 afdb3cb..da0b8ac 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
@@ -38,7 +38,6 @@
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.layout.boundsInWindow
-import androidx.compose.ui.layout.layoutId
import androidx.compose.ui.layout.onPlaced
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.dp
@@ -66,7 +65,6 @@
import com.android.systemui.shade.ui.composable.OverlayShade
import com.android.systemui.shade.ui.composable.OverlayShadeHeader
import com.android.systemui.shade.ui.composable.QuickSettingsOverlayHeader
-import com.android.systemui.shade.ui.composable.SingleShadeMeasurePolicy
import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimBounds
import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimShape
import com.android.systemui.statusbar.notification.stack.ui.view.NotificationScrollView
@@ -108,6 +106,11 @@
rememberViewModel("QuickSettingsShadeOverlayContainer") {
quickSettingsContainerViewModelFactory.create(supportsBrightnessMirroring = true)
}
+ val hunPlaceholderViewModel =
+ rememberViewModel("QuickSettingsShadeOverlayPlaceholder") {
+ notificationsPlaceholderViewModelFactory.create()
+ }
+
val panelCornerRadius =
with(LocalDensity.current) { OverlayShade.Dimensions.PanelCornerRadius.toPx().toInt() }
val showBrightnessMirror =
@@ -119,13 +122,6 @@
DisposableEffect(Unit) { onDispose { contentViewModel.onPanelShapeChanged(null) } }
Box(modifier = modifier.graphicsLayer { alpha = contentAlphaFromBrightnessMirror }) {
- SnoozeableHeadsUpNotificationSpace(
- stackScrollView = notificationStackScrollView.get(),
- viewModel =
- rememberViewModel("QuickSettingsShadeOverlayPlaceholder") {
- notificationsPlaceholderViewModelFactory.create()
- },
- )
OverlayShade(
panelElement = QuickSettingsShade.Elements.Panel,
alignmentOnWideScreens = Alignment.TopEnd,
@@ -133,50 +129,34 @@
header = {
OverlayShadeHeader(
viewModel = quickSettingsContainerViewModel.shadeHeaderViewModel,
- modifier =
- Modifier.element(QuickSettingsShade.Elements.StatusBar)
- .layoutId(SingleShadeMeasurePolicy.LayoutId.ShadeHeader),
+ modifier = Modifier.element(QuickSettingsShade.Elements.StatusBar),
)
},
) {
- ShadeBody(
+ QuickSettingsContainer(
viewModel = quickSettingsContainerViewModel,
modifier =
Modifier.onPlaced { coordinates ->
- val boundsInWindow = coordinates.boundsInWindow()
- val shadeScrimBounds =
- ShadeScrimBounds(
- left = boundsInWindow.left,
- top = boundsInWindow.top,
- right = boundsInWindow.right,
- bottom = boundsInWindow.bottom,
- )
val shape =
ShadeScrimShape(
- bounds = shadeScrimBounds,
+ bounds = ShadeScrimBounds(coordinates.boundsInWindow()),
topRadius = 0,
bottomRadius = panelCornerRadius,
)
contentViewModel.onPanelShapeChanged(shape)
},
- header = {
- if (quickSettingsContainerViewModel.showHeader) {
- QuickSettingsOverlayHeader(
- viewModel = quickSettingsContainerViewModel.shadeHeaderViewModel,
- modifier =
- Modifier.element(QuickSettingsShade.Elements.Header)
- .padding(top = QuickSettingsShade.Dimensions.Padding),
- )
- }
- },
)
}
+ SnoozeableHeadsUpNotificationSpace(
+ stackScrollView = notificationStackScrollView.get(),
+ viewModel = hunPlaceholderViewModel,
+ )
}
}
}
-// The possible states of the `ShadeBody`.
-sealed interface ShadeBodyState {
+/** The possible states of the `ShadeBody`. */
+private sealed interface ShadeBodyState {
data object Editing : ShadeBodyState
data object TileDetails : ShadeBodyState
@@ -185,10 +165,9 @@
}
@Composable
-fun ContentScope.ShadeBody(
+fun ContentScope.QuickSettingsContainer(
viewModel: QuickSettingsContainerViewModel,
modifier: Modifier = Modifier,
- header: @Composable () -> Unit,
) {
val isEditing by viewModel.editModeViewModel.isEditing.collectAsStateWithLifecycle()
val tileDetails =
@@ -216,11 +195,10 @@
TileDetails(modifier = modifier, viewModel.detailsViewModel)
}
- else -> {
+ ShadeBodyState.Default -> {
QuickSettingsLayout(
viewModel = viewModel,
modifier = modifier.sysuiResTag("quick_settings_panel"),
- header = header,
)
}
}
@@ -232,7 +210,6 @@
fun ContentScope.QuickSettingsLayout(
viewModel: QuickSettingsContainerViewModel,
modifier: Modifier = Modifier,
- header: @Composable () -> Unit,
) {
Column(
verticalArrangement = Arrangement.spacedBy(QuickSettingsShade.Dimensions.Padding),
@@ -244,7 +221,14 @@
bottom = QuickSettingsShade.Dimensions.Padding,
),
) {
- header()
+ if (viewModel.showHeader) {
+ QuickSettingsOverlayHeader(
+ viewModel = viewModel.shadeHeaderViewModel,
+ modifier =
+ Modifier.element(QuickSettingsShade.Elements.Header)
+ .padding(top = QuickSettingsShade.Dimensions.Padding),
+ )
+ }
Toolbar(
modifier =
Modifier.fillMaxWidth().requiredHeight(QuickSettingsShade.Dimensions.ToolbarHeight),
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneTransitionLayoutDataSource.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneTransitionLayoutDataSource.kt
index 8aa5bc7..60eaa28 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneTransitionLayoutDataSource.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneTransitionLayoutDataSource.kt
@@ -21,6 +21,7 @@
import com.android.compose.animation.scene.OverlayKey
import com.android.compose.animation.scene.SceneKey
import com.android.compose.animation.scene.TransitionKey
+import com.android.compose.animation.scene.content.state.TransitionState
import com.android.compose.animation.scene.observableTransitionState
import com.android.systemui.scene.shared.model.SceneDataSource
import kotlinx.coroutines.CoroutineScope
@@ -103,4 +104,8 @@
override fun instantlyHideOverlay(overlay: OverlayKey) {
state.snapTo(overlays = state.currentOverlays - overlay)
}
+
+ override fun freezeAndAnimateToCurrentState() {
+ (state.transitionState as? TransitionState.Transition)?.freezeAndAnimateToCurrentState()
+ }
}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt
index 05958a2..907b5bc 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt
@@ -169,7 +169,7 @@
Modifier.maybeElevateInContent(layoutImpl, content, key, currentTransitionStates)
}
.then(ElementModifier(layoutImpl, currentTransitionStates, content, key))
- .thenIf(layoutImpl.implicitTestTags) { Modifier.testTag(key.testTag) }
+ .testTag(key.testTag)
}
/**
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt
index d47210c..72bb82b 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt
@@ -65,8 +65,6 @@
swipeSourceDetector: SwipeSourceDetector = DefaultEdgeDetector,
swipeDetector: SwipeDetector = DefaultSwipeDetector,
@FloatRange(from = 0.0, to = 0.5) transitionInterceptionThreshold: Float = 0.05f,
- // TODO(b/240432457) Remove this once test utils can access the internal STLForTesting().
- implicitTestTags: Boolean = false,
builder: SceneTransitionLayoutScope<ContentScope>.() -> Unit,
) {
SceneTransitionLayoutForTesting(
@@ -75,7 +73,6 @@
swipeSourceDetector,
swipeDetector,
transitionInterceptionThreshold,
- implicitTestTags = implicitTestTags,
onLayoutImpl = null,
builder = builder,
)
@@ -728,8 +725,10 @@
}
/**
- * An internal version of [SceneTransitionLayout] to be used for tests, that provides access to the
- * internal [SceneTransitionLayoutImpl] and implicitly tags all scenes and elements.
+ * An internal version of [SceneTransitionLayout] to be used for tests.
+ *
+ * Important: You should use this only in tests and if you need to access the underlying
+ * [SceneTransitionLayoutImpl]. In other cases, you should use [SceneTransitionLayout].
*/
@Composable
internal fun SceneTransitionLayoutForTesting(
@@ -742,7 +741,6 @@
sharedElementMap: MutableMap<ElementKey, Element> = remember { mutableMapOf() },
ancestors: List<Ancestor> = remember { emptyList() },
lookaheadScope: LookaheadScope? = null,
- implicitTestTags: Boolean = true,
builder: SceneTransitionLayoutScope<InternalContentScope>.() -> Unit,
) {
val density = LocalDensity.current
@@ -767,7 +765,6 @@
directionChangeSlop = directionChangeSlop,
defaultEffectFactory = defaultEffectFactory,
decayAnimationSpec = decayAnimationSpec,
- implicitTestTags = implicitTestTags,
)
.also { onLayoutImpl?.invoke(it) }
}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt
index e3c4eb0..53996d2 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt
@@ -122,9 +122,6 @@
* This is used to enable transformations and shared elements across NestedSTLs.
*/
internal val ancestors: List<Ancestor> = emptyList(),
-
- /** Whether elements and scene should be tagged using `Modifier.testTag`. */
- internal val implicitTestTags: Boolean = false,
lookaheadScope: LookaheadScope? = null,
defaultEffectFactory: OverscrollFactory,
) {
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/UserActionDistanceScopeImpl.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/UserActionDistanceScopeImpl.kt
index fffc7f9..2d2a8154 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/UserActionDistanceScopeImpl.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/UserActionDistanceScopeImpl.kt
@@ -16,6 +16,8 @@
package com.android.compose.animation.scene
+import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
+import androidx.compose.material3.MotionScheme
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.LayoutDirection
@@ -59,4 +61,8 @@
override val layoutDirection: LayoutDirection
get() = layoutImpl.layoutDirection
+
+ @ExperimentalMaterial3ExpressiveApi
+ override val motionScheme: MotionScheme
+ get() = layoutImpl.state.motionScheme
}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Content.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Content.kt
index 64cfe38..95d6440 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Content.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Content.kt
@@ -171,7 +171,7 @@
.thenIf(layoutImpl.state.isElevationPossible(content = key, element = null)) {
Modifier.container(containerState)
}
- .thenIf(layoutImpl.implicitTestTags) { Modifier.testTag(key.testTag) }
+ .testTag(key.testTag)
) {
CompositionLocalProvider(LocalOverscrollFactory provides lastFactory) {
scope.content()
@@ -290,7 +290,6 @@
sharedElementMap = layoutImpl.elements,
ancestors = ancestors,
lookaheadScope = layoutImpl.lookaheadScope,
- implicitTestTags = layoutImpl.implicitTestTags,
)
}
}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Transformation.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Transformation.kt
index e0b4218..613afe2 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Transformation.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Transformation.kt
@@ -18,7 +18,8 @@
import androidx.compose.animation.core.Easing
import androidx.compose.animation.core.LinearEasing
-import androidx.compose.ui.geometry.Offset
+import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
+import androidx.compose.material3.MotionScheme
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.LayoutDirection
@@ -29,8 +30,8 @@
import com.android.compose.animation.scene.ElementKey
import com.android.compose.animation.scene.ElementMatcher
import com.android.compose.animation.scene.ElementStateScope
-import com.android.compose.animation.scene.Scale
import com.android.compose.animation.scene.content.state.TransitionState
+import com.android.compose.animation.scene.transformation.PropertyTransformation.Property
import kotlinx.coroutines.CoroutineScope
/** A transformation applied to one or more elements during a transition. */
@@ -126,9 +127,13 @@
): T
}
+@OptIn(ExperimentalMaterial3ExpressiveApi::class)
interface PropertyTransformationScope : Density, ElementStateScope {
/** The current [direction][LayoutDirection] of the layout. */
val layoutDirection: LayoutDirection
+
+ /** The [MotionScheme] in use by the [SceneTransitionLayout]. */
+ val motionScheme: MotionScheme
}
/** Defines the transformation-type to be applied to all elements matching [matcher]. */
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 8fce708..698a808 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
@@ -227,7 +227,7 @@
to = SceneB,
transitionLayout = { state ->
coroutineScope = rememberCoroutineScope()
- SceneTransitionLayoutForTesting(state) {
+ SceneTransitionLayout(state) {
scene(SceneA) {
Box(Modifier.size(layoutSize)) {
// Transformed element
@@ -633,7 +633,7 @@
val scope =
rule.setContentAndCreateMainScope {
- SceneTransitionLayoutForTesting(state) {
+ SceneTransitionLayout(state) {
scene(SceneA) { Box(Modifier.element(TestElements.Foo).size(20.dp)) }
scene(SceneB) {}
}
@@ -674,7 +674,7 @@
CompositionLocalProvider(
LocalOverscrollFactory provides rememberOffsetOverscrollEffectFactory()
) {
- SceneTransitionLayoutForTesting(state, Modifier.size(layoutWidth, layoutHeight)) {
+ SceneTransitionLayout(state, Modifier.size(layoutWidth, layoutHeight)) {
scene(key = SceneA, userActions = mapOf(Swipe.Down to SceneB)) {
Spacer(Modifier.fillMaxSize())
}
@@ -734,7 +734,7 @@
CompositionLocalProvider(
LocalOverscrollFactory provides rememberOffsetOverscrollEffectFactory()
) {
- SceneTransitionLayoutForTesting(state, Modifier.size(layoutWidth, layoutHeight)) {
+ SceneTransitionLayout(state, Modifier.size(layoutWidth, layoutHeight)) {
scene(key = SceneA, userActions = mapOf(Swipe.Down to SceneB)) {
Spacer(
Modifier.overscroll(verticalOverscrollEffect)
@@ -834,7 +834,7 @@
CompositionLocalProvider(
LocalOverscrollFactory provides rememberOffsetOverscrollEffectFactory()
) {
- SceneTransitionLayoutForTesting(state, Modifier.size(layoutWidth, layoutHeight)) {
+ SceneTransitionLayout(state, Modifier.size(layoutWidth, layoutHeight)) {
scene(key = SceneA, userActions = mapOf(Swipe.Down to SceneB)) {
Spacer(Modifier.fillMaxSize())
}
@@ -893,7 +893,7 @@
CompositionLocalProvider(
LocalOverscrollFactory provides rememberOffsetOverscrollEffectFactory()
) {
- SceneTransitionLayoutForTesting(
+ SceneTransitionLayout(
state = state,
modifier = Modifier.size(layoutWidth, layoutHeight),
) {
@@ -970,7 +970,7 @@
rule.setContent {
touchSlop = LocalViewConfiguration.current.touchSlop
- SceneTransitionLayoutForTesting(
+ SceneTransitionLayout(
state = state,
modifier = Modifier.size(layoutWidth, layoutHeight),
) {
@@ -1057,7 +1057,7 @@
rule.setContent {
coroutineScope = rememberCoroutineScope()
- SceneTransitionLayoutForTesting(state) {
+ SceneTransitionLayout(state) {
scene(SceneA) {
Box(Modifier.size(layoutSize)) {
Box(
@@ -1374,7 +1374,7 @@
val scope =
rule.setContentAndCreateMainScope {
- SceneTransitionLayoutForTesting(state, Modifier.size(layoutSize)) {
+ SceneTransitionLayout(state, Modifier.size(layoutSize)) {
scene(SceneA) {
Box(Modifier.fillMaxSize()) { Foo(Modifier.align(Alignment.TopStart)) }
}
@@ -1742,7 +1742,7 @@
val scope =
rule.setContentAndCreateMainScope {
- SceneTransitionLayoutForTesting(state, Modifier.size(200.dp)) {
+ SceneTransitionLayout(state, Modifier.size(200.dp)) {
scene(SceneA) { Foo(offset = 0.dp) }
scene(SceneB) { Foo(offset = 20.dp) }
scene(SceneC) { Foo(offset = 40.dp) }
@@ -1828,7 +1828,7 @@
val scope =
rule.setContentAndCreateMainScope {
- SceneTransitionLayoutForTesting(state) {
+ SceneTransitionLayout(state) {
scene(SceneB) { Foo(Modifier.offset(40.dp, 60.dp)) }
// Define A after B so that Foo is placed in A during A <=> B.
@@ -1887,7 +1887,7 @@
val scope =
rule.setContentAndCreateMainScope {
- SceneTransitionLayoutForTesting(state) {
+ SceneTransitionLayout(state) {
scene(SceneA) { Foo() }
scene(SceneB) { Foo(Modifier.offset(40.dp, 60.dp)) }
}
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/OverlayTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/OverlayTest.kt
index 98ecb64..04c762f 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/OverlayTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/OverlayTest.kt
@@ -90,7 +90,7 @@
lateinit var coroutineScope: CoroutineScope
rule.setContent {
coroutineScope = rememberCoroutineScope()
- SceneTransitionLayoutForTesting(state, Modifier.size(200.dp)) {
+ SceneTransitionLayout(state, Modifier.size(200.dp)) {
scene(SceneA) { Box(Modifier.fillMaxSize()) { Foo() } }
overlay(OverlayA) { Foo() }
}
@@ -132,7 +132,7 @@
lateinit var coroutineScope: CoroutineScope
rule.setContent {
coroutineScope = rememberCoroutineScope()
- SceneTransitionLayoutForTesting(state, Modifier.size(200.dp)) {
+ SceneTransitionLayout(state, Modifier.size(200.dp)) {
scene(SceneA) { Box(Modifier.fillMaxSize()) { Foo() } }
overlay(OverlayA) { Foo() }
overlay(OverlayB) { Foo() }
@@ -230,7 +230,7 @@
lateinit var coroutineScope: CoroutineScope
rule.setContent {
coroutineScope = rememberCoroutineScope()
- SceneTransitionLayoutForTesting(state, Modifier.size(200.dp)) {
+ SceneTransitionLayout(state, Modifier.size(200.dp)) {
scene(SceneA) { Box(Modifier.fillMaxSize()) { MovableBar() } }
overlay(OverlayA) { MovableBar() }
overlay(OverlayB) { MovableBar() }
@@ -302,7 +302,7 @@
}
var alignment by mutableStateOf(Alignment.Center)
rule.setContent {
- SceneTransitionLayoutForTesting(state, Modifier.size(200.dp)) {
+ SceneTransitionLayout(state, Modifier.size(200.dp)) {
scene(SceneA) { Box(Modifier.fillMaxSize()) { Foo() } }
overlay(OverlayA, alignment = alignment) { Foo() }
}
@@ -761,7 +761,7 @@
val movableElementChildTag = "movableElementChildTag"
val scope =
rule.setContentAndCreateMainScope {
- SceneTransitionLayoutForTesting(state) {
+ SceneTransitionLayout(state) {
scene(SceneA) {
MovableElement(key, Modifier) {
content { Box(Modifier.testTag(movableElementChildTag).size(100.dp)) }
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/PredictiveBackHandlerTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/PredictiveBackHandlerTest.kt
index 366b11d..2bf2358 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/PredictiveBackHandlerTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/PredictiveBackHandlerTest.kt
@@ -250,7 +250,7 @@
}
rule.setContent {
- SceneTransitionLayoutForTesting(state, Modifier.size(200.dp)) {
+ SceneTransitionLayout(state, Modifier.size(200.dp)) {
scene(SceneA) { Box(Modifier.fillMaxSize()) }
overlay(OverlayA) { Box(Modifier.fillMaxSize()) }
overlay(OverlayB) { Box(Modifier.fillMaxSize()) }
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutTest.kt
index 5cbc98f..3578be4 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutTest.kt
@@ -97,7 +97,7 @@
MutableSceneTransitionLayoutStateForTests(SceneA, EmptyTestTransitions)
}
- SceneTransitionLayoutForTesting(state = layoutState, modifier = Modifier.size(LayoutSize)) {
+ SceneTransitionLayout(state = layoutState, modifier = Modifier.size(LayoutSize)) {
scene(SceneA, userActions = mapOf(Back to SceneB)) {
Box(Modifier.fillMaxSize()) {
SharedFoo(size = 50.dp, childOffset = 0.dp, Modifier.align(Alignment.TopEnd))
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SwipeToSceneTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SwipeToSceneTest.kt
index 11abbbe..751b314 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SwipeToSceneTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SwipeToSceneTest.kt
@@ -763,7 +763,7 @@
var touchSlop = 0f
rule.setContent {
touchSlop = LocalViewConfiguration.current.touchSlop
- SceneTransitionLayoutForTesting(state, Modifier.size(layoutSize)) {
+ SceneTransitionLayout(state, Modifier.size(layoutSize)) {
scene(SceneA, userActions = mapOf(Swipe.Start to SceneB, Swipe.End to SceneC)) {
Box(Modifier.fillMaxSize())
}
@@ -837,7 +837,7 @@
rule.setContent {
touchSlop = LocalViewConfiguration.current.touchSlop
CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) {
- SceneTransitionLayoutForTesting(state, Modifier.size(layoutSize)) {
+ SceneTransitionLayout(state, Modifier.size(layoutSize)) {
scene(SceneA, userActions = mapOf(Swipe.Start to SceneB, Swipe.End to SceneC)) {
Box(Modifier.fillMaxSize())
}
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/NestedElementTransformationTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/NestedElementTransformationTest.kt
index 8b56892..bb511bc 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/NestedElementTransformationTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/NestedElementTransformationTest.kt
@@ -40,7 +40,7 @@
import com.android.compose.animation.scene.MutableSceneTransitionLayoutStateForTests
import com.android.compose.animation.scene.Scale
import com.android.compose.animation.scene.SceneKey
-import com.android.compose.animation.scene.SceneTransitionLayoutForTesting
+import com.android.compose.animation.scene.SceneTransitionLayout
import com.android.compose.animation.scene.SceneTransitions
import com.android.compose.animation.scene.TestScenes
import com.android.compose.animation.scene.testNestedTransition
@@ -114,7 +114,7 @@
@Composable
(states: List<MutableSceneTransitionLayoutState>) -> Unit =
{ states ->
- SceneTransitionLayoutForTesting(states[0]) {
+ SceneTransitionLayout(states[0]) {
scene(TestScenes.SceneA, content = { TestElement(elementVariant0A) })
scene(
TestScenes.SceneB,
diff --git a/packages/SystemUI/compose/scene/tests/utils/src/com/android/compose/animation/scene/TestContentScope.kt b/packages/SystemUI/compose/scene/tests/utils/src/com/android/compose/animation/scene/TestContentScope.kt
index e56d1be..6d47bab 100644
--- a/packages/SystemUI/compose/scene/tests/utils/src/com/android/compose/animation/scene/TestContentScope.kt
+++ b/packages/SystemUI/compose/scene/tests/utils/src/com/android/compose/animation/scene/TestContentScope.kt
@@ -30,7 +30,5 @@
content: @Composable ContentScope.() -> Unit,
) {
val state = rememberMutableSceneTransitionLayoutState(currentScene)
- SceneTransitionLayout(state, modifier, implicitTestTags = true) {
- scene(currentScene, content = content)
- }
+ SceneTransitionLayout(state, modifier) { scene(currentScene, content = content) }
}
diff --git a/packages/SystemUI/compose/scene/tests/utils/src/com/android/compose/animation/scene/TestTransition.kt b/packages/SystemUI/compose/scene/tests/utils/src/com/android/compose/animation/scene/TestTransition.kt
index a362a37..f94a7ed 100644
--- a/packages/SystemUI/compose/scene/tests/utils/src/com/android/compose/animation/scene/TestTransition.kt
+++ b/packages/SystemUI/compose/scene/tests/utils/src/com/android/compose/animation/scene/TestTransition.kt
@@ -137,7 +137,7 @@
},
changeState = changeState,
transitionLayout = { state ->
- SceneTransitionLayout(state, layoutModifier, implicitTestTags = true) {
+ SceneTransitionLayout(state, layoutModifier) {
scene(fromScene, content = fromSceneContent)
scene(toScene, content = toSceneContent)
}
@@ -163,7 +163,7 @@
)
},
transitionLayout = { state ->
- SceneTransitionLayout(state, implicitTestTags = true) {
+ SceneTransitionLayout(state) {
scene(fromScene) { fromSceneContent() }
overlay(overlay) { overlayContent() }
}
@@ -191,7 +191,7 @@
)
},
transitionLayout = { state ->
- SceneTransitionLayout(state, implicitTestTags = true) {
+ SceneTransitionLayout(state) {
scene(toScene) { toSceneContent() }
overlay(overlay) { overlayContent() }
}
@@ -223,7 +223,7 @@
)
},
transitionLayout = { state ->
- SceneTransitionLayout(state, implicitTestTags = true) {
+ SceneTransitionLayout(state) {
scene(currentScene) { currentSceneContent() }
overlay(from, alignment = fromAlignment) { fromContent() }
overlay(to, alignment = toAlignment) { toContent() }
@@ -273,7 +273,7 @@
}
}
- SceneTransitionLayout(state, layoutModifier, implicitTestTags = true) {
+ SceneTransitionLayout(state, layoutModifier) {
scene(fromScene, content = fromSceneContent)
scene(toScene, content = toSceneContent)
}
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/AnimatableClockView.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/AnimatableClockView.kt
index b76656d..4bf0ceb 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/AnimatableClockView.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/AnimatableClockView.kt
@@ -366,7 +366,7 @@
fun animateCharge(isDozing: () -> Boolean) {
// Skip charge animation if dozing animation is already playing.
- if (textAnimator == null || textAnimator!!.isRunning()) {
+ if (textAnimator == null || textAnimator!!.isRunning) {
return
}
@@ -444,29 +444,28 @@
delay: Long,
onAnimationEnd: Runnable?,
) {
- textAnimator?.let {
- it.setTextStyle(
- weight = weight,
- color = color,
+ val style = TextAnimator.Style(color = color)
+ val animation =
+ TextAnimator.Animation(
animate = animate && isAnimationEnabled,
duration = duration,
- interpolator = interpolator,
- delay = delay,
+ interpolator = interpolator ?: Interpolators.LINEAR,
+ startDelay = delay,
onAnimationEnd = onAnimationEnd,
)
+ textAnimator?.let {
+ it.setTextStyle(
+ style.withUpdatedFVar(it.fontVariationUtils, weight = weight),
+ animation,
+ )
it.glyphFilter = glyphFilter
}
?: run {
// when the text animator is set, update its start values
onTextAnimatorInitialized = { textAnimator ->
textAnimator.setTextStyle(
- weight = weight,
- color = color,
- animate = false,
- duration = duration,
- interpolator = interpolator,
- delay = delay,
- onAnimationEnd = onAnimationEnd,
+ style.withUpdatedFVar(textAnimator.fontVariationUtils, weight = weight),
+ animation.copy(animate = false),
)
textAnimator.glyphFilter = glyphFilter
}
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/SimpleDigitalHandLayerController.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/SimpleDigitalHandLayerController.kt
index a5adfa2..0b7ea1a 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/SimpleDigitalHandLayerController.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/SimpleDigitalHandLayerController.kt
@@ -21,6 +21,7 @@
import android.view.animation.Interpolator
import android.widget.RelativeLayout
import androidx.annotation.VisibleForTesting
+import com.android.systemui.animation.TextAnimator
import com.android.systemui.customization.R
import com.android.systemui.log.core.Logger
import com.android.systemui.plugins.clocks.AlarmData
@@ -65,7 +66,7 @@
data class FontTextStyle(
val lineHeight: Float? = null,
val fontSizeScale: Float? = null,
- val transitionDuration: Long = -1L,
+ val transitionDuration: Long = TextAnimator.DEFAULT_ANIMATION_DURATION,
val transitionInterpolator: Interpolator? = null,
)
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextView.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextView.kt
index 92fa6b5..8317aa3 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextView.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextView.kt
@@ -33,7 +33,9 @@
import android.util.TypedValue
import android.view.View.MeasureSpec.EXACTLY
import android.view.animation.Interpolator
+import android.view.animation.PathInterpolator
import android.widget.TextView
+import com.android.app.animation.Interpolators
import com.android.internal.annotations.VisibleForTesting
import com.android.systemui.animation.GSFAxes
import com.android.systemui.animation.TextAnimator
@@ -84,17 +86,20 @@
else -> listOf(FLEX_AOD_SMALL_WEIGHT_AXIS, FLEX_AOD_WIDTH_AXIS)
}
- private var lsFontVariation =
- if (!isLegacyFlex) listOf(LS_WEIGHT_AXIS, WIDTH_AXIS, ROUND_AXIS, SLANT_AXIS).toFVar()
- else listOf(FLEX_LS_WEIGHT_AXIS, FLEX_LS_WIDTH_AXIS, FLEX_ROUND_AXIS, SLANT_AXIS).toFVar()
+ private var lsFontVariation: String
+ private var aodFontVariation: String
+ private var fidgetFontVariation: String
- private var aodFontVariation = run {
+ init {
val roundAxis = if (!isLegacyFlex) ROUND_AXIS else FLEX_ROUND_AXIS
- (fixedAodAxes + listOf(roundAxis, SLANT_AXIS)).toFVar()
- }
+ val lsFontAxes =
+ if (!isLegacyFlex) listOf(LS_WEIGHT_AXIS, WIDTH_AXIS, ROUND_AXIS, SLANT_AXIS)
+ else listOf(FLEX_LS_WEIGHT_AXIS, FLEX_LS_WIDTH_AXIS, FLEX_ROUND_AXIS, SLANT_AXIS)
- // TODO(b/374306512): Fidget endpoint to spec
- private var fidgetFontVariation = aodFontVariation
+ lsFontVariation = lsFontAxes.toFVar()
+ aodFontVariation = (fixedAodAxes + listOf(roundAxis, SLANT_AXIS)).toFVar()
+ fidgetFontVariation = buildFidgetVariation(lsFontAxes).toFVar()
+ }
private val parser = DimensionParser(clockCtx.context)
var maxSingleDigitHeight = -1
@@ -121,7 +126,7 @@
protected val logger = ClockLogger(this, clockCtx.messageBuffer, this::class.simpleName!!)
get() = field ?: ClockLogger.INIT_LOGGER
- private var aodDozingInterpolator: Interpolator? = null
+ private var aodDozingInterpolator: Interpolator = Interpolators.LINEAR
@VisibleForTesting lateinit var textAnimator: TextAnimator
@@ -149,7 +154,7 @@
lockscreenColor = color
lockScreenPaint.color = lockscreenColor
if (dozeFraction < 1f) {
- textAnimator.setTextStyle(color = lockscreenColor, animate = false)
+ textAnimator.setTextStyle(TextAnimator.Style(color = lockscreenColor))
}
invalidate()
}
@@ -157,10 +162,8 @@
fun updateAxes(lsAxes: List<ClockFontAxisSetting>) {
lsFontVariation = lsAxes.toFVar()
aodFontVariation = lsAxes.replace(fixedAodAxes).toFVar()
- logger.i({ "updateAxes(LS = $str1, AOD = $str2)" }) {
- str1 = lsFontVariation
- str2 = aodFontVariation
- }
+ fidgetFontVariation = buildFidgetVariation(lsAxes).toFVar()
+ logger.updateAxes(lsFontVariation, aodFontVariation)
lockScreenPaint.typeface = typefaceCache.getTypefaceForVariant(lsFontVariation)
typeface = lockScreenPaint.typeface
@@ -168,13 +171,28 @@
lockScreenPaint.getTextBounds(text, 0, text.length, textBounds)
targetTextBounds.set(textBounds)
- textAnimator.setTextStyle(fvar = lsFontVariation, animate = false)
+ textAnimator.setTextStyle(TextAnimator.Style(fVar = lsFontVariation))
measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED)
recomputeMaxSingleDigitSizes()
requestLayout()
invalidate()
}
+ fun buildFidgetVariation(axes: List<ClockFontAxisSetting>): List<ClockFontAxisSetting> {
+ val result = mutableListOf<ClockFontAxisSetting>()
+ for (axis in axes) {
+ result.add(
+ FIDGET_DISTS.get(axis.key)?.let { (dist, midpoint) ->
+ ClockFontAxisSetting(
+ axis.key,
+ axis.value + dist * if (axis.value > midpoint) -1 else 1,
+ )
+ } ?: axis
+ )
+ }
+ return result
+ }
+
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
logger.onMeasure()
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
@@ -245,40 +263,54 @@
fun animateDoze(isDozing: Boolean, isAnimated: Boolean) {
if (!this::textAnimator.isInitialized) return
+ logger.animateDoze()
textAnimator.setTextStyle(
- animate = isAnimated && isAnimationEnabled,
- color = if (isDozing) AOD_COLOR else lockscreenColor,
- textSize = if (isDozing) aodFontSizePx else lockScreenPaint.textSize,
- fvar = if (isDozing) aodFontVariation else lsFontVariation,
- duration = aodStyle.transitionDuration,
- interpolator = aodDozingInterpolator,
+ TextAnimator.Style(
+ fVar = if (isDozing) aodFontVariation else lsFontVariation,
+ color = if (isDozing) AOD_COLOR else lockscreenColor,
+ textSize = if (isDozing) aodFontSizePx else lockScreenPaint.textSize,
+ ),
+ TextAnimator.Animation(
+ animate = isAnimated && isAnimationEnabled,
+ duration = aodStyle.transitionDuration,
+ interpolator = aodDozingInterpolator,
+ ),
)
updateTextBoundsForTextAnimator()
}
fun animateCharge() {
- if (!this::textAnimator.isInitialized || textAnimator.isRunning()) {
+ if (!this::textAnimator.isInitialized || textAnimator.isRunning) {
// Skip charge animation if dozing animation is already playing.
return
}
- logger.d("animateCharge()")
+ logger.animateCharge()
+
+ val lsStyle = TextAnimator.Style(fVar = lsFontVariation)
+ val aodStyle = TextAnimator.Style(fVar = aodFontVariation)
+
textAnimator.setTextStyle(
- fvar = if (dozeFraction == 0F) aodFontVariation else lsFontVariation,
- animate = isAnimationEnabled,
- onAnimationEnd =
- Runnable {
+ if (dozeFraction == 0f) aodStyle else lsStyle,
+ TextAnimator.Animation(
+ animate = isAnimationEnabled,
+ duration = CHARGE_ANIMATION_DURATION,
+ onAnimationEnd = {
textAnimator.setTextStyle(
- fvar = if (dozeFraction == 0F) lsFontVariation else aodFontVariation,
- animate = isAnimationEnabled,
+ if (dozeFraction == 0f) lsStyle else aodStyle,
+ TextAnimator.Animation(
+ animate = isAnimationEnabled,
+ duration = CHARGE_ANIMATION_DURATION,
+ ),
)
updateTextBoundsForTextAnimator()
},
+ ),
)
updateTextBoundsForTextAnimator()
}
fun animateFidget(x: Float, y: Float) {
- if (!this::textAnimator.isInitialized || textAnimator.isRunning()) {
+ if (!this::textAnimator.isInitialized || textAnimator.isRunning) {
// Skip fidget animation if other animation is already playing.
return
}
@@ -286,19 +318,25 @@
logger.animateFidget(x, y)
clockCtx.vibrator?.vibrate(FIDGET_HAPTICS)
- // TODO(b/374306512): Duplicated charge animation as placeholder. Implement final version
- // when we have a complete spec. May require additional code to animate individual digits.
+ // TODO(b/374306512): Delay each glyph's animation based on x/y position
textAnimator.setTextStyle(
- fvar = fidgetFontVariation,
- animate = isAnimationEnabled,
- onAnimationEnd =
- Runnable {
+ TextAnimator.Style(fVar = fidgetFontVariation),
+ TextAnimator.Animation(
+ animate = isAnimationEnabled,
+ duration = FIDGET_ANIMATION_DURATION,
+ interpolator = FIDGET_INTERPOLATOR,
+ onAnimationEnd = {
textAnimator.setTextStyle(
- fvar = if (dozeFraction == 0F) lsFontVariation else aodFontVariation,
- animate = isAnimationEnabled,
+ TextAnimator.Style(fVar = lsFontVariation),
+ TextAnimator.Animation(
+ animate = isAnimationEnabled,
+ duration = FIDGET_ANIMATION_DURATION,
+ interpolator = FIDGET_INTERPOLATOR,
+ ),
)
updateTextBoundsForTextAnimator()
},
+ ),
)
updateTextBoundsForTextAnimator()
}
@@ -329,42 +367,20 @@
}
private fun getInterpolatedTextBounds(): Rect {
- val interpolatedTextBounds = Rect()
- if (textAnimator.animator.animatedFraction != 1.0f && textAnimator.animator.isRunning) {
- interpolatedTextBounds.left =
- MathUtils.lerp(
- prevTextBounds.left,
- targetTextBounds.left,
- textAnimator.animator.animatedValue as Float,
- )
- .toInt()
-
- interpolatedTextBounds.right =
- MathUtils.lerp(
- prevTextBounds.right,
- targetTextBounds.right,
- textAnimator.animator.animatedValue as Float,
- )
- .toInt()
-
- interpolatedTextBounds.top =
- MathUtils.lerp(
- prevTextBounds.top,
- targetTextBounds.top,
- textAnimator.animator.animatedValue as Float,
- )
- .toInt()
-
- interpolatedTextBounds.bottom =
- MathUtils.lerp(
- prevTextBounds.bottom,
- targetTextBounds.bottom,
- textAnimator.animator.animatedValue as Float,
- )
- .toInt()
- } else {
- interpolatedTextBounds.set(targetTextBounds)
+ val progress = textAnimator.animator?.let { it.animatedValue as Float } ?: 1f
+ if (!textAnimator.isRunning || progress >= 1f) {
+ return Rect(targetTextBounds)
}
+
+ val interpolatedTextBounds = Rect()
+ interpolatedTextBounds.left =
+ MathUtils.lerp(prevTextBounds.left, targetTextBounds.left, progress).toInt()
+ interpolatedTextBounds.right =
+ MathUtils.lerp(prevTextBounds.right, targetTextBounds.right, progress).toInt()
+ interpolatedTextBounds.top =
+ MathUtils.lerp(prevTextBounds.top, targetTextBounds.top, progress).toInt()
+ interpolatedTextBounds.bottom =
+ MathUtils.lerp(prevTextBounds.bottom, targetTextBounds.bottom, progress).toInt()
return interpolatedTextBounds
}
@@ -471,7 +487,7 @@
textStyle.lineHeight?.let { lineHeight = it.toInt() }
this.aodStyle = aodStyle ?: textStyle.copy()
- this.aodStyle.transitionInterpolator?.let { aodDozingInterpolator = it }
+ aodDozingInterpolator = this.aodStyle.transitionInterpolator ?: Interpolators.LINEAR
lockScreenPaint.strokeWidth = textBorderWidth
measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED)
setInterpolatorPaint()
@@ -500,7 +516,7 @@
recomputeMaxSingleDigitSizes()
if (this::textAnimator.isInitialized) {
- textAnimator.setTextStyle(textSize = lockScreenPaint.textSize, animate = false)
+ textAnimator.setTextStyle(TextAnimator.Style(textSize = lockScreenPaint.textSize))
}
}
@@ -525,10 +541,11 @@
textAnimator.textInterpolator.targetPaint.set(lockScreenPaint)
textAnimator.textInterpolator.onTargetPaintModified()
textAnimator.setTextStyle(
- fvar = lsFontVariation,
- textSize = lockScreenPaint.textSize,
- color = lockscreenColor,
- animate = false,
+ TextAnimator.Style(
+ fVar = lsFontVariation,
+ textSize = lockScreenPaint.textSize,
+ color = lockscreenColor,
+ )
)
}
}
@@ -572,6 +589,17 @@
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_QUICK_RISE, 1.0f, 43)
.compose()
+ val CHARGE_ANIMATION_DURATION = 500L
+ val FIDGET_ANIMATION_DURATION = 250L
+ val FIDGET_INTERPOLATOR = PathInterpolator(0.26873f, 0f, 0.45042f, 1f)
+ val FIDGET_DISTS =
+ mapOf(
+ GSFAxes.WEIGHT to Pair(200f, 500f),
+ GSFAxes.WIDTH to Pair(30f, 75f),
+ GSFAxes.ROUND to Pair(0f, 50f),
+ GSFAxes.SLANT to Pair(0f, -5f),
+ )
+
val AOD_COLOR = Color.WHITE
val LS_WEIGHT_AXIS = ClockFontAxisSetting(GSFAxes.WEIGHT, 400f)
val AOD_WEIGHT_AXIS = ClockFontAxisSetting(GSFAxes.WEIGHT, 200f)
diff --git a/packages/SystemUI/docs/qs-tiles.md b/packages/SystemUI/docs/qs-tiles.md
index ee388ec..87d9b7c 100644
--- a/packages/SystemUI/docs/qs-tiles.md
+++ b/packages/SystemUI/docs/qs-tiles.md
@@ -8,6 +8,14 @@
Settings tiles. It provides descriptions about the lifecycle of a tile, how to create new tiles and
how SystemUI manages and displays tiles, among other topics.
+A lot of the tile backend architecture is in the process of being replaced by a new architecture in
+order to align with the
+[recommended architecture](https://developer.android.com/topic/architecture#recommended-app-arch).
+
+While we are in the process of migrating, this document will try to provide a comprehensive
+overview of the current architecture as well as the new one. The sections documenting the new
+architecture are marked with the tag [NEW-ARCH].
+
## What are Quick Settings Tiles?
Quick Settings (from now on, QS) is the expanded panel that contains shortcuts for the user to
@@ -72,6 +80,27 @@
implement plugins to add additional tiles or different behavior. For more information,
see [plugins.md](plugins.md)
+
+#### [NEW-ARCH] Tile backend
+Instead of `QSTileImpl` the tile backend is made of a view model called `QSTileViewModelImpl`,
+which in turn is composed of 3 interfaces:
+
+* [`QSTileDataInteractor`](/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileDataInteractor.kt)
+is responsible for providing the data for the tile. It is responsible for fetching the state of
+the tile from the source of truth and providing that information to the tile. Typically the data
+interactor will read system state from a repository or a controller and provide a flow of
+domain-specific data model.
+
+* [`QSTileUserActionInteractor`](/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileUserActionInteractor.kt) is responsible for handling the user actions on the tile.
+This interactor decides what should happen when the user clicks, long clicks on the tile.
+
+* [`QSTileDataToStateMapper`](/packages/SystemUI/src/com/android/systemui/qs/tiles/base/mapper/QSTileMapper.kt)
+is responsible for mapping the data received from the data interactor to a state that the view
+model can use to update the UI.
+
+At the time being, the `QSTileViewModel`s are adapted to `QSTile`. This conversion is done by
+`QSTileViewModelAdapter`.
+
#### Tile State
Each tile has an associated `State` object that is used to communicate information to the
@@ -94,6 +123,11 @@
to `state == Tile#STATE_ACTIVE`. This is used by accessibility services along
with `expandedAccessibilityClassName`.
+#### [NEW-ARCH] Tile State
+In the new architecture, the mapper generates
+[`QSTileState`](packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileState.kt),
+which again is converted to the old state by `QSTileViewModelAdapter`.
+
#### SystemUI tiles
Each tile defined in SystemUI extends `QSTileImpl`. This abstract class implements some common
@@ -103,6 +137,9 @@
For more information on how to implement a tile in SystemUI,
see [Implementing a SystemUI tile](#implementing-a-systemui-tile).
+As mentioned before, when the [NEW-ARCH] migration is complete, we will remove the `QSTileImpl`
+and `QSTileViewModelAdapter` and directly use`QSTileViewModelImpl`.
+
### Tile views
Each Tile has a couple of associated views for displaying it in QS and QQS. These views are updated
@@ -154,37 +191,24 @@
#### Life of a tile click
This is a brief run-down of what happens when a user clicks on a tile. Internal changes on the
-device (for example, changes from Settings) will trigger this process starting in step 3. Throughout
-this section, we assume that we are dealing with a `QSTileImpl`.
+device (for example, changes from Settings) will trigger this process starting in step 5.
-1. User clicks on tile. The following calls happen in sequence:
- 1. `QSTileViewImpl#onClickListener`.
- 2. `QSTile#click`.
- 3. `QSTileImpl#handleClick`. This last call sets the new state for the device by using the
- associated controller.
-2. State in the device changes. This is normally outside of SystemUI's control.
-3. Controller receives a callback (or `Intent`) indicating the change in the device. The following
- calls happen:
- 1. `QSTileImpl#refreshState`, maybe passing an object with necessary information regarding the
- new state.
- 2. `QSTileImpl#handleRefreshState`
-4. `QSTileImpl#handleUpdateState` is called to update the state with the new information. This
- information can be obtained both from the `Object` passed to `refreshState` as well as from the
- controller.
-5. If the state has changed (in at least one element), `QSTileImpl#handleStateChanged` is called.
- This will trigger a call to all the associated `QSTile.Callback#onStateChanged`, passing the
- new `State`.
-6. `QSTileView#onStateChanged` is called and this calls `QSTileView#handleStateChanged`. This method
- maps the state into the view:
- * The tile colors change to match the new state.
- * `QSIconView.setIcon` is called to apply the correct state to the icon and the correct icon to
- the view.
- * The tile labels change to match the new state.
+Step | Legacy Tiles | [NEW-ARCH] Tiles
+-------|-------|---------
+1 | User clicks on tile. | Same as legacy tiles.
+2 | `QSTileViewImpl#onClickListener` | Same as legacy tiles.
+3 | `QSTile#click` | Same as legacy tiles.
+4| `QSTileImpl#handleClick` | `QSTileUserActionInteractor#handleInput`
+5| State in the device changes. This is normally outside of SystemUI's control. Controller receives a callback (or `Intent`) indicating the change in the device. | Same as legacy tiles.
+6 | `QSTile#refreshState`and `QSTileImpl#handleRefreshState` | `QSTileDataInteractor#tileData()`
+7| `QSTileImpl#handleUpdateState` is called to update the state with the new information. This information can be obtained both from the `Object` passed to `refreshState` as well as from the controller. | The data that was generated by the data interactor is read by the `QSTileViewModelImpl.state` flow which calls `QSTileMapper#map` on the data to generate a new `QSTileState`.
+8| If the state has changed (in at least one element `QSTileImpl#handleStateChanged` is called. This will trigger a call to all the associated `QSTile.Callback#onStateChanged`, passing the new `State`. | The newly mapped QSTileState is read by the `QSTileViewModelAdapter` which then maps it to a legacy `State`. Similarly to the legacy tiles, the new state is compared to the old one and if there is a difference, `QSTile.Callback#onStateChanged` is called for all the associated callbacks.
+9 | `QSTileView#onStateChanged` is called and this calls `QSTileView#handleStateChanged`. This method maps the state updating tile color and label, and calling `QSIconView.setIcon` | Same as legacy tiles.
## Third party tiles (TileService)
-A third party tile is any Quick Settings tile that is provided by an app (that's not SystemUI). This
-is implemented by developers
+A third party tile is any Quick Settings tile that is provided by an app (that's not SystemUI).
+This is implemented by developers
subclassing [`TileService`](/core/java/android/service/quicksettings/TileService.java) and
interacting with its API.
@@ -220,9 +244,9 @@
* **`onTileAdded`**: called when the tile is added to QS.
* **`onTileRemoved`**: called when the tile is removed from QS.
* **`onStartListening`**: called when QS is opened and the tile is showing. This marks the start of
- the window when calling `getQSTile` is safe and will provide the correct object.
-* **`onStopListening`**: called when QS is closed or the tile is no longer visible by the user. This
- marks the end of the window described in `onStartListening`.
+the window when calling `getQSTile` is safe and will provide the correct object.
+* **`onStopListening`**: called when QS is closed or the tile is no longer visible by the user.
+This marks the end of the window described in `onStartListening`.
* **`onClick`**: called when the user clicks on the tile.
Additionally, the following final methods are provided:
@@ -379,13 +403,14 @@
### QSFactory
+`CurrentTilesInteractorImpl` uses the `QSFactory` interface to create the tiles.
+
This interface provides a way of creating tiles and views from a spec. It can be used in plugins to
provide different definitions for tiles.
-In SystemUI there is only one implementation of this factory and that is the default
-factory (`QSFactoryImpl`) in `CurrentTilesInteractorImpl`.
+In SystemUI there are two implementation of this factory. The first one is `QSFactoryImpl` in used for legacy tiles. The second one is `NewQSFactory` used for [NEW-ARCH] tiles.
-#### QSFactoryImpl
+#### QSFactoryImpl (legacy tiles)
This class implements the following method as specified in the `QSFactory` interface:
@@ -402,6 +427,12 @@
As part of filtering not valid tiles, custom tiles that don't have a corresponding valid service
component are never instantiated.
+#### NewQSFactory ([NEW-ARCH] tiles)
+
+This class also implements the `createTile` method as specified in the `QSFactory` interface.
+However, it first uses the spec to get a `QSTileViewModel`. The view model is then adapted into a
+`QSTile` using the `QSTileViewModelAdapter`.
+
### Lifecycle of a Tile
We describe first the parts of the lifecycle that are common to SystemUI tiles and third party
@@ -415,7 +446,7 @@
2. This updates the flow that `CurrentTilesInteractor` is collecting from, triggering the process
described above.
3. `CurrentTilesInteractor` calls the available `QSFactory` classes in order to find one that will
- be able to create a tile with that spec. Assuming that `QSFactoryImpl` managed to create the
+ be able to create a tile with that spec. Assuming that some factory managed to create the
tile, which is some implementation of `QSTile` (either a SystemUI subclass
of `QSTileImpl` or a `CustomTile`) it will be added to the current list.
If the tile is available, it's stored in a map and things proceed forward.
@@ -452,7 +483,7 @@
This section describes necessary and recommended steps when implementing a Quick Settings tile. Some
of them are optional and depend on the requirements of the tile.
-### Implementing a SystemUI tile
+### Implementing a legacy SystemUI tile
1. Create a class (preferably
in [`SystemUI/src/com/android/systemui/qs/tiles`](/packages/SystemUI/src/com/android/systemui/qs/tiles))
@@ -579,6 +610,70 @@
Provides a default label for this Tile. Used by the QS Panel customizer to show a name next to
each available tile.
+### Implementing a [NEW-ARCH] SystemUI tile
+In the new system the tiles are created in the path
+[`packages/SystemUI/src/com/android/systemui/qs/tiles/impl/<spec>`](packages/SystemUI/src/com/android/systemui/qs/tiles/impl/<spec>)
+where the `<spec>` should be replaced by the spec of the tile e.g. rotation for `RotationLockTile`.
+
+To create a new tile, the developer needs to implement the following data class and interfaces:
+
+[`DataModel`] is a class that describes the system state of the feature that the tile is trying to
+represent. Let's refer to the type of this class as DATA_TYPE. For example a simplified version of
+the data model for a flashlight tile could be a class with a boolean field that represents
+whether the flashlight is on or not.
+
+This file should be placed in the relative path `domain/model/` down from the tile's package.
+
+[`QSTileDataInteractor`] There are two abstract methods that need to be implemented:
+* `fun tileData(user: UserHandle, triggers: Flow<DataUpdateTrigger>): Flow<DATA_TYPE>`: This method
+returns a flow of data that will be used to create the state of the tile. This is where the system
+state is listened to and converted to a flow of data model. Avoid loading data or settings up
+listeners on the main thread. The userHandle is the user for which the tile is created.
+The triggers flow is a flow of events that can be used to trigger a refresh of the data.
+The most common triggers the force update and initial request.
+
+* `fun availability(user: UserHandle): Flow<Boolean>`: This method returns a flow of booleans that
+indicates if the tile should be shown or not. This is where the availability of the system feature
+(e.g. wifi) is checked. The userHandle is the user for which the tile is created.
+
+This file should be placed in the relative path `domain/interactor/` down from the tile's package.
+
+[`QSTileUserActionInteractor`]
+* `fun handleInput(input: QSTileInput)` is the method that needs to be implemented. This is the
+method that will be called when the user interacts with the tile. The input parameter contains
+the type of interaction (click, long click, toggle) and the DATA_TYPE of the latest data when the
+input was received.
+
+This file should be placed in the relative path `/domain/interactor` down from the tile's package.
+
+[`QSTileDataToStateMapper`]
+* `fun map(data: DATA_TYPE): QSTileState` is the method that needs to be implemented. This method
+is responsible for mapping the data received from the data interactor to a state that the view
+model can use to update the UI. This is where for example the icon should be loaded, and the
+label and content description set. The map function will run on UIBackground thread, a single
+thread which has higher priority than the background thread and lower than UI thread. Loading a
+resource on UI thread can cause jank by blocking the UI thread. On the other end of the spectrum,
+loading resources using a background dispatcher may cause jank due to background thread contention
+since it is possible for the background dispatcher to use more than one background thread
+at the same time. In contrast, the UIBackground dispatcher uses a single thread that is
+shared by all tiles. Therefore the system will use UIBackground dispatcher to execute
+the map function.
+
+The most important resource to load in the map function is the icon. We prefer `Icon.Loaded` with a
+resource id over `Icon.Resource`, because then (a) we can guarantee that the drawable loading will
+happen on the UIBackground thread and (b) we can cache the drawables using the resource id.
+
+This file should be placed in the relative path `/ui/mapper` down from the tile's package.
+
+#### Testing a [NEW-ARCH] SystemUI tile
+
+When writing tests, the mapper is usually a good place to start, since that is where the
+business logic decisions are being made that can inform the shape of data interactor.
+
+We suggest taking advantage of the existing class `QSTileStateSubject`. So rather than
+asserting an individual field's value, a test will assert the whole state. That can be
+achieved by `QSTileStateSubject.assertThat(outputState).isEqualTo(expectedState)`.
+
### Implementing a third party tile
For information about this, use the Android Developer documentation
diff --git a/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardMessageAreaControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardMessageAreaControllerTest.java
index bd81181..4140a95 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardMessageAreaControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardMessageAreaControllerTest.java
@@ -18,9 +18,7 @@
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
@@ -28,8 +26,6 @@
import android.hardware.biometrics.BiometricSourceType;
import android.testing.TestableLooper;
-import android.text.Editable;
-import android.text.TextWatcher;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
@@ -99,19 +95,6 @@
}
@Test
- public void textChanged_AnnounceForAccessibility() {
- ArgumentCaptor<TextWatcher> textWatcherArgumentCaptor = ArgumentCaptor.forClass(
- TextWatcher.class);
- mMessageAreaController.onViewAttached();
- verify(mKeyguardMessageArea).addTextChangedListener(textWatcherArgumentCaptor.capture());
-
- textWatcherArgumentCaptor.getValue().afterTextChanged(
- Editable.Factory.getInstance().newEditable("abc"));
- verify(mKeyguardMessageArea).removeCallbacks(any(Runnable.class));
- verify(mKeyguardMessageArea).postDelayed(any(Runnable.class), anyLong());
- }
-
- @Test
public void testSetBouncerVisible() {
mMessageAreaController.setIsVisible(true);
verify(mKeyguardMessageArea).setIsVisible(true);
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegateTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegateTest.java
index e4539b7..0b13900 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegateTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegateTest.java
@@ -45,7 +45,6 @@
import android.content.pm.ResolveInfo;
import android.graphics.drawable.Drawable;
import android.media.AudioManager;
-import android.os.Handler;
import android.platform.test.annotations.EnableFlags;
import android.provider.Settings;
import android.testing.TestableLooper;
@@ -75,6 +74,8 @@
import com.android.systemui.res.R;
import com.android.systemui.statusbar.phone.SystemUIDialog;
import com.android.systemui.statusbar.phone.SystemUIDialogManager;
+import com.android.systemui.util.concurrency.FakeExecutor;
+import com.android.systemui.util.time.FakeSystemClock;
import org.junit.After;
import org.junit.Before;
@@ -107,6 +108,7 @@
private static final String TEST_LABEL = "label";
private static final int TEST_PRESET_INDEX = 1;
private static final String TEST_PRESET_NAME = "test_preset";
+ private final FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
@Mock
private SystemUIDialogManager mSystemUIDialogManager;
@@ -150,11 +152,9 @@
private SystemUIDialog mDialog;
private SystemUIDialog.Factory mDialogFactory;
private HearingDevicesDialogDelegate mDialogDelegate;
- private TestableLooper mTestableLooper;
@Before
public void setUp() {
- mTestableLooper = TestableLooper.get(this);
when(mLocalBluetoothManager.getBluetoothAdapter()).thenReturn(mLocalBluetoothAdapter);
when(mLocalBluetoothManager.getProfileManager()).thenReturn(mProfileManager);
when(mProfileManager.getHapClientProfile()).thenReturn(mHapClientProfile);
@@ -186,6 +186,7 @@
public void clickPairNewDeviceButton_intentActionMatch() {
setUpDeviceDialogWithPairNewDeviceButton();
mDialog.show();
+ mExecutor.runAllReady();
getPairNewDeviceButton(mDialog).performClick();
@@ -232,6 +233,7 @@
setUpDeviceDialogWithoutPairNewDeviceButton();
mDialog.show();
+ mExecutor.runAllReady();
assertToolsUi(0);
}
@@ -246,6 +248,7 @@
setUpDeviceDialogWithoutPairNewDeviceButton();
mDialog.show();
+ mExecutor.runAllReady();
assertToolsUi(1);
}
@@ -267,6 +270,7 @@
setUpDeviceDialogWithoutPairNewDeviceButton();
mDialog.show();
+ mExecutor.runAllReady();
assertToolsUi(2);
}
@@ -278,6 +282,7 @@
setUpDeviceDialogWithoutPairNewDeviceButton();
mDialog.show();
+ mExecutor.runAllReady();
ViewGroup presetLayout = getPresetLayout(mDialog);
assertThat(presetLayout.getVisibility()).isEqualTo(View.GONE);
@@ -291,7 +296,7 @@
setUpDeviceDialogWithoutPairNewDeviceButton();
mDialog.show();
- mTestableLooper.processAllMessages();
+ mExecutor.runAllReady();
ViewGroup presetLayout = getPresetLayout(mDialog);
assertThat(presetLayout.getVisibility()).isEqualTo(View.VISIBLE);
@@ -306,6 +311,7 @@
setUpDeviceDialogWithoutPairNewDeviceButton();
mDialog.show();
+ mExecutor.runAllReady();
ViewGroup ambientLayout = getAmbientLayout(mDialog);
assertThat(ambientLayout.getVisibility()).isEqualTo(View.GONE);
@@ -318,6 +324,7 @@
setUpDeviceDialogWithoutPairNewDeviceButton();
mDialog.show();
+ mExecutor.runAllReady();
ViewGroup ambientLayout = getAmbientLayout(mDialog);
assertThat(ambientLayout.getVisibility()).isEqualTo(View.GONE);
@@ -343,6 +350,7 @@
public void onActiveDeviceChanged_presetExist_presetSelected() {
setUpDeviceDialogWithoutPairNewDeviceButton();
mDialog.show();
+ mExecutor.runAllReady();
BluetoothHapPresetInfo info = getTestPresetInfo();
when(mHapClientProfile.getAllPresetInfo(mDevice)).thenReturn(List.of(info));
when(mHapClientProfile.getActivePresetIndex(mDevice)).thenReturn(TEST_PRESET_INDEX);
@@ -351,7 +359,7 @@
assertThat(spinner.getSelectedItemPosition()).isEqualTo(-1);
mDialogDelegate.onActiveDeviceChanged(mCachedDevice, BluetoothProfile.LE_AUDIO);
- mTestableLooper.processAllMessages();
+ mExecutor.runAllReady();
ViewGroup presetLayout = getPresetLayout(mDialog);
assertThat(presetLayout.getVisibility()).isEqualTo(View.VISIBLE);
@@ -381,7 +389,8 @@
mActivityStarter,
mDialogTransitionAnimator,
mLocalBluetoothManager,
- new Handler(mTestableLooper.getLooper()),
+ mExecutor,
+ mExecutor,
mAudioManager,
mUiEventLogger
);
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/animation/GhostedViewTransitionAnimatorControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/animation/GhostedViewTransitionAnimatorControllerTest.kt
index e492c63..052d520 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/animation/GhostedViewTransitionAnimatorControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/animation/GhostedViewTransitionAnimatorControllerTest.kt
@@ -17,16 +17,20 @@
package com.android.systemui.animation
import android.os.HandlerThread
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
import android.testing.TestableLooper
import android.view.View
import android.widget.FrameLayout
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.jank.InteractionJankMonitor
+import com.android.systemui.Flags
import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.view.LaunchableFrameLayout
import com.google.common.truth.Truth.assertThat
import org.junit.Assert.assertThrows
+import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -40,6 +44,14 @@
}
private val interactionJankMonitor = FakeInteractionJankMonitor()
+ private lateinit var transitionRegistry: FakeViewTransitionRegistry
+ private lateinit var transitioningView: View
+
+ @Before
+ fun setup() {
+ transitioningView = LaunchableFrameLayout(mContext)
+ transitionRegistry = FakeViewTransitionRegistry()
+ }
@Test
fun animatingOrphanViewDoesNotCrash() {
@@ -67,7 +79,7 @@
parent.addView((launchView))
val launchController =
GhostedViewTransitionAnimatorController(
- launchView,
+ launchView,
launchCujType = LAUNCH_CUJ,
returnCujType = RETURN_CUJ,
interactionJankMonitor = interactionJankMonitor
@@ -96,6 +108,26 @@
assertThat(interactionJankMonitor.finished).containsExactly(LAUNCH_CUJ, RETURN_CUJ)
}
+ @EnableFlags(Flags.FLAG_DECOUPLE_VIEW_CONTROLLER_IN_ANIMLIB)
+ @Test
+ fun testViewsAreRegisteredInTransitionRegistry() {
+ GhostedViewTransitionAnimatorController(
+ transitioningView = transitioningView,
+ transitionRegistry = transitionRegistry
+ )
+ assertThat(transitionRegistry.registry).isNotEmpty()
+ }
+
+ @DisableFlags(Flags.FLAG_DECOUPLE_VIEW_CONTROLLER_IN_ANIMLIB)
+ @Test
+ fun testNotUseRegistryIfDecouplingFlagDisabled() {
+ GhostedViewTransitionAnimatorController(
+ transitioningView = transitioningView,
+ transitionRegistry = transitionRegistry
+ )
+ assertThat(transitionRegistry.registry).isEmpty()
+ }
+
/**
* A fake implementation of [InteractionJankMonitor] which stores ongoing and finished CUJs and
* allows inspection.
@@ -117,4 +149,30 @@
return true
}
}
+
+ private class FakeViewTransitionRegistry : IViewTransitionRegistry {
+
+ val registry = mutableMapOf<ViewTransitionToken, View>()
+
+ override fun register(token: ViewTransitionToken, view: View) {
+ registry[token] = view
+ view.setTag(R.id.tag_view_transition_token, token)
+ }
+
+ override fun unregister(token: ViewTransitionToken) {
+ registry.remove(token)?.setTag(R.id.tag_view_transition_token, null)
+ }
+
+ override fun getView(token: ViewTransitionToken): View? {
+ return registry[token]
+ }
+
+ override fun getViewToken(view: View): ViewTransitionToken? {
+ return view.getTag(R.id.tag_view_transition_token) as? ViewTransitionToken
+ }
+
+ override fun onRegistryUpdate() {
+ //empty
+ }
+ }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/viewmodel/CommunalTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/viewmodel/CommunalTransitionViewModelTest.kt
index 1a3606e..da25bca 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/viewmodel/CommunalTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/viewmodel/CommunalTransitionViewModelTest.kt
@@ -35,6 +35,7 @@
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runCurrent
@@ -44,6 +45,7 @@
import platform.test.runner.parameterized.ParameterizedAndroidJunit4
import platform.test.runner.parameterized.Parameters
+@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(ParameterizedAndroidJunit4::class)
class CommunalTransitionViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
@@ -65,7 +67,7 @@
private val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository
private val communalSceneRepository = kosmos.fakeCommunalSceneRepository
- private val sceneInteractor = kosmos.sceneInteractor
+ private val sceneInteractor by lazy { kosmos.sceneInteractor }
private val underTest: CommunalTransitionViewModel by lazy {
kosmos.communalTransitionViewModel
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt
index 329627a..e36d245 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt
@@ -61,6 +61,7 @@
import com.android.systemui.user.data.repository.fakeUserRepository
import com.android.systemui.util.mockito.eq
import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.test.TestScope
@@ -73,6 +74,7 @@
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
+@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(AndroidJUnit4::class)
class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() {
@@ -80,21 +82,26 @@
private val testScope: TestScope = kosmos.testScope
private lateinit var underTest: SystemUIDeviceEntryFaceAuthInteractor
+
private val bouncerRepository = kosmos.fakeKeyguardBouncerRepository
private val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository
- private val keyguardTransitionInteractor = kosmos.keyguardTransitionInteractor
private val faceAuthRepository = kosmos.fakeDeviceEntryFaceAuthRepository
private val fakeUserRepository = kosmos.fakeUserRepository
private val facePropertyRepository = kosmos.facePropertyRepository
- private val fakeDeviceEntryFingerprintAuthInteractor =
- kosmos.deviceEntryFingerprintAuthInteractor
- private val powerInteractor = kosmos.powerInteractor
private val fakeBiometricSettingsRepository = kosmos.fakeBiometricSettingsRepository
- private val keyguardUpdateMonitor = kosmos.keyguardUpdateMonitor
+ private val keyguardUpdateMonitor by lazy { kosmos.keyguardUpdateMonitor }
private val faceWakeUpTriggersConfig = kosmos.fakeFaceWakeUpTriggersConfig
private val trustManager = kosmos.trustManager
- private val deviceEntryFaceAuthStatusInteractor = kosmos.deviceEntryFaceAuthStatusInteractor
+
+ private val keyguardTransitionInteractor by lazy { kosmos.keyguardTransitionInteractor }
+ private val fakeDeviceEntryFingerprintAuthInteractor by lazy {
+ kosmos.deviceEntryFingerprintAuthInteractor
+ }
+ private val powerInteractor by lazy { kosmos.powerInteractor }
+ private val deviceEntryFaceAuthStatusInteractor by lazy {
+ kosmos.deviceEntryFaceAuthStatusInteractor
+ }
@Before
fun setup() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialNotificationCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialNotificationCoordinatorTest.kt
index ff5fa39..7374f18 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialNotificationCoordinatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialNotificationCoordinatorTest.kt
@@ -37,7 +37,6 @@
import com.android.systemui.touchpad.data.repository.FakeTouchpadRepository
import com.google.common.truth.Truth.assertThat
import kotlin.time.Duration.Companion.hours
-import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.advanceTimeBy
import kotlinx.coroutines.test.runTest
import org.junit.Before
@@ -51,7 +50,6 @@
import org.mockito.junit.MockitoJUnit
import org.mockito.kotlin.any
import org.mockito.kotlin.eq
-import org.mockito.kotlin.firstValue
import org.mockito.kotlin.never
import org.mockito.kotlin.secondValue
import org.mockito.kotlin.verify
@@ -116,7 +114,6 @@
fun showTouchpadNotification() = runTestAndClear {
touchpadRepository.setIsAnyTouchpadConnected(true)
testScope.advanceTimeBy(LAUNCH_DELAY)
- mockExistingNotification()
verifyNotification(
R.string.launch_touchpad_tutorial_notification_title,
R.string.launch_touchpad_tutorial_notification_content,
@@ -142,14 +139,10 @@
}
@Test
- fun showKeyboardNotificationThenDisconnectKeyboard() = runTestAndClear {
+ fun cancelKeyboardNotificationWhenKeyboardDisconnects() = runTestAndClear {
keyboardRepository.setIsAnyKeyboardConnected(true)
testScope.advanceTimeBy(LAUNCH_DELAY)
- verifyNotification(
- R.string.launch_keyboard_tutorial_notification_title,
- R.string.launch_keyboard_tutorial_notification_content,
- )
- mockExistingNotification()
+ mockNotifications(hasTutorialNotification = true)
// After the keyboard is disconnected, i.e. there is nothing connected, the notification
// should be cancelled
@@ -158,22 +151,71 @@
}
@Test
- fun showKeyboardTouchpadNotificationThenDisconnectKeyboard() = runTestAndClear {
+ fun updateNotificationToTouchpadOnlyWhenKeyboardDisconnects() = runTestAndClear {
keyboardRepository.setIsAnyKeyboardConnected(true)
touchpadRepository.setIsAnyTouchpadConnected(true)
testScope.advanceTimeBy(LAUNCH_DELAY)
- mockExistingNotification()
+ mockNotifications(hasTutorialNotification = true)
+
keyboardRepository.setIsAnyKeyboardConnected(false)
verify(notificationManager, times(2))
.notifyAsUser(eq(TAG), eq(NOTIFICATION_ID), notificationCaptor.capture(), any())
- // Connect both device and the first notification is for both
- notificationCaptor.firstValue.verify(
+ // Connect both device and the first notification is for both. After the keyboard is
+ // disconnected, i.e. with only the touchpad left, the notification should be update to
+ // touchpad only
+ notificationCaptor.secondValue.verify(
+ R.string.launch_touchpad_tutorial_notification_title,
+ R.string.launch_touchpad_tutorial_notification_content,
+ )
+ }
+
+ @Test
+ fun updateNotificationToBothDevicesWhenTouchpadConnects() = runTestAndClear {
+ keyboardRepository.setIsAnyKeyboardConnected(true)
+ testScope.advanceTimeBy(LAUNCH_DELAY)
+ mockNotifications(hasTutorialNotification = true)
+
+ touchpadRepository.setIsAnyTouchpadConnected(true)
+
+ verify(notificationManager, times(2))
+ .notifyAsUser(eq(TAG), eq(NOTIFICATION_ID), notificationCaptor.capture(), any())
+ // Update the notification from keyboard to both devices
+ notificationCaptor.secondValue.verify(
R.string.launch_keyboard_touchpad_tutorial_notification_title,
R.string.launch_keyboard_touchpad_tutorial_notification_content,
)
- // After the keyboard is disconnected, i.e. with only the touchpad left, the notification
- // should be update to the one for only touchpad
+ }
+
+ @Test
+ fun doNotShowUpdateNotificationWhenInitialNotificationIsDismissed() = runTestAndClear {
+ keyboardRepository.setIsAnyKeyboardConnected(true)
+ testScope.advanceTimeBy(LAUNCH_DELAY)
+ mockNotifications(hasTutorialNotification = false)
+
+ touchpadRepository.setIsAnyTouchpadConnected(true)
+
+ // There's only one notification being shown throughout this scenario. We don't update the
+ // notification because it has been dismissed when the touchpad connects
+ verifyNotification(
+ R.string.launch_keyboard_tutorial_notification_title,
+ R.string.launch_keyboard_tutorial_notification_content,
+ )
+ }
+
+ @Test
+ fun showTouchpadNotificationAfterDelayAndKeyboardNotificationIsDismissed() = runTestAndClear {
+ keyboardRepository.setIsAnyKeyboardConnected(true)
+ testScope.advanceTimeBy(LAUNCH_DELAY)
+ mockNotifications(hasTutorialNotification = false)
+
+ touchpadRepository.setIsAnyTouchpadConnected(true)
+ testScope.advanceTimeBy(LAUNCH_DELAY)
+
+ verify(notificationManager, times(2))
+ .notifyAsUser(eq(TAG), eq(NOTIFICATION_ID), notificationCaptor.capture(), any())
+ // The keyboard notification was shown and dismissed; the touchpad notification is scheduled
+ // independently
notificationCaptor.secondValue.verify(
R.string.launch_touchpad_tutorial_notification_title,
R.string.launch_touchpad_tutorial_notification_content,
@@ -189,10 +231,12 @@
}
}
- // Assume that there's an existing notification when the updater checks activeNotifications
- private fun mockExistingNotification() {
+ // Mock an active notification, so when the updater checks activeNotifications, it returns one
+ // with the given id. Otherwise, return an empty array (i.e. no active notifications)
+ private fun mockNotifications(hasTutorialNotification: Boolean) {
whenever(notification.id).thenReturn(NOTIFICATION_ID)
- whenever(notificationManager.activeNotifications).thenReturn(arrayOf(notification))
+ val notifications = if (hasTutorialNotification) arrayOf(notification) else emptyArray()
+ whenever(notificationManager.activeNotifications).thenReturn(notifications)
}
private fun verifyNotification(@StringRes titleResId: Int, @StringRes contentResId: Int) {
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 183e4d6..98486a2 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
@@ -541,7 +541,7 @@
simpleShortcutCategory(System, "System apps", "Take a note"),
simpleShortcutCategory(System, "System controls", "Take screenshot"),
simpleShortcutCategory(System, "System controls", "Go back"),
- simpleShortcutCategory(MultiTasking, "Split screen", "Switch to full screen"),
+ simpleShortcutCategory(MultiTasking, "Split screen", "Use full screen"),
simpleShortcutCategory(
MultiTasking,
"Split screen",
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModelTest.kt
index 6eef5eb..b91e259 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModelTest.kt
@@ -337,6 +337,43 @@
}
}
+ @Test
+ fun uiState_pressedKeysDescription_emptyByDefault() {
+ testScope.runTest {
+ val uiState by collectLastValue(viewModel.shortcutCustomizationUiState)
+ viewModel.onShortcutCustomizationRequested(standardAddShortcutRequest)
+
+ assertThat((uiState as AddShortcutDialog).pressedKeysDescription).isEmpty()
+ }
+ }
+
+ @Test
+ fun uiState_pressedKeysDescription_updatesToNonEmptyDescriptionWhenKeyCombinationIsPressed() {
+ testScope.runTest {
+ val uiState by collectLastValue(viewModel.shortcutCustomizationUiState)
+ viewModel.onShortcutCustomizationRequested(standardAddShortcutRequest)
+ viewModel.onShortcutKeyCombinationSelected(keyDownEventWithActionKeyPressed)
+ viewModel.onShortcutKeyCombinationSelected(keyUpEventWithActionKeyPressed)
+
+ // Note that Action Key is excluded as it's already displayed on the UI
+ assertThat((uiState as AddShortcutDialog).pressedKeysDescription)
+ .isEqualTo("Ctrl, plus A")
+ }
+ }
+
+ @Test
+ fun uiState_pressedKeysDescription_resetsToEmpty_onClearSelectedShortcutKeyCombination() {
+ testScope.runTest {
+ val uiState by collectLastValue(viewModel.shortcutCustomizationUiState)
+ viewModel.onShortcutCustomizationRequested(standardAddShortcutRequest)
+ viewModel.onShortcutKeyCombinationSelected(keyDownEventWithActionKeyPressed)
+ viewModel.onShortcutKeyCombinationSelected(keyUpEventWithActionKeyPressed)
+ viewModel.clearSelectedKeyCombination()
+
+ assertThat((uiState as AddShortcutDialog).pressedKeysDescription).isEmpty()
+ }
+ }
+
private suspend fun openAddShortcutDialogAndSetShortcut() {
openAddShortcutDialogAndPressKeyCombination()
viewModel.onSetShortcut()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt
index 29e95cd..0b42898 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt
@@ -23,6 +23,7 @@
import com.android.systemui.coroutines.collectValues
import com.android.systemui.flags.DisableSceneContainer
import com.android.systemui.flags.EnableSceneContainer
+import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
import com.android.systemui.keyguard.shared.model.Edge
import com.android.systemui.keyguard.shared.model.KeyguardState
@@ -46,20 +47,31 @@
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import junit.framework.Assert.assertEquals
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Assert.assertThrows
+import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(AndroidJUnit4::class)
class KeyguardTransitionInteractorTest : SysuiTestCase() {
- val kosmos = testKosmos()
- val underTest = kosmos.keyguardTransitionInteractor
- val repository = kosmos.fakeKeyguardTransitionRepository
- val testScope = kosmos.testScope
+
+ private val kosmos = testKosmos()
+ private val testScope = kosmos.testScope
+
+ private lateinit var repository: FakeKeyguardTransitionRepository
+ private lateinit var underTest: KeyguardTransitionInteractor
+
+ @Before
+ fun setup() {
+ repository = kosmos.fakeKeyguardTransitionRepository
+ underTest = kosmos.keyguardTransitionInteractor
+ }
@Test
fun transitionCollectorsReceivesOnlyAppropriateEvents() =
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractorTest.kt
index 26fe379..3cff0fc 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractorTest.kt
@@ -1358,6 +1358,45 @@
)
}
+ /**
+ * When a transition away from the lockscreen is interrupted by an `Idle(Lockscreen)`, a
+ * `sceneState` that was set during the transition is consumed and passed to KTF.
+ */
+ @Test
+ fun transition_from_ls_scene_sceneStateSet_then_interrupted_by_idle_on_ls() =
+ testScope.runTest {
+ val currentStep by collectLastValue(kosmos.realKeyguardTransitionRepository.transitions)
+ sceneTransitions.value =
+ ObservableTransitionState.Transition(
+ Scenes.Lockscreen,
+ Scenes.Gone,
+ flowOf(Scenes.Lockscreen),
+ progress,
+ false,
+ flowOf(false),
+ )
+ progress.value = 0.4f
+ assertTransition(
+ step = currentStep!!,
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.UNDEFINED,
+ state = TransitionState.RUNNING,
+ progress = 0.4f,
+ )
+
+ val sceneState = KeyguardState.AOD
+ underTest.onSceneAboutToChange(toScene = Scenes.Lockscreen, sceneState = sceneState)
+ sceneTransitions.value = ObservableTransitionState.Idle(Scenes.Lockscreen)
+
+ assertTransition(
+ step = currentStep!!,
+ from = KeyguardState.UNDEFINED,
+ to = KeyguardState.AOD,
+ state = TransitionState.FINISHED,
+ progress = 1f,
+ )
+ }
+
private fun assertTransition(
step: TransitionStep,
from: KeyguardState? = null,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DozingToDreamingTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DozingToDreamingTransitionViewModelTest.kt
deleted file mode 100644
index 052dfd5..0000000
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DozingToDreamingTransitionViewModelTest.kt
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2025 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.keyguard.ui.viewmodel
-
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.SmallTest
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
-import com.android.systemui.keyguard.shared.model.KeyguardState
-import com.android.systemui.kosmos.collectValues
-import com.android.systemui.kosmos.runTest
-import com.android.systemui.kosmos.testScope
-import com.android.systemui.testKosmos
-import com.google.common.truth.Truth.assertThat
-import org.junit.Test
-import org.junit.runner.RunWith
-
-@SmallTest
-@RunWith(AndroidJUnit4::class)
-class DozingToDreamingTransitionViewModelTest : SysuiTestCase() {
- val kosmos = testKosmos()
-
- val underTest by lazy { kosmos.dozingToDreamingTransitionViewModel }
-
- @Test
- fun notificationShadeAlpha() =
- kosmos.runTest {
- val values by collectValues(underTest.notificationAlpha)
- assertThat(values).isEmpty()
-
- fakeKeyguardTransitionRepository.sendTransitionSteps(
- from = KeyguardState.DOZING,
- to = KeyguardState.DREAMING,
- testScope,
- )
-
- assertThat(values).isNotEmpty()
- values.forEach { assertThat(it).isEqualTo(0) }
- }
-}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelTest.kt
index 25c1572..0b34a01 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelTest.kt
@@ -23,6 +23,7 @@
import com.android.systemui.biometrics.authController
import com.android.systemui.common.ui.data.repository.fakeConfigurationRepository
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.fakeKeyguardClockRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
@@ -47,6 +48,7 @@
import com.android.systemui.shade.domain.interactor.enableDualShade
import com.android.systemui.shade.domain.interactor.enableSingleShade
import com.android.systemui.shade.domain.interactor.enableSplitShade
+import com.android.systemui.shade.domain.interactor.shadeModeInteractor
import com.android.systemui.shade.shared.model.ShadeMode
import com.android.systemui.testKosmos
import com.android.systemui.unfold.fakeUnfoldTransitionProgressProvider
@@ -123,6 +125,7 @@
}
@Test
+ @EnableSceneContainer
fun notificationsPlacement_dualShadeSmallClock_below() =
kosmos.runTest {
setupState(
@@ -135,6 +138,7 @@
}
@Test
+ @EnableSceneContainer
fun notificationsPlacement_dualShadeLargeClock_topStart() =
kosmos.runTest {
setupState(
@@ -156,6 +160,7 @@
}
@Test
+ @EnableSceneContainer
fun areNotificationsVisible_dualShadeWideOnLockscreen_true() =
kosmos.runTest {
setupState(
@@ -298,6 +303,7 @@
) {
val isShadeLayoutWide by collectLastValue(kosmos.shadeRepository.isShadeLayoutWide)
val collectedClockSize by collectLastValue(kosmos.keyguardClockInteractor.clockSize)
+ val collectedShadeMode by collectLastValue(kosmos.shadeModeInteractor.shadeMode)
when (shadeMode) {
ShadeMode.Dual -> kosmos.enableDualShade(wideLayout = shadeLayoutWide)
ShadeMode.Single -> kosmos.enableSingleShade()
@@ -309,6 +315,7 @@
if (shadeLayoutWide != null) {
assertThat(isShadeLayoutWide).isEqualTo(shadeLayoutWide)
}
+ assertThat(collectedShadeMode).isEqualTo(shadeMode)
assertThat(collectedClockSize).isEqualTo(clockSize)
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/dialog/MediaOutputAdapterLegacyTest.java
similarity index 90%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/media/dialog/MediaOutputAdapterLegacyTest.java
index f5a7111..f293614 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/dialog/MediaOutputAdapterLegacyTest.java
@@ -33,8 +33,6 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.app.WallpaperColors;
-import android.graphics.Bitmap;
import android.graphics.drawable.Icon;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
@@ -68,7 +66,7 @@
@SmallTest
@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
-public class MediaOutputAdapterTest extends SysuiTestCase {
+public class MediaOutputAdapterLegacyTest extends SysuiTestCase {
private static final String TEST_DEVICE_NAME_1 = "test_device_name_1";
private static final String TEST_DEVICE_NAME_2 = "test_device_name_2";
@@ -92,8 +90,8 @@
@Captor
private ArgumentCaptor<SeekBar.OnSeekBarChangeListener> mOnSeekBarChangeListenerCaptor;
- private MediaOutputAdapter mMediaOutputAdapter;
- private MediaOutputAdapter.MediaDeviceViewHolder mViewHolder;
+ private MediaOutputAdapterLegacy mMediaOutputAdapter;
+ private MediaOutputAdapterLegacy.MediaDeviceViewHolderLegacy mViewHolder;
private List<MediaDevice> mMediaDevices = new ArrayList<>();
private List<MediaItem> mMediaItems = new ArrayList<>();
MediaOutputSeekbar mSpyMediaOutputSeekbar;
@@ -124,9 +122,9 @@
mMediaItems.add(MediaItem.createDeviceMediaItem(mMediaDevice1, true));
mMediaItems.add(MediaItem.createDeviceMediaItem(mMediaDevice2, false));
- mMediaOutputAdapter = new MediaOutputAdapter(mMediaSwitchingController);
+ mMediaOutputAdapter = new MediaOutputAdapterLegacy(mMediaSwitchingController);
mMediaOutputAdapter.updateItems();
- mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
+ mViewHolder = (MediaOutputAdapterLegacy.MediaDeviceViewHolderLegacy) mMediaOutputAdapter
.onCreateViewHolder(new LinearLayout(mContext), 0);
mSpyMediaOutputSeekbar = spy(mViewHolder.mSeekBar);
}
@@ -150,9 +148,9 @@
@Test
public void onBindViewHolder_bindPairNew_verifyView() {
- mMediaOutputAdapter = new MediaOutputAdapter(mMediaSwitchingController);
+ mMediaOutputAdapter = new MediaOutputAdapterLegacy(mMediaSwitchingController);
mMediaOutputAdapter.updateItems();
- mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
+ mViewHolder = (MediaOutputAdapterLegacy.MediaDeviceViewHolderLegacy) mMediaOutputAdapter
.onCreateViewHolder(new LinearLayout(mContext), 0);
mMediaItems.add(MediaItem.createPairNewDeviceMediaItem());
mMediaItems.add(MediaItem.createPairNewDeviceMediaItem());
@@ -175,9 +173,9 @@
.map((item) -> item.getMediaDevice().get())
.collect(Collectors.toList()));
when(mMediaSwitchingController.getSessionName()).thenReturn(TEST_SESSION_NAME);
- mMediaOutputAdapter = new MediaOutputAdapter(mMediaSwitchingController);
+ mMediaOutputAdapter = new MediaOutputAdapterLegacy(mMediaSwitchingController);
mMediaOutputAdapter.updateItems();
- mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
+ mViewHolder = (MediaOutputAdapterLegacy.MediaDeviceViewHolderLegacy) mMediaOutputAdapter
.onCreateViewHolder(new LinearLayout(mContext), 0);
mMediaOutputAdapter.getItemCount();
mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
@@ -197,9 +195,9 @@
.map((item) -> item.getMediaDevice().get())
.collect(Collectors.toList()));
when(mMediaSwitchingController.getSessionName()).thenReturn(null);
- mMediaOutputAdapter = new MediaOutputAdapter(mMediaSwitchingController);
+ mMediaOutputAdapter = new MediaOutputAdapterLegacy(mMediaSwitchingController);
mMediaOutputAdapter.updateItems();
- mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
+ mViewHolder = (MediaOutputAdapterLegacy.MediaDeviceViewHolderLegacy) mMediaOutputAdapter
.onCreateViewHolder(new LinearLayout(mContext), 0);
mMediaOutputAdapter.getItemCount();
mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
@@ -225,7 +223,7 @@
@Test
public void onBindViewHolder_bindNonRemoteConnectedDevice_verifyView() {
when(mMediaSwitchingController.isActiveRemoteDevice(mMediaDevice1)).thenReturn(false);
- mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
+ mViewHolder = (MediaOutputAdapterLegacy.MediaDeviceViewHolderLegacy) mMediaOutputAdapter
.onCreateViewHolder(new LinearLayout(mContext), 0);
mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
@@ -245,7 +243,7 @@
when(mMediaSwitchingController.getSelectableMediaDevice())
.thenReturn(ImmutableList.of(mMediaDevice2));
when(mMediaSwitchingController.isCurrentConnectedDeviceRemote()).thenReturn(true);
- mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
+ mViewHolder = (MediaOutputAdapterLegacy.MediaDeviceViewHolderLegacy) mMediaOutputAdapter
.onCreateViewHolder(new LinearLayout(mContext), 0);
mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
@@ -264,7 +262,7 @@
when(mMediaSwitchingController.getSelectableMediaDevice())
.thenReturn(ImmutableList.of(mMediaDevice2));
when(mMediaSwitchingController.isCurrentConnectedDeviceRemote()).thenReturn(true);
- mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
+ mViewHolder = (MediaOutputAdapterLegacy.MediaDeviceViewHolderLegacy) mMediaOutputAdapter
.onCreateViewHolder(new LinearLayout(mContext), 0);
mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
@@ -276,7 +274,7 @@
public void onBindViewHolder_bindSingleConnectedRemoteDevice_verifyView() {
when(mMediaSwitchingController.getSelectableMediaDevice()).thenReturn(ImmutableList.of());
when(mMediaSwitchingController.isCurrentConnectedDeviceRemote()).thenReturn(true);
- mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
+ mViewHolder = (MediaOutputAdapterLegacy.MediaDeviceViewHolderLegacy) mMediaOutputAdapter
.onCreateViewHolder(new LinearLayout(mContext), 0);
mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
@@ -294,7 +292,7 @@
when(mMediaDevice1.hasOngoingSession()).thenReturn(true);
when(mMediaSwitchingController.getSelectableMediaDevice()).thenReturn(ImmutableList.of());
when(mMediaSwitchingController.isCurrentConnectedDeviceRemote()).thenReturn(true);
- mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
+ mViewHolder = (MediaOutputAdapterLegacy.MediaDeviceViewHolderLegacy) mMediaOutputAdapter
.onCreateViewHolder(new LinearLayout(mContext), 0);
mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
@@ -315,7 +313,7 @@
when(mMediaDevice1.isHostForOngoingSession()).thenReturn(true);
when(mMediaSwitchingController.getSelectableMediaDevice()).thenReturn(ImmutableList.of());
when(mMediaSwitchingController.isCurrentConnectedDeviceRemote()).thenReturn(true);
- mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
+ mViewHolder = (MediaOutputAdapterLegacy.MediaDeviceViewHolderLegacy) mMediaOutputAdapter
.onCreateViewHolder(new LinearLayout(mContext), 0);
mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
@@ -348,7 +346,7 @@
when(mMediaDevice1.isMutingExpectedDevice()).thenReturn(true);
when(mMediaSwitchingController.isCurrentConnectedDeviceRemote()).thenReturn(false);
when(mMediaSwitchingController.isActiveRemoteDevice(mMediaDevice1)).thenReturn(false);
- mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
+ mViewHolder = (MediaOutputAdapterLegacy.MediaDeviceViewHolderLegacy) mMediaOutputAdapter
.onCreateViewHolder(new LinearLayout(mContext), 0);
mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
@@ -371,6 +369,37 @@
}
@Test
+ public void onBindViewHolder_initSeekbarWithUnmutedVolume_displaysMuteIcon() {
+ when(mMediaSwitchingController.isVolumeControlEnabled(mMediaDevice1)).thenReturn(true);
+ when(mMediaDevice1.getMaxVolume()).thenReturn(TEST_MAX_VOLUME);
+ when(mMediaDevice1.getCurrentVolume()).thenReturn(TEST_CURRENT_VOLUME);
+ mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
+
+ assertThat(mViewHolder.mSeekBar.getVisibility()).isEqualTo(View.VISIBLE);
+ assertThat(mViewHolder.mIconAreaLayout.getVisibility()).isEqualTo(View.VISIBLE);
+
+ mViewHolder.mIconAreaLayout.performClick();
+ verify(mMediaSwitchingController).adjustVolume(mMediaDevice1, 0);
+ verify(mMediaSwitchingController).logInteractionMuteDevice(mMediaDevice1);
+ }
+
+ @Test
+ public void onBindViewHolder_initSeekbarWithMutedVolume_displaysUnmuteIcon() {
+ when(mMediaSwitchingController.isVolumeControlEnabled(mMediaDevice1)).thenReturn(true);
+ when(mMediaDevice1.getMaxVolume()).thenReturn(TEST_MAX_VOLUME);
+ when(mMediaDevice1.getCurrentVolume()).thenReturn(0); // muted.
+ mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
+
+ assertThat(mViewHolder.mSeekBar.getVisibility()).isEqualTo(View.VISIBLE);
+ assertThat(mViewHolder.mIconAreaLayout.getVisibility()).isEqualTo(View.VISIBLE);
+
+ mViewHolder.mIconAreaLayout.performClick();
+ // Default unmute volume is 2.
+ verify(mMediaSwitchingController).adjustVolume(mMediaDevice1, 2);
+ verify(mMediaSwitchingController).logInteractionUnmuteDevice(mMediaDevice1);
+ }
+
+ @Test
public void onBindViewHolder_dragSeekbar_setsVolume() {
mOnSeekBarChangeListenerCaptor = ArgumentCaptor.forClass(
SeekBar.OnSeekBarChangeListener.class);
@@ -498,7 +527,7 @@
when(mMediaDevice1.getSubtextString()).thenReturn(TEST_CUSTOM_SUBTEXT);
when(mMediaDevice1.hasOngoingSession()).thenReturn(true);
when(mMediaDevice1.getSelectionBehavior()).thenReturn(SELECTION_BEHAVIOR_GO_TO_APP);
- mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
+ mViewHolder = (MediaOutputAdapterLegacy.MediaDeviceViewHolderLegacy) mMediaOutputAdapter
.onCreateViewHolder(new LinearLayout(mContext), 0);
mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
@@ -522,7 +551,7 @@
when(mMediaDevice2.getSubtext()).thenReturn(SUBTEXT_SUBSCRIPTION_REQUIRED);
when(mMediaDevice2.getSubtextString()).thenReturn(deviceStatus);
when(mMediaDevice2.getSelectionBehavior()).thenReturn(SELECTION_BEHAVIOR_GO_TO_APP);
- mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
+ mViewHolder = (MediaOutputAdapterLegacy.MediaDeviceViewHolderLegacy) mMediaOutputAdapter
.onCreateViewHolder(new LinearLayout(mContext), 0);
mMediaOutputAdapter.onBindViewHolder(mViewHolder, 1);
@@ -545,7 +574,7 @@
when(mMediaDevice2.getSubtext()).thenReturn(SUBTEXT_AD_ROUTING_DISALLOWED);
when(mMediaDevice2.getSubtextString()).thenReturn(deviceStatus);
when(mMediaDevice2.getSelectionBehavior()).thenReturn(SELECTION_BEHAVIOR_NONE);
- mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
+ mViewHolder = (MediaOutputAdapterLegacy.MediaDeviceViewHolderLegacy) mMediaOutputAdapter
.onCreateViewHolder(new LinearLayout(mContext), 0);
mMediaOutputAdapter.onBindViewHolder(mViewHolder, 1);
@@ -567,7 +596,7 @@
when(mMediaDevice1.getSubtextString()).thenReturn(TEST_CUSTOM_SUBTEXT);
when(mMediaDevice1.hasOngoingSession()).thenReturn(true);
when(mMediaDevice1.getSelectionBehavior()).thenReturn(SELECTION_BEHAVIOR_GO_TO_APP);
- mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
+ mViewHolder = (MediaOutputAdapterLegacy.MediaDeviceViewHolderLegacy) mMediaOutputAdapter
.onCreateViewHolder(new LinearLayout(mContext), 0);
mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
@@ -627,9 +656,9 @@
@Test
public void onItemClick_clickPairNew_verifyLaunchBluetoothPairing() {
- mMediaOutputAdapter = new MediaOutputAdapter(mMediaSwitchingController);
+ mMediaOutputAdapter = new MediaOutputAdapterLegacy(mMediaSwitchingController);
mMediaOutputAdapter.updateItems();
- mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
+ mViewHolder = (MediaOutputAdapterLegacy.MediaDeviceViewHolderLegacy) mMediaOutputAdapter
.onCreateViewHolder(new LinearLayout(mContext), 0);
mMediaItems.add(MediaItem.createPairNewDeviceMediaItem());
mMediaOutputAdapter.updateItems();
@@ -645,9 +674,9 @@
assertThat(mMediaDevice2.getState()).isEqualTo(
LocalMediaManager.MediaDeviceState.STATE_DISCONNECTED);
when(mMediaDevice2.getSelectionBehavior()).thenReturn(SELECTION_BEHAVIOR_TRANSFER);
- mMediaOutputAdapter = new MediaOutputAdapter(mMediaSwitchingController);
+ mMediaOutputAdapter = new MediaOutputAdapterLegacy(mMediaSwitchingController);
mMediaOutputAdapter.updateItems();
- mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
+ mViewHolder = (MediaOutputAdapterLegacy.MediaDeviceViewHolderLegacy) mMediaOutputAdapter
.onCreateViewHolder(new LinearLayout(mContext), 0);
mMediaOutputAdapter.getItemCount();
mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
@@ -663,11 +692,12 @@
assertThat(mMediaDevice2.getState()).isEqualTo(
LocalMediaManager.MediaDeviceState.STATE_DISCONNECTED);
when(mMediaDevice2.getSelectionBehavior()).thenReturn(SELECTION_BEHAVIOR_TRANSFER);
- mMediaOutputAdapter = new MediaOutputAdapter(mMediaSwitchingController);
+ mMediaOutputAdapter = new MediaOutputAdapterLegacy(mMediaSwitchingController);
mMediaOutputAdapter.updateItems();
- mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
+ mViewHolder = (MediaOutputAdapterLegacy.MediaDeviceViewHolderLegacy) mMediaOutputAdapter
.onCreateViewHolder(new LinearLayout(mContext), 0);
- MediaOutputAdapter.MediaDeviceViewHolder spyMediaDeviceViewHolder = spy(mViewHolder);
+ MediaOutputAdapterLegacy.MediaDeviceViewHolderLegacy spyMediaDeviceViewHolder = spy(
+ mViewHolder);
mMediaOutputAdapter.getItemCount();
mMediaOutputAdapter.onBindViewHolder(spyMediaDeviceViewHolder, 0);
@@ -684,11 +714,12 @@
when(mMediaDevice2.getState()).thenReturn(
LocalMediaManager.MediaDeviceState.STATE_DISCONNECTED);
when(mMediaDevice2.getSelectionBehavior()).thenReturn(SELECTION_BEHAVIOR_GO_TO_APP);
- mMediaOutputAdapter = new MediaOutputAdapter(mMediaSwitchingController);
+ mMediaOutputAdapter = new MediaOutputAdapterLegacy(mMediaSwitchingController);
mMediaOutputAdapter.updateItems();
- mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
+ mViewHolder = (MediaOutputAdapterLegacy.MediaDeviceViewHolderLegacy) mMediaOutputAdapter
.onCreateViewHolder(new LinearLayout(mContext), 0);
- MediaOutputAdapter.MediaDeviceViewHolder spyMediaDeviceViewHolder = spy(mViewHolder);
+ MediaOutputAdapterLegacy.MediaDeviceViewHolderLegacy spyMediaDeviceViewHolder = spy(
+ mViewHolder);
mMediaOutputAdapter.onBindViewHolder(spyMediaDeviceViewHolder, 1);
spyMediaDeviceViewHolder.mContainerLayout.performClick();
@@ -715,7 +746,7 @@
List<MediaDevice> selectableDevices = new ArrayList<>();
selectableDevices.add(mMediaDevice2);
when(mMediaSwitchingController.getSelectableMediaDevice()).thenReturn(selectableDevices);
- mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
+ mViewHolder = (MediaOutputAdapterLegacy.MediaDeviceViewHolderLegacy) mMediaOutputAdapter
.onCreateViewHolder(new LinearLayout(mContext), 0);
mMediaOutputAdapter.onBindViewHolder(mViewHolder, 1);
@@ -859,7 +890,7 @@
when(mMediaSwitchingController.getSelectedMediaDevice())
.thenReturn(ImmutableList.of(mMediaDevice1));
when(mMediaSwitchingController.isCurrentConnectedDeviceRemote()).thenReturn(true);
- mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
+ mViewHolder = (MediaOutputAdapterLegacy.MediaDeviceViewHolderLegacy) mMediaOutputAdapter
.onCreateViewHolder(new LinearLayout(mContext), 0);
mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
@@ -899,16 +930,6 @@
}
@Test
- public void updateColorScheme_triggerController() {
- WallpaperColors wallpaperColors = WallpaperColors.fromBitmap(
- Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888));
-
- mMediaOutputAdapter.updateColorScheme(wallpaperColors, true);
-
- verify(mMediaSwitchingController).setCurrentColorScheme(wallpaperColors, true);
- }
-
- @Test
public void updateItems_controllerItemsUpdated_notUpdatesInAdapterUntilUpdateItems() {
mMediaOutputAdapter.updateItems();
List<MediaItem> updatedList = new ArrayList<>();
@@ -990,7 +1011,7 @@
public void multipleSelectedDevices_verifySessionView() {
initializeSession();
- mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
+ mViewHolder = (MediaOutputAdapterLegacy.MediaDeviceViewHolderLegacy) mMediaOutputAdapter
.onCreateViewHolder(
new LinearLayout(mContext), MediaItem.MediaItemType.TYPE_DEVICE);
mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
@@ -1011,7 +1032,7 @@
public void multipleSelectedDevices_verifyCollapsedView() {
initializeSession();
- mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
+ mViewHolder = (MediaOutputAdapterLegacy.MediaDeviceViewHolderLegacy) mMediaOutputAdapter
.onCreateViewHolder(
new LinearLayout(mContext), MediaItem.MediaItemType.TYPE_DEVICE);
mMediaOutputAdapter.onBindViewHolder(mViewHolder, 1);
@@ -1024,13 +1045,13 @@
@Test
public void multipleSelectedDevices_expandIconClicked_verifyInitialView() {
initializeSession();
- mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
+ mViewHolder = (MediaOutputAdapterLegacy.MediaDeviceViewHolderLegacy) mMediaOutputAdapter
.onCreateViewHolder(
new LinearLayout(mContext), MediaItem.MediaItemType.TYPE_DEVICE);
mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
mViewHolder.mEndTouchArea.performClick();
- mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
+ mViewHolder = (MediaOutputAdapterLegacy.MediaDeviceViewHolderLegacy) mMediaOutputAdapter
.onCreateViewHolder(
new LinearLayout(mContext), MediaItem.MediaItemType.TYPE_DEVICE);
mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
@@ -1047,13 +1068,13 @@
@Test
public void multipleSelectedDevices_expandIconClicked_verifyCollapsedView() {
initializeSession();
- mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
+ mViewHolder = (MediaOutputAdapterLegacy.MediaDeviceViewHolderLegacy) mMediaOutputAdapter
.onCreateViewHolder(
new LinearLayout(mContext), MediaItem.MediaItemType.TYPE_DEVICE);
mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
mViewHolder.mEndTouchArea.performClick();
- mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
+ mViewHolder = (MediaOutputAdapterLegacy.MediaDeviceViewHolderLegacy) mMediaOutputAdapter
.onCreateViewHolder(
new LinearLayout(mContext), MediaItem.MediaItemType.TYPE_DEVICE);
mMediaOutputAdapter.onBindViewHolder(mViewHolder, 1);
@@ -1075,7 +1096,7 @@
when(mMediaSwitchingController.getSelectedMediaDevice()).thenReturn(selectedDevices);
when(mMediaSwitchingController.getDeselectableMediaDevice()).thenReturn(new ArrayList<>());
- mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
+ mViewHolder = (MediaOutputAdapterLegacy.MediaDeviceViewHolderLegacy) mMediaOutputAdapter
.onCreateViewHolder(
new LinearLayout(mContext), MediaItem.MediaItemType.TYPE_DEVICE);
mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayContentViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayContentViewModelTest.kt
index 0bba8bb..b23cd5e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayContentViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayContentViewModelTest.kt
@@ -16,6 +16,7 @@
package com.android.systemui.notifications.ui.viewmodel
+import android.app.StatusBarManager.DISABLE2_QUICK_SETTINGS
import android.testing.TestableLooper
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
@@ -28,6 +29,8 @@
import com.android.systemui.kosmos.runCurrent
import com.android.systemui.kosmos.testScope
import com.android.systemui.lifecycle.activateIn
+import com.android.systemui.media.controls.data.repository.mediaFilterRepository
+import com.android.systemui.media.controls.shared.model.MediaData
import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest
import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest
import com.android.systemui.power.domain.interactor.powerInteractor
@@ -39,10 +42,13 @@
import com.android.systemui.shade.domain.interactor.enableDualShade
import com.android.systemui.shade.domain.interactor.shadeInteractor
import com.android.systemui.shade.ui.viewmodel.notificationsShadeOverlayContentViewModel
+import com.android.systemui.statusbar.disableflags.data.repository.fakeDisableFlagsRepository
import com.android.systemui.statusbar.notification.data.repository.activeNotificationListRepository
import com.android.systemui.statusbar.notification.data.repository.setActiveNotifs
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.update
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
@@ -50,6 +56,7 @@
import org.junit.Test
import org.junit.runner.RunWith
+@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
@@ -155,6 +162,36 @@
assertThat(underTest.showClock).isFalse()
}
+ @Test
+ fun showMedia_activeMedia_true() =
+ testScope.runTest {
+ kosmos.mediaFilterRepository.addSelectedUserMediaEntry(MediaData(active = true))
+ runCurrent()
+
+ assertThat(underTest.showMedia).isTrue()
+ }
+
+ @Test
+ fun showMedia_noActiveMedia_false() =
+ testScope.runTest {
+ kosmos.mediaFilterRepository.addSelectedUserMediaEntry(MediaData(active = false))
+ runCurrent()
+
+ assertThat(underTest.showMedia).isFalse()
+ }
+
+ @Test
+ fun showMedia_qsDisabled_false() =
+ testScope.runTest {
+ kosmos.mediaFilterRepository.addSelectedUserMediaEntry(MediaData(active = true))
+ kosmos.fakeDisableFlagsRepository.disableFlags.update {
+ it.copy(disable2 = DISABLE2_QUICK_SETTINGS)
+ }
+ runCurrent()
+
+ assertThat(underTest.showMedia).isFalse()
+ }
+
private fun TestScope.lockDevice() {
val currentScene by collectLastValue(sceneInteractor.currentScene)
kosmos.powerInteractor.setAsleepForTest()
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
index c775bfd..9e400a6 100644
--- 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
@@ -19,6 +19,7 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.collectLastValue
import com.android.systemui.kosmos.runTest
@@ -34,6 +35,7 @@
@SmallTest
@RunWith(AndroidJUnit4::class)
+@EnableSceneContainer
class GridLayoutTypeInteractorTest : SysuiTestCase() {
val kosmos = testKosmos()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/QSColumnsInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/QSColumnsInteractorTest.kt
index 2e7aeb4..9fe783b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/QSColumnsInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/QSColumnsInteractorTest.kt
@@ -22,6 +22,7 @@
import com.android.systemui.SysuiTestCase
import com.android.systemui.common.ui.data.repository.configurationRepository
import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.kosmos.testCase
import com.android.systemui.kosmos.testScope
import com.android.systemui.qs.panels.data.repository.QSColumnsRepository
@@ -76,6 +77,7 @@
}
@Test
+ @EnableSceneContainer
fun withDualShade_returnsCorrectValue() =
with(kosmos) {
testScope.runTest {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/MediaInRowInLandscapeViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/MediaInRowInLandscapeViewModelTest.kt
index fdbf42c..d5e502e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/MediaInRowInLandscapeViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/MediaInRowInLandscapeViewModelTest.kt
@@ -21,6 +21,7 @@
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.common.ui.data.repository.fakeConfigurationRepository
+import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.kosmos.testScope
import com.android.systemui.lifecycle.activateIn
import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager.Companion.LOCATION_QQS
@@ -36,6 +37,7 @@
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlin.test.Test
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
@@ -43,6 +45,7 @@
import platform.test.runner.parameterized.ParameterizedAndroidJunit4
import platform.test.runner.parameterized.Parameters
+@OptIn(ExperimentalCoroutinesApi::class)
@RunWith(ParameterizedAndroidJunit4::class)
@SmallTest
class MediaInRowInLandscapeViewModelTest(private val testData: TestData) : SysuiTestCase() {
@@ -63,6 +66,7 @@
}
@Test
+ @EnableSceneContainer
fun shouldMediaShowInRow() =
with(kosmos) {
testScope.runTest {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/QSColumnsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/QSColumnsViewModelTest.kt
index 241cdbf..4912c31 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/QSColumnsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/QSColumnsViewModelTest.kt
@@ -21,6 +21,7 @@
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.common.ui.data.repository.configurationRepository
+import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.runCurrent
import com.android.systemui.kosmos.testCase
@@ -88,6 +89,7 @@
}
@Test
+ @EnableSceneContainer
fun mediaLocationNull_dualShade_alwaysDualShadeColumns() =
with(kosmos) {
testScope.runTest {
@@ -111,6 +113,7 @@
}
@Test
+ @EnableSceneContainer
fun mediaLocationQS_dualShade_alwaysDualShadeColumns() =
with(kosmos) {
testScope.runTest {
@@ -133,6 +136,7 @@
}
@Test
+ @EnableSceneContainer
fun mediaLocationQQS_dualShade_alwaysDualShadeColumns() =
with(kosmos) {
testScope.runTest {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
index 80c7026..23a0f62 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
@@ -757,4 +757,46 @@
verify(processor, never()).onSceneAboutToChange(any(), any())
}
+
+ @Test
+ fun changeScene_sameScene_withFreeze() =
+ kosmos.runTest {
+ val currentScene by collectLastValue(underTest.currentScene)
+ assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
+ val processor = mock<SceneInteractor.OnSceneAboutToChangeListener>()
+ underTest.registerSceneStateProcessor(processor)
+ verify(processor, never()).onSceneAboutToChange(any(), any())
+ assertThat(fakeSceneDataSource.freezeAndAnimateToCurrentStateCallCount).isEqualTo(0)
+
+ underTest.changeScene(
+ toScene = Scenes.Lockscreen,
+ loggingReason = "test",
+ sceneState = KeyguardState.AOD,
+ forceSettleToTargetScene = true,
+ )
+
+ verify(processor).onSceneAboutToChange(Scenes.Lockscreen, KeyguardState.AOD)
+ assertThat(fakeSceneDataSource.freezeAndAnimateToCurrentStateCallCount).isEqualTo(1)
+ }
+
+ @Test
+ fun changeScene_sameScene_withoutFreeze() =
+ kosmos.runTest {
+ val currentScene by collectLastValue(underTest.currentScene)
+ assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
+ val processor = mock<SceneInteractor.OnSceneAboutToChangeListener>()
+ underTest.registerSceneStateProcessor(processor)
+ verify(processor, never()).onSceneAboutToChange(any(), any())
+ assertThat(fakeSceneDataSource.freezeAndAnimateToCurrentStateCallCount).isEqualTo(0)
+
+ underTest.changeScene(
+ toScene = Scenes.Lockscreen,
+ loggingReason = "test",
+ sceneState = KeyguardState.AOD,
+ forceSettleToTargetScene = false,
+ )
+
+ verify(processor, never()).onSceneAboutToChange(any(), any())
+ assertThat(fakeSceneDataSource.freezeAndAnimateToCurrentStateCallCount).isEqualTo(0)
+ }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/data/repository/ShadeDisplaysRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/data/repository/ShadeDisplaysRepositoryTest.kt
index 35368ca..9498daa 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/data/repository/ShadeDisplaysRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/data/repository/ShadeDisplaysRepositoryTest.kt
@@ -60,6 +60,7 @@
policies,
shadeOnDefaultDisplayWhenLocked = shadeOnDefaultDisplayWhenLocked,
keyguardRepository,
+ displayRepository,
)
@Test
@@ -90,6 +91,30 @@
}
@Test
+ fun displayId_afterDisplayDisconnected_fallsBackToDefaultDisplay() =
+ testScope.runTest {
+ val underTest = createUnderTest()
+ globalSettings.putString(
+ DEVELOPMENT_SHADE_DISPLAY_AWARENESS,
+ FakeShadeDisplayPolicy.name,
+ )
+ val displayId by collectLastValue(underTest.displayId)
+
+ displayRepository.addDisplay(displayId = 1)
+
+ FakeShadeDisplayPolicy.setDisplayId(1)
+ assertThat(displayId).isEqualTo(1)
+
+ // Let's disconnect and make sure it goes back to the default one
+ displayRepository.removeDisplay(displayId = 1)
+ assertThat(displayId).isEqualTo(Display.DEFAULT_DISPLAY)
+
+ // Let's re-connect it and make sure it goes back to the non-default one
+ displayRepository.addDisplay(displayId = 1)
+ assertThat(displayId).isEqualTo(1)
+ }
+
+ @Test
fun policy_updatesBasedOnSettingValue_defaultDisplay() =
testScope.runTest {
val underTest = createUnderTest()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeModeInteractorImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeModeInteractorImplTest.kt
index 668f568..d26e195 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeModeInteractorImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeModeInteractorImplTest.kt
@@ -20,6 +20,7 @@
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.kosmos.testScope
import com.android.systemui.shade.shared.model.ShadeMode
import com.android.systemui.testKosmos
@@ -31,6 +32,7 @@
@SmallTest
@RunWith(AndroidJUnit4::class)
+@EnableSceneContainer
class ShadeModeInteractorImplTest : SysuiTestCase() {
private val kosmos = testKosmos()
@@ -80,7 +82,7 @@
}
@Test
- fun isDualShade_settingEnabled_returnsTrue() =
+ fun isDualShade_settingEnabledSceneContainerEnabled_returnsTrue() =
testScope.runTest {
// TODO(b/391578667): Add a test case for user switching once the bug is fixed.
val shadeMode by collectLastValue(underTest.shadeMode)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/startable/ShadeStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/startable/ShadeStartableTest.kt
index b8f66ac..dde8678 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/startable/ShadeStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/startable/ShadeStartableTest.kt
@@ -48,6 +48,7 @@
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.test.TestScope
@@ -59,6 +60,7 @@
import platform.test.runner.parameterized.ParameterizedAndroidJunit4
import platform.test.runner.parameterized.Parameters
+@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(ParameterizedAndroidJunit4::class)
class ShadeStartableTest(flags: FlagsParameterization) : SysuiTestCase() {
@@ -103,6 +105,7 @@
}
@Test
+ @EnableSceneContainer
fun hydrateShadeMode_dualShadeEnabled() =
testScope.runTest {
overrideResource(R.bool.config_use_split_notification_shade, false)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/DragDownHelperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/DragDownHelperTest.kt
index 05d9495..a8aac39 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/DragDownHelperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/DragDownHelperTest.kt
@@ -74,7 +74,7 @@
dragDownHelper.cancelChildExpansion(expandableView, animationDuration = 0)
- verify(expandableView, atLeast(1)).actualHeight = collapsedHeight
+ verify(expandableView, atLeast(1)).setFinalActualHeight(collapsedHeight)
}
@Test
@@ -83,6 +83,6 @@
dragDownHelper.cancelChildExpansion(expandableView, animationDuration = 0)
- verify(expandableView, never()).actualHeight = anyInt()
+ verify(expandableView, never()).setFinalActualHeight(anyInt())
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/PulseExpansionHandlerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/PulseExpansionHandlerTest.kt
index cd66ef3..242da0b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/PulseExpansionHandlerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/PulseExpansionHandlerTest.kt
@@ -86,7 +86,7 @@
pulseExpansionHandler.reset(expandableView, animationDuration = 0)
- verify(expandableView, atLeast(1)).actualHeight = collapsedHeight
+ verify(expandableView, atLeast(1)).setFinalActualHeight(collapsedHeight)
}
@Test
@@ -95,6 +95,6 @@
pulseExpansionHandler.reset(expandableView, animationDuration = 0)
- verify(expandableView, never()).actualHeight = anyInt()
+ verify(expandableView, never()).setFinalActualHeight(anyInt())
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt
index cd3c8cd..ccc844a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt
@@ -17,7 +17,6 @@
package com.android.systemui.statusbar.chips.casttootherdevice.ui.viewmodel
import android.content.DialogInterface
-import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import android.view.View
import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -48,10 +47,10 @@
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.OngoingActivityChipsViewModelTest.Companion.getStopActionFromDialog
-import com.android.systemui.statusbar.core.StatusBarRootModernization
import com.android.systemui.statusbar.phone.SystemUIDialog
import com.android.systemui.statusbar.phone.mockSystemUIDialogFactory
-import com.android.systemui.statusbar.phone.ongoingcall.StatusBarChipsModernization
+import com.android.systemui.statusbar.phone.ongoingcall.DisableChipsModernization
+import com.android.systemui.statusbar.phone.ongoingcall.EnableChipsModernization
import com.android.systemui.statusbar.policy.CastDevice
import com.android.systemui.util.time.fakeSystemClock
import com.google.common.truth.Truth.assertThat
@@ -438,7 +437,7 @@
}
@Test
- @DisableFlags(StatusBarChipsModernization.FLAG_NAME)
+ @DisableChipsModernization
fun chip_projectionStateEntireScreen_clickListenerShowsScreenCastDialog() =
testScope.runTest {
val latest by collectLastValue(underTest.chip)
@@ -454,7 +453,7 @@
}
@Test
- @DisableFlags(StatusBarChipsModernization.FLAG_NAME)
+ @DisableChipsModernization
fun chip_projectionStateSingleTask_clickListenerShowsScreenCastDialog() =
testScope.runTest {
val latest by collectLastValue(underTest.chip)
@@ -475,7 +474,7 @@
}
@Test
- @DisableFlags(StatusBarChipsModernization.FLAG_NAME)
+ @DisableChipsModernization
fun chip_routerStateCasting_clickListenerShowsGenericCastDialog() =
testScope.runTest {
val latest by collectLastValue(underTest.chip)
@@ -505,7 +504,7 @@
}
@Test
- @DisableFlags(StatusBarChipsModernization.FLAG_NAME)
+ @DisableChipsModernization
fun chip_projectionStateCasting_clickListenerHasCuj() =
testScope.runTest {
val latest by collectLastValue(underTest.chip)
@@ -525,7 +524,7 @@
}
@Test
- @DisableFlags(StatusBarChipsModernization.FLAG_NAME)
+ @DisableChipsModernization
fun chip_routerStateCasting_clickListenerHasCuj() =
testScope.runTest {
val latest by collectLastValue(underTest.chip)
@@ -554,7 +553,7 @@
}
@Test
- @EnableFlags(StatusBarChipsModernization.FLAG_NAME)
+ @EnableChipsModernization
fun chip_routerStateCasting_hasClickBehavior() =
testScope.runTest {
val latest by collectLastValue(underTest.chip)
@@ -575,7 +574,7 @@
}
@Test
- @EnableFlags(StatusBarChipsModernization.FLAG_NAME)
+ @EnableChipsModernization
fun chip_projectionStateCasting_hasClickBehavior() =
testScope.runTest {
val latest by collectLastValue(underTest.chip)
@@ -588,7 +587,7 @@
}
@Test
- @EnableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME)
+ @EnableChipsModernization
fun chip_projectionStateEntireScreen_clickBehaviorShowsScreenCastDialog() =
testScope.runTest {
val latest by collectLastValue(underTest.chip)
@@ -605,7 +604,7 @@
}
@Test
- @EnableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME)
+ @EnableChipsModernization
fun chip_projectionStateSingleTask_clickBehaviorShowsScreenCastDialog() =
testScope.runTest {
val latest by collectLastValue(underTest.chip)
@@ -627,7 +626,7 @@
}
@Test
- @EnableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME)
+ @EnableChipsModernization
fun chip_routerStateCasting_clickBehaviorShowsGenericCastDialog() =
testScope.runTest {
val latest by collectLastValue(underTest.chip)
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 aaa9b58..4993b56 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
@@ -38,19 +38,23 @@
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 com.android.systemui.statusbar.core.StatusBarRootModernization
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.UnconfinedFakeHeadsUpRowRepository
import com.android.systemui.statusbar.notification.data.repository.activeNotificationListRepository
import com.android.systemui.statusbar.notification.headsup.PinnedStatus
import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel
+import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel.When
import com.android.systemui.statusbar.notification.shared.ActiveNotificationModel
import com.android.systemui.statusbar.notification.stack.data.repository.headsUpNotificationRepository
-import com.android.systemui.statusbar.phone.ongoingcall.StatusBarChipsModernization
+import com.android.systemui.statusbar.phone.ongoingcall.DisableChipsModernization
+import com.android.systemui.statusbar.phone.ongoingcall.EnableChipsModernization
import com.android.systemui.testKosmos
+import com.android.systemui.util.time.fakeSystemClock
import com.google.common.truth.Truth.assertThat
import kotlin.test.Test
+import kotlin.time.Duration.Companion.minutes
+import kotlin.time.Duration.Companion.seconds
import kotlinx.coroutines.flow.MutableStateFlow
import org.junit.Before
import org.junit.runner.RunWith
@@ -286,15 +290,13 @@
fun chips_hasShortCriticalText_usesTextInsteadOfTime() =
kosmos.runTest {
val latest by collectLastValue(underTest.chips)
+ val currentTime = 30.minutes.inWholeMilliseconds
+ fakeSystemClock.setCurrentTimeMillis(currentTime)
val promotedContentBuilder =
PromotedNotificationContentModel.Builder("notif").apply {
this.shortCriticalText = "Arrived"
- this.time =
- PromotedNotificationContentModel.When(
- time = 6543L,
- mode = PromotedNotificationContentModel.When.Mode.BasicTime,
- )
+ this.time = When.Time(currentTime + 30.minutes.inWholeMilliseconds)
}
setNotifs(
listOf(
@@ -340,15 +342,13 @@
fun chips_basicTime_timeHiddenIfAutomaticallyPromoted() =
kosmos.runTest {
val latest by collectLastValue(underTest.chips)
+ val currentTime = 30.minutes.inWholeMilliseconds
+ fakeSystemClock.setCurrentTimeMillis(currentTime)
val promotedContentBuilder =
PromotedNotificationContentModel.Builder("notif").apply {
this.wasPromotedAutomatically = true
- this.time =
- PromotedNotificationContentModel.When(
- time = 6543L,
- mode = PromotedNotificationContentModel.When.Mode.BasicTime,
- )
+ this.time = When.Time(currentTime + 30.minutes.inWholeMilliseconds)
}
setNotifs(
listOf(
@@ -370,15 +370,13 @@
fun chips_basicTime_timeShownIfNotAutomaticallyPromoted() =
kosmos.runTest {
val latest by collectLastValue(underTest.chips)
+ val currentTime = 30.minutes.inWholeMilliseconds
+ fakeSystemClock.setCurrentTimeMillis(currentTime)
val promotedContentBuilder =
PromotedNotificationContentModel.Builder("notif").apply {
this.wasPromotedAutomatically = false
- this.time =
- PromotedNotificationContentModel.When(
- time = 6543L,
- mode = PromotedNotificationContentModel.When.Mode.BasicTime,
- )
+ this.time = When.Time(currentTime + 30.minutes.inWholeMilliseconds)
}
setNotifs(
listOf(
@@ -397,18 +395,17 @@
@Test
@DisableFlags(FLAG_PROMOTE_NOTIFICATIONS_AUTOMATICALLY)
- fun chips_basicTime_isShortTimeDelta() =
+ fun chips_basicTime_timeInFuture_isShortTimeDelta() =
kosmos.runTest {
val latest by collectLastValue(underTest.chips)
+ val currentTime = 3.minutes.inWholeMilliseconds
+ fakeSystemClock.setCurrentTimeMillis(currentTime)
val promotedContentBuilder =
PromotedNotificationContentModel.Builder("notif").apply {
- this.time =
- PromotedNotificationContentModel.When(
- time = 6543L,
- mode = PromotedNotificationContentModel.When.Mode.BasicTime,
- )
+ this.time = When.Time(currentTime + 13.minutes.inWholeMilliseconds)
}
+
setNotifs(
listOf(
activeNotificationModel(
@@ -426,17 +423,141 @@
@Test
@DisableFlags(FLAG_PROMOTE_NOTIFICATIONS_AUTOMATICALLY)
+ fun chips_basicTime_timeLessThanOneMinInFuture_isIconOnly() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.chips)
+ val currentTime = 3.minutes.inWholeMilliseconds
+ fakeSystemClock.setCurrentTimeMillis(currentTime)
+
+ val promotedContentBuilder =
+ PromotedNotificationContentModel.Builder("notif").apply {
+ this.time = When.Time(currentTime + 500)
+ }
+
+ setNotifs(
+ listOf(
+ activeNotificationModel(
+ key = "notif",
+ statusBarChipIcon = createStatusBarIconViewOrNull(),
+ promotedContent = promotedContentBuilder.build(),
+ )
+ )
+ )
+
+ assertThat(latest).hasSize(1)
+ assertThat(latest!![0])
+ .isInstanceOf(OngoingActivityChipModel.Active.IconOnly::class.java)
+ }
+
+ @Test
+ @DisableFlags(FLAG_PROMOTE_NOTIFICATIONS_AUTOMATICALLY)
+ fun chips_basicTime_timeIsNow_isIconOnly() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.chips)
+ val currentTime = 62.seconds.inWholeMilliseconds
+ fakeSystemClock.setCurrentTimeMillis(currentTime)
+
+ val promotedContentBuilder =
+ PromotedNotificationContentModel.Builder("notif").apply {
+ this.time = When.Time(currentTime)
+ }
+
+ setNotifs(
+ listOf(
+ activeNotificationModel(
+ key = "notif",
+ statusBarChipIcon = createStatusBarIconViewOrNull(),
+ promotedContent = promotedContentBuilder.build(),
+ )
+ )
+ )
+
+ assertThat(latest).hasSize(1)
+ assertThat(latest!![0])
+ .isInstanceOf(OngoingActivityChipModel.Active.IconOnly::class.java)
+ }
+
+ @Test
+ @DisableFlags(FLAG_PROMOTE_NOTIFICATIONS_AUTOMATICALLY)
+ fun chips_basicTime_timeInPast_isIconOnly() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.chips)
+ val currentTime = 62.minutes.inWholeMilliseconds
+ fakeSystemClock.setCurrentTimeMillis(currentTime)
+
+ val promotedContentBuilder =
+ PromotedNotificationContentModel.Builder("notif").apply {
+ this.time = When.Time(currentTime - 2.minutes.inWholeMilliseconds)
+ }
+
+ setNotifs(
+ listOf(
+ activeNotificationModel(
+ key = "notif",
+ statusBarChipIcon = createStatusBarIconViewOrNull(),
+ promotedContent = promotedContentBuilder.build(),
+ )
+ )
+ )
+
+ assertThat(latest).hasSize(1)
+ assertThat(latest!![0])
+ .isInstanceOf(OngoingActivityChipModel.Active.IconOnly::class.java)
+ }
+
+ // Not necessarily the behavior we *want* to have, but it's the currently implemented behavior.
+ @Test
+ @DisableFlags(FLAG_PROMOTE_NOTIFICATIONS_AUTOMATICALLY)
+ fun chips_basicTime_timeIsInFuture_thenTimeAdvances_stillShortTimeDelta() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.chips)
+ val currentTime = 30.minutes.inWholeMilliseconds
+ fakeSystemClock.setCurrentTimeMillis(currentTime)
+
+ val promotedContentBuilder =
+ PromotedNotificationContentModel.Builder("notif").apply {
+ this.time = When.Time(currentTime + 3.minutes.inWholeMilliseconds)
+ }
+
+ setNotifs(
+ listOf(
+ activeNotificationModel(
+ key = "notif",
+ statusBarChipIcon = createStatusBarIconViewOrNull(),
+ promotedContent = promotedContentBuilder.build(),
+ )
+ )
+ )
+
+ assertThat(latest).hasSize(1)
+ assertThat(latest!![0])
+ .isInstanceOf(OngoingActivityChipModel.Active.ShortTimeDelta::class.java)
+
+ fakeSystemClock.advanceTime(5.minutes.inWholeMilliseconds)
+
+ assertThat(latest).hasSize(1)
+ assertThat(latest!![0])
+ .isInstanceOf(OngoingActivityChipModel.Active.ShortTimeDelta::class.java)
+ }
+
+ @Test
+ @DisableFlags(FLAG_PROMOTE_NOTIFICATIONS_AUTOMATICALLY)
fun chips_countUpTime_isTimer() =
kosmos.runTest {
val latest by collectLastValue(underTest.chips)
+ val currentTime = 30.minutes.inWholeMilliseconds
+ fakeSystemClock.setCurrentTimeMillis(currentTime)
+
+ val currentElapsed =
+ currentTime + fakeSystemClock.elapsedRealtime() -
+ fakeSystemClock.currentTimeMillis()
+
+ val whenElapsed = currentElapsed - 1.minutes.inWholeMilliseconds
val promotedContentBuilder =
PromotedNotificationContentModel.Builder("notif").apply {
this.time =
- PromotedNotificationContentModel.When(
- time = 6543L,
- mode = PromotedNotificationContentModel.When.Mode.CountUp,
- )
+ When.Chronometer(elapsedRealtimeMillis = whenElapsed, isCountDown = false)
}
setNotifs(
listOf(
@@ -450,6 +571,8 @@
assertThat(latest).hasSize(1)
assertThat(latest!![0]).isInstanceOf(OngoingActivityChipModel.Active.Timer::class.java)
+ assertThat((latest!![0] as OngoingActivityChipModel.Active.Timer).startTimeMs)
+ .isEqualTo(whenElapsed)
}
@Test
@@ -457,14 +580,19 @@
fun chips_countDownTime_isTimer() =
kosmos.runTest {
val latest by collectLastValue(underTest.chips)
+ val currentTime = 30.minutes.inWholeMilliseconds
+ fakeSystemClock.setCurrentTimeMillis(currentTime)
+
+ val currentElapsed =
+ currentTime + fakeSystemClock.elapsedRealtime() -
+ fakeSystemClock.currentTimeMillis()
+
+ val whenElapsed = currentElapsed + 10.minutes.inWholeMilliseconds
val promotedContentBuilder =
PromotedNotificationContentModel.Builder("notif").apply {
this.time =
- PromotedNotificationContentModel.When(
- time = 6543L,
- mode = PromotedNotificationContentModel.When.Mode.CountDown,
- )
+ When.Chronometer(elapsedRealtimeMillis = whenElapsed, isCountDown = true)
}
setNotifs(
listOf(
@@ -478,6 +606,8 @@
assertThat(latest).hasSize(1)
assertThat(latest!![0]).isInstanceOf(OngoingActivityChipModel.Active.Timer::class.java)
+ assertThat((latest!![0] as OngoingActivityChipModel.Active.Timer).startTimeMs)
+ .isEqualTo(whenElapsed)
}
@Test
@@ -485,14 +615,12 @@
fun chips_noHeadsUp_showsTime() =
kosmos.runTest {
val latest by collectLastValue(underTest.chips)
+ val currentTime = 30.minutes.inWholeMilliseconds
+ fakeSystemClock.setCurrentTimeMillis(currentTime)
val promotedContentBuilder =
PromotedNotificationContentModel.Builder("notif").apply {
- this.time =
- PromotedNotificationContentModel.When(
- time = 6543L,
- mode = PromotedNotificationContentModel.When.Mode.BasicTime,
- )
+ this.time = When.Time(currentTime + 10.minutes.inWholeMilliseconds)
}
setNotifs(
listOf(
@@ -517,14 +645,12 @@
fun chips_hasHeadsUpBySystem_showsTime() =
kosmos.runTest {
val latest by collectLastValue(underTest.chips)
+ val currentTime = 30.minutes.inWholeMilliseconds
+ fakeSystemClock.setCurrentTimeMillis(currentTime)
val promotedContentBuilder =
PromotedNotificationContentModel.Builder("notif").apply {
- this.time =
- PromotedNotificationContentModel.When(
- time = 6543L,
- mode = PromotedNotificationContentModel.When.Mode.BasicTime,
- )
+ this.time = When.Time(currentTime + 10.minutes.inWholeMilliseconds)
}
setNotifs(
listOf(
@@ -556,22 +682,16 @@
fun chips_hasHeadsUpByUser_forOtherNotif_showsTime() =
kosmos.runTest {
val latest by collectLastValue(underTest.chips)
+ val currentTime = 30.minutes.inWholeMilliseconds
+ fakeSystemClock.setCurrentTimeMillis(currentTime)
val promotedContentBuilder =
PromotedNotificationContentModel.Builder("notif").apply {
- this.time =
- PromotedNotificationContentModel.When(
- time = 6543L,
- mode = PromotedNotificationContentModel.When.Mode.BasicTime,
- )
+ this.time = When.Time(currentTime + 10.minutes.inWholeMilliseconds)
}
val otherPromotedContentBuilder =
PromotedNotificationContentModel.Builder("other notif").apply {
- this.time =
- PromotedNotificationContentModel.When(
- time = 654321L,
- mode = PromotedNotificationContentModel.When.Mode.BasicTime,
- )
+ this.time = When.Time(currentTime + 10.minutes.inWholeMilliseconds)
}
val icon = createStatusBarIconViewOrNull()
val otherIcon = createStatusBarIconViewOrNull()
@@ -610,14 +730,12 @@
fun chips_hasHeadsUpByUser_forThisNotif_onlyShowsIcon() =
kosmos.runTest {
val latest by collectLastValue(underTest.chips)
+ val currentTime = 30.minutes.inWholeMilliseconds
+ fakeSystemClock.setCurrentTimeMillis(currentTime)
val promotedContentBuilder =
PromotedNotificationContentModel.Builder("notif").apply {
- this.time =
- PromotedNotificationContentModel.When(
- time = 6543L,
- mode = PromotedNotificationContentModel.When.Mode.BasicTime,
- )
+ this.time = When.Time(currentTime + 10.minutes.inWholeMilliseconds)
}
setNotifs(
listOf(
@@ -643,11 +761,8 @@
}
@Test
- @DisableFlags(
- FLAG_PROMOTE_NOTIFICATIONS_AUTOMATICALLY,
- StatusBarRootModernization.FLAG_NAME,
- StatusBarChipsModernization.FLAG_NAME,
- )
+ @DisableFlags(FLAG_PROMOTE_NOTIFICATIONS_AUTOMATICALLY)
+ @DisableChipsModernization
fun chips_chipsModernizationDisabled_clickingChipNotifiesInteractor() =
kosmos.runTest {
val latest by collectLastValue(underTest.chips)
@@ -675,7 +790,7 @@
@Test
@DisableFlags(FLAG_PROMOTE_NOTIFICATIONS_AUTOMATICALLY)
- @EnableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME)
+ @EnableChipsModernization
fun chips_chipsModernizationEnabled_clickingChipNotifiesInteractor() =
kosmos.runTest {
val latest by collectLastValue(underTest.chips)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsWithNotifsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsWithNotifsViewModelTest.kt
index 20637cd..2887de3 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsWithNotifsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsWithNotifsViewModelTest.kt
@@ -22,7 +22,6 @@
import android.content.res.mainResources
import android.graphics.Bitmap
import android.graphics.drawable.BitmapDrawable
-import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import android.view.View
import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -57,7 +56,6 @@
import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipsViewModelTest.Companion.assertIsScreenRecordChip
import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipsViewModelTest.Companion.assertIsShareToAppChip
import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipsViewModelTest.Companion.getStopActionFromDialog
-import com.android.systemui.statusbar.core.StatusBarRootModernization
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
@@ -66,7 +64,8 @@
import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel
import com.android.systemui.statusbar.notification.shared.ActiveNotificationModel
import com.android.systemui.statusbar.phone.SystemUIDialog
-import com.android.systemui.statusbar.phone.ongoingcall.StatusBarChipsModernization
+import com.android.systemui.statusbar.phone.ongoingcall.DisableChipsModernization
+import com.android.systemui.statusbar.phone.ongoingcall.EnableChipsModernization
import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallTestHelper.addOngoingCallState
import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallTestHelper.removeOngoingCallState
import com.android.systemui.testKosmos
@@ -138,7 +137,7 @@
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Inactive::class.java)
}
- @DisableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME)
+ @DisableChipsModernization
@Test
fun chipsLegacy_allHidden_bothPrimaryAndSecondaryHidden() =
kosmos.runTest {
@@ -155,7 +154,7 @@
assertThat(unused).isEqualTo(MultipleOngoingActivityChipsModel())
}
- @EnableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME)
+ @EnableChipsModernization
@Test
fun chips_allInactive() =
kosmos.runTest {
@@ -184,7 +183,7 @@
assertIsScreenRecordChip(latest)
}
- @DisableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME)
+ @DisableChipsModernization
@Test
fun chipsLegacy_screenRecordShow_restHidden_primaryIsScreenRecordSecondaryIsHidden() =
kosmos.runTest {
@@ -201,7 +200,7 @@
assertThat(unused).isEqualTo(MultipleOngoingActivityChipsModel())
}
- @EnableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME)
+ @EnableChipsModernization
@Test
fun chips_screenRecordActive_restInactive() =
kosmos.runTest {
@@ -230,7 +229,7 @@
assertIsScreenRecordChip(latest)
}
- @DisableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME)
+ @DisableChipsModernization
@Test
fun chipsLegacy_screenRecordShowAndCallShow_primaryIsScreenRecordSecondaryIsCall() =
kosmos.runTest {
@@ -246,7 +245,7 @@
assertThat(unused).isEqualTo(MultipleOngoingActivityChipsModel())
}
- @EnableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME)
+ @EnableChipsModernization
@Test
fun chips_screenRecordAndCallActive_inThatOrder() =
kosmos.runTest {
@@ -265,7 +264,7 @@
assertThat(unused).isEqualTo(MultipleOngoingActivityChipsModelLegacy())
}
- @DisableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME)
+ @DisableChipsModernization
@Test
fun chipsLegacy_oneChip_notSquished() =
kosmos.runTest {
@@ -278,7 +277,7 @@
.isInstanceOf(OngoingActivityChipModel.Active.Timer::class.java)
}
- @EnableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME)
+ @EnableChipsModernization
@Test
fun chips_oneChip_notSquished() =
kosmos.runTest {
@@ -291,7 +290,7 @@
.isInstanceOf(OngoingActivityChipModel.Active.Timer::class.java)
}
- @DisableFlags(StatusBarChipsModernization.FLAG_NAME, StatusBarRootModernization.FLAG_NAME)
+ @DisableChipsModernization
@Test
fun chipsLegacy_twoTimerChips_isSmallPortrait_bothSquished() =
kosmos.runTest {
@@ -307,7 +306,7 @@
.isInstanceOf(OngoingActivityChipModel.Active.IconOnly::class.java)
}
- @EnableFlags(StatusBarChipsModernization.FLAG_NAME, StatusBarRootModernization.FLAG_NAME)
+ @EnableChipsModernization
@Test
fun chips_twoTimerChips_isSmallPortrait_bothSquished() =
kosmos.runTest {
@@ -323,7 +322,7 @@
.isInstanceOf(OngoingActivityChipModel.Active.IconOnly::class.java)
}
- @DisableFlags(StatusBarChipsModernization.FLAG_NAME, StatusBarRootModernization.FLAG_NAME)
+ @DisableChipsModernization
@Test
fun chipsLegacy_countdownChipAndTimerChip_countdownNotSquished_butTimerSquished() =
kosmos.runTest {
@@ -340,7 +339,7 @@
.isInstanceOf(OngoingActivityChipModel.Active.IconOnly::class.java)
}
- @EnableFlags(StatusBarChipsModernization.FLAG_NAME, StatusBarRootModernization.FLAG_NAME)
+ @EnableChipsModernization
@Test
fun chips_countdownChipAndTimerChip_countdownNotSquished_butTimerSquished() =
kosmos.runTest {
@@ -357,7 +356,7 @@
.isInstanceOf(OngoingActivityChipModel.Active.IconOnly::class.java)
}
- @DisableFlags(StatusBarChipsModernization.FLAG_NAME, StatusBarRootModernization.FLAG_NAME)
+ @DisableChipsModernization
@Test
fun chipsLegacy_numberOfChipsChanges_chipsGetSquishedAndUnsquished() =
kosmos.runTest {
@@ -393,7 +392,7 @@
.isInstanceOf(OngoingActivityChipModel.Inactive::class.java)
}
- @EnableFlags(StatusBarChipsModernization.FLAG_NAME, StatusBarRootModernization.FLAG_NAME)
+ @EnableChipsModernization
@Test
fun chips_numberOfChipsChanges_chipsGetSquishedAndUnsquished() =
kosmos.runTest {
@@ -425,7 +424,7 @@
.isInstanceOf(OngoingActivityChipModel.Active.Timer::class.java)
}
- @DisableFlags(StatusBarChipsModernization.FLAG_NAME, StatusBarRootModernization.FLAG_NAME)
+ @DisableChipsModernization
@Test
fun chipsLegacy_twoChips_isLandscape_notSquished() =
kosmos.runTest {
@@ -448,7 +447,7 @@
.isInstanceOf(OngoingActivityChipModel.Active.Timer::class.java)
}
- @EnableFlags(StatusBarChipsModernization.FLAG_NAME, StatusBarRootModernization.FLAG_NAME)
+ @EnableChipsModernization
@Test
fun chips_twoChips_isLandscape_notSquished() =
kosmos.runTest {
@@ -471,7 +470,7 @@
.isInstanceOf(OngoingActivityChipModel.Active.Timer::class.java)
}
- @DisableFlags(StatusBarChipsModernization.FLAG_NAME, StatusBarRootModernization.FLAG_NAME)
+ @DisableChipsModernization
@Test
fun chipsLegacy_twoChips_isLargeScreen_notSquished() =
kosmos.runTest {
@@ -490,7 +489,7 @@
.isInstanceOf(OngoingActivityChipModel.Active.Timer::class.java)
}
- @EnableFlags(StatusBarChipsModernization.FLAG_NAME, StatusBarRootModernization.FLAG_NAME)
+ @EnableChipsModernization
@Test
fun chips_twoChips_isLargeScreen_notSquished() =
kosmos.runTest {
@@ -522,7 +521,7 @@
assertIsScreenRecordChip(latest)
}
- @DisableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME)
+ @DisableChipsModernization
@Test
fun chipsLegacy_screenRecordShowAndShareToAppShow_primaryIsScreenRecordSecondaryIsHidden() =
kosmos.runTest {
@@ -542,7 +541,7 @@
assertThat(unused).isEqualTo(MultipleOngoingActivityChipsModel())
}
- @EnableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME)
+ @EnableChipsModernization
@Test
fun chips_screenRecordAndShareToApp_screenRecordIsActiveShareToAppIsInOverflow() =
kosmos.runTest {
@@ -577,7 +576,7 @@
assertIsShareToAppChip(latest)
}
- @DisableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME)
+ @DisableChipsModernization
@Test
fun chipsLegacy_shareToAppShowAndCallShow_primaryIsShareToAppSecondaryIsCall() =
kosmos.runTest {
@@ -595,7 +594,7 @@
assertThat(unused).isEqualTo(MultipleOngoingActivityChipsModel())
}
- @EnableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME)
+ @EnableChipsModernization
@Test
fun chips_shareToAppAndCallActive() =
kosmos.runTest {
@@ -631,7 +630,7 @@
assertIsCallChip(latest, callNotificationKey)
}
- @DisableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME)
+ @DisableChipsModernization
@Test
fun chipsLegacy_onlyCallShown_primaryIsCallSecondaryIsHidden() =
kosmos.runTest {
@@ -651,7 +650,7 @@
assertThat(unused).isEqualTo(MultipleOngoingActivityChipsModel())
}
- @EnableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME)
+ @EnableChipsModernization
@Test
fun chips_callActive_restInactive() =
kosmos.runTest {
@@ -671,7 +670,7 @@
assertThat(unused).isEqualTo(MultipleOngoingActivityChipsModelLegacy())
}
- @DisableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME)
+ @DisableChipsModernization
@Test
fun chipsLegacy_singlePromotedNotif_primaryIsNotifSecondaryIsHidden() =
kosmos.runTest {
@@ -695,7 +694,7 @@
assertThat(unused).isEqualTo(MultipleOngoingActivityChipsModel())
}
- @EnableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME)
+ @EnableChipsModernization
@Test
fun chips_singlePromotedNotif() =
kosmos.runTest {
@@ -720,7 +719,7 @@
assertThat(unused).isEqualTo(MultipleOngoingActivityChipsModelLegacy())
}
- @DisableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME)
+ @DisableChipsModernization
@Test
fun chipsLegacy_twoPromotedNotifs_primaryAndSecondaryAreNotifsInOrder() =
kosmos.runTest {
@@ -751,7 +750,7 @@
assertThat(unused).isEqualTo(MultipleOngoingActivityChipsModel())
}
- @EnableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME)
+ @EnableChipsModernization
@Test
fun chips_twoPromotedNotifs_bothActiveInOrder() =
kosmos.runTest {
@@ -785,7 +784,7 @@
assertThat(unused).isEqualTo(MultipleOngoingActivityChipsModelLegacy())
}
- @DisableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME)
+ @DisableChipsModernization
@Test
fun chipsLegacy_threePromotedNotifs_topTwoShown() =
kosmos.runTest {
@@ -823,7 +822,7 @@
assertThat(unused).isEqualTo(MultipleOngoingActivityChipsModel())
}
- @EnableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME)
+ @EnableChipsModernization
@Test
fun chips_threePromotedNotifs_topTwoActiveThirdInOverflow() =
kosmos.runTest {
@@ -865,7 +864,7 @@
assertThat(unused).isEqualTo(MultipleOngoingActivityChipsModelLegacy())
}
- @DisableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME)
+ @DisableChipsModernization
@Test
fun chipsLegacy_callAndPromotedNotifs_primaryIsCallSecondaryIsNotif() =
kosmos.runTest {
@@ -898,7 +897,7 @@
assertThat(unused).isEqualTo(MultipleOngoingActivityChipsModel())
}
- @EnableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME)
+ @EnableChipsModernization
@Test
fun chips_callAndPromotedNotifs_callAndFirstNotifActiveSecondNotifInOverflow() =
kosmos.runTest {
@@ -935,7 +934,7 @@
assertThat(unused).isEqualTo(MultipleOngoingActivityChipsModelLegacy())
}
- @DisableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME)
+ @DisableChipsModernization
@Test
fun chipsLegacy_screenRecordAndCallAndPromotedNotifs_notifsNotShown() =
kosmos.runTest {
@@ -958,7 +957,7 @@
assertThat(unused).isEqualTo(MultipleOngoingActivityChipsModel())
}
- @EnableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME)
+ @EnableChipsModernization
@Test
fun chips_screenRecordAndCallAndPromotedNotif_notifInOverflow() =
kosmos.runTest {
@@ -1076,7 +1075,7 @@
assertIsNotifChip(latest, context, notifIcon, "notif")
}
- @DisableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME)
+ @DisableChipsModernization
@Test
fun chipsLegacy_movesChipsAroundAccordingToPriority() =
kosmos.runTest {
@@ -1152,7 +1151,7 @@
assertThat(unused).isEqualTo(MultipleOngoingActivityChipsModel())
}
- @EnableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME)
+ @EnableChipsModernization
@Test
fun chips_movesChipsAroundAccordingToPriority() =
kosmos.runTest {
@@ -1291,7 +1290,7 @@
}
/** Regression test for b/347726238. */
- @DisableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME)
+ @DisableChipsModernization
@Test
fun chipsLegacy_timerDoesNotResetAfterSubscribersRestart() =
kosmos.runTest {
@@ -1327,7 +1326,7 @@
}
/** Regression test for b/347726238. */
- @EnableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME)
+ @EnableChipsModernization
@Test
fun chips_timerDoesNotResetAfterSubscribersRestart() =
kosmos.runTest {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/featurepods/media/domain/interactor/MediaControlChipInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/featurepods/media/domain/interactor/MediaControlChipInteractorTest.kt
index 1a5f57d..6409a20 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/featurepods/media/domain/interactor/MediaControlChipInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/featurepods/media/domain/interactor/MediaControlChipInteractorTest.kt
@@ -17,100 +17,119 @@
package com.android.systemui.statusbar.featurepods.media.domain.interactor
import android.graphics.drawable.Drawable
-import androidx.test.ext.junit.runners.AndroidJUnit4
+import android.platform.test.flag.junit.FlagsParameterization
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.flags.parameterizeSceneContainerFlag
+import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.collectLastValue
import com.android.systemui.kosmos.runTest
import com.android.systemui.kosmos.useUnconfinedTestDispatcher
import com.android.systemui.media.controls.data.repository.mediaFilterRepository
+import com.android.systemui.media.controls.domain.pipeline.MediaDataManager
import com.android.systemui.media.controls.shared.model.MediaAction
import com.android.systemui.media.controls.shared.model.MediaButton
import com.android.systemui.media.controls.shared.model.MediaData
import com.android.systemui.media.controls.shared.model.MediaDataLoadingModel
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
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.ArgumentCaptor
+import org.mockito.Captor
+import org.mockito.MockitoAnnotations
import org.mockito.kotlin.mock
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
+@RunWith(ParameterizedAndroidJunit4::class)
@SmallTest
-@RunWith(AndroidJUnit4::class)
-class MediaControlChipInteractorTest : SysuiTestCase() {
-
+class MediaControlChipInteractorTest(flags: FlagsParameterization) : SysuiTestCase() {
private val kosmos = testKosmos().useUnconfinedTestDispatcher()
- private val underTest = kosmos.mediaControlChipInteractor
+ private val mediaFilterRepository = kosmos.mediaFilterRepository
+ private val Kosmos.underTest by Kosmos.Fixture { kosmos.mediaControlChipInteractor }
+ @Captor lateinit var listener: ArgumentCaptor<MediaDataManager.Listener>
+
+ companion object {
+ @JvmStatic
+ @Parameters(name = "{0}")
+ fun getParams(): List<FlagsParameterization> {
+ return parameterizeSceneContainerFlag()
+ }
+ }
+
+ @Before
+ fun setUp() {
+ kosmos.underTest.initialize()
+ MockitoAnnotations.initMocks(this)
+ }
+
+ init {
+ mSetFlagsRule.setFlagsParameterization(flags)
+ }
@Test
- fun mediaControlModel_noActiveMedia_null() =
+ fun mediaControlChipModel_noActiveMedia_null() =
kosmos.runTest {
- val model by collectLastValue(underTest.mediaControlModel)
+ val model by collectLastValue(underTest.mediaControlChipModel)
assertThat(model).isNull()
}
@Test
- fun mediaControlModel_activeMedia_notNull() =
+ fun mediaControlChipModel_activeMedia_notNull() =
kosmos.runTest {
- val model by collectLastValue(underTest.mediaControlModel)
+ val model by collectLastValue(underTest.mediaControlChipModel)
val userMedia = MediaData(active = true)
- val instanceId = userMedia.instanceId
- mediaFilterRepository.addSelectedUserMediaEntry(userMedia)
- mediaFilterRepository.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId))
+ updateMedia(userMedia)
assertThat(model).isNotNull()
}
@Test
- fun mediaControlModel_mediaRemoved_null() =
+ fun mediaControlChipModel_mediaRemoved_null() =
kosmos.runTest {
- val model by collectLastValue(underTest.mediaControlModel)
+ val model by collectLastValue(underTest.mediaControlChipModel)
val userMedia = MediaData(active = true)
- val instanceId = userMedia.instanceId
- mediaFilterRepository.addSelectedUserMediaEntry(userMedia)
- mediaFilterRepository.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId))
+ updateMedia(userMedia)
assertThat(model).isNotNull()
- assertThat(mediaFilterRepository.removeSelectedUserMediaEntry(instanceId, userMedia))
- .isTrue()
- mediaFilterRepository.addMediaDataLoadingState(
- MediaDataLoadingModel.Removed(instanceId)
- )
+ removeMedia(userMedia)
assertThat(model).isNull()
}
@Test
- fun mediaControlModel_songNameChanged_emitsUpdatedModel() =
+ fun mediaControlChipModel_songNameChanged_emitsUpdatedModel() =
kosmos.runTest {
- val model by collectLastValue(underTest.mediaControlModel)
+ val model by collectLastValue(underTest.mediaControlChipModel)
val initialSongName = "Initial Song"
val newSongName = "New Song"
val userMedia = MediaData(active = true, song = initialSongName)
- val instanceId = userMedia.instanceId
- mediaFilterRepository.addSelectedUserMediaEntry(userMedia)
- mediaFilterRepository.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId))
+ updateMedia(userMedia)
assertThat(model).isNotNull()
assertThat(model?.songName).isEqualTo(initialSongName)
val updatedUserMedia = userMedia.copy(song = newSongName)
- mediaFilterRepository.addSelectedUserMediaEntry(updatedUserMedia)
+ updateMedia(updatedUserMedia)
assertThat(model?.songName).isEqualTo(newSongName)
}
@Test
- fun mediaControlModel_playPauseActionChanges_emitsUpdatedModel() =
+ fun mediaControlChipModel_playPauseActionChanges_emitsUpdatedModel() =
kosmos.runTest {
- val model by collectLastValue(underTest.mediaControlModel)
+ val model by collectLastValue(underTest.mediaControlChipModel)
val mockDrawable = mock<Drawable>()
@@ -123,9 +142,7 @@
)
val mediaButton = MediaButton(playOrPause = initialAction)
val userMedia = MediaData(active = true, semanticActions = mediaButton)
- val instanceId = userMedia.instanceId
- mediaFilterRepository.addSelectedUserMediaEntry(userMedia)
- mediaFilterRepository.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId))
+ updateMedia(userMedia)
assertThat(model).isNotNull()
assertThat(model?.playOrPause).isEqualTo(initialAction)
@@ -139,15 +156,15 @@
)
val updatedMediaButton = MediaButton(playOrPause = newAction)
val updatedUserMedia = userMedia.copy(semanticActions = updatedMediaButton)
- mediaFilterRepository.addSelectedUserMediaEntry(updatedUserMedia)
+ updateMedia(updatedUserMedia)
assertThat(model?.playOrPause).isEqualTo(newAction)
}
@Test
- fun mediaControlModel_playPauseActionRemoved_playPauseNull() =
+ fun mediaControlChipModel_playPauseActionRemoved_playPauseNull() =
kosmos.runTest {
- val model by collectLastValue(underTest.mediaControlModel)
+ val model by collectLastValue(underTest.mediaControlChipModel)
val mockDrawable = mock<Drawable>()
@@ -160,16 +177,36 @@
)
val mediaButton = MediaButton(playOrPause = initialAction)
val userMedia = MediaData(active = true, semanticActions = mediaButton)
- val instanceId = userMedia.instanceId
- mediaFilterRepository.addSelectedUserMediaEntry(userMedia)
- mediaFilterRepository.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId))
+ updateMedia(userMedia)
assertThat(model).isNotNull()
assertThat(model?.playOrPause).isEqualTo(initialAction)
val updatedUserMedia = userMedia.copy(semanticActions = MediaButton())
- mediaFilterRepository.addSelectedUserMediaEntry(updatedUserMedia)
+ updateMedia(updatedUserMedia)
assertThat(model?.playOrPause).isNull()
}
+
+ private fun updateMedia(mediaData: MediaData) {
+ if (SceneContainerFlag.isEnabled) {
+ val instanceId = mediaData.instanceId
+ mediaFilterRepository.addSelectedUserMediaEntry(mediaData)
+ mediaFilterRepository.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId))
+ } else {
+ kosmos.underTest.updateMediaControlChipModelLegacy(mediaData)
+ }
+ }
+
+ private fun removeMedia(mediaData: MediaData) {
+ if (SceneContainerFlag.isEnabled) {
+ val instanceId = mediaData.instanceId
+ mediaFilterRepository.removeSelectedUserMediaEntry(instanceId, mediaData)
+ mediaFilterRepository.addMediaDataLoadingState(
+ MediaDataLoadingModel.Removed(instanceId)
+ )
+ } else {
+ kosmos.underTest.updateMediaControlChipModelLegacy(null)
+ }
+ }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/featurepods/media/ui/viewmodel/MediaControlChipViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/featurepods/media/ui/viewmodel/MediaControlChipViewModelTest.kt
index 8650e4b..d36dbbe 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/featurepods/media/ui/viewmodel/MediaControlChipViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/featurepods/media/ui/viewmodel/MediaControlChipViewModelTest.kt
@@ -16,26 +16,57 @@
package com.android.systemui.statusbar.featurepods.media.ui.viewmodel
-import androidx.test.ext.junit.runners.AndroidJUnit4
+import android.platform.test.flag.junit.FlagsParameterization
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.flags.parameterizeSceneContainerFlag
+import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.collectLastValue
import com.android.systemui.kosmos.runTest
import com.android.systemui.kosmos.useUnconfinedTestDispatcher
import com.android.systemui.media.controls.data.repository.mediaFilterRepository
+import com.android.systemui.media.controls.domain.pipeline.MediaDataManager
import com.android.systemui.media.controls.shared.model.MediaData
import com.android.systemui.media.controls.shared.model.MediaDataLoadingModel
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import com.android.systemui.statusbar.featurepods.media.domain.interactor.mediaControlChipInteractor
import com.android.systemui.statusbar.featurepods.popups.shared.model.PopupChipModel
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlin.test.Test
+import org.junit.Before
import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.Captor
+import org.mockito.MockitoAnnotations
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
@SmallTest
-@RunWith(AndroidJUnit4::class)
-class MediaControlChipViewModelTest : SysuiTestCase() {
+@RunWith(ParameterizedAndroidJunit4::class)
+class MediaControlChipViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
private val kosmos = testKosmos().useUnconfinedTestDispatcher()
- private val underTest = kosmos.mediaControlChipViewModel
+ private val mediaControlChipInteractor by lazy { kosmos.mediaControlChipInteractor }
+ private val Kosmos.underTest by Kosmos.Fixture { kosmos.mediaControlChipViewModel }
+ @Captor lateinit var listener: ArgumentCaptor<MediaDataManager.Listener>
+
+ companion object {
+ @JvmStatic
+ @Parameters(name = "{0}")
+ fun getParams(): List<FlagsParameterization> {
+ return parameterizeSceneContainerFlag()
+ }
+ }
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+ mediaControlChipInteractor.initialize()
+ }
+
+ init {
+ mSetFlagsRule.setFlagsParameterization(flags)
+ }
@Test
fun chip_noActiveMedia_IsHidden() =
@@ -51,10 +82,7 @@
val chip by collectLastValue(underTest.chip)
val userMedia = MediaData(active = true, song = "test")
- val instanceId = userMedia.instanceId
-
- mediaFilterRepository.addSelectedUserMediaEntry(userMedia)
- mediaFilterRepository.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId))
+ updateMedia(userMedia)
assertThat(chip).isInstanceOf(PopupChipModel.Shown::class.java)
}
@@ -67,16 +95,25 @@
val initialSongName = "Initial Song"
val newSongName = "New Song"
val userMedia = MediaData(active = true, song = initialSongName)
- val instanceId = userMedia.instanceId
-
- mediaFilterRepository.addSelectedUserMediaEntry(userMedia)
- mediaFilterRepository.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId))
-
+ updateMedia(userMedia)
+ assertThat(chip).isInstanceOf(PopupChipModel.Shown::class.java)
assertThat((chip as PopupChipModel.Shown).chipText).isEqualTo(initialSongName)
val updatedUserMedia = userMedia.copy(song = newSongName)
- mediaFilterRepository.addSelectedUserMediaEntry(updatedUserMedia)
+ updateMedia(updatedUserMedia)
assertThat((chip as PopupChipModel.Shown).chipText).isEqualTo(newSongName)
}
+
+ private fun updateMedia(mediaData: MediaData) {
+ if (SceneContainerFlag.isEnabled) {
+ val instanceId = mediaData.instanceId
+ kosmos.mediaFilterRepository.addSelectedUserMediaEntry(mediaData)
+ kosmos.mediaFilterRepository.addMediaDataLoadingState(
+ MediaDataLoadingModel.Loaded(instanceId)
+ )
+ } else {
+ mediaControlChipInteractor.updateMediaControlChipModelLegacy(mediaData)
+ }
+ }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/featurepods/popups/ui/viewmodel/StatusBarPopupChipsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/featurepods/popups/ui/viewmodel/StatusBarPopupChipsViewModelTest.kt
deleted file mode 100644
index fcbf0fe..0000000
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/featurepods/popups/ui/viewmodel/StatusBarPopupChipsViewModelTest.kt
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.featurepods.popups.ui.viewmodel
-
-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.coroutines.collectLastValue
-import com.android.systemui.kosmos.testScope
-import com.android.systemui.media.controls.data.repository.mediaFilterRepository
-import com.android.systemui.media.controls.shared.model.MediaData
-import com.android.systemui.media.controls.shared.model.MediaDataLoadingModel
-import com.android.systemui.statusbar.featurepods.popups.shared.model.PopupChipId
-import com.android.systemui.statusbar.featurepods.popups.StatusBarPopupChips
-import com.android.systemui.testKosmos
-import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.test.runTest
-import org.junit.Test
-import org.junit.runner.RunWith
-
-@SmallTest
-@EnableFlags(StatusBarPopupChips.FLAG_NAME)
-@RunWith(AndroidJUnit4::class)
-class StatusBarPopupChipsViewModelTest : SysuiTestCase() {
- private val kosmos = testKosmos()
- private val testScope = kosmos.testScope
- private val mediaFilterRepository = kosmos.mediaFilterRepository
- private val underTest = kosmos.statusBarPopupChipsViewModel
-
- @Test
- fun shownPopupChips_allHidden_empty() =
- testScope.runTest {
- val shownPopupChips by collectLastValue(underTest.shownPopupChips)
- assertThat(shownPopupChips).isEmpty()
- }
-
- @Test
- fun shownPopupChips_activeMedia_restHidden_mediaControlChipShown() =
- testScope.runTest {
- val shownPopupChips by collectLastValue(underTest.shownPopupChips)
-
- val userMedia = MediaData(active = true, song = "test")
- val instanceId = userMedia.instanceId
-
- mediaFilterRepository.addSelectedUserMediaEntry(userMedia)
- mediaFilterRepository.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId))
-
- assertThat(shownPopupChips).hasSize(1)
- assertThat(shownPopupChips!!.first().chipId).isEqualTo(PopupChipId.MediaControl)
- }
-}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/AssistantFeedbackControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/AssistantFeedbackControllerTest.java
index d66b010..a58f7f7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/AssistantFeedbackControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/AssistantFeedbackControllerTest.java
@@ -51,8 +51,10 @@
import com.android.systemui.SysuiTestCase;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
+import com.android.systemui.statusbar.notification.people.NotificationPersonExtractor;
import com.android.systemui.util.DeviceConfigProxyFake;
+import org.jetbrains.annotations.NotNull;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/DynamicChildBindControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/DynamicChildBindControllerTest.java
index 77fd067..8520508 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/DynamicChildBindControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/DynamicChildBindControllerTest.java
@@ -132,7 +132,7 @@
LayoutInflater inflater = LayoutInflater.from(mContext);
inflater.setFactory2(
new RowInflaterTask.RowAsyncLayoutInflater(entry, new FakeSystemClock(), mock(
- RowInflaterTaskLogger.class)));
+ RowInflaterTaskLogger.class), mContext.getUser()));
ExpandableNotificationRow row = (ExpandableNotificationRow)
inflater.inflate(R.layout.status_bar_notification_row, null);
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/PhysicsPropertyAnimatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/PhysicsPropertyAnimatorTest.kt
new file mode 100644
index 0000000..56cd72e
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/PhysicsPropertyAnimatorTest.kt
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+package com.android.systemui.statusbar.notification
+
+import android.util.FloatProperty
+import android.util.Property
+import android.view.View
+import androidx.dynamicanimation.animation.DynamicAnimation
+import androidx.test.annotation.UiThreadTest
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.res.R
+import com.android.systemui.statusbar.notification.stack.AnimationProperties
+import com.android.systemui.statusbar.notification.stack.ViewState
+import org.junit.Assert
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito
+import org.mockito.kotlin.any
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+@UiThreadTest
+class PhysicsPropertyAnimatorTest : SysuiTestCase() {
+ private var view: View = View(context)
+ private val effectiveProperty =
+ object : FloatProperty<View>("TEST") {
+ private var _value: Float = 100f
+
+ override fun setValue(view: View, value: Float) {
+ this._value = value
+ }
+
+ override fun get(`object`: View): Float {
+ return _value
+ }
+ }
+ private val property: PhysicsProperty =
+ PhysicsProperty(R.id.scale_x_animator_tag, effectiveProperty)
+ private var finishListener: DynamicAnimation.OnAnimationEndListener? = null
+ private val animationProperties: AnimationProperties = AnimationProperties()
+
+ @Before
+ fun setUp() {
+ finishListener = Mockito.mock(DynamicAnimation.OnAnimationEndListener::class.java)
+ }
+
+ @Test
+ fun testAnimationStarted() {
+ PhysicsPropertyAnimator.setProperty(
+ view,
+ property,
+ 200f,
+ animationProperties,
+ true, /* animate */
+ )
+ Assert.assertTrue(PhysicsPropertyAnimator.isAnimating(view, property))
+ }
+
+ @Test
+ fun testNoAnimationStarted() {
+ PhysicsPropertyAnimator.setProperty(view, property, 200f, animationProperties, false)
+ Assert.assertFalse(PhysicsPropertyAnimator.isAnimating(view, property))
+ }
+
+ @Test
+ fun testEndValueUpdated() {
+ PhysicsPropertyAnimator.setProperty(
+ view,
+ property,
+ 200f,
+ animationProperties,
+ true, /* animate */
+ )
+ Assert.assertEquals(
+ (ViewState.getChildTag(view, property.tag) as PropertyData).finalValue,
+ 200f,
+ )
+ }
+
+ @Test
+ fun testOffset() {
+ effectiveProperty.setValue(view, 100f)
+ PhysicsPropertyAnimator.setProperty(
+ view,
+ property,
+ 200f,
+ animationProperties,
+ true, /* animate */
+ )
+ val propertyData = ViewState.getChildTag(view, property.tag) as PropertyData
+ Assert.assertEquals(propertyData.finalValue, 200f)
+ Assert.assertEquals(propertyData.offset, -100f)
+ }
+
+ @Test
+ fun testValueIsSetUnAnimated() {
+ effectiveProperty.setValue(view, 100f)
+ PhysicsPropertyAnimator.setProperty(
+ view,
+ property,
+ 200f,
+ animationProperties,
+ false, /* animate */
+ )
+ Assert.assertEquals(200f, effectiveProperty[view])
+ }
+
+ @Test
+ fun testAnimationToRightValueUpdated() {
+ effectiveProperty.setValue(view, 100f)
+ PhysicsPropertyAnimator.setProperty(
+ view,
+ property,
+ 200f,
+ animationProperties,
+ true, /* animate */
+ )
+ PhysicsPropertyAnimator.setProperty(
+ view,
+ property,
+ 220f,
+ animationProperties,
+ false, /* animate */
+ )
+ Assert.assertTrue(PhysicsPropertyAnimator.isAnimating(view, property))
+ Assert.assertEquals(120f, effectiveProperty[view])
+ Assert.assertEquals(
+ (ViewState.getChildTag(view, property.tag) as PropertyData).finalValue,
+ 220f,
+ )
+ }
+
+ @Test
+ fun testAnimationToRightValueUpdateAnimated() {
+ effectiveProperty.setValue(view, 100f)
+ PhysicsPropertyAnimator.setProperty(
+ view,
+ property,
+ 200f,
+ animationProperties,
+ true, /* animate */
+ )
+ PhysicsPropertyAnimator.setProperty(
+ view,
+ property,
+ 220f,
+ animationProperties,
+ true, /* animate */
+ )
+ Assert.assertTrue(PhysicsPropertyAnimator.isAnimating(view, property))
+ Assert.assertEquals(100f, effectiveProperty[view])
+ val propertyData = ViewState.getChildTag(view, property.tag) as PropertyData
+ Assert.assertEquals(propertyData.finalValue, 220f)
+ Assert.assertEquals(propertyData.offset, -120f)
+ }
+
+ @Test
+ fun testUsingDelay() {
+ effectiveProperty.setValue(view, 100f)
+ animationProperties.setDelay(200)
+ PhysicsPropertyAnimator.setProperty(
+ view,
+ property,
+ 200f,
+ animationProperties,
+ true, /* animate */
+ )
+ val propertyData = ViewState.getChildTag(view, property.tag) as PropertyData
+ Assert.assertNotNull(propertyData.delayRunnable)
+ Assert.assertFalse(propertyData.animator?.isRunning ?: true)
+ }
+
+ @Test
+ fun testUsingListener() {
+ PhysicsPropertyAnimator.setProperty(
+ view,
+ property,
+ 200f,
+ animationProperties,
+ true,
+ finishListener,
+ )
+ val propertyData = ViewState.getChildTag(view, property.tag) as PropertyData
+ propertyData.animator?.cancel()
+ Mockito.verify(finishListener!!).onAnimationEnd(any(), any(), any(), any())
+ }
+
+ @Test
+ fun testUsingListenerProperties() {
+ val finishListener2 = Mockito.mock(DynamicAnimation.OnAnimationEndListener::class.java)
+ val animationProperties: AnimationProperties =
+ object : AnimationProperties() {
+ override fun getAnimationEndListener(
+ property: Property<*, *>?
+ ): DynamicAnimation.OnAnimationEndListener {
+ return finishListener2
+ }
+ }
+ PhysicsPropertyAnimator.setProperty(view, property, 200f, animationProperties, true)
+ val propertyData = ViewState.getChildTag(view, property.tag) as PropertyData
+ propertyData.animator?.cancel()
+ Mockito.verify(finishListener2).onAnimationEnd(any(), any(), any(), any())
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/BundleEntryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/BundleEntryTest.kt
new file mode 100644
index 0000000..426af26
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/BundleEntryTest.kt
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2025 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
+
+import android.platform.test.annotations.EnableFlags
+import android.platform.test.flag.junit.SetFlagsRule
+import android.testing.TestableLooper.RunWithLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.statusbar.notification.shared.NotificationBundleUi
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+@RunWithLooper
+class BundleEntryTest : SysuiTestCase() {
+ private lateinit var underTest: BundleEntry
+
+ @get:Rule
+ val setFlagsRule = SetFlagsRule()
+
+ @Before
+ fun setUp() {
+ underTest = BundleEntry("key")
+ }
+
+ @Test
+ @EnableFlags(NotificationBundleUi.FLAG_NAME)
+ fun getParent_adapter() {
+ assertThat(underTest.entryAdapter.parent).isEqualTo(GroupEntry.ROOT_ENTRY)
+ }
+
+ @Test
+ @EnableFlags(NotificationBundleUi.FLAG_NAME)
+ fun isTopLevelEntry_adapter() {
+ assertThat(underTest.entryAdapter.isTopLevelEntry).isTrue()
+ }
+
+ @Test
+ @EnableFlags(NotificationBundleUi.FLAG_NAME)
+ fun getRow_adapter() {
+ assertThat(underTest.entryAdapter.row).isNull()
+ }
+
+ @Test
+ @EnableFlags(NotificationBundleUi.FLAG_NAME)
+ fun getGroupRoot_adapter() {
+ assertThat(underTest.entryAdapter.groupRoot).isEqualTo(underTest.entryAdapter)
+ }
+
+ @Test
+ @EnableFlags(NotificationBundleUi.FLAG_NAME)
+ fun getKey_adapter() {
+ assertThat(underTest.entryAdapter.key).isEqualTo("key")
+ }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/HighPriorityProviderTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/HighPriorityProviderTest.java
index 8e95ac5..76e2d61 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/HighPriorityProviderTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/HighPriorityProviderTest.java
@@ -30,6 +30,9 @@
import android.app.Notification;
import android.app.NotificationChannel;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
@@ -39,8 +42,10 @@
import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
+import com.android.systemui.statusbar.notification.shared.NotificationBundleUi;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -57,6 +62,9 @@
@Mock private GroupMembershipManager mGroupMembershipManager;
private HighPriorityProvider mHighPriorityProvider;
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
@@ -210,6 +218,7 @@
}
@Test
+ @DisableFlags(NotificationBundleUi.FLAG_NAME)
public void testIsHighPriority_checkChildrenToCalculatePriority_legacy() {
// GIVEN: a summary with low priority has a highPriorityChild and a lowPriorityChild
final NotificationEntry summary = createNotifEntry(false);
@@ -247,20 +256,18 @@
}
@Test
- public void testIsHighPriority_checkChildrenToCalculatePriority() {
+ public void testIsHighPriority_checkChildrenViewsToCalculatePriority() {
// GIVEN:
// parent with summary = lowPrioritySummary
// NotificationEntry = lowPriorityChild
// NotificationEntry = highPriorityChild
+ List<NotificationEntry> children = List.of(createNotifEntry(false), createNotifEntry(true));
final NotificationEntry lowPrioritySummary = createNotifEntry(false);
final GroupEntry parentEntry = new GroupEntryBuilder()
.setSummary(lowPrioritySummary)
+ .setChildren(children)
.build();
- when(mGroupMembershipManager.getChildren(parentEntry)).thenReturn(
- new ArrayList<>(
- List.of(
- createNotifEntry(false),
- createNotifEntry(true))));
+ when(mGroupMembershipManager.getChildren(parentEntry)).thenReturn(children);
// THEN the GroupEntry parentEntry is high priority since it has a high priority child
assertTrue(mHighPriorityProvider.isHighPriority(parentEntry));
@@ -272,10 +279,11 @@
// parent with summary = lowPrioritySummary
// NotificationEntry = lowPriorityChild
final NotificationEntry lowPrioritySummary = createNotifEntry(false);
+ final NotificationEntry lowPriorityChild = createNotifEntry(false);
final GroupEntry parentEntry = new GroupEntryBuilder()
.setSummary(lowPrioritySummary)
+ .setChildren(List.of(lowPriorityChild))
.build();
- final NotificationEntry lowPriorityChild = createNotifEntry(false);
when(mGroupMembershipManager.getChildren(parentEntry)).thenReturn(
new ArrayList<>(List.of(lowPriorityChild)));
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.kt
index e93c742..7fa157f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.kt
@@ -27,14 +27,29 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.kosmos.collectLastValue
+import com.android.systemui.kosmos.runTest
import com.android.systemui.kosmos.useUnconfinedTestDispatcher
+import com.android.systemui.statusbar.chips.notification.domain.interactor.statusBarNotificationChipsInteractor
+import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips
+import com.android.systemui.statusbar.core.StatusBarRootModernization
+import com.android.systemui.statusbar.notification.buildNotificationEntry
+import com.android.systemui.statusbar.notification.buildOngoingCallEntry
+import com.android.systemui.statusbar.notification.buildPromotedOngoingEntry
import com.android.systemui.statusbar.notification.collection.buildEntry
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner
import com.android.systemui.statusbar.notification.collection.notifPipeline
+import com.android.systemui.statusbar.notification.domain.interactor.renderNotificationListInteractor
import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUi
+import com.android.systemui.statusbar.notification.promoted.domain.interactor.promotedNotificationsInteractor
+import com.android.systemui.statusbar.phone.ongoingcall.StatusBarChipsModernization
import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.withArgCaptor
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.runTest
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Before
@@ -59,7 +74,13 @@
fun setup() {
allowTestableLooperAsMainThread()
- colorizedFgsCoordinator = ColorizedFgsCoordinator()
+ kosmos.statusBarNotificationChipsInteractor.start()
+
+ colorizedFgsCoordinator =
+ ColorizedFgsCoordinator(
+ kosmos.applicationCoroutineScope,
+ kosmos.promotedNotificationsInteractor,
+ )
colorizedFgsCoordinator.attach(notifPipeline)
sectioner = colorizedFgsCoordinator.sectioner
}
@@ -178,6 +199,37 @@
verify(notifPipeline, never()).addPromoter(any())
}
+ @Test
+ @EnableFlags(
+ PromotedNotificationUi.FLAG_NAME,
+ StatusBarNotifChips.FLAG_NAME,
+ StatusBarChipsModernization.FLAG_NAME,
+ StatusBarRootModernization.FLAG_NAME,
+ )
+ fun comparatorPutsCallBeforeOther() =
+ kosmos.runTest {
+ // GIVEN a call and a promoted ongoing notification
+ val callEntry = buildOngoingCallEntry(promoted = false)
+ val ronEntry = buildPromotedOngoingEntry()
+ val otherEntry = buildNotificationEntry(tag = "other")
+
+ kosmos.renderNotificationListInteractor.setRenderedList(
+ listOf(callEntry, ronEntry, otherEntry)
+ )
+
+ val orderedChipNotificationKeys by
+ collectLastValue(kosmos.promotedNotificationsInteractor.orderedChipNotificationKeys)
+
+ // THEN the order of the notification keys should be the call then the RON
+ assertThat(orderedChipNotificationKeys)
+ .containsExactly("0|test_pkg|0|call|0", "0|test_pkg|0|ron|0")
+
+ // VERIFY that the comparator puts the call before the ron
+ assertThat(sectioner.comparator!!.compare(callEntry, ronEntry)).isLessThan(0)
+ // VERIFY that the comparator puts the ron before the other
+ assertThat(sectioner.comparator!!.compare(ronEntry, otherEntry)).isLessThan(0)
+ }
+
private fun makeCallStyle(): Notification.CallStyle {
val pendingIntent =
PendingIntent.getBroadcast(mContext, 0, Intent("action"), PendingIntent.FLAG_IMMUTABLE)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerTest.kt
index db5921d..3dd0982 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerTest.kt
@@ -17,23 +17,29 @@
package com.android.systemui.statusbar.notification.collection.render
import android.os.Build
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
+import android.platform.test.flag.junit.SetFlagsRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.dump.DumpManager
import com.android.systemui.log.assertLogsWtf
+import com.android.systemui.statusbar.notification.collection.GroupEntry
import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder
import com.android.systemui.statusbar.notification.collection.ListEntry
import com.android.systemui.statusbar.notification.collection.NotifPipeline
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeRenderListListener
import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager.OnGroupExpansionChangeListener
+import com.android.systemui.statusbar.notification.shared.NotificationBundleUi
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.withArgCaptor
import com.google.common.truth.Truth.assertThat
import org.junit.Assume
import org.junit.Before
+import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.never
@@ -44,6 +50,9 @@
@SmallTest
@RunWith(AndroidJUnit4::class)
class GroupExpansionManagerTest : SysuiTestCase() {
+ @get:Rule
+ val setFlagsRule = SetFlagsRule()
+
private lateinit var underTest: GroupExpansionManagerImpl
private val dumpManager: DumpManager = mock()
@@ -52,8 +61,8 @@
private val pipeline: NotifPipeline = mock()
private lateinit var beforeRenderListListener: OnBeforeRenderListListener
- private val summary1 = notificationEntry("foo", 1)
- private val summary2 = notificationEntry("bar", 1)
+ private val summary1 = notificationSummaryEntry("foo", 1)
+ private val summary2 = notificationSummaryEntry("bar", 1)
private val entries =
listOf<ListEntry>(
GroupEntryBuilder()
@@ -82,15 +91,25 @@
private fun notificationEntry(pkg: String, id: Int) =
NotificationEntryBuilder().setPkg(pkg).setId(id).build().apply { row = mock() }
+ private fun notificationSummaryEntry(pkg: String, id: Int) =
+ NotificationEntryBuilder().setPkg(pkg).setId(id).setParent(GroupEntry.ROOT_ENTRY).build()
+ .apply { row = mock() }
+
@Before
fun setUp() {
whenever(groupMembershipManager.getGroupSummary(summary1)).thenReturn(summary1)
whenever(groupMembershipManager.getGroupSummary(summary2)).thenReturn(summary2)
+ whenever(groupMembershipManager.getGroupRoot(summary1.entryAdapter))
+ .thenReturn(summary1.entryAdapter)
+ whenever(groupMembershipManager.getGroupRoot(summary2.entryAdapter))
+ .thenReturn(summary2.entryAdapter)
+
underTest = GroupExpansionManagerImpl(dumpManager, groupMembershipManager)
}
@Test
+ @DisableFlags(NotificationBundleUi.FLAG_NAME)
fun notifyOnlyOnChange() {
var listenerCalledCount = 0
underTest.registerGroupExpansionChangeListener { _, _ -> listenerCalledCount++ }
@@ -108,6 +127,25 @@
}
@Test
+ @EnableFlags(NotificationBundleUi.FLAG_NAME)
+ fun notifyOnlyOnChange_withEntryAdapter() {
+ var listenerCalledCount = 0
+ underTest.registerGroupExpansionChangeListener { _, _ -> listenerCalledCount++ }
+
+ underTest.setGroupExpanded(summary1.entryAdapter, false)
+ assertThat(listenerCalledCount).isEqualTo(0)
+ underTest.setGroupExpanded(summary1.entryAdapter, true)
+ assertThat(listenerCalledCount).isEqualTo(1)
+ underTest.setGroupExpanded(summary2.entryAdapter, true)
+ assertThat(listenerCalledCount).isEqualTo(2)
+ underTest.setGroupExpanded(summary1.entryAdapter, true)
+ assertThat(listenerCalledCount).isEqualTo(2)
+ underTest.setGroupExpanded(summary2.entryAdapter, false)
+ assertThat(listenerCalledCount).isEqualTo(3)
+ }
+
+ @Test
+ @DisableFlags(NotificationBundleUi.FLAG_NAME)
fun expandUnattachedEntry() {
// First, expand the entry when it is attached.
underTest.setGroupExpanded(summary1, true)
@@ -122,6 +160,22 @@
}
@Test
+ @EnableFlags(NotificationBundleUi.FLAG_NAME)
+ fun expandUnattachedEntryAdapter() {
+ // First, expand the entry when it is attached.
+ underTest.setGroupExpanded(summary1.entryAdapter, true)
+ assertThat(underTest.isGroupExpanded(summary1.entryAdapter)).isTrue()
+
+ // Un-attach it, and un-expand it.
+ NotificationEntryBuilder.setNewParent(summary1, null)
+ underTest.setGroupExpanded(summary1.entryAdapter, false)
+
+ // Expanding again should throw.
+ assertLogsWtf { underTest.setGroupExpanded(summary1.entryAdapter, true) }
+ }
+
+ @Test
+ @DisableFlags(NotificationBundleUi.FLAG_NAME)
fun syncWithPipeline() {
underTest.attach(pipeline)
beforeRenderListListener = withArgCaptor {
@@ -143,4 +197,28 @@
verify(listener).onGroupExpansionChange(summary1.row, false)
verifyNoMoreInteractions(listener)
}
+
+ @Test
+ @EnableFlags(NotificationBundleUi.FLAG_NAME)
+ fun syncWithPipeline_withEntryAdapter() {
+ underTest.attach(pipeline)
+ beforeRenderListListener = withArgCaptor {
+ verify(pipeline).addOnBeforeRenderListListener(capture())
+ }
+
+ val listener: OnGroupExpansionChangeListener = mock()
+ underTest.registerGroupExpansionChangeListener(listener)
+
+ beforeRenderListListener.onBeforeRenderList(entries)
+ verify(listener, never()).onGroupExpansionChange(any(), any())
+
+ // Expand one of the groups.
+ underTest.setGroupExpanded(summary1.entryAdapter, true)
+ verify(listener).onGroupExpansionChange(summary1.row, true)
+
+ // Empty the pipeline list and verify that the group is no longer expanded.
+ beforeRenderListListener.onBeforeRenderList(emptyList())
+ verify(listener).onGroupExpansionChange(summary1.row, false)
+ verifyNoMoreInteractions(listener)
+ }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerTest.kt
index 2cbcc5a..dcbf44e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerTest.kt
@@ -16,34 +16,46 @@
package com.android.systemui.statusbar.notification.collection.render
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
+import android.platform.test.flag.junit.SetFlagsRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.notification.collection.GroupEntry
import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
+import com.android.systemui.statusbar.notification.shared.NotificationBundleUi
import com.google.common.truth.Truth.assertThat
+import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@SmallTest
@RunWith(AndroidJUnit4::class)
class GroupMembershipManagerTest : SysuiTestCase() {
+
+ @get:Rule
+ val setFlagsRule = SetFlagsRule()
+
private var underTest = GroupMembershipManagerImpl()
@Test
+ @DisableFlags(NotificationBundleUi.FLAG_NAME)
fun isChildInGroup_topLevel() {
val topLevelEntry = NotificationEntryBuilder().setParent(GroupEntry.ROOT_ENTRY).build()
assertThat(underTest.isChildInGroup(topLevelEntry)).isFalse()
}
@Test
+ @DisableFlags(NotificationBundleUi.FLAG_NAME)
fun isChildInGroup_noParent() {
val noParentEntry = NotificationEntryBuilder().setParent(null).build()
assertThat(underTest.isChildInGroup(noParentEntry)).isFalse()
}
@Test
+ @DisableFlags(NotificationBundleUi.FLAG_NAME)
fun isChildInGroup_summary() {
val groupKey = "group"
val summary =
@@ -57,12 +69,14 @@
}
@Test
+ @DisableFlags(NotificationBundleUi.FLAG_NAME)
fun isGroupSummary_topLevelEntry() {
val entry = NotificationEntryBuilder().setParent(GroupEntry.ROOT_ENTRY).build()
assertThat(underTest.isGroupSummary(entry)).isFalse()
}
@Test
+ @DisableFlags(NotificationBundleUi.FLAG_NAME)
fun isGroupSummary_summary() {
val groupKey = "group"
val summary =
@@ -76,6 +90,7 @@
}
@Test
+ @DisableFlags(NotificationBundleUi.FLAG_NAME)
fun isGroupSummary_child() {
val groupKey = "group"
val summary =
@@ -90,12 +105,14 @@
}
@Test
+ @DisableFlags(NotificationBundleUi.FLAG_NAME)
fun getGroupSummary_topLevelEntry() {
val entry = NotificationEntryBuilder().setParent(GroupEntry.ROOT_ENTRY).build()
assertThat(underTest.getGroupSummary(entry)).isNull()
}
@Test
+ @DisableFlags(NotificationBundleUi.FLAG_NAME)
fun getGroupSummary_summary() {
val groupKey = "group"
val summary =
@@ -109,6 +126,7 @@
}
@Test
+ @DisableFlags(NotificationBundleUi.FLAG_NAME)
fun getGroupSummary_child() {
val groupKey = "group"
val summary =
@@ -121,4 +139,104 @@
assertThat(underTest.getGroupSummary(entry)).isEqualTo(summary)
}
+
+ @Test
+ @EnableFlags(NotificationBundleUi.FLAG_NAME)
+ fun isChildEntryAdapterInGroup_topLevel() {
+ val topLevelEntry = NotificationEntryBuilder().setParent(GroupEntry.ROOT_ENTRY).build()
+ assertThat(underTest.isChildInGroup(topLevelEntry.entryAdapter)).isFalse()
+ }
+
+ @Test
+ @EnableFlags(NotificationBundleUi.FLAG_NAME)
+ fun isChildEntryAdapterInGroup_noParent() {
+ val noParentEntry = NotificationEntryBuilder().setParent(null).build()
+ assertThat(underTest.isChildInGroup(noParentEntry.entryAdapter)).isFalse()
+ }
+
+ @Test
+ @EnableFlags(NotificationBundleUi.FLAG_NAME)
+ fun isChildEntryAdapterInGroup_summary() {
+ val groupKey = "group"
+ val summary =
+ NotificationEntryBuilder()
+ .setGroup(mContext, groupKey)
+ .setGroupSummary(mContext, true)
+ .build()
+ GroupEntryBuilder().setKey(groupKey).setSummary(summary).build()
+
+ assertThat(underTest.isChildInGroup(summary.entryAdapter)).isFalse()
+ }
+
+ @Test
+ @EnableFlags(NotificationBundleUi.FLAG_NAME)
+ fun isGroupRoot_topLevelEntry() {
+ val entry = NotificationEntryBuilder().setParent(GroupEntry.ROOT_ENTRY).build()
+ assertThat(underTest.isGroupRoot(entry.entryAdapter)).isFalse()
+ }
+
+ @Test
+ @EnableFlags(NotificationBundleUi.FLAG_NAME)
+ fun isGroupRoot_summary() {
+ val groupKey = "group"
+ val summary =
+ NotificationEntryBuilder()
+ .setGroup(mContext, groupKey)
+ .setGroupSummary(mContext, true)
+ .build()
+ GroupEntryBuilder().setKey(groupKey).setSummary(summary).build()
+
+ assertThat(underTest.isGroupRoot(summary.entryAdapter)).isTrue()
+ }
+
+ @Test
+ @EnableFlags(NotificationBundleUi.FLAG_NAME)
+ fun isGroupRoot_child() {
+ val groupKey = "group"
+ val summary =
+ NotificationEntryBuilder()
+ .setGroup(mContext, groupKey)
+ .setGroupSummary(mContext, true)
+ .build()
+ val entry = NotificationEntryBuilder().setGroup(mContext, groupKey).build()
+ GroupEntryBuilder().setKey(groupKey).setSummary(summary).addChild(entry).build()
+
+ assertThat(underTest.isGroupRoot(entry.entryAdapter)).isFalse()
+ }
+
+ @Test
+ @EnableFlags(NotificationBundleUi.FLAG_NAME)
+ fun getGroupRoot_topLevelEntry() {
+ val entry = NotificationEntryBuilder().setParent(GroupEntry.ROOT_ENTRY).build()
+ assertThat(underTest.getGroupRoot(entry.entryAdapter)).isNull()
+ }
+
+ @Test
+ @EnableFlags(NotificationBundleUi.FLAG_NAME)
+ fun getGroupRoot_summary() {
+ val groupKey = "group"
+ val summary =
+ NotificationEntryBuilder()
+ .setGroup(mContext, groupKey)
+ .setGroupSummary(mContext, true)
+ .build()
+ GroupEntryBuilder().setKey(groupKey).setSummary(summary).build()
+
+ assertThat(underTest.getGroupRoot(summary.entryAdapter)).isEqualTo(summary.entryAdapter)
+ }
+
+ @Test
+ @EnableFlags(NotificationBundleUi.FLAG_NAME)
+ fun getGroupRoot_child() {
+ val groupKey = "group"
+ val summary =
+ NotificationEntryBuilder()
+ .setGroup(mContext, groupKey)
+ .setGroupSummary(mContext, true)
+ .build()
+ val entry = NotificationEntryBuilder().setGroup(mContext, groupKey).build()
+ GroupEntryBuilder().setKey(groupKey).setSummary(summary).addChild(entry).build()
+
+ assertThat(underTest.getGroupRoot(entry.entryAdapter)).isEqualTo(summary.entryAdapter)
+ }
}
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 339f8fa..e22acd5 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
@@ -106,11 +106,15 @@
this.addOverride(R.integer.touch_acceptance_delay, TEST_TOUCH_ACCEPTANCE_TIME)
this.addOverride(
R.integer.heads_up_notification_minimum_time,
- TEST_MINIMUM_DISPLAY_TIME,
+ TEST_MINIMUM_DISPLAY_TIME_DEFAULT,
)
this.addOverride(
R.integer.heads_up_notification_minimum_time_with_throttling,
- TEST_MINIMUM_DISPLAY_TIME,
+ TEST_MINIMUM_DISPLAY_TIME_DEFAULT,
+ )
+ this.addOverride(
+ R.integer.heads_up_notification_minimum_time_for_user_initiated,
+ TEST_MINIMUM_DISPLAY_TIME_FOR_USER_INITIATED,
)
this.addOverride(R.integer.heads_up_notification_decay, TEST_AUTO_DISMISS_TIME)
this.addOverride(
@@ -414,7 +418,7 @@
}
@Test
- fun testRemoveNotification_beforeMinimumDisplayTime() {
+ fun testRemoveNotification_beforeMinimumDisplayTime_notUserInitiatedHun() {
val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
useAccessibilityTimeout(false)
@@ -429,18 +433,22 @@
assertThat(removedImmediately).isFalse()
assertThat(underTest.isHeadsUpEntry(entry.key)).isTrue()
- systemClock.advanceTime(((TEST_MINIMUM_DISPLAY_TIME + TEST_AUTO_DISMISS_TIME) / 2).toLong())
+ systemClock.advanceTime(
+ ((TEST_MINIMUM_DISPLAY_TIME_DEFAULT + TEST_AUTO_DISMISS_TIME) / 2).toLong()
+ )
assertThat(underTest.isHeadsUpEntry(entry.key)).isFalse()
}
@Test
- fun testRemoveNotification_afterMinimumDisplayTime() {
+ fun testRemoveNotification_afterMinimumDisplayTime_notUserInitiatedHun() {
val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
useAccessibilityTimeout(false)
underTest.showNotification(entry)
- systemClock.advanceTime(((TEST_MINIMUM_DISPLAY_TIME + TEST_AUTO_DISMISS_TIME) / 2).toLong())
+ systemClock.advanceTime(
+ ((TEST_MINIMUM_DISPLAY_TIME_DEFAULT + TEST_AUTO_DISMISS_TIME) / 2).toLong()
+ )
assertThat(underTest.isHeadsUpEntry(entry.key)).isTrue()
@@ -455,6 +463,57 @@
}
@Test
+ @EnableFlags(StatusBarNotifChips.FLAG_NAME)
+ fun testRemoveNotification_beforeMinimumDisplayTime_forUserInitiatedHun() {
+ useAccessibilityTimeout(false)
+
+ val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+ entry.row = testHelper.createRow()
+ underTest.showNotification(entry, isPinnedByUser = true)
+
+ val removedImmediately =
+ underTest.removeNotification(
+ entry.key,
+ /* releaseImmediately = */ false,
+ "beforeMinimumDisplayTime",
+ )
+ assertThat(removedImmediately).isFalse()
+ assertThat(underTest.isHeadsUpEntry(entry.key)).isTrue()
+
+ systemClock.advanceTime(
+ ((TEST_MINIMUM_DISPLAY_TIME_FOR_USER_INITIATED + TEST_AUTO_DISMISS_TIME) / 2).toLong()
+ )
+
+ assertThat(underTest.isHeadsUpEntry(entry.key)).isFalse()
+ }
+
+ @Test
+ @EnableFlags(StatusBarNotifChips.FLAG_NAME)
+ fun testRemoveNotification_afterMinimumDisplayTime_forUserInitiatedHun() {
+ useAccessibilityTimeout(false)
+
+ val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+ entry.row = testHelper.createRow()
+ underTest.showNotification(entry, isPinnedByUser = true)
+
+ systemClock.advanceTime(
+ ((TEST_MINIMUM_DISPLAY_TIME_FOR_USER_INITIATED + 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)
@@ -1047,16 +1106,21 @@
}
companion object {
- const val TEST_TOUCH_ACCEPTANCE_TIME = 200
- const val TEST_A11Y_AUTO_DISMISS_TIME = 1000
- const val TEST_EXTENSION_TIME = 500
+ private const val TEST_TOUCH_ACCEPTANCE_TIME = 200
+ private const val TEST_A11Y_AUTO_DISMISS_TIME = 1000
+ private 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
+ private const val TEST_MINIMUM_DISPLAY_TIME_DEFAULT = 400
+ private const val TEST_MINIMUM_DISPLAY_TIME_FOR_USER_INITIATED = 500
+ private const val TEST_AUTO_DISMISS_TIME = 600
+ private const val TEST_STICKY_AUTO_DISMISS_TIME = 800
init {
- assertThat(TEST_MINIMUM_DISPLAY_TIME).isLessThan(TEST_AUTO_DISMISS_TIME)
+ assertThat(TEST_MINIMUM_DISPLAY_TIME_DEFAULT)
+ .isLessThan(TEST_MINIMUM_DISPLAY_TIME_FOR_USER_INITIATED)
+ assertThat(TEST_MINIMUM_DISPLAY_TIME_DEFAULT).isLessThan(TEST_AUTO_DISMISS_TIME)
+ assertThat(TEST_MINIMUM_DISPLAY_TIME_FOR_USER_INITIATED)
+ .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)
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/people/PeopleNotificationIdentifierTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/people/PeopleNotificationIdentifierTest.kt
new file mode 100644
index 0000000..75f5de0
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/people/PeopleNotificationIdentifierTest.kt
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2025 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.people
+
+import android.app.Notification
+import android.app.NotificationChannel
+import android.content.pm.ShortcutInfo
+import android.service.notification.NotificationListenerService.Ranking
+import android.service.notification.StatusBarNotification
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.statusbar.RankingBuilder
+import com.android.systemui.statusbar.notification.collection.GroupEntry
+import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder
+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.people.PeopleNotificationIdentifier.Companion.TYPE_FULL_PERSON
+import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_IMPORTANT_PERSON
+import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_NON_PERSON
+import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_PERSON
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito
+import org.mockito.Mockito.mock
+
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class PeopleNotificationIdentifierTest : SysuiTestCase() {
+
+ private lateinit var underTest: PeopleNotificationIdentifierImpl
+
+ private val summary1 = notificationEntry("foo", 1, summary = true)
+ private val summary2 = notificationEntry("bar", 1, summary = true)
+ private val entries =
+ listOf<GroupEntry>(
+ GroupEntryBuilder()
+ .setSummary(summary1)
+ .setChildren(
+ listOf(
+ notificationEntry("foo", 2),
+ notificationEntry("foo", 3),
+ notificationEntry("foo", 4)
+ )
+ )
+ .build(),
+ GroupEntryBuilder()
+ .setSummary(summary2)
+ .setChildren(
+ listOf(
+ notificationEntry("bar", 2),
+ notificationEntry("bar", 3),
+ notificationEntry("bar", 4)
+ )
+ )
+ .build()
+ )
+
+ private fun notificationEntry(
+ pkg: String,
+ id: Int,
+ summary: Boolean = false
+ ): NotificationEntry {
+ val sbn = mock(StatusBarNotification::class.java)
+ Mockito.`when`(sbn.key).thenReturn("key")
+ Mockito.`when`(sbn.notification).thenReturn(mock(Notification::class.java))
+ if (summary)
+ Mockito.`when`(sbn.notification.isGroupSummary).thenReturn(true)
+ return NotificationEntryBuilder().setPkg(pkg)
+ .setId(id)
+ .setSbn(sbn)
+ .build().apply {
+ row = mock(ExpandableNotificationRow::class.java)
+ }
+ }
+
+ private fun personRanking(entry: NotificationEntry, personType: Int): Ranking {
+ val channel = NotificationChannel("person", "person", 4)
+ channel.setConversationId("parent", "person")
+ channel.setImportantConversation(true)
+
+ val br = RankingBuilder(entry.ranking)
+
+ when (personType) {
+ TYPE_NON_PERSON -> br.setIsConversation(false)
+ TYPE_PERSON -> {
+ br.setIsConversation(true)
+ br.setShortcutInfo(null)
+ }
+
+ TYPE_IMPORTANT_PERSON -> {
+ br.setIsConversation(true)
+ br.setShortcutInfo(mock(ShortcutInfo::class.java))
+ br.setChannel(channel)
+ }
+
+ else -> {
+ br.setIsConversation(true)
+ br.setShortcutInfo(mock(ShortcutInfo::class.java))
+ }
+ }
+
+ return br.build()
+ }
+
+ @Before
+ fun setUp() {
+ val personExtractor = object : NotificationPersonExtractor {
+ public override fun isPersonNotification(sbn: StatusBarNotification): Boolean {
+ return true
+ }
+ }
+
+ underTest = PeopleNotificationIdentifierImpl(
+ personExtractor,
+ GroupMembershipManagerImpl()
+ )
+ }
+
+ private val Ranking.personTypeInfo
+ get() = when {
+ !isConversation -> TYPE_NON_PERSON
+ conversationShortcutInfo == null -> TYPE_PERSON
+ channel?.isImportantConversation == true -> TYPE_IMPORTANT_PERSON
+ else -> TYPE_FULL_PERSON
+ }
+
+ @Test
+ fun getPeopleNotificationType_entryIsImportant() {
+ summary1.setRanking(personRanking(summary1, TYPE_IMPORTANT_PERSON))
+
+ assertThat(underTest.getPeopleNotificationType(summary1)).isEqualTo(TYPE_IMPORTANT_PERSON)
+ }
+
+ @Test
+ fun getPeopleNotificationType_importantChild() {
+ entries.get(0).getChildren().get(0).setRanking(
+ personRanking(entries.get(0).getChildren().get(0), TYPE_IMPORTANT_PERSON)
+ )
+
+ assertThat(entries.get(0).summary?.let { underTest.getPeopleNotificationType(it) })
+ .isEqualTo(TYPE_IMPORTANT_PERSON)
+ }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorImplTest.kt
index a3fde5a..216fd2d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorImplTest.kt
@@ -39,18 +39,24 @@
import com.android.systemui.statusbar.notification.promoted.AutomaticPromotionCoordinator.Companion.EXTRA_WAS_AUTOMATICALLY_PROMOTED
import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel
import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel.Style
+import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel.When
import com.android.systemui.statusbar.notification.row.RowImageInflater
import com.android.systemui.testKosmos
+import com.android.systemui.util.time.fakeSystemClock
+import com.android.systemui.util.time.systemClock
import com.google.common.truth.Truth.assertThat
+import kotlin.time.Duration
+import kotlin.time.Duration.Companion.minutes
import org.junit.Test
import org.junit.runner.RunWith
@SmallTest
@RunWith(AndroidJUnit4::class)
class PromotedNotificationContentExtractorImplTest : SysuiTestCase() {
- private val kosmos = testKosmos()
+ private val kosmos = testKosmos().apply { systemClock = fakeSystemClock }
private val underTest = kosmos.promotedNotificationContentExtractor
+ private val systemClock = kosmos.fakeSystemClock
private val rowImageInflater = RowImageInflater.newInstance(previousIndex = null)
private val imageModelProvider by lazy { rowImageInflater.useForContentModel() }
@@ -177,7 +183,176 @@
@Test
@EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
- fun extractsContent_fromBaseStyle() {
+ fun extractTime_none() {
+ assertExtractedTime(hasTime = false, hasChronometer = false, expected = ExpectedTime.Null)
+ }
+
+ @Test
+ @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
+ fun extractTime_basicTimeNow() {
+ assertExtractedTime(
+ hasTime = true,
+ hasChronometer = false,
+ whenOffset = Duration.ZERO,
+ expected = ExpectedTime.Time,
+ )
+ }
+
+ @Test
+ @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
+ fun extractTime_basicTimePast() {
+ assertExtractedTime(
+ hasTime = true,
+ hasChronometer = false,
+ whenOffset = (-5).minutes,
+ expected = ExpectedTime.Time,
+ )
+ }
+
+ @Test
+ @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
+ fun extractTime_basicTimeFuture() {
+ assertExtractedTime(
+ hasTime = true,
+ hasChronometer = false,
+ whenOffset = 5.minutes,
+ expected = ExpectedTime.Time,
+ )
+ }
+
+ @Test
+ @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
+ fun extractTime_countUpNow() {
+ assertExtractedTime(
+ hasTime = false,
+ hasChronometer = true,
+ isCountDown = false,
+ whenOffset = Duration.ZERO,
+ expected = ExpectedTime.CountUp,
+ )
+ }
+
+ @Test
+ @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
+ fun extractTime_countUpPast() {
+ assertExtractedTime(
+ hasTime = false,
+ hasChronometer = true,
+ isCountDown = false,
+ whenOffset = (-5).minutes,
+ expected = ExpectedTime.CountUp,
+ )
+ }
+
+ @Test
+ @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
+ fun extractTime_countUpFuture() {
+ assertExtractedTime(
+ hasTime = false,
+ hasChronometer = true,
+ isCountDown = false,
+ whenOffset = 5.minutes,
+ expected = ExpectedTime.CountUp,
+ )
+ }
+
+ @Test
+ @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
+ fun extractTime_countDownNow() {
+ assertExtractedTime(
+ hasTime = false,
+ hasChronometer = true,
+ isCountDown = true,
+ whenOffset = Duration.ZERO,
+ expected = ExpectedTime.CountDown,
+ )
+ }
+
+ @Test
+ @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
+ fun extractTime_countDownPast() {
+ assertExtractedTime(
+ hasTime = false,
+ hasChronometer = true,
+ isCountDown = true,
+ whenOffset = (-5).minutes,
+ expected = ExpectedTime.CountDown,
+ )
+ }
+
+ @Test
+ @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
+ fun extractTime_countDownFuture() {
+ assertExtractedTime(
+ hasTime = false,
+ hasChronometer = true,
+ isCountDown = true,
+ whenOffset = 5.minutes,
+ expected = ExpectedTime.CountDown,
+ )
+ }
+
+ @Test
+ @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
+ fun extractTime_prefersChronometerToWhen() {
+ assertExtractedTime(hasTime = true, hasChronometer = true, expected = ExpectedTime.CountUp)
+ }
+
+ private enum class ExpectedTime {
+ Null,
+ Time,
+ CountUp,
+ CountDown,
+ }
+
+ private fun assertExtractedTime(
+ hasTime: Boolean = false,
+ hasChronometer: Boolean = false,
+ isCountDown: Boolean = false,
+ whenOffset: Duration = Duration.ZERO,
+ expected: ExpectedTime,
+ ) {
+ // Set the two timebases to different (arbitrary) numbers, so we can verify whether the
+ // extractor is doing the timebase adjustment correctly.
+ systemClock.setCurrentTimeMillis(1_739_570_992_579L)
+ systemClock.setElapsedRealtime(1_380_967_080L)
+
+ val whenCurrentTime = systemClock.currentTimeMillis() + whenOffset.inWholeMilliseconds
+ val whenElapsedRealtime = systemClock.elapsedRealtime() + whenOffset.inWholeMilliseconds
+
+ val entry = createEntry {
+ setShowWhen(hasTime)
+ setUsesChronometer(hasChronometer)
+ setChronometerCountDown(isCountDown)
+ setWhen(whenCurrentTime)
+ }
+
+ val content = extractContent(entry)
+
+ assertThat(content).isNotNull()
+
+ when (expected) {
+ ExpectedTime.Null -> assertThat(content?.time).isNull()
+
+ ExpectedTime.Time -> {
+ val actual = content?.time as? When.Time
+ assertThat(actual).isNotNull()
+ assertThat(actual?.currentTimeMillis).isEqualTo(whenCurrentTime)
+ }
+
+ ExpectedTime.CountDown,
+ ExpectedTime.CountUp -> {
+ val actual = content?.time as? When.Chronometer
+ assertThat(actual).isNotNull()
+ assertThat(actual?.elapsedRealtimeMillis).isEqualTo(whenElapsedRealtime)
+ assertThat(actual?.isCountDown).isEqualTo(expected == ExpectedTime.CountDown)
+ }
+ }
+ }
+
+ @Test
+ @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
+ fun extractContent_fromBaseStyle() {
val entry = createEntry { setStyle(null) }
val content = extractContent(entry)
@@ -188,7 +363,7 @@
@Test
@EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
- fun extractsContent_fromBigPictureStyle() {
+ fun extractContent_fromBigPictureStyle() {
val entry = createEntry { setStyle(BigPictureStyle()) }
val content = extractContent(entry)
@@ -261,7 +436,7 @@
@Test
@EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
- fun extractsContent_fromOldProgressDeterminate() {
+ fun extractContent_fromOldProgressDeterminate() {
val entry = createEntry {
setProgress(TEST_PROGRESS_MAX, TEST_PROGRESS, /* indeterminate= */ false)
}
@@ -282,7 +457,7 @@
@Test
@EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
- fun extractsContent_fromOldProgressIndeterminate() {
+ fun extractContent_fromOldProgressIndeterminate() {
val entry = createEntry {
setProgress(TEST_PROGRESS_MAX, TEST_PROGRESS, /* indeterminate= */ true)
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PromotedNotificationsInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PromotedNotificationsInteractorTest.kt
new file mode 100644
index 0000000..aa6e76d
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PromotedNotificationsInteractorTest.kt
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.promoted.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
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.kosmos.collectLastValue
+import com.android.systemui.kosmos.runTest
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
+import com.android.systemui.statusbar.chips.notification.domain.interactor.statusBarNotificationChipsInteractor
+import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips
+import com.android.systemui.statusbar.core.StatusBarRootModernization
+import com.android.systemui.statusbar.notification.buildNotificationEntry
+import com.android.systemui.statusbar.notification.buildOngoingCallEntry
+import com.android.systemui.statusbar.notification.buildPromotedOngoingEntry
+import com.android.systemui.statusbar.notification.domain.interactor.renderNotificationListInteractor
+import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUi
+import com.android.systemui.statusbar.phone.ongoingcall.StatusBarChipsModernization
+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
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+@EnableFlags(
+ PromotedNotificationUi.FLAG_NAME,
+ StatusBarNotifChips.FLAG_NAME,
+ StatusBarChipsModernization.FLAG_NAME,
+ StatusBarRootModernization.FLAG_NAME,
+)
+class PromotedNotificationsInteractorTest : SysuiTestCase() {
+ private val kosmos = testKosmos().useUnconfinedTestDispatcher()
+
+ private val Kosmos.underTest by Fixture { promotedNotificationsInteractor }
+
+ @Before
+ fun setUp() {
+ kosmos.statusBarNotificationChipsInteractor.start()
+ }
+
+ @Test
+ fun orderedChipNotificationKeys_containsNonPromotedCalls() =
+ kosmos.runTest {
+ // GIVEN a call and a promoted ongoing notification
+ val callEntry = buildOngoingCallEntry(promoted = false)
+ val ronEntry = buildPromotedOngoingEntry()
+ val otherEntry = buildNotificationEntry(tag = "other")
+
+ renderNotificationListInteractor.setRenderedList(
+ listOf(callEntry, ronEntry, otherEntry)
+ )
+
+ val orderedChipNotificationKeys by
+ collectLastValue(underTest.orderedChipNotificationKeys)
+
+ // THEN the order of the notification keys should be the call then the RON
+ assertThat(orderedChipNotificationKeys)
+ .containsExactly("0|test_pkg|0|call|0", "0|test_pkg|0|ron|0")
+ }
+
+ @Test
+ fun orderedChipNotificationKeys_containsPromotedCalls() =
+ kosmos.runTest {
+ // GIVEN a call and a promoted ongoing notification
+ val callEntry = buildOngoingCallEntry(promoted = true)
+ val ronEntry = buildPromotedOngoingEntry()
+ val otherEntry = buildNotificationEntry(tag = "other")
+
+ renderNotificationListInteractor.setRenderedList(
+ listOf(callEntry, ronEntry, otherEntry)
+ )
+
+ val orderedChipNotificationKeys by
+ collectLastValue(underTest.orderedChipNotificationKeys)
+
+ // THEN the order of the notification keys should be the call then the RON
+ assertThat(orderedChipNotificationKeys)
+ .containsExactly("0|test_pkg|0|call|0", "0|test_pkg|0|ron|0")
+ }
+
+ @Test
+ fun topPromotedNotificationContent_skipsNonPromotedCalls() =
+ kosmos.runTest {
+ // GIVEN a non-promoted call and a promoted ongoing notification
+ val callEntry = buildOngoingCallEntry(promoted = false)
+ val ronEntry = buildPromotedOngoingEntry()
+ val otherEntry = buildNotificationEntry(tag = "other")
+
+ renderNotificationListInteractor.setRenderedList(
+ listOf(callEntry, ronEntry, otherEntry)
+ )
+
+ val topPromotedNotificationContent by
+ collectLastValue(underTest.topPromotedNotificationContent)
+
+ // THEN the ron is first because the call has no content
+ assertThat(topPromotedNotificationContent?.identity?.key)
+ .isEqualTo("0|test_pkg|0|ron|0")
+ }
+
+ @Test
+ fun topPromotedNotificationContent_includesPromotedCalls() =
+ kosmos.runTest {
+ // GIVEN a promoted call and a promoted ongoing notification
+ val callEntry = buildOngoingCallEntry(promoted = true)
+ val ronEntry = buildPromotedOngoingEntry()
+ val otherEntry = buildNotificationEntry(tag = "other")
+
+ renderNotificationListInteractor.setRenderedList(
+ listOf(callEntry, ronEntry, otherEntry)
+ )
+
+ val topPromotedNotificationContent by
+ collectLastValue(underTest.topPromotedNotificationContent)
+
+ // THEN the call is the top notification
+ assertThat(topPromotedNotificationContent?.identity?.key)
+ .isEqualTo("0|test_pkg|0|call|0")
+ }
+
+ @Test
+ fun topPromotedNotificationContent_nullWithNoPromotedNotifications() =
+ kosmos.runTest {
+ // GIVEN a a non-promoted call and no promoted ongoing entry
+ val callEntry = buildOngoingCallEntry(promoted = false)
+ val otherEntry = buildNotificationEntry(tag = "other")
+
+ renderNotificationListInteractor.setRenderedList(listOf(callEntry, otherEntry))
+
+ val topPromotedNotificationContent by
+ collectLastValue(underTest.topPromotedNotificationContent)
+
+ // THEN there is no top promoted notification
+ assertThat(topPromotedNotificationContent).isNull()
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java
index 7d406b4..9f35d63 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java
@@ -67,6 +67,7 @@
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips;
import com.android.systemui.statusbar.notification.ConversationNotificationProcessor;
+import com.android.systemui.statusbar.notification.collection.EntryAdapter;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.promoted.FakePromotedNotificationContentExtractor;
import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUi;
@@ -248,14 +249,13 @@
true /* isNewView */, (v, p, r) -> true,
new InflationCallback() {
@Override
- public void handleInflationException(NotificationEntry entry,
- Exception e) {
+ public void handleInflationException(Exception e) {
countDownLatch.countDown();
throw new RuntimeException("No Exception expected");
}
@Override
- public void onAsyncInflationFinished(NotificationEntry entry) {
+ public void onAsyncInflationFinished() {
countDownLatch.countDown();
}
}, mRow.getPrivateLayout(), null, null, new HashMap<>(),
@@ -539,8 +539,7 @@
inflater.setInflateSynchronously(true);
InflationCallback callback = new InflationCallback() {
@Override
- public void handleInflationException(NotificationEntry entry,
- Exception e) {
+ public void handleInflationException(Exception e) {
if (!expectingException) {
exceptionHolder.setException(e);
}
@@ -548,7 +547,7 @@
}
@Override
- public void onAsyncInflationFinished(NotificationEntry entry) {
+ public void onAsyncInflationFinished() {
if (expectingException) {
exceptionHolder.setException(new RuntimeException(
"Inflation finished even though there should be an error"));
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImplTest.kt
index 82eca37..ce3aee1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImplTest.kt
@@ -41,6 +41,7 @@
import com.android.systemui.statusbar.NotificationLockscreenUserManager.RedactionType
import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips
import com.android.systemui.statusbar.notification.ConversationNotificationProcessor
+import com.android.systemui.statusbar.notification.collection.EntryAdapter
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.promoted.FakePromotedNotificationContentExtractor
import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUi
@@ -223,12 +224,12 @@
remoteViewClickHandler = { _, _, _ -> true },
callback =
object : InflationCallback {
- override fun handleInflationException(entry: NotificationEntry, e: Exception) {
+ override fun handleInflationException(e: Exception) {
countDownLatch.countDown()
throw RuntimeException("No Exception expected")
}
- override fun onAsyncInflationFinished(entry: NotificationEntry) {
+ override fun onAsyncInflationFinished() {
countDownLatch.countDown()
}
},
@@ -675,14 +676,14 @@
inflater.setInflateSynchronously(true)
val callback: InflationCallback =
object : InflationCallback {
- override fun handleInflationException(entry: NotificationEntry, e: Exception) {
+ override fun handleInflationException(e: Exception) {
if (!expectingException) {
exceptionHolder.exception = e
}
countDownLatch.countDown()
}
- override fun onAsyncInflationFinished(entry: NotificationEntry) {
+ override fun onAsyncInflationFinished() {
if (expectingException) {
exceptionHolder.exception =
RuntimeException(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
index c39b252c..f2131da 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
@@ -615,7 +615,7 @@
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
inflater.setFactory2(new RowInflaterTask.RowAsyncLayoutInflater(entry, mSystemClock,
- mRowInflaterTaskLogger));
+ mRowInflaterTaskLogger, UserHandle.of(entry.getSbn().getNormalizedUserId())));
mRow = (ExpandableNotificationRow) inflater.inflate(
R.layout.status_bar_notification_row,
null /* root */,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelTest.kt
index d570f18..6381b4e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelTest.kt
@@ -57,11 +57,12 @@
statusBarStateController = mock()
whenever(screenOffAnimationController.allowWakeUpIfDozing()).thenReturn(true)
}
- private val underTest = kosmos.notificationShelfViewModel
private val deviceEntryFaceAuthRepository = kosmos.fakeDeviceEntryFaceAuthRepository
private val keyguardRepository = kosmos.fakeKeyguardRepository
- private val keyguardTransitionController = kosmos.lockscreenShadeTransitionController
private val powerRepository = kosmos.fakePowerRepository
+ private val keyguardTransitionController by lazy { kosmos.lockscreenShadeTransitionController }
+
+ private val underTest by lazy { kosmos.notificationShelfViewModel }
@Test
fun canModifyColorOfNotifications_whenKeyguardNotShowing() =
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/MediaContainerViewTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/MediaContainerViewTest.kt
index 3a77d82..52f903e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/MediaContainerViewTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/MediaContainerViewTest.kt
@@ -31,7 +31,7 @@
fun testUpdateClipping_updatesClipHeight() {
assertTrue(mediaContainerView.clipHeight == 0)
- mediaContainerView.actualHeight = 10
+ mediaContainerView.setFinalActualHeight(10)
mediaContainerView.updateClipping()
assertTrue(mediaContainerView.clipHeight == 10)
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt
index 256da253..9c5d65e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt
@@ -1,5 +1,6 @@
package com.android.systemui.statusbar.notification.stack
+import android.os.UserHandle
import android.platform.test.annotations.EnableFlags
import android.service.notification.StatusBarNotification
import android.testing.TestableLooper.RunWithLooper
@@ -21,6 +22,7 @@
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.row.ExpandableView
+import com.android.systemui.statusbar.notification.shared.NotificationBundleUi
import com.android.systemui.statusbar.notification.shared.NotificationMinimalism
import com.android.systemui.statusbar.notification.shelf.NotificationShelfIconContainer
import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm.StackScrollAlgorithmState
@@ -978,7 +980,10 @@
) {
val sbnMock: StatusBarNotification = mock()
val mockEntry = mock<NotificationEntry>().apply { whenever(this.sbn).thenReturn(sbnMock) }
- val row = ExpandableNotificationRow(mContext, null, mockEntry)
+ val row = when (NotificationBundleUi.isEnabled) {
+ true -> ExpandableNotificationRow(mContext, null, UserHandle.CURRENT)
+ false -> ExpandableNotificationRow(mContext, null, mockEntry)
+ }
whenever(ambientState.lastVisibleBackgroundChild).thenReturn(row)
whenever(ambientState.isExpansionChanging).thenReturn(true)
whenever(ambientState.expansionFraction).thenReturn(expansionFraction)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationTargetsHelperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationTargetsHelperTest.kt
index 51de9d5..87cd728 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationTargetsHelperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationTargetsHelperTest.kt
@@ -14,6 +14,7 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.kotlin.whenever
/** Tests for {@link NotificationTargetsHelper}. */
@SmallTest
@@ -21,7 +22,7 @@
@RunWithLooper
class NotificationTargetsHelperTest : SysuiTestCase() {
private val featureFlags = FakeFeatureFlagsClassic()
- lateinit var notificationTestHelper: NotificationTestHelper
+ private lateinit var notificationTestHelper: NotificationTestHelper
private val sectionsManager: NotificationSectionsManager = mock()
private val stackScrollLayout: NotificationStackScrollLayout = mock()
@@ -107,7 +108,12 @@
// THEN all the views that surround it become targets with the swiped view at the middle
val actual =
notificationTargetsHelper()
- .findMagneticTargets(viewSwiped = swiped, stackScrollLayout = stackScrollLayout, 5)
+ .findMagneticTargets(
+ viewSwiped = swiped,
+ stackScrollLayout = stackScrollLayout,
+ sectionsManager,
+ totalMagneticTargets = 5,
+ )
assertMagneticTargetsForChildren(actual, children.attachedChildren)
}
@@ -123,7 +129,12 @@
// to the left
val actual =
notificationTargetsHelper()
- .findMagneticTargets(viewSwiped = swiped, stackScrollLayout = stackScrollLayout, 5)
+ .findMagneticTargets(
+ viewSwiped = swiped,
+ stackScrollLayout = stackScrollLayout,
+ sectionsManager,
+ totalMagneticTargets = 5,
+ )
val expectedRows =
listOf(null, null, swiped, children.attachedChildren[1], children.attachedChildren[2])
assertMagneticTargetsForChildren(actual, expectedRows)
@@ -141,7 +152,12 @@
// to the right
val actual =
notificationTargetsHelper()
- .findMagneticTargets(viewSwiped = swiped, stackScrollLayout = stackScrollLayout, 5)
+ .findMagneticTargets(
+ viewSwiped = swiped,
+ stackScrollLayout = stackScrollLayout,
+ sectionsManager,
+ totalMagneticTargets = 5,
+ )
val expectedRows =
listOf(
children.attachedChildren[childrenNumber - 3],
@@ -153,6 +169,54 @@
assertMagneticTargetsForChildren(actual, expectedRows)
}
+ @Test
+ fun findMagneticTargets_doesNotCrossSectionAtTop() {
+ val childrenNumber = 5
+ val children = notificationTestHelper.createGroup(childrenNumber).childrenContainer
+
+ // WHEN the second child is swiped and the first one begins a new section
+ val swiped = children.attachedChildren[1]
+ whenever(sectionsManager.beginsSection(swiped, children.attachedChildren[0])).then { true }
+
+ // THEN the neighboring views become targets, with the swiped view at the middle and nulls
+ // to the left since the top view relative to swiped begins a new section
+ val actual =
+ notificationTargetsHelper()
+ .findMagneticTargets(
+ viewSwiped = swiped,
+ stackScrollLayout = stackScrollLayout,
+ sectionsManager,
+ totalMagneticTargets = 5,
+ )
+ val expectedRows =
+ listOf(null, null, swiped, children.attachedChildren[2], children.attachedChildren[3])
+ assertMagneticTargetsForChildren(actual, expectedRows)
+ }
+
+ @Test
+ fun findMagneticTargets_doesNotCrossSectionAtBottom() {
+ val childrenNumber = 5
+ val children = notificationTestHelper.createGroup(childrenNumber).childrenContainer
+
+ // WHEN the fourth child is swiped and the last one begins a new section
+ val swiped = children.attachedChildren[3]
+ whenever(sectionsManager.beginsSection(children.attachedChildren[4], swiped)).then { true }
+
+ // THEN the neighboring views become targets, with the swiped view at the middle and nulls
+ // to the right since the bottom view relative to swiped begins a new section
+ val actual =
+ notificationTargetsHelper()
+ .findMagneticTargets(
+ viewSwiped = swiped,
+ stackScrollLayout = stackScrollLayout,
+ sectionsManager,
+ totalMagneticTargets = 5,
+ )
+ val expectedRows =
+ listOf(children.attachedChildren[1], children.attachedChildren[2], swiped, null, null)
+ assertMagneticTargetsForChildren(actual, expectedRows)
+ }
+
private fun assertMagneticTargetsForChildren(
targets: List<MagneticRowListener?>,
children: List<ExpandableNotificationRow?>,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackStateAnimatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackStateAnimatorTest.kt
index e4dd29a..67415de 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackStateAnimatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackStateAnimatorTest.kt
@@ -81,7 +81,7 @@
stackStateAnimator.startAnimationForEvents(arrayListOf(event), 0)
- verify(view).setActualHeight(VIEW_HEIGHT, false)
+ verify(view).setFinalActualHeight(VIEW_HEIGHT)
verify(view, description("should animate from the top")).translationY = expectedStartY
verify(view)
.performAddAnimation(
@@ -104,7 +104,7 @@
stackStateAnimator.startAnimationForEvents(arrayListOf(event), 0)
- verify(view).setActualHeight(VIEW_HEIGHT, false)
+ verify(view).setFinalActualHeight(VIEW_HEIGHT)
verify(view, description("should animate from the bottom")).translationY = expectedStartY
verify(view)
.performAddAnimation(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ViewStateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ViewStateTest.kt
index e493420..ef415c9 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ViewStateTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ViewStateTest.kt
@@ -16,21 +16,28 @@
package com.android.systemui.statusbar.notification.stack
+import android.animation.ValueAnimator
+import android.view.View
+import androidx.test.annotation.UiThreadTest
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.log.assertDoesNotLogWtf
import com.android.systemui.log.assertLogsWtf
-import kotlin.math.log2
-import kotlin.math.sqrt
+import com.android.systemui.statusbar.notification.PhysicsPropertyAnimator
+import com.android.systemui.statusbar.notification.PhysicsPropertyAnimator.Companion.TAG_ANIMATOR_TRANSLATION_Y
+import com.android.systemui.statusbar.notification.PhysicsPropertyAnimator.Companion.Y_TRANSLATION
import org.junit.Assert
import org.junit.Test
import org.junit.runner.RunWith
+import kotlin.math.log2
+import kotlin.math.sqrt
@RunWith(AndroidJUnit4::class)
@SmallTest
+@UiThreadTest
class ViewStateTest : SysuiTestCase() {
- private val viewState = ViewState()
+ private val viewState = ViewState(true /* usePhysicsForMovement */)
@Suppress("DIVISION_BY_ZERO")
@Test
@@ -64,4 +71,37 @@
assertLogsWtf { viewState.scaleY = Float.POSITIVE_INFINITY * 0 }
Assert.assertEquals(viewState.scaleY, 0.25f)
}
+
+ @Test
+ fun testUsingPhysics() {
+ val animatedView = View(context)
+ viewState.setUsePhysicsForMovement(true)
+ viewState.applyToView(animatedView)
+ viewState.yTranslation = 100f
+ val animationFilter = AnimationFilter().animateY()
+ val animationProperties = object : AnimationProperties() {
+ override fun getAnimationFilter(): AnimationFilter {
+ return animationFilter
+ }
+ }
+ viewState.animateTo(animatedView, animationProperties)
+ Assert.assertTrue(PhysicsPropertyAnimator.isAnimating(animatedView, Y_TRANSLATION))
+ }
+
+ @Test
+ fun testNotUsingPhysics() {
+ val animatedView = View(context)
+ viewState.setUsePhysicsForMovement(false)
+ viewState.applyToView(animatedView)
+ viewState.yTranslation = 100f
+ val animationFilter = AnimationFilter().animateY()
+ val animationProperties = object : AnimationProperties() {
+ override fun getAnimationFilter(): AnimationFilter {
+ return animationFilter
+ }
+ }
+ viewState.animateTo(animatedView, animationProperties)
+ val tag = animatedView.getTag(TAG_ANIMATOR_TRANSLATION_Y)
+ Assert.assertTrue(tag is ValueAnimator)
+ }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java
index 8ec17da..345ddae 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java
@@ -46,9 +46,11 @@
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.collection.NotificationEntry.NotifEntryAdapter;
import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.NotificationContentView;
+import com.android.systemui.statusbar.notification.shared.NotificationBundleUi;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.concurrency.FakeExecutor;
@@ -133,9 +135,11 @@
final ExpandableNotificationRow enr = mock(ExpandableNotificationRow.class);
final NotificationContentView privateLayout = mock(NotificationContentView.class);
final NotificationEntry enrEntry = mock(NotificationEntry.class);
+ final NotifEntryAdapter enrEntryAdapter = mock(NotifEntryAdapter.class);
when(enr.getPrivateLayout()).thenReturn(privateLayout);
when(enr.getEntry()).thenReturn(enrEntry);
+ when(enr.getEntryAdapter()).thenReturn(enrEntryAdapter);
when(enr.isChildInGroup()).thenReturn(true);
when(enr.areChildrenExpanded()).thenReturn(false);
@@ -144,7 +148,11 @@
enr, mock(View.class), false, onExpandedVisibleRunner);
// THEN
- verify(mGroupExpansionManager).toggleGroupExpansion(enrEntry);
+ if (NotificationBundleUi.isEnabled()) {
+ verify(mGroupExpansionManager).toggleGroupExpansion(enrEntryAdapter);
+ } else {
+ verify(mGroupExpansionManager).toggleGroupExpansion(enrEntry);
+ }
verify(enr).setUserExpanded(true);
verify(privateLayout).setOnExpandedVisibleListener(onExpandedVisibleRunner);
}
@@ -169,7 +177,8 @@
enr, mock(View.class), false, onExpandedVisibleRunner);
// THEN
- verify(mGroupExpansionManager, never()).toggleGroupExpansion(any());
+ verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotificationEntry.class));
+ verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotifEntryAdapter.class));
verify(enr).setUserExpanded(true);
verify(privateLayout).setOnExpandedVisibleListener(onExpandedVisibleRunner);
}
@@ -193,7 +202,8 @@
enr, mock(View.class), false, onExpandedVisibleRunner);
// THEN
- verify(mGroupExpansionManager, never()).toggleGroupExpansion(any());
+ verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotificationEntry.class));
+ verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotifEntryAdapter.class));
verify(enr).setUserExpanded(true);
verify(privateLayout).setOnExpandedVisibleListener(onExpandedVisibleRunner);
}
@@ -207,9 +217,11 @@
final ExpandableNotificationRow enr = mock(ExpandableNotificationRow.class);
final NotificationContentView privateLayout = mock(NotificationContentView.class);
final NotificationEntry enrEntry = mock(NotificationEntry.class);
+ final NotifEntryAdapter enrEntryAdapter = mock(NotifEntryAdapter.class);
when(enr.getPrivateLayout()).thenReturn(privateLayout);
when(enr.getEntry()).thenReturn(enrEntry);
+ when(enr.getEntryAdapter()).thenReturn(enrEntryAdapter);
when(enr.isChildInGroup()).thenReturn(true);
when(enr.areChildrenExpanded()).thenReturn(false);
@@ -218,7 +230,11 @@
enr, mock(View.class), false, onExpandedVisibleRunner);
// THEN
- verify(mGroupExpansionManager).toggleGroupExpansion(enrEntry);
+ if (NotificationBundleUi.isEnabled()) {
+ verify(mGroupExpansionManager).toggleGroupExpansion(enrEntryAdapter);
+ } else {
+ verify(mGroupExpansionManager).toggleGroupExpansion(enrEntry);
+ }
verify(enr, never()).setUserExpanded(anyBoolean());
verify(privateLayout, never()).setOnExpandedVisibleListener(any());
}
@@ -244,6 +260,7 @@
// THEN
verify(mGroupExpansionManager, never()).toggleGroupExpansion(enrEntry);
+ verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotifEntryAdapter.class));
verify(enr, never()).setUserExpanded(anyBoolean());
verify(privateLayout, never()).setOnExpandedVisibleListener(any());
}
@@ -272,7 +289,8 @@
verify(enr).toggleExpansionState();
verify(privateLayout).setOnExpandedVisibleListener(onExpandedVisibleRunner);
verify(enr, never()).setUserExpanded(anyBoolean());
- verify(mGroupExpansionManager, never()).toggleGroupExpansion(any());
+ verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotificationEntry.class));
+ verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotifEntryAdapter.class));
}
@Test
@@ -299,7 +317,8 @@
verify(enr, never()).toggleExpansionState();
verify(privateLayout, never()).setOnExpandedVisibleListener(onExpandedVisibleRunner);
verify(enr, never()).setUserExpanded(anyBoolean());
- verify(mGroupExpansionManager, never()).toggleGroupExpansion(any());
+ verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotificationEntry.class));
+ verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotifEntryAdapter.class));
}
@Test
@@ -326,7 +345,8 @@
verify(enr).toggleExpansionState();
verify(privateLayout).setOnExpandedVisibleListener(onExpandedVisibleRunner);
verify(enr, never()).setUserExpanded(anyBoolean());
- verify(mGroupExpansionManager, never()).toggleGroupExpansion(any());
+ verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotificationEntry.class));
+ verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotifEntryAdapter.class));
}
@Test
@@ -353,6 +373,7 @@
verify(enr, never()).toggleExpansionState();
verify(privateLayout, never()).setOnExpandedVisibleListener(onExpandedVisibleRunner);
verify(enr, never()).setUserExpanded(anyBoolean());
- verify(mGroupExpansionManager, never()).toggleGroupExpansion(any());
+ verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotificationEntry.class));
+ verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotifEntryAdapter.class));
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractorTest.kt
index c48287c..9d17348 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractorTest.kt
@@ -29,6 +29,7 @@
import com.android.systemui.kosmos.runTest
import com.android.systemui.kosmos.useUnconfinedTestDispatcher
import com.android.systemui.statusbar.StatusBarIconView
+import com.android.systemui.statusbar.core.StatusBarRootModernization
import com.android.systemui.statusbar.data.repository.fakeStatusBarModeRepository
import com.android.systemui.statusbar.gesture.swipeStatusBarAwayGestureHandler
import com.android.systemui.statusbar.notification.data.repository.activeNotificationListRepository
@@ -51,7 +52,7 @@
@SmallTest
@RunWith(AndroidJUnit4::class)
-@EnableFlags(StatusBarChipsModernization.FLAG_NAME)
+@EnableFlags(StatusBarChipsModernization.FLAG_NAME, StatusBarRootModernization.FLAG_NAME)
class OngoingCallInteractorTest : SysuiTestCase() {
private val kosmos = Kosmos().useUnconfinedTestDispatcher()
private val repository = kosmos.activeNotificationListRepository
@@ -69,18 +70,19 @@
}
@Test
- fun ongoingCallNotification_setsAllFields() =
+ fun ongoingCallNotification_setsAllFields_withAppHidden() =
kosmos.runTest {
val latest by collectLastValue(underTest.ongoingCallState)
// Set up notification with icon view and intent
+ val key = "promotedCall"
+ val startTimeMs = 1000L
val testIconView: StatusBarIconView = mock()
val testIntent: PendingIntent = mock()
- val testPromotedContent =
- PromotedNotificationContentModel.Builder("promotedCall").build()
+ val testPromotedContent = PromotedNotificationContentModel.Builder(key).build()
addOngoingCallState(
- key = "promotedCall",
- startTimeMs = 1000L,
+ key = key,
+ startTimeMs = startTimeMs,
statusBarChipIconView = testIconView,
contentIntent = testIntent,
promotedContent = testPromotedContent,
@@ -89,8 +91,41 @@
// Verify model is InCall and has the correct icon, intent, and promoted content.
assertThat(latest).isInstanceOf(OngoingCallModel.InCall::class.java)
val model = latest as OngoingCallModel.InCall
+ assertThat(model.startTimeMs).isEqualTo(startTimeMs)
assertThat(model.notificationIconView).isSameInstanceAs(testIconView)
assertThat(model.intent).isSameInstanceAs(testIntent)
+ assertThat(model.notificationKey).isEqualTo(key)
+ assertThat(model.promotedContent).isSameInstanceAs(testPromotedContent)
+ }
+
+ @Test
+ fun ongoingCallNotification_setsAllFields_withAppVisible() =
+ kosmos.runTest {
+ kosmos.activityManagerRepository.fake.startingIsAppVisibleValue = true
+ val latest by collectLastValue(underTest.ongoingCallState)
+
+ // Set up notification with icon view and intent
+ val key = "promotedCall"
+ val startTimeMs = 1000L
+ val testIconView: StatusBarIconView = mock()
+ val testIntent: PendingIntent = mock()
+ val testPromotedContent = PromotedNotificationContentModel.Builder(key).build()
+ addOngoingCallState(
+ key = key,
+ startTimeMs = startTimeMs,
+ statusBarChipIconView = testIconView,
+ contentIntent = testIntent,
+ promotedContent = testPromotedContent,
+ )
+
+ // Verify model is InCallWithVisibleApp and has the correct icon, intent, and promoted
+ // content.
+ assertThat(latest).isInstanceOf(OngoingCallModel.InCallWithVisibleApp::class.java)
+ val model = latest as OngoingCallModel.InCallWithVisibleApp
+ assertThat(model.startTimeMs).isEqualTo(startTimeMs)
+ assertThat(model.notificationIconView).isSameInstanceAs(testIconView)
+ assertThat(model.intent).isSameInstanceAs(testIntent)
+ assertThat(model.notificationKey).isEqualTo(key)
assertThat(model.promotedContent).isSameInstanceAs(testPromotedContent)
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt
index 4009144..8c70da7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt
@@ -719,7 +719,6 @@
job.cancel()
}
- @EnableFlags(com.android.internal.telephony.flags.Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
@Test
fun satBasedIcon_isUsedWhenNonTerrestrial() =
testScope.runTest {
@@ -733,7 +732,6 @@
assertThat(latest).isInstanceOf(SignalIconModel.Satellite::class.java)
}
- @EnableFlags(com.android.internal.telephony.flags.Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
@DisableFlags(com.android.internal.telephony.flags.Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
@Test
// See b/346904529 for more context
@@ -756,10 +754,7 @@
assertThat(latest!!.level).isEqualTo(4)
}
- @EnableFlags(
- com.android.internal.telephony.flags.Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG,
- com.android.internal.telephony.flags.Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN,
- )
+ @EnableFlags(com.android.internal.telephony.flags.Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
@Test
// See b/346904529 for more context
fun satBasedIcon_doesNotInflateSignalStrength_flagOn() =
@@ -781,7 +776,6 @@
assertThat(latest!!.level).isEqualTo(4)
}
- @EnableFlags(com.android.internal.telephony.flags.Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
@DisableFlags(com.android.internal.telephony.flags.Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
@Test
fun satBasedIcon_usesPrimaryLevel_flagOff() =
@@ -799,10 +793,7 @@
assertThat(latest!!.level).isEqualTo(4)
}
- @EnableFlags(
- com.android.internal.telephony.flags.Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG,
- com.android.internal.telephony.flags.Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN,
- )
+ @EnableFlags(com.android.internal.telephony.flags.Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
@Test
fun satBasedIcon_usesSatelliteLevel_flagOn() =
testScope.runTest {
@@ -823,7 +814,6 @@
* Context (b/377518113), this test will not be needed after FLAG_CARRIER_ROAMING_NB_IOT_NTN is
* rolled out. The new API should report 0 automatically if not in service.
*/
- @EnableFlags(com.android.internal.telephony.flags.Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
@DisableFlags(com.android.internal.telephony.flags.Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
@Test
fun satBasedIcon_reportsLevelZeroWhenOutOfService() =
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt
index 61ed04c..8ea888e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt
@@ -856,7 +856,6 @@
.isEqualTo(Icon.Resource(R.drawable.mobile_network_type_background, null))
}
- @EnableFlags(com.android.internal.telephony.flags.Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
@Test
fun nonTerrestrial_defaultProperties() =
testScope.runTest {
@@ -877,7 +876,6 @@
assertThat(activityContainerVisible).isFalse()
}
- @EnableFlags(com.android.internal.telephony.flags.Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
@Test
fun nonTerrestrial_ignoresDefaultProperties() =
testScope.runTest {
@@ -905,7 +903,6 @@
assertThat(activityContainerVisible).isFalse()
}
- @EnableFlags(com.android.internal.telephony.flags.Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
@DisableFlags(com.android.internal.telephony.flags.Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
@Test
fun nonTerrestrial_usesSatelliteIcon_flagOff() =
@@ -940,10 +937,7 @@
assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_2)
}
- @EnableFlags(
- com.android.internal.telephony.flags.Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG,
- com.android.internal.telephony.flags.Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN,
- )
+ @EnableFlags(com.android.internal.telephony.flags.Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
@Test
fun nonTerrestrial_usesSatelliteIcon_flagOn() =
testScope.runTest {
@@ -972,7 +966,6 @@
assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_2)
}
- @EnableFlags(com.android.internal.telephony.flags.Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
@DisableFlags(com.android.internal.telephony.flags.Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
@Test
fun satelliteIcon_ignoresInflateSignalStrength_flagOff() =
@@ -1010,10 +1003,7 @@
assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_2)
}
- @EnableFlags(
- com.android.internal.telephony.flags.Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG,
- com.android.internal.telephony.flags.Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN,
- )
+ @EnableFlags(com.android.internal.telephony.flags.Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
@Test
fun satelliteIcon_ignoresInflateSignalStrength_flagOn() =
testScope.runTest {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt
index 183cd8f..eb961bd 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt
@@ -57,7 +57,7 @@
override val ongoingActivityChipsLegacy =
MutableStateFlow(MultipleOngoingActivityChipsModelLegacy())
- override val statusBarPopupChips = MutableStateFlow(emptyList<PopupChipModel.Shown>())
+ override val popupChips = emptyList<PopupChipModel.Shown>()
override val mediaProjectionStopDialogDueToCallEndedState =
MutableStateFlow(MediaProjectionStopDialogModel.Hidden)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerFlagDisabledTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerFlagDisabledTest.kt
index 799e957..bab5a2d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerFlagDisabledTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerFlagDisabledTest.kt
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.policy
import android.app.IActivityManager
+import android.app.role.RoleManager
import android.content.pm.PackageManager
import android.media.projection.MediaProjectionManager
import android.os.Handler
@@ -48,6 +49,7 @@
@Mock private lateinit var mediaProjectionManager: MediaProjectionManager
@Mock private lateinit var packageManager: PackageManager
@Mock private lateinit var telephonyManager: TelephonyManager
+ @Mock private lateinit var roleManager: RoleManager
private lateinit var controller: SensitiveNotificationProtectionControllerImpl
@Before
@@ -62,9 +64,10 @@
activityManager,
packageManager,
telephonyManager,
+ roleManager,
handler,
FakeExecutor(FakeSystemClock()),
- logger
+ logger,
)
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/theme/HardwareColorRule.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/theme/HardwareColorRule.java
new file mode 100644
index 0000000..ecd04a4
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/theme/HardwareColorRule.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2025 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.theme;
+
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+
+public class HardwareColorRule implements TestRule {
+ public String color = "";
+ public String[] options = {};
+ public boolean isTesting = false;
+
+ @Override
+ public Statement apply(Statement base, Description description) {
+ HardwareColors hardwareColors = description.getAnnotation(HardwareColors.class);
+ if (hardwareColors != null) {
+ color = hardwareColors.color();
+ options = hardwareColors.options();
+ isTesting = true;
+ }
+ return base;
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/theme/HardwareColors.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/theme/HardwareColors.java
new file mode 100644
index 0000000..0b8df2e
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/theme/HardwareColors.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2025 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.theme;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface HardwareColors {
+ String color();
+ String[] options();
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java
index 5cd0846..9a0b812 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java
@@ -64,6 +64,7 @@
import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags;
+import com.android.systemui.flags.SystemPropertiesHelper;
import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
import com.android.systemui.monet.DynamicColors;
@@ -77,6 +78,7 @@
import com.google.common.util.concurrent.MoreExecutors;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -98,6 +100,9 @@
private static final UserHandle MANAGED_USER_HANDLE = UserHandle.of(100);
private static final UserHandle PRIVATE_USER_HANDLE = UserHandle.of(101);
+ @Rule
+ public HardwareColorRule rule = new HardwareColorRule();
+
@Mock
private JavaAdapter mJavaAdapter;
@Mock
@@ -148,13 +153,17 @@
@Captor
private ArgumentCaptor<ContentObserver> mSettingsObserver;
+ @Mock
+ private SystemPropertiesHelper mSystemProperties;
+
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
+
when(mFeatureFlags.isEnabled(Flags.MONET)).thenReturn(true);
when(mWakefulnessLifecycle.getWakefulness()).thenReturn(WAKEFULNESS_AWAKE);
when(mUiModeManager.getContrast()).thenReturn(0.5f);
- when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(true);
+
when(mResources.getColor(eq(android.R.color.system_accent1_500), any()))
.thenReturn(Color.RED);
when(mResources.getColor(eq(android.R.color.system_accent2_500), any()))
@@ -166,11 +175,20 @@
when(mResources.getColor(eq(android.R.color.system_neutral2_500), any()))
.thenReturn(Color.BLACK);
+ when(mResources.getStringArray(com.android.internal.R.array.theming_defaults))
+ .thenReturn(rule.options);
+
+ // should fallback to `*|TONAL_SPOT|home_wallpaper`
+ when(mSystemProperties.get("ro.boot.hardware.color")).thenReturn(rule.color);
+ // will try set hardware colors as boot ONLY if user is not set yet
+ when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(!rule.isTesting);
+
mThemeOverlayController = new ThemeOverlayController(mContext,
mBroadcastDispatcher, mBgHandler, mMainExecutor, mBgExecutor, mThemeOverlayApplier,
mSecureSettings, mWallpaperManager, mUserManager, mDeviceProvisionedController,
mUserTracker, mDumpManager, mFeatureFlags, mResources, mWakefulnessLifecycle,
- mJavaAdapter, mKeyguardTransitionInteractor, mUiModeManager, mActivityManager) {
+ mJavaAdapter, mKeyguardTransitionInteractor, mUiModeManager, mActivityManager,
+ mSystemProperties) {
@VisibleForTesting
protected boolean isNightMode() {
return false;
@@ -214,12 +232,59 @@
public void start_checksWallpaper() {
ArgumentCaptor<Runnable> registrationRunnable = ArgumentCaptor.forClass(Runnable.class);
verify(mBgExecutor).execute(registrationRunnable.capture());
-
registrationRunnable.getValue().run();
verify(mWallpaperManager).getWallpaperColors(eq(WallpaperManager.FLAG_SYSTEM));
}
@Test
+ @HardwareColors(color = "BLK", options = {
+ "BLK|MONOCHROMATIC|#FF0000",
+ "*|VIBRANT|home_wallpaper"
+ })
+ @EnableFlags(com.android.systemui.Flags.FLAG_HARDWARE_COLOR_STYLES)
+ public void start_checkHardwareColor() {
+ // getWallpaperColors should not be called
+ ArgumentCaptor<Runnable> registrationRunnable = ArgumentCaptor.forClass(Runnable.class);
+ verify(mMainExecutor).execute(registrationRunnable.capture());
+ registrationRunnable.getValue().run();
+ verify(mWallpaperManager, never()).getWallpaperColors(anyInt());
+
+ assertThat(mThemeOverlayController.mThemeStyle).isEqualTo(Style.MONOCHROMATIC);
+ assertThat(mThemeOverlayController.mCurrentColors.get(0).getMainColors().get(
+ 0).toArgb()).isEqualTo(Color.RED);
+ }
+
+ @Test
+ @HardwareColors(color = "", options = {
+ "BLK|MONOCHROMATIC|#FF0000",
+ "*|VIBRANT|home_wallpaper"
+ })
+ @EnableFlags(com.android.systemui.Flags.FLAG_HARDWARE_COLOR_STYLES)
+ public void start_wildcardColor() {
+ // getWallpaperColors will be called because we srt wildcard to `home_wallpaper`
+ ArgumentCaptor<Runnable> registrationRunnable = ArgumentCaptor.forClass(Runnable.class);
+ verify(mMainExecutor).execute(registrationRunnable.capture());
+ registrationRunnable.getValue().run();
+ verify(mWallpaperManager).getWallpaperColors(eq(WallpaperManager.FLAG_SYSTEM));
+
+ assertThat(mThemeOverlayController.mThemeStyle).isEqualTo(Style.VIBRANT);
+ }
+
+ @Test
+ @HardwareColors(color = "NONEXISTENT", options = {})
+ @EnableFlags(com.android.systemui.Flags.FLAG_HARDWARE_COLOR_STYLES)
+ public void start_fallbackColor() {
+ // getWallpaperColors will be called because we default color source is `home_wallpaper`
+ ArgumentCaptor<Runnable> registrationRunnable = ArgumentCaptor.forClass(Runnable.class);
+ verify(mMainExecutor).execute(registrationRunnable.capture());
+ registrationRunnable.getValue().run();
+ verify(mWallpaperManager).getWallpaperColors(eq(WallpaperManager.FLAG_SYSTEM));
+
+ assertThat(mThemeOverlayController.mThemeStyle).isEqualTo(Style.TONAL_SPOT);
+ }
+
+
+ @Test
public void onWallpaperColorsChanged_setsTheme_whenForeground() {
// Should ask for a new theme when wallpaper colors change
WallpaperColors mainColors = new WallpaperColors(Color.valueOf(Color.RED),
@@ -287,9 +352,9 @@
WallpaperColors mainColors = new WallpaperColors(Color.valueOf(Color.RED),
Color.valueOf(Color.BLUE), null);
- String jsonString =
- "{\"android.theme.customization.system_palette\":\"override.package.name\","
- + "\"android.theme.customization.color_source\":\"preset\"}";
+ String jsonString = createJsonString(TestColorSource.preset, "override.package.name",
+ "TONAL_SPOT");
+
when(mSecureSettings.getStringForUser(
eq(Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES), anyInt()))
.thenReturn(jsonString);
@@ -313,11 +378,7 @@
WallpaperColors mainColors = new WallpaperColors(Color.valueOf(Color.RED),
Color.valueOf(Color.BLUE), null);
- String jsonString =
- "{\"android.theme.customization.color_source\":\"home_wallpaper\","
- + "\"android.theme.customization.system_palette\":\"A16B00\","
- + "\"android.theme.customization.accent_color\":\"A16B00\","
- + "\"android.theme.customization.color_index\":\"2\"}";
+ String jsonString = createJsonString(TestColorSource.home_wallpaper);
when(mSecureSettings.getStringForUser(
eq(Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES), anyInt()))
@@ -348,11 +409,7 @@
WallpaperColors mainColors = new WallpaperColors(Color.valueOf(Color.RED),
Color.valueOf(Color.BLUE), null);
- String jsonString =
- "{\"android.theme.customization.color_source\":\"home_wallpaper\","
- + "\"android.theme.customization.system_palette\":\"A16B00\","
- + "\"android.theme.customization.accent_color\":\"A16B00\","
- + "\"android.theme.customization.color_index\":\"2\"}";
+ String jsonString = createJsonString(TestColorSource.home_wallpaper);
when(mSecureSettings.getStringForUser(
eq(Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES), anyInt()))
@@ -381,11 +438,7 @@
// Should ask for a new theme when wallpaper colors change
WallpaperColors mainColors = new WallpaperColors(Color.valueOf(Color.RED),
Color.valueOf(Color.BLUE), null);
- String jsonString =
- "{\"android.theme.customization.color_source\":\"lock_wallpaper\","
- + "\"android.theme.customization.system_palette\":\"A16B00\","
- + "\"android.theme.customization.accent_color\":\"A16B00\","
- + "\"android.theme.customization.color_index\":\"2\"}";
+ String jsonString = createJsonString(TestColorSource.lock_wallpaper);
when(mSecureSettings.getStringForUser(
eq(Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES), anyInt()))
.thenReturn(jsonString);
@@ -404,11 +457,7 @@
// Should ask for a new theme when wallpaper colors change
WallpaperColors mainColors = new WallpaperColors(Color.valueOf(Color.RED),
Color.valueOf(Color.BLUE), null);
- String jsonString =
- "{\"android.theme.customization.color_source\":\"lock_wallpaper\","
- + "\"android.theme.customization.system_palette\":\"A16B00\","
- + "\"android.theme.customization.accent_color\":\"A16B00\","
- + "\"android.theme.customization.color_index\":\"2\"}";
+ String jsonString = createJsonString(TestColorSource.lock_wallpaper);
when(mSecureSettings.getStringForUser(
eq(Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES), anyInt()))
.thenReturn(jsonString);
@@ -455,8 +504,8 @@
@Test
public void onSettingChanged_invalidStyle() {
when(mDeviceProvisionedController.isUserSetup(anyInt())).thenReturn(true);
- String jsonString = "{\"android.theme.customization.system_palette\":\"A16B00\","
- + "\"android.theme.customization.theme_style\":\"some_invalid_name\"}";
+ String jsonString = createJsonString(TestColorSource.home_wallpaper, "A16B00",
+ "some_invalid_name");
when(mSecureSettings.getStringForUser(
eq(Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES), anyInt()))
@@ -473,11 +522,7 @@
WallpaperColors mainColors = new WallpaperColors(Color.valueOf(Color.RED),
Color.valueOf(Color.BLUE), null);
- String jsonString =
- "{\"android.theme.customization.color_source\":\"home_wallpaper\","
- + "\"android.theme.customization.system_palette\":\"A16B00\","
- + "\"android.theme.customization.accent_color\":\"A16B00\","
- + "\"android.theme.customization.color_index\":\"2\"}";
+ String jsonString = createJsonString(TestColorSource.home_wallpaper);
when(mSecureSettings.getStringForUser(
eq(Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES), anyInt()))
@@ -506,11 +551,7 @@
// Should ask for a new theme when wallpaper colors change
WallpaperColors mainColors = new WallpaperColors(Color.valueOf(Color.RED),
Color.valueOf(Color.BLUE), null);
- String jsonString =
- "{\"android.theme.customization.color_source\":\"home_wallpaper\","
- + "\"android.theme.customization.system_palette\":\"A16B00\","
- + "\"android.theme.customization.accent_color\":\"A16B00\","
- + "\"android.theme.customization.color_index\":\"2\"}";
+ String jsonString = createJsonString(TestColorSource.home_wallpaper);
when(mSecureSettings.getStringForUser(
eq(Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES), anyInt()))
.thenReturn(jsonString);
@@ -537,11 +578,7 @@
// Should ask for a new theme when wallpaper colors change
WallpaperColors mainColors = new WallpaperColors(Color.valueOf(Color.RED),
Color.valueOf(Color.BLUE), null);
- String jsonString =
- "{\"android.theme.customization.color_source\":\"home_wallpaper\","
- + "\"android.theme.customization.system_palette\":\"A16B00\","
- + "\"android.theme.customization.accent_color\":\"A16B00\","
- + "\"android.theme.customization.color_index\":\"2\"}";
+ String jsonString = createJsonString(TestColorSource.home_wallpaper);
when(mSecureSettings.getStringForUser(
eq(Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES), anyInt()))
.thenReturn(jsonString);
@@ -570,11 +607,7 @@
WallpaperColors mainColors = new WallpaperColors(Color.valueOf(Color.RED),
Color.valueOf(Color.BLUE), null);
- String jsonString =
- "{\"android.theme.customization.color_source\":\"home_wallpaper\","
- + "\"android.theme.customization.system_palette\":\"A16B00\","
- + "\"android.theme.customization.accent_color\":\"A16B00\","
- + "\"android.theme.customization.color_index\":\"2\"}";
+ String jsonString = createJsonString(TestColorSource.home_wallpaper);
when(mSecureSettings.getStringForUser(
eq(Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES), anyInt()))
@@ -599,7 +632,6 @@
}
-
@Test
@EnableFlags(com.android.systemui.shared.Flags.FLAG_NEW_CUSTOMIZATION_PICKER_UI)
public void onWallpaperColorsChanged_homeWallpaperWithSameColor_shouldKeepThemeAndReapply() {
@@ -608,11 +640,7 @@
WallpaperColors mainColors = new WallpaperColors(Color.valueOf(Color.RED),
Color.valueOf(0xffa16b00), null);
- String jsonString =
- "{\"android.theme.customization.color_source\":\"home_wallpaper\","
- + "\"android.theme.customization.system_palette\":\"A16B00\","
- + "\"android.theme.customization.accent_color\":\"A16B00\","
- + "\"android.theme.customization.color_index\":\"2\"}";
+ String jsonString = createJsonString(TestColorSource.home_wallpaper);
when(mSecureSettings.getStringForUser(
eq(Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES), anyInt()))
@@ -642,11 +670,7 @@
WallpaperColors mainColors = new WallpaperColors(Color.valueOf(Color.RED),
Color.valueOf(Color.BLUE), null);
- String jsonString =
- "{\"android.theme.customization.color_source\":\"home_wallpaper\","
- + "\"android.theme.customization.system_palette\":\"A16B00\","
- + "\"android.theme.customization.accent_color\":\"A16B00\","
- + "\"android.theme.customization.color_index\":\"2\"}";
+ String jsonString = createJsonString(TestColorSource.home_wallpaper);
when(mSecureSettings.getStringForUser(
eq(Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES), anyInt()))
@@ -676,11 +700,7 @@
WallpaperColors mainColors = new WallpaperColors(Color.valueOf(Color.RED),
Color.valueOf(Color.BLUE), null);
- String jsonString =
- "{\"android.theme.customization.color_source\":\"home_wallpaper\","
- + "\"android.theme.customization.system_palette\":\"A16B00\","
- + "\"android.theme.customization.accent_color\":\"A16B00\","
- + "\"android.theme.customization.color_index\":\"2\"}";
+ String jsonString = createJsonString(TestColorSource.home_wallpaper);
when(mSecureSettings.getStringForUser(
eq(Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES), anyInt()))
@@ -711,11 +731,7 @@
WallpaperColors mainColors = new WallpaperColors(Color.valueOf(Color.RED),
Color.valueOf(0xffa16b00), null);
- String jsonString =
- "{\"android.theme.customization.color_source\":\"home_wallpaper\","
- + "\"android.theme.customization.system_palette\":\"A16B00\","
- + "\"android.theme.customization.accent_color\":\"A16B00\","
- + "\"android.theme.customization.color_index\":\"2\"}";
+ String jsonString = createJsonString(TestColorSource.home_wallpaper);
when(mSecureSettings.getStringForUser(
eq(Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES), anyInt()))
@@ -745,11 +761,7 @@
WallpaperColors mainColors = new WallpaperColors(Color.valueOf(Color.RED),
Color.valueOf(Color.BLUE), null);
- String jsonString =
- "{\"android.theme.customization.color_source\":\"home_wallpaper\","
- + "\"android.theme.customization.system_palette\":\"A16B00\","
- + "\"android.theme.customization.accent_color\":\"A16B00\","
- + "\"android.theme.customization.color_index\":\"2\"}";
+ String jsonString = createJsonString(TestColorSource.home_wallpaper);
when(mSecureSettings.getStringForUser(
eq(Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES), anyInt()))
@@ -886,7 +898,8 @@
mBroadcastDispatcher, mBgHandler, executor, executor, mThemeOverlayApplier,
mSecureSettings, mWallpaperManager, mUserManager, mDeviceProvisionedController,
mUserTracker, mDumpManager, mFeatureFlags, mResources, mWakefulnessLifecycle,
- mJavaAdapter, mKeyguardTransitionInteractor, mUiModeManager, mActivityManager) {
+ mJavaAdapter, mKeyguardTransitionInteractor, mUiModeManager, mActivityManager,
+ mSystemProperties) {
@VisibleForTesting
protected boolean isNightMode() {
return false;
@@ -926,7 +939,8 @@
mBroadcastDispatcher, mBgHandler, executor, executor, mThemeOverlayApplier,
mSecureSettings, mWallpaperManager, mUserManager, mDeviceProvisionedController,
mUserTracker, mDumpManager, mFeatureFlags, mResources, mWakefulnessLifecycle,
- mJavaAdapter, mKeyguardTransitionInteractor, mUiModeManager, mActivityManager) {
+ mJavaAdapter, mKeyguardTransitionInteractor, mUiModeManager, mActivityManager,
+ mSystemProperties) {
@VisibleForTesting
protected boolean isNightMode() {
return false;
@@ -992,7 +1006,7 @@
clearInvocations(mThemeOverlayApplier);
// Device went to sleep and second set of colors was applied.
- mainColors = new WallpaperColors(Color.valueOf(Color.BLUE),
+ mainColors = new WallpaperColors(Color.valueOf(Color.BLUE),
Color.valueOf(Color.RED), null);
mColorsListener.getValue().onColorsChanged(mainColors, WallpaperManager.FLAG_SYSTEM,
USER_SYSTEM);
@@ -1018,7 +1032,7 @@
clearInvocations(mThemeOverlayApplier);
// Device went to sleep and second set of colors was applied.
- mainColors = new WallpaperColors(Color.valueOf(Color.BLUE),
+ mainColors = new WallpaperColors(Color.valueOf(Color.BLUE),
Color.valueOf(Color.RED), null);
mColorsListener.getValue().onColorsChanged(mainColors, WallpaperManager.FLAG_SYSTEM,
USER_SYSTEM);
@@ -1034,8 +1048,9 @@
WallpaperColors mainColors = new WallpaperColors(Color.valueOf(Color.RED),
Color.valueOf(Color.BLUE), null);
- String jsonString =
- "{\"android.theme.customization.system_palette\":\"00FF00\"}";
+ String jsonString = createJsonString(TestColorSource.home_wallpaper, "00FF00",
+ "TONAL_SPOT");
+
when(mSecureSettings.getStringForUser(
eq(Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES), anyInt()))
.thenReturn(jsonString);
@@ -1115,4 +1130,25 @@
+ DynamicColors.getCustomColorsMapped(false).size() * 2)
).setResourceValue(any(String.class), eq(TYPE_INT_COLOR_ARGB8), anyInt(), eq(null));
}
+
+ private enum TestColorSource {
+ preset,
+ home_wallpaper,
+ lock_wallpaper
+ }
+
+ private String createJsonString(TestColorSource colorSource, String seedColorHex,
+ String style) {
+ return "{\"android.theme.customization.color_source\":\"" + colorSource.toString() + "\","
+ + "\"android.theme.customization.system_palette\":\"" + seedColorHex + "\","
+ + "\"android.theme.customization.accent_color\":\"" + seedColorHex + "\","
+ + "\"android.theme.customization.color_index\":\"2\","
+ + "\"android.theme.customization.theme_style\":\"" + style + "\"}";
+ }
+
+ private String createJsonString(TestColorSource colorSource) {
+ return createJsonString(colorSource, "A16B00", "TONAL_SPOT");
+ }
+
+
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/DisplaySwitchLatencyTrackerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/DisplaySwitchLatencyTrackerTest.kt
index 36e18e6..92bec70 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/DisplaySwitchLatencyTrackerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/DisplaySwitchLatencyTrackerTest.kt
@@ -173,15 +173,13 @@
runCurrent()
setDeviceState(UNFOLDED)
- verify(displaySwitchLatencyLogger).log(capture(loggerArgumentCaptor))
- val loggedEvent = loggerArgumentCaptor.value
val expectedLoggedEvent =
- DisplaySwitchLatencyEvent(
+ successfulEvent(
latencyMs = 250,
fromFoldableDeviceState = FOLDABLE_DEVICE_STATE_CLOSED,
toFoldableDeviceState = FOLDABLE_DEVICE_STATE_HALF_OPEN,
)
- assertThat(loggedEvent).isEqualTo(expectedLoggedEvent)
+ assertThat(capturedLogEvent()).isEqualTo(expectedLoggedEvent)
}
}
@@ -225,15 +223,13 @@
runCurrent()
setDeviceState(UNFOLDED)
- verify(displaySwitchLatencyLogger).log(capture(loggerArgumentCaptor))
- val loggedEvent = loggerArgumentCaptor.value
val expectedLoggedEvent =
- DisplaySwitchLatencyEvent(
+ successfulEvent(
latencyMs = 50,
fromFoldableDeviceState = FOLDABLE_DEVICE_STATE_CLOSED,
toFoldableDeviceState = FOLDABLE_DEVICE_STATE_HALF_OPEN,
)
- assertThat(loggedEvent).isEqualTo(expectedLoggedEvent)
+ assertThat(capturedLogEvent()).isEqualTo(expectedLoggedEvent)
}
}
@@ -258,15 +254,13 @@
runCurrent()
setDeviceState(UNFOLDED)
- verify(displaySwitchLatencyLogger).log(capture(loggerArgumentCaptor))
- val loggedEvent = loggerArgumentCaptor.value
val expectedLoggedEvent =
- DisplaySwitchLatencyEvent(
+ successfulEvent(
latencyMs = 50,
fromFoldableDeviceState = FOLDABLE_DEVICE_STATE_CLOSED,
toFoldableDeviceState = FOLDABLE_DEVICE_STATE_HALF_OPEN,
)
- assertThat(loggedEvent).isEqualTo(expectedLoggedEvent)
+ assertThat(capturedLogEvent()).isEqualTo(expectedLoggedEvent)
}
}
@@ -287,15 +281,13 @@
powerInteractor.setScreenPowerState(SCREEN_ON)
runCurrent()
- verify(displaySwitchLatencyLogger).log(capture(loggerArgumentCaptor))
- val loggedEvent = loggerArgumentCaptor.value
val expectedLoggedEvent =
- DisplaySwitchLatencyEvent(
+ successfulEvent(
latencyMs = 200,
fromFoldableDeviceState = FOLDABLE_DEVICE_STATE_HALF_OPEN,
toFoldableDeviceState = FOLDABLE_DEVICE_STATE_CLOSED,
)
- assertThat(loggedEvent).isEqualTo(expectedLoggedEvent)
+ assertThat(capturedLogEvent()).isEqualTo(expectedLoggedEvent)
}
}
@@ -317,16 +309,14 @@
powerInteractor.setScreenPowerState(SCREEN_ON)
runCurrent()
- verify(displaySwitchLatencyLogger).log(capture(loggerArgumentCaptor))
- val loggedEvent = loggerArgumentCaptor.value
val expectedLoggedEvent =
- DisplaySwitchLatencyEvent(
+ successfulEvent(
latencyMs = 200,
fromFoldableDeviceState = FOLDABLE_DEVICE_STATE_HALF_OPEN,
toFoldableDeviceState = FOLDABLE_DEVICE_STATE_CLOSED,
toState = SysUiStatsLog.DISPLAY_SWITCH_LATENCY_TRACKED__TO_STATE__AOD,
)
- assertThat(loggedEvent).isEqualTo(expectedLoggedEvent)
+ assertThat(capturedLogEvent()).isEqualTo(expectedLoggedEvent)
}
}
@@ -369,16 +359,14 @@
powerInteractor.setScreenPowerState(SCREEN_OFF)
runCurrent()
- verify(displaySwitchLatencyLogger).log(capture(loggerArgumentCaptor))
- val loggedEvent = loggerArgumentCaptor.value
val expectedLoggedEvent =
- DisplaySwitchLatencyEvent(
+ successfulEvent(
latencyMs = 0,
fromFoldableDeviceState = FOLDABLE_DEVICE_STATE_HALF_OPEN,
toFoldableDeviceState = FOLDABLE_DEVICE_STATE_CLOSED,
toState = SysUiStatsLog.DISPLAY_SWITCH_LATENCY_TRACKED__TO_STATE__SCREEN_OFF,
)
- assertThat(loggedEvent).isEqualTo(expectedLoggedEvent)
+ assertThat(capturedLogEvent()).isEqualTo(expectedLoggedEvent)
}
}
@@ -555,6 +543,23 @@
}
@Test
+ fun interruptedDisplaySwitchFinished_coolDownPassed_eventWithCorruptedResultSent() {
+ testScope.runTest {
+ startInFoldedState(displaySwitchLatencyTracker)
+
+ startUnfolding()
+ startFolding()
+ systemClock.advanceTime(5000) // clock for measuring latency
+ advanceTimeBy(COOL_DOWN_DURATION.plus(10.milliseconds)) // clock for triggering timeout
+
+ val event = capturedLogEvent()
+ assertThat(event.trackingResult)
+ .isEqualTo(SysUiStatsLog.DISPLAY_SWITCH_LATENCY_TRACKED__TRACKING_RESULT__CORRUPTED)
+ assertThat(event.latencyMs).isEqualTo(5000)
+ }
+ }
+
+ @Test
fun displaySwitchInterrupted_coolDownExtendedByStartEvents() {
testScope.runTest {
startInFoldedState(displaySwitchLatencyTracker)
@@ -605,6 +610,27 @@
}
@Test
+ fun displaySwitchTimedOut_eventLoggedWithTimeOut() {
+ testScope.runTest {
+ startInFoldedState(displaySwitchLatencyTracker)
+
+ startUnfolding()
+ advanceTimeBy(SCREEN_EVENT_TIMEOUT + 10.milliseconds)
+ finishUnfolding()
+
+ val event = capturedLogEvent()
+ assertThat(event.trackingResult)
+ .isEqualTo(SysUiStatsLog.DISPLAY_SWITCH_LATENCY_TRACKED__TRACKING_RESULT__TIMED_OUT)
+ assertThat(event.latencyMs).isEqualTo(SCREEN_EVENT_TIMEOUT.inWholeMilliseconds)
+ }
+ }
+
+ private fun capturedLogEvent(): DisplaySwitchLatencyEvent {
+ verify(displaySwitchLatencyLogger).log(capture(loggerArgumentCaptor))
+ return loggerArgumentCaptor.value
+ }
+
+ @Test
fun foldingStarted_screenStillOn_eventSentOnlyAfterScreenSwitches() {
// can happen for both folding and unfolding (with animations off) but it's more likely to
// happen when folding as waiting for screen on is the default case then
@@ -625,6 +651,21 @@
}
}
+ private fun successfulEvent(
+ latencyMs: Int,
+ fromFoldableDeviceState: Int,
+ toFoldableDeviceState: Int,
+ toState: Int = SysUiStatsLog.DISPLAY_SWITCH_LATENCY_TRACKED__FROM_STATE__UNKNOWN,
+ ): DisplaySwitchLatencyEvent {
+ return DisplaySwitchLatencyEvent(
+ latencyMs = latencyMs,
+ fromFoldableDeviceState = fromFoldableDeviceState,
+ toFoldableDeviceState = toFoldableDeviceState,
+ toState = toState,
+ trackingResult = SysUiStatsLog.DISPLAY_SWITCH_LATENCY_TRACKED__TRACKING_RESULT__SUCCESS,
+ )
+ }
+
private suspend fun TestScope.startInFoldedState(tracker: DisplaySwitchLatencyTracker) {
setDeviceState(FOLDED)
tracker.start()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/wallpapers/data/repository/WallpaperRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/wallpapers/data/repository/WallpaperRepositoryImplTest.kt
index 7c166de..cc6a7b9 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/wallpapers/data/repository/WallpaperRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/wallpapers/data/repository/WallpaperRepositoryImplTest.kt
@@ -42,7 +42,6 @@
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
-import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.any
@@ -53,7 +52,6 @@
@SmallTest
@RunWith(AndroidJUnit4::class)
class WallpaperRepositoryImplTest : SysuiTestCase() {
-
private var isWallpaperSupported = true
private val kosmos =
testKosmos().apply {
@@ -293,12 +291,9 @@
Intent(Intent.ACTION_WALLPAPER_CHANGED),
)
assertThat(latest).isTrue()
- assertThat(underTest.sendLockscreenLayoutJob).isNotNull()
- assertThat(underTest.sendLockscreenLayoutJob!!.isActive).isEqualTo(true)
}
@Test
- @Ignore("ag/31591766")
@EnableFlags(SharedFlags.FLAG_EXTENDED_WALLPAPER_EFFECTS)
fun shouldSendNotificationLayout_setNotExtendedEffectsWallpaper_cancelSendLayoutJob() =
testScope.runTest {
@@ -315,8 +310,6 @@
Intent(Intent.ACTION_WALLPAPER_CHANGED),
)
assertThat(latest).isTrue()
- assertThat(underTest.sendLockscreenLayoutJob).isNotNull()
- assertThat(underTest.sendLockscreenLayoutJob!!.isActive).isEqualTo(true)
whenever(kosmos.wallpaperManager.getWallpaperInfoForUser(any()))
.thenReturn(UNSUPPORTED_WP)
@@ -327,7 +320,6 @@
runCurrent()
assertThat(latest).isFalse()
- assertThat(underTest.sendLockscreenLayoutJob?.isCancelled).isEqualTo(true)
}
private companion object {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/wallpapers/domain/interactor/WallpaperFocalAreaInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/wallpapers/domain/interactor/WallpaperFocalAreaInteractorTest.kt
index 31afc29..31a611c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/wallpapers/domain/interactor/WallpaperFocalAreaInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/wallpapers/domain/interactor/WallpaperFocalAreaInteractorTest.kt
@@ -30,11 +30,8 @@
import com.android.systemui.res.R
import com.android.systemui.shade.data.repository.ShadeRepository
import com.android.systemui.shade.data.repository.shadeRepository
-import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor
import com.android.systemui.testKosmos
-import com.android.systemui.wallpapers.data.repository.fakeWallpaperFocalAreaRepository
import com.android.systemui.wallpapers.data.repository.wallpaperFocalAreaRepository
-import com.android.systemui.wallpapers.data.repository.wallpaperRepository
import com.android.systemui.wallpapers.ui.viewmodel.wallpaperFocalAreaViewModel
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -75,36 +72,22 @@
.thenReturn(2f)
underTest =
WallpaperFocalAreaInteractor(
- applicationScope = testScope.backgroundScope,
context = kosmos.mockedContext,
- wallpaperFocalAreaRepository = kosmos.fakeWallpaperFocalAreaRepository,
+ wallpaperFocalAreaRepository = kosmos.wallpaperFocalAreaRepository,
shadeRepository = kosmos.shadeRepository,
- activeNotificationsInteractor = kosmos.activeNotificationsInteractor,
- wallpaperRepository = kosmos.wallpaperRepository,
)
}
- private fun overrideMockedResources(overrideResources: OverrideResources) {
- val displayMetrics =
- DisplayMetrics().apply {
- widthPixels = overrideResources.screenWidth
- heightPixels = overrideResources.screenHeight
- density = 2f
- }
- whenever(mockedResources.displayMetrics).thenReturn(displayMetrics)
- whenever(mockedResources.getBoolean(R.bool.center_align_focal_area_shape))
- .thenReturn(overrideResources.centerAlignFocalArea)
- }
-
@Test
fun focalAreaBounds_withoutNotifications_inHandheldDevices() =
testScope.runTest {
overrideMockedResources(
+ mockedResources,
OverrideResources(
screenWidth = 1000,
screenHeight = 2000,
centerAlignFocalArea = false,
- )
+ ),
)
val bounds by collectLastValue(underTest.wallpaperFocalAreaBounds)
kosmos.shadeRepository.setShadeLayoutWide(false)
@@ -120,11 +103,12 @@
fun focalAreaBounds_withNotifications_inHandheldDevices() =
testScope.runTest {
overrideMockedResources(
+ mockedResources,
OverrideResources(
screenWidth = 1000,
screenHeight = 2000,
centerAlignFocalArea = false,
- )
+ ),
)
val bounds by collectLastValue(underTest.wallpaperFocalAreaBounds)
kosmos.shadeRepository.setShadeLayoutWide(false)
@@ -139,11 +123,12 @@
fun focalAreaBounds_inUnfoldLandscape() =
testScope.runTest {
overrideMockedResources(
+ mockedResources,
OverrideResources(
screenWidth = 2000,
screenHeight = 1600,
centerAlignFocalArea = false,
- )
+ ),
)
val bounds by collectLastValue(underTest.wallpaperFocalAreaBounds)
kosmos.shadeRepository.setShadeLayoutWide(true)
@@ -158,11 +143,12 @@
fun focalAreaBounds_withNotifications_inUnfoldPortrait() =
testScope.runTest {
overrideMockedResources(
+ mockedResources,
OverrideResources(
screenWidth = 1600,
screenHeight = 2000,
centerAlignFocalArea = false,
- )
+ ),
)
val bounds by collectLastValue(underTest.wallpaperFocalAreaBounds)
kosmos.shadeRepository.setShadeLayoutWide(false)
@@ -177,11 +163,12 @@
fun focalAreaBounds_withoutNotifications_inUnfoldPortrait() =
testScope.runTest {
overrideMockedResources(
+ mockedResources,
OverrideResources(
screenWidth = 1600,
screenHeight = 2000,
centerAlignFocalArea = false,
- )
+ ),
)
val bounds by collectLastValue(underTest.wallpaperFocalAreaBounds)
kosmos.shadeRepository.setShadeLayoutWide(false)
@@ -196,11 +183,12 @@
fun focalAreaBounds_inTabletLandscape() =
testScope.runTest {
overrideMockedResources(
+ mockedResources,
OverrideResources(
screenWidth = 3000,
screenHeight = 2000,
centerAlignFocalArea = true,
- )
+ ),
)
val bounds by collectLastValue(underTest.wallpaperFocalAreaBounds)
kosmos.shadeRepository.setShadeLayoutWide(true)
@@ -216,11 +204,12 @@
testScope.runTest {
kosmos.wallpaperFocalAreaRepository.setTapPosition(PointF(0F, 0F))
overrideMockedResources(
+ mockedResources,
OverrideResources(
screenWidth = 1000,
screenHeight = 2000,
centerAlignFocalArea = false,
- )
+ ),
)
kosmos.wallpaperFocalAreaRepository.setWallpaperFocalAreaBounds(
RectF(250f, 700F, 750F, 1400F)
@@ -240,11 +229,12 @@
testScope.runTest {
kosmos.wallpaperFocalAreaRepository.setTapPosition(PointF(0F, 0F))
overrideMockedResources(
+ mockedResources,
OverrideResources(
screenWidth = 1000,
screenHeight = 2000,
centerAlignFocalArea = false,
- )
+ ),
)
kosmos.wallpaperFocalAreaViewModel = mock()
kosmos.wallpaperFocalAreaRepository.setWallpaperFocalAreaBounds(
@@ -262,4 +252,21 @@
val screenHeight: Int,
val centerAlignFocalArea: Boolean,
)
+
+ companion object {
+ fun overrideMockedResources(
+ mockedResources: Resources,
+ overrideResources: OverrideResources,
+ ) {
+ val displayMetrics =
+ DisplayMetrics().apply {
+ widthPixels = overrideResources.screenWidth
+ heightPixels = overrideResources.screenHeight
+ density = 2f
+ }
+ whenever(mockedResources.displayMetrics).thenReturn(displayMetrics)
+ whenever(mockedResources.getBoolean(R.bool.center_align_focal_area_shape))
+ .thenReturn(overrideResources.centerAlignFocalArea)
+ }
+ }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/wallpapers/ui/viewmodel/WallpaperFocalAreaViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/wallpapers/ui/viewmodel/WallpaperFocalAreaViewModelTest.kt
new file mode 100644
index 0000000..3cd2072
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/wallpapers/ui/viewmodel/WallpaperFocalAreaViewModelTest.kt
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2025 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.wallpapers.ui.viewmodel
+
+import android.content.mockedContext
+import android.content.res.Resources
+import android.graphics.RectF
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
+import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN
+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.shade.data.repository.shadeRepository
+import com.android.systemui.statusbar.notification.data.repository.activeNotificationListRepository
+import com.android.systemui.statusbar.notification.data.repository.setActiveNotifs
+import com.android.systemui.testKosmos
+import com.android.systemui.wallpapers.data.repository.wallpaperFocalAreaRepository
+import com.android.systemui.wallpapers.domain.interactor.WallpaperFocalAreaInteractor
+import com.android.systemui.wallpapers.domain.interactor.WallpaperFocalAreaInteractorTest.Companion.overrideMockedResources
+import com.android.systemui.wallpapers.domain.interactor.WallpaperFocalAreaInteractorTest.OverrideResources
+import com.android.systemui.wallpapers.domain.interactor.wallpaperFocalAreaInteractor
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
+
+@ExperimentalCoroutinesApi
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class WallpaperFocalAreaViewModelTest : SysuiTestCase() {
+ private val kosmos = testKosmos()
+ private val testScope = kosmos.testScope
+ private lateinit var mockedResources: Resources
+ lateinit var underTest: WallpaperFocalAreaViewModel
+
+ @Before
+ fun setup() {
+ MockitoAnnotations.initMocks(this)
+ mockedResources = mock<Resources>()
+ overrideMockedResources(
+ mockedResources,
+ OverrideResources(screenWidth = 1000, screenHeight = 2000, centerAlignFocalArea = false),
+ )
+ whenever(kosmos.mockedContext.resources).thenReturn(mockedResources)
+ whenever(
+ mockedResources.getFloat(
+ Resources.getSystem()
+ .getIdentifier(
+ /* name= */ "config_wallpaperMaxScale",
+ /* defType= */ "dimen",
+ /* defPackage= */ "android",
+ )
+ )
+ )
+ .thenReturn(2f)
+ kosmos.wallpaperFocalAreaInteractor =
+ WallpaperFocalAreaInteractor(
+ context = kosmos.mockedContext,
+ wallpaperFocalAreaRepository = kosmos.wallpaperFocalAreaRepository,
+ shadeRepository = kosmos.shadeRepository,
+ )
+ underTest =
+ WallpaperFocalAreaViewModel(
+ wallpaperFocalAreaInteractor = kosmos.wallpaperFocalAreaInteractor,
+ keyguardTransitionInteractor = kosmos.keyguardTransitionInteractor,
+ )
+ }
+
+ @Test
+ fun focalAreaBoundsSent_whenFinishTransitioningToLockscreen() =
+ testScope.runTest {
+ overrideMockedResources(
+ mockedResources,
+ OverrideResources(
+ screenWidth = 1600,
+ screenHeight = 2000,
+ centerAlignFocalArea = false,
+ ),
+ )
+ val bounds by collectLastValue(underTest.wallpaperFocalAreaBounds)
+
+ kosmos.fakeKeyguardTransitionRepository.sendTransitionSteps(
+ listOf(
+ TransitionStep(transitionState = TransitionState.STARTED, to = LOCKSCREEN),
+ TransitionStep(transitionState = TransitionState.FINISHED, to = LOCKSCREEN),
+ ),
+ testScope,
+ )
+
+ setTestFocalAreaBounds()
+
+ assertThat(bounds).isEqualTo(RectF(400F, 510F, 1200F, 700F))
+ }
+
+ @Test
+ fun focalAreaBoundsNotSent_whenNotFinishTransitioningToLockscreen() =
+ testScope.runTest {
+ overrideMockedResources(
+ mockedResources,
+ OverrideResources(
+ screenWidth = 1600,
+ screenHeight = 2000,
+ centerAlignFocalArea = false,
+ ),
+ )
+ val bounds by collectLastValue(underTest.wallpaperFocalAreaBounds)
+
+ kosmos.fakeKeyguardTransitionRepository.sendTransitionSteps(
+ listOf(TransitionStep(transitionState = TransitionState.STARTED, to = LOCKSCREEN)),
+ testScope,
+ )
+ setTestFocalAreaBounds()
+
+ assertThat(bounds).isEqualTo(null)
+ }
+
+ private fun setTestFocalAreaBounds() {
+ kosmos.shadeRepository.setShadeLayoutWide(false)
+ kosmos.activeNotificationListRepository.setActiveNotifs(0)
+ kosmos.wallpaperFocalAreaRepository.setShortcutAbsoluteTop(400F)
+ kosmos.wallpaperFocalAreaRepository.setNotificationDefaultTop(20F)
+ kosmos.wallpaperFocalAreaRepository.setNotificationStackAbsoluteBottom(20F)
+ }
+}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockLogger.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockLogger.kt
index 9a83744..3ed321e 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockLogger.kt
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockLogger.kt
@@ -83,6 +83,13 @@
}
}
+ fun updateAxes(lsFVar: String, aodFVar: String) {
+ i({ "updateAxes(LS = $str1, AOD = $str2)" }) {
+ str1 = lsFVar
+ str2 = aodFVar
+ }
+ }
+
fun addView(child: View) {
d({ "addView($str1 @$int1)" }) {
str1 = child::class.simpleName!!
@@ -90,6 +97,14 @@
}
}
+ fun animateDoze() {
+ d("animateDoze()")
+ }
+
+ fun animateCharge() {
+ d("animateCharge()")
+ }
+
fun animateFidget(x: Float, y: Float) {
d({ "animateFidget($str1, $str2)" }) {
str1 = x.toString()
diff --git a/packages/SystemUI/res-keyguard/drawable/pin_bouncer_confirm.xml b/packages/SystemUI/res-keyguard/drawable/pin_bouncer_confirm.xml
index 61d6a904..a27e29f 100644
--- a/packages/SystemUI/res-keyguard/drawable/pin_bouncer_confirm.xml
+++ b/packages/SystemUI/res-keyguard/drawable/pin_bouncer_confirm.xml
@@ -19,12 +19,13 @@
android:height="40dp"
android:viewportHeight="40"
android:viewportWidth="40">
+ <group>
+ <clip-path android:pathData="M8,12h24.5v15.5h-24.5z" />
<path
- android:fillColor="#F7DAEE"
- android:fillType="evenOdd"
- android:pathData="M20.76,19C21.65,19 22.096,17.924 21.467,17.294L19.284,15.105C18.895,14.716 18.895,14.085 19.285,13.695C19.674,13.306 20.306,13.306 20.695,13.695L26.293,19.293C26.683,19.683 26.683,20.317 26.293,20.707L20.705,26.295C20.315,26.685 19.683,26.686 19.292,26.298C18.9,25.907 18.898,25.272 19.29,24.88L21.463,22.707C22.093,22.077 21.647,21 20.756,21H10C9.448,21 9,20.552 9,20C9,19.448 9.448,19 10,19H20.76ZM32,26C32,26.552 31.552,27 31,27C30.448,27 30,26.552 30,26V14C30,13.448 30.448,13 31,13C31.552,13 32,13.448 32,14V26Z"
- android:strokeColor="#F7DAEE"
- android:strokeLineCap="round"
- android:strokeLineJoin="round"
- android:strokeWidth="2" />
+ android:fillColor="#000000"
+ android:pathData="M30.75,12C29.79,12 29,12.79 29,13.75V25.75C29,26.71 29.79,27.5 30.75,27.5C31.71,27.5 32.5,26.71 32.5,25.75V13.75C32.5,12.79 31.71,12 30.75,12Z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M20.98,12.92C20.3,12.24 19.19,12.24 18.51,12.92C17.83,13.6 17.83,14.71 18.51,15.39L21.12,18H9.75C8.79,18 8,18.79 8,19.75C8,20.71 8.79,21.5 9.75,21.5H21.11L18.51,24.1C18.18,24.43 18,24.87 18,25.34C18,25.81 18.18,26.25 18.52,26.58C18.86,26.92 19.31,27.09 19.75,27.09C20.19,27.09 20.65,26.92 20.99,26.58L26.61,20.96C27.28,20.29 27.28,19.21 26.61,18.55L20.98,12.92Z" />
+ </group>
</vector>
diff --git a/packages/SystemUI/res-keyguard/drawable/pin_bouncer_delete.xml b/packages/SystemUI/res-keyguard/drawable/pin_bouncer_delete.xml
deleted file mode 100644
index 044656d..0000000
--- a/packages/SystemUI/res-keyguard/drawable/pin_bouncer_delete.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
- ~ Copyright (C) 2025 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="40dp"
- android:height="40dp"
- android:viewportHeight="40"
- android:viewportWidth="40">
- <path
- android:fillColor="#ECDFE5"
- android:pathData="M18.792,26.5L23.333,21.958L27.875,26.5L29.875,24.542L25.292,20L29.792,15.458L27.833,13.5L23.333,18.042L18.792,13.5L16.792,15.458L21.375,20L16.792,24.542L18.792,26.5ZM14.708,33.333C14.292,33.333 13.875,33.236 13.458,33.042C13.069,32.847 12.75,32.569 12.5,32.208L3.333,20L12.458,7.792C12.708,7.431 13.028,7.153 13.417,6.958C13.833,6.764 14.264,6.667 14.708,6.667H33.917C34.694,6.667 35.347,6.944 35.875,7.5C36.431,8.028 36.708,8.681 36.708,9.458V30.542C36.708,31.319 36.431,31.986 35.875,32.542C35.347,33.069 34.694,33.333 33.917,33.333H14.708Z" />
-</vector>
diff --git a/packages/SystemUI/res-keyguard/drawable/pin_bouncer_delete_filled.xml b/packages/SystemUI/res-keyguard/drawable/pin_bouncer_delete_filled.xml
new file mode 100644
index 0000000..86f95bc
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/pin_bouncer_delete_filled.xml
@@ -0,0 +1,25 @@
+<!--
+ ~ Copyright (C) 2025 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="40dp"
+ android:height="40dp"
+ android:viewportHeight="40"
+ android:viewportWidth="40">
+ <path
+ android:fillColor="#000000"
+ android:pathData="M22.167,21.9L25.531,25.265C25.795,25.502 26.112,25.621 26.481,25.621C26.851,25.621 27.167,25.502 27.431,25.265C27.669,25.001 27.788,24.684 27.788,24.315C27.788,23.919 27.669,23.589 27.431,23.325L24.067,20L27.392,16.675C27.656,16.411 27.788,16.094 27.788,15.725C27.788,15.356 27.656,15.039 27.392,14.775C27.128,14.511 26.798,14.379 26.402,14.379C26.033,14.379 25.729,14.511 25.492,14.775L22.167,18.1L18.802,14.735C18.538,14.498 18.222,14.379 17.852,14.379C17.483,14.379 17.166,14.498 16.902,14.735C16.665,14.999 16.546,15.329 16.546,15.725C16.546,16.094 16.665,16.411 16.902,16.675L20.267,20L16.902,23.325C16.665,23.589 16.546,23.906 16.546,24.275C16.546,24.644 16.665,24.961 16.902,25.225C17.166,25.489 17.483,25.621 17.852,25.621C18.248,25.621 18.578,25.489 18.842,25.225L22.167,21.9ZM14.012,32.667C13.59,32.667 13.181,32.574 12.785,32.39C12.416,32.179 12.099,31.915 11.835,31.598L4.394,21.623C4.024,21.148 3.84,20.607 3.84,20C3.84,19.393 4.024,18.852 4.394,18.377L11.835,8.402C12.073,8.085 12.39,7.835 12.785,7.65C13.181,7.439 13.59,7.333 14.012,7.333H32.142C32.907,7.333 33.554,7.597 34.081,8.125C34.609,8.653 34.873,9.286 34.873,10.025V29.975C34.873,30.714 34.609,31.347 34.081,31.875C33.554,32.403 32.907,32.667 32.142,32.667H14.012Z" />
+</vector>
diff --git a/packages/SystemUI/res-keyguard/drawable/pin_bouncer_delete_outline.xml b/packages/SystemUI/res-keyguard/drawable/pin_bouncer_delete_outline.xml
new file mode 100644
index 0000000..7f551f4
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/pin_bouncer_delete_outline.xml
@@ -0,0 +1,31 @@
+<!--
+ ~ Copyright (C) 2025 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="40dp"
+ android:height="40dp"
+ android:viewportHeight="40"
+ android:viewportWidth="40">
+ <group>
+ <clip-path android:pathData="M5,7h29.89v25h-29.89z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M30.96,32H15.59C14.21,32 12.89,31.34 12.06,30.24L5.78,21.86C4.74,20.47 4.74,18.54 5.78,17.15L12.06,8.77C12.89,7.67 14.21,7 15.59,7H30.96C33.13,7 34.89,8.76 34.89,10.93V28.08C34.89,30.25 33.13,32.01 30.96,32.01V32ZM14.46,28.44C14.73,28.79 15.15,29 15.59,29H30.96C31.47,29 31.89,28.58 31.89,28.07V10.93C31.89,10.42 31.47,10 30.96,10H15.59C15.15,10 14.73,10.21 14.46,10.56L8.18,18.94C7.93,19.27 7.93,19.72 8.18,20.05L14.46,28.43V28.44Z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M22.46,21.27L25.36,24.17C25.6,24.43 25.89,24.56 26.25,24.56C26.61,24.56 26.9,24.43 27.14,24.17C27.4,23.93 27.53,23.64 27.53,23.28C27.53,22.92 27.4,22.63 27.14,22.39L24.24,19.49L27.14,16.59C27.38,16.35 27.49,16.06 27.49,15.7C27.49,15.34 27.37,15.05 27.14,14.81C26.91,14.57 26.61,14.46 26.25,14.46C25.89,14.46 25.59,14.58 25.33,14.81L22.46,17.71L19.56,14.81C19.32,14.55 19.03,14.42 18.67,14.42C18.31,14.42 18.02,14.55 17.78,14.81C17.52,15.05 17.39,15.34 17.39,15.7C17.39,16.06 17.52,16.35 17.78,16.59L20.68,19.49L17.78,22.39C17.52,22.63 17.39,22.92 17.39,23.28C17.39,23.64 17.52,23.93 17.78,24.17C18.02,24.41 18.31,24.52 18.67,24.52C19.03,24.52 19.32,24.4 19.56,24.17L22.46,21.27Z" />
+ </group>
+</vector>
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_bouncer_message_area.xml b/packages/SystemUI/res-keyguard/layout/keyguard_bouncer_message_area.xml
index 0b35559..87d06bf 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_bouncer_message_area.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_bouncer_message_area.xml
@@ -21,7 +21,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/keyguard_lock_padding"
- android:importantForAccessibility="no"
+ android:accessibilityLiveRegion="polite"
android:ellipsize="marquee"
android:focusable="false"
android:gravity="center"
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_password_motion_layout.xml b/packages/SystemUI/res-keyguard/layout/keyguard_password_motion_layout.xml
index f231df2..c7f320c 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_password_motion_layout.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_password_motion_layout.xml
@@ -67,6 +67,7 @@
<com.android.systemui.bouncer.ui.BouncerMessageView
android:id="@+id/bouncer_message_view"
android:screenReaderFocusable="true"
+ android:accessibilityLiveRegion="polite"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_password_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_password_view.xml
index 0445722..9359838 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_password_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_password_view.xml
@@ -32,6 +32,7 @@
<com.android.systemui.bouncer.ui.BouncerMessageView
android:id="@+id/bouncer_message_view"
android:screenReaderFocusable="true"
+ android:accessibilityLiveRegion="polite"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_pattern_motion_layout.xml b/packages/SystemUI/res-keyguard/layout/keyguard_pattern_motion_layout.xml
index b184344..6cbe96a 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_pattern_motion_layout.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_pattern_motion_layout.xml
@@ -68,6 +68,7 @@
<com.android.systemui.bouncer.ui.BouncerMessageView
android:id="@+id/bouncer_message_view"
android:screenReaderFocusable="true"
+ android:accessibilityLiveRegion="polite"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_pattern_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_pattern_view.xml
index 0e15ff66..cf38887 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_pattern_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_pattern_view.xml
@@ -36,6 +36,7 @@
<com.android.systemui.bouncer.ui.BouncerMessageView
android:id="@+id/bouncer_message_view"
android:screenReaderFocusable="true"
+ android:accessibilityLiveRegion="polite"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_pin_motion_layout.xml b/packages/SystemUI/res-keyguard/layout/keyguard_pin_motion_layout.xml
index f6ac02a..33eab17 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_pin_motion_layout.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_pin_motion_layout.xml
@@ -75,6 +75,7 @@
<com.android.systemui.bouncer.ui.BouncerMessageView
android:id="@+id/bouncer_message_view"
android:screenReaderFocusable="true"
+ android:accessibilityLiveRegion="polite"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml
index ba4da79..fd5eeb8 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml
@@ -33,6 +33,7 @@
<com.android.systemui.bouncer.ui.BouncerMessageView
android:id="@+id/bouncer_message_view"
android:screenReaderFocusable="true"
+ android:accessibilityLiveRegion="polite"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />
diff --git a/packages/SystemUI/res-keyguard/values-bg/strings.xml b/packages/SystemUI/res-keyguard/values-bg/strings.xml
index ea3cbcf..739e868 100644
--- a/packages/SystemUI/res-keyguard/values-bg/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-bg/strings.xml
@@ -27,7 +27,7 @@
<string name="keyguard_enter_your_password" msgid="7225626204122735501">"Въведете паролата си"</string>
<string name="keyguard_enter_password" msgid="6483623792371009758">"Въведете паролата"</string>
<string name="keyguard_sim_error_message_short" msgid="633630844240494070">"Картата е невалидна."</string>
- <string name="keyguard_charged" msgid="5478247181205188995">"Заредена"</string>
+ <string name="keyguard_charged" msgid="5478247181205188995">"Заредено"</string>
<string name="keyguard_plugged_in_wireless" msgid="2537874724955057383">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Зарежда се безжично"</string>
<string name="keyguard_plugged_in_dock" msgid="2122073051904360987">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Зарежда се"</string>
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Зарежда се"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ca/strings.xml b/packages/SystemUI/res-keyguard/values-ca/strings.xml
index 226d193..0da0636 100644
--- a/packages/SystemUI/res-keyguard/values-ca/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ca/strings.xml
@@ -27,7 +27,7 @@
<string name="keyguard_enter_your_password" msgid="7225626204122735501">"Introdueix la contrasenya"</string>
<string name="keyguard_enter_password" msgid="6483623792371009758">"Introdueix la contrasenya"</string>
<string name="keyguard_sim_error_message_short" msgid="633630844240494070">"La targeta no és vàlida."</string>
- <string name="keyguard_charged" msgid="5478247181205188995">"Bateria carregada"</string>
+ <string name="keyguard_charged" msgid="5478247181205188995">"Carregat"</string>
<string name="keyguard_plugged_in_wireless" msgid="2537874724955057383">"<xliff:g id="PERCENTAGE">%s</xliff:g> • S\'està carregant sense fil"</string>
<string name="keyguard_plugged_in_dock" msgid="2122073051904360987">"<xliff:g id="PERCENTAGE">%s</xliff:g> • S\'està carregant"</string>
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • S\'està carregant"</string>
diff --git a/packages/SystemUI/res-keyguard/values-et/strings.xml b/packages/SystemUI/res-keyguard/values-et/strings.xml
index 0b8ad02..0913f72 100644
--- a/packages/SystemUI/res-keyguard/values-et/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-et/strings.xml
@@ -62,9 +62,9 @@
<string name="kg_bio_try_again_or_pin" msgid="4752168242723808390">"Proovige uuesti või sisestage PIN-kood"</string>
<string name="kg_bio_try_again_or_password" msgid="1473132729225398039">"Proovige uuesti või sisestage parool"</string>
<string name="kg_bio_try_again_or_pattern" msgid="4867893307468801501">"Proovige uuesti või joonistage muster"</string>
- <string name="kg_bio_too_many_attempts_pin" msgid="5850845723433047605">"PIN-koodi nõutakse pärast liiga paljusid katseid"</string>
+ <string name="kg_bio_too_many_attempts_pin" msgid="5850845723433047605">"PIN-koodi nõutakse pärast liiga paljusid katseid."</string>
<string name="kg_bio_too_many_attempts_password" msgid="5551690347827728042">"Parool on nõutav pärast liiga paljusid katseid"</string>
- <string name="kg_bio_too_many_attempts_pattern" msgid="736884689355181602">"Muster on nõutav pärast liiga paljusid katseid"</string>
+ <string name="kg_bio_too_many_attempts_pattern" msgid="736884689355181602">"Muster on nõutav pärast liiga paljusid katseid."</string>
<string name="kg_unlock_with_pin_or_fp" msgid="5635161174698729890">"Avage PIN-koodi või sõrmejäljega"</string>
<string name="kg_unlock_with_password_or_fp" msgid="2251295907826814237">"Avage parooli või sõrmejäljega"</string>
<string name="kg_unlock_with_pattern_or_fp" msgid="2391870539909135046">"Avage mustri või sõrmejäljega"</string>
diff --git a/packages/SystemUI/res-keyguard/values-kk/strings.xml b/packages/SystemUI/res-keyguard/values-kk/strings.xml
index 103f8ad..c3fccf2 100644
--- a/packages/SystemUI/res-keyguard/values-kk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-kk/strings.xml
@@ -36,7 +36,7 @@
<string name="keyguard_plugged_in_charging_limited" msgid="5369697538556777542">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Батареяны қорғау мақсатында зарядтау кідіртілді."</string>
<string name="keyguard_plugged_in_incompatible_charger" msgid="6384203333154532125">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Зарядтау құрылғысын тексеріңіз."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Желі құлыптаулы"</string>
- <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"SIM картасы жоқ."</string>
+ <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"SIM картасы жоқ"</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"SIM картасын пайдалану мүмкін емес."</string>
<string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM картасы құлыпталған."</string>
<string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM картасы PUK кодымен құлыпталды."</string>
diff --git a/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml b/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml
index 9a26f7d..1bdfd42 100644
--- a/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml
@@ -27,7 +27,7 @@
<string name="keyguard_enter_your_password" msgid="7225626204122735501">"Introduza a palavra-passe"</string>
<string name="keyguard_enter_password" msgid="6483623792371009758">"Introduza a palavra-passe"</string>
<string name="keyguard_sim_error_message_short" msgid="633630844240494070">"Cartão inválido."</string>
- <string name="keyguard_charged" msgid="5478247181205188995">"Carregada"</string>
+ <string name="keyguard_charged" msgid="5478247181205188995">"Bateria carregada"</string>
<string name="keyguard_plugged_in_wireless" msgid="2537874724955057383">"<xliff:g id="PERCENTAGE">%s</xliff:g> • A carregar sem fios"</string>
<string name="keyguard_plugged_in_dock" msgid="2122073051904360987">"<xliff:g id="PERCENTAGE">%s</xliff:g> • A carregar"</string>
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • A carregar…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ru/strings.xml b/packages/SystemUI/res-keyguard/values-ru/strings.xml
index cf2057c..cab9cb9 100644
--- a/packages/SystemUI/res-keyguard/values-ru/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ru/strings.xml
@@ -36,7 +36,7 @@
<string name="keyguard_plugged_in_charging_limited" msgid="5369697538556777542">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Зарядка приостановлена для защиты батареи."</string>
<string name="keyguard_plugged_in_incompatible_charger" msgid="6384203333154532125">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Проверьте зарядное устройство."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Сеть заблокирована"</string>
- <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"SIM-карта отсутствует"</string>
+ <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Нет SIM-карты"</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"SIM-карту невозможно использовать."</string>
<string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM-карта заблокирована."</string>
<string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM-карта заблокирована с помощью PUK-кода."</string>
diff --git a/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml
index bc047be..6dcc65e 100644
--- a/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml
@@ -46,9 +46,9 @@
<string name="keyguard_accessibility_sim_pin_area" msgid="6272116591533888062">"SIM 卡 PIN 區"</string>
<string name="keyguard_accessibility_sim_puk_area" msgid="5537294043180237374">"SIM 卡 PUK 區"</string>
<string name="keyboardview_keycode_delete" msgid="8489719929424895174">"刪除"</string>
- <string name="disable_carrier_button_text" msgid="7153361131709275746">"停用 eSIM 卡"</string>
- <string name="error_disable_esim_title" msgid="3802652622784813119">"無法停用 eSIM 卡"</string>
- <string name="error_disable_esim_msg" msgid="2441188596467999327">"發生錯誤,因此無法停用 eSIM 卡。"</string>
+ <string name="disable_carrier_button_text" msgid="7153361131709275746">"停用 eSIM"</string>
+ <string name="error_disable_esim_title" msgid="3802652622784813119">"無法停用 eSIM"</string>
+ <string name="error_disable_esim_msg" msgid="2441188596467999327">"發生錯誤,因此無法停用 eSIM。"</string>
<string name="keyboardview_keycode_enter" msgid="6727192265631761174">"Enter 鍵"</string>
<string name="kg_wrong_pattern" msgid="5907301342430102842">"圖案錯誤"</string>
<string name="kg_wrong_pattern_try_again" msgid="3603524940234151881">"解鎖圖案錯誤,請再試一次。"</string>
@@ -86,7 +86,7 @@
<string name="kg_too_many_failed_attempts_countdown" msgid="2038195171919795529">"{count,plural, =1{請於 # 秒後再試一次。}other{請於 # 秒後再試一次。}}"</string>
<string name="kg_sim_pin_instructions" msgid="1942424305184242951">"輸入 SIM 卡的 PIN 碼。"</string>
<string name="kg_sim_pin_instructions_multi" msgid="3639863309953109649">"輸入「<xliff:g id="CARRIER">%1$s</xliff:g>」SIM 卡的 PIN 碼。"</string>
- <string name="kg_sim_lock_esim_instructions" msgid="5577169988158738030">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g>停用 eSIM 卡即可在沒有行動服務的情況下使用裝置。"</string>
+ <string name="kg_sim_lock_esim_instructions" msgid="5577169988158738030">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g>停用 eSIM 即可在沒有行動服務的情況下使用裝置。"</string>
<string name="kg_puk_enter_puk_hint" msgid="3005288372875367017">"SIM 卡已遭停用,輸入 PUK 碼即可繼續使用。如需瞭解詳情,請與電信業者聯絡。"</string>
<string name="kg_puk_enter_puk_hint_multi" msgid="4876780689904862943">"SIM 卡「<xliff:g id="CARRIER">%1$s</xliff:g>」現已遭停用,輸入 PUK 碼即可繼續使用。如需瞭解詳情,請與電信業者聯絡。"</string>
<string name="kg_puk_enter_pin_hint" msgid="6028432138916150399">"輸入所需的 PIN 碼"</string>
diff --git a/packages/SystemUI/res-keyguard/values/dimens.xml b/packages/SystemUI/res-keyguard/values/dimens.xml
index bfb37a0d..6d44645 100644
--- a/packages/SystemUI/res-keyguard/values/dimens.xml
+++ b/packages/SystemUI/res-keyguard/values/dimens.xml
@@ -31,6 +31,10 @@
<!-- height for the keyguard pin input field -->
<dimen name="keyguard_pin_field_height">56dp</dimen>
+ <dimen name="keyguard_pattern_dot_size">16dp</dimen>
+ <dimen name="keyguard_pattern_activated_dot_size">24dp</dimen>
+ <dimen name="keyguard_pattern_stroke_width">32dp</dimen>
+
<!-- height for the keyguard password input field -->
<dimen name="keyguard_password_field_height">56dp</dimen>
diff --git a/packages/SystemUI/res/color/media_player_outline_button_bg.xml b/packages/SystemUI/res/color/media_player_outline_button_bg.xml
deleted file mode 100644
index ba7848a..0000000
--- a/packages/SystemUI/res/color/media_player_outline_button_bg.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?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/colorAccentPrimaryVariant"/>
-</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/media_player_solid_button_bg.xml b/packages/SystemUI/res/color/media_player_solid_button_bg.xml
index 69c9711..cc54fa3 100644
--- a/packages/SystemUI/res/color/media_player_solid_button_bg.xml
+++ b/packages/SystemUI/res/color/media_player_solid_button_bg.xml
@@ -15,7 +15,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/colorAccentPrimary"/>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:color="@android:color/system_primary_dark"/>
</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_legacy_speaker_mute.xml b/packages/SystemUI/res/drawable/ic_legacy_speaker_mute.xml
new file mode 100644
index 0000000..4e402cf
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_legacy_speaker_mute.xml
@@ -0,0 +1,25 @@
+<!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:tint="?android:attr/textColorPrimary"
+ android:autoMirrored="true">
+ <path android:fillColor="#FFFFFFFF"
+ android:pathData="M19.8,22.6 L16.775,19.575Q16.15,19.975 15.45,20.263Q14.75,20.55 14,20.725V18.675Q14.35,18.55 14.688,18.425Q15.025,18.3 15.325,18.125L12,14.8V20L7,15H3V9H6.2L1.4,4.2L2.8,2.8L21.2,21.2ZM19.6,16.8 L18.15,15.35Q18.575,14.575 18.788,13.725Q19,12.875 19,11.975Q19,9.625 17.625,7.775Q16.25,5.925 14,5.275V3.225Q17.1,3.925 19.05,6.362Q21,8.8 21,11.975Q21,13.3 20.638,14.525Q20.275,15.75 19.6,16.8ZM16.25,13.45 L14,11.2V7.95Q15.175,8.5 15.838,9.6Q16.5,10.7 16.5,12Q16.5,12.375 16.438,12.738Q16.375,13.1 16.25,13.45ZM12,9.2 L9.4,6.6 12,4ZM10,15.15V12.8L8.2,11H5V13H7.85ZM9.1,11.9Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_legacy_speaker_on.xml b/packages/SystemUI/res/drawable/ic_legacy_speaker_on.xml
new file mode 100644
index 0000000..2a90e05
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_legacy_speaker_on.xml
@@ -0,0 +1,25 @@
+<!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:tint="?android:attr/textColorPrimary"
+ android:autoMirrored="true">
+ <path android:fillColor="#FFFFFFFF"
+ android:pathData="M14,20.725V18.675Q16.25,18.025 17.625,16.175Q19,14.325 19,11.975Q19,9.625 17.625,7.775Q16.25,5.925 14,5.275V3.225Q17.1,3.925 19.05,6.362Q21,8.8 21,11.975Q21,15.15 19.05,17.587Q17.1,20.025 14,20.725ZM3,15V9H7L12,4V20L7,15ZM14,16V7.95Q15.175,8.5 15.838,9.6Q16.5,10.7 16.5,12Q16.5,13.275 15.838,14.362Q15.175,15.45 14,16ZM10,8.85 L7.85,11H5V13H7.85L10,15.15ZM7.5,12Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_legacy_volume_ringer_vibrate.xml b/packages/SystemUI/res/drawable/ic_legacy_volume_ringer_vibrate.xml
new file mode 100644
index 0000000..b18e0a7
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_legacy_volume_ringer_vibrate.xml
@@ -0,0 +1,27 @@
+<!--
+ Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="19dp"
+ android:width="19dp"
+ android:viewportHeight="24.0"
+ android:viewportWidth="24.0"
+ android:tint="?android:attr/textColorPrimary">
+
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M1,9h2v6H1V9zM4,17h2V7H4V17zM21,9v6h2V9H21zM18,17h2V7h-2V17zM17,5.5v13c0,0.83 -0.67,1.5 -1.5,1.5h-7C7.67,20 7,19.33 7,18.5v-13C7,4.67 7.67,4 8.5,4h7C16.33,4 17,4.67 17,5.5zM15,6H9v12h6V6z"/>
+
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_speaker_mute.xml b/packages/SystemUI/res/drawable/ic_speaker_mute.xml
index 4e402cf..bf31580 100644
--- a/packages/SystemUI/res/drawable/ic_speaker_mute.xml
+++ b/packages/SystemUI/res/drawable/ic_speaker_mute.xml
@@ -1,5 +1,5 @@
<!--
- ~ Copyright (C) 2022 The Android Open Source Project
+ ~ Copyright (C) 2025 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
@@ -14,12 +14,15 @@
~ limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
- android:viewportWidth="24"
- android:viewportHeight="24"
- android:tint="?android:attr/textColorPrimary"
- android:autoMirrored="true">
- <path android:fillColor="#FFFFFFFF"
- android:pathData="M19.8,22.6 L16.775,19.575Q16.15,19.975 15.45,20.263Q14.75,20.55 14,20.725V18.675Q14.35,18.55 14.688,18.425Q15.025,18.3 15.325,18.125L12,14.8V20L7,15H3V9H6.2L1.4,4.2L2.8,2.8L21.2,21.2ZM19.6,16.8 L18.15,15.35Q18.575,14.575 18.788,13.725Q19,12.875 19,11.975Q19,9.625 17.625,7.775Q16.25,5.925 14,5.275V3.225Q17.1,3.925 19.05,6.362Q21,8.8 21,11.975Q21,13.3 20.638,14.525Q20.275,15.75 19.6,16.8ZM16.25,13.45 L14,11.2V7.95Q15.175,8.5 15.838,9.6Q16.5,10.7 16.5,12Q16.5,12.375 16.438,12.738Q16.375,13.1 16.25,13.45ZM12,9.2 L9.4,6.6 12,4ZM10,15.15V12.8L8.2,11H5V13H7.85ZM9.1,11.9Z"/>
-</vector>
\ No newline at end of file
+ android:width="20dp"
+ android:height="20dp"
+ android:viewportWidth="20"
+ android:viewportHeight="20">
+ <group>
+ <clip-path
+ android:pathData="M0,0h20v20h-20z"/>
+ <path
+ android:pathData="M16,18.125L13.771,15.896C13.465,16.09 13.097,16.278 12.667,16.458C12.25,16.625 11.861,16.75 11.5,16.833V15.292C11.667,15.222 11.861,15.146 12.083,15.063C12.319,14.965 12.514,14.875 12.667,14.792L10,12.125V16.021L6,12.021H3V8.021H5.875L1.875,4L2.938,2.938L17.063,17.063L16,18.125ZM15.875,13.771L14.792,12.688C15.014,12.285 15.188,11.861 15.313,11.417C15.438,10.958 15.5,10.493 15.5,10.021C15.5,8.785 15.125,7.688 14.375,6.729C13.639,5.757 12.681,5.09 11.5,4.729V3.188C13.125,3.507 14.444,4.313 15.458,5.604C16.486,6.896 17,8.368 17,10.021C17,10.688 16.903,11.34 16.708,11.979C16.514,12.604 16.236,13.201 15.875,13.771ZM13.292,11.188L11.5,9.396V6.854C12.125,7.132 12.611,7.563 12.958,8.146C13.319,8.715 13.5,9.34 13.5,10.021C13.5,10.215 13.486,10.41 13.458,10.604C13.431,10.799 13.375,10.993 13.292,11.188ZM10,7.896L8.063,5.958L10,4.021V7.896Z"
+ android:fillColor="#ECDFE5"/>
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_speaker_on.xml b/packages/SystemUI/res/drawable/ic_speaker_on.xml
index 2a90e05..f0d057e 100644
--- a/packages/SystemUI/res/drawable/ic_speaker_on.xml
+++ b/packages/SystemUI/res/drawable/ic_speaker_on.xml
@@ -1,5 +1,5 @@
<!--
- ~ Copyright (C) 2022 The Android Open Source Project
+ ~ Copyright (C) 2025 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
@@ -14,12 +14,15 @@
~ limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
- android:viewportWidth="24"
- android:viewportHeight="24"
- android:tint="?android:attr/textColorPrimary"
- android:autoMirrored="true">
- <path android:fillColor="#FFFFFFFF"
- android:pathData="M14,20.725V18.675Q16.25,18.025 17.625,16.175Q19,14.325 19,11.975Q19,9.625 17.625,7.775Q16.25,5.925 14,5.275V3.225Q17.1,3.925 19.05,6.362Q21,8.8 21,11.975Q21,15.15 19.05,17.587Q17.1,20.025 14,20.725ZM3,15V9H7L12,4V20L7,15ZM14,16V7.95Q15.175,8.5 15.838,9.6Q16.5,10.7 16.5,12Q16.5,13.275 15.838,14.362Q15.175,15.45 14,16ZM10,8.85 L7.85,11H5V13H7.85L10,15.15ZM7.5,12Z"/>
-</vector>
\ No newline at end of file
+ android:width="20dp"
+ android:height="20dp"
+ android:viewportWidth="20"
+ android:viewportHeight="20">
+ <group>
+ <clip-path
+ android:pathData="M0,0h20v20h-20z"/>
+ <path
+ android:pathData="M11.5,16.833V15.271C12.694,14.951 13.66,14.306 14.396,13.333C15.132,12.347 15.5,11.236 15.5,10C15.5,8.764 15.125,7.667 14.375,6.708C13.639,5.736 12.681,5.069 11.5,4.708V3.146C13.111,3.493 14.431,4.306 15.458,5.583C16.486,6.861 17,8.326 17,9.979C17,11.632 16.486,13.104 15.458,14.396C14.444,15.674 13.125,16.486 11.5,16.833ZM3,11.979V7.979H6L10,3.979V15.979L6,11.979H3ZM11.5,13.125V6.833C12.125,7.111 12.611,7.535 12.958,8.104C13.319,8.674 13.5,9.299 13.5,9.979C13.5,10.66 13.319,11.285 12.958,11.854C12.611,12.41 12.125,12.833 11.5,13.125Z"
+ android:fillColor="#ECDFE5"/>
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_ringer_vibrate.xml b/packages/SystemUI/res/drawable/ic_volume_ringer_vibrate.xml
index b18e0a7..2cbbb0d 100644
--- a/packages/SystemUI/res/drawable/ic_volume_ringer_vibrate.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_ringer_vibrate.xml
@@ -1,27 +1,28 @@
<!--
- Copyright (C) 2017 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
+ ~ Copyright (C) 2025 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:height="19dp"
- android:width="19dp"
- android:viewportHeight="24.0"
- android:viewportWidth="24.0"
- android:tint="?android:attr/textColorPrimary">
-
+ android:width="20dp"
+ android:height="20dp"
+ android:viewportWidth="20"
+ android:viewportHeight="20">
+ <group>
+ <clip-path
+ android:pathData="M0,0h20v20h-20z"/>
<path
- android:fillColor="#FFFFFFFF"
- android:pathData="M1,9h2v6H1V9zM4,17h2V7H4V17zM21,9v6h2V9H21zM18,17h2V7h-2V17zM17,5.5v13c0,0.83 -0.67,1.5 -1.5,1.5h-7C7.67,20 7,19.33 7,18.5v-13C7,4.67 7.67,4 8.5,4h7C16.33,4 17,4.67 17,5.5zM15,6H9v12h6V6z"/>
-
+ android:pathData="M0,12.5V7.5H1.5V12.5H0ZM2.5,14V6H4V14H2.5ZM18.5,12.5V7.5H20V12.5H18.5ZM16,14V6H17.5V14H16ZM6.5,17C6.083,17 5.729,16.854 5.438,16.563C5.146,16.271 5,15.917 5,15.5V4.5C5,4.083 5.146,3.729 5.438,3.438C5.729,3.146 6.083,3 6.5,3H13.5C13.917,3 14.271,3.146 14.563,3.438C14.854,3.729 15,4.083 15,4.5V15.5C15,15.917 14.854,16.271 14.563,16.563C14.271,16.854 13.917,17 13.5,17H6.5Z"
+ android:fillColor="#ECDFE5"/>
+ </group>
</vector>
diff --git a/packages/SystemUI/res/drawable/mobile_network_type_background_updated.xml b/packages/SystemUI/res/drawable/mobile_network_type_background_updated.xml
new file mode 100644
index 0000000..7b55b3c
--- /dev/null
+++ b/packages/SystemUI/res/drawable/mobile_network_type_background_updated.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2023 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ ~
+ -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle"
+ >
+ <corners
+ android:topLeftRadius="0dp"
+ android:topRightRadius="@dimen/status_bar_mobile_container_corner_radius_updated"
+ android:bottomRightRadius="0dp"
+ android:bottomLeftRadius="@dimen/status_bar_mobile_container_corner_radius_updated"/>
+ <solid android:color="#FFF" />
+ <padding
+ android:left="2sp"
+ android:right="2sp"/>
+</shape>
diff --git a/packages/SystemUI/res/drawable/qs_media_art_background.xml b/packages/SystemUI/res/drawable/qs_media_art_background.xml
index 95a1870..e59f82b 100644
--- a/packages/SystemUI/res/drawable/qs_media_art_background.xml
+++ b/packages/SystemUI/res/drawable/qs_media_art_background.xml
@@ -15,6 +15,7 @@
~ limitations under the License
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <corners android:radius="@dimen/qs_media_album_radius"/>
+ android:shape="rectangle">
+ <solid android:color="#FF000000" />
+ <corners android:radius="@dimen/notification_corner_radius"/>
</shape>
diff --git a/packages/SystemUI/res/drawable/stat_sys_ringer_silent.xml b/packages/SystemUI/res/drawable/stat_sys_ringer_silent.xml
index b83f15a..c0cb5ef 100644
--- a/packages/SystemUI/res/drawable/stat_sys_ringer_silent.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_ringer_silent.xml
@@ -14,4 +14,4 @@
limitations under the License.
-->
<inset xmlns:android="http://schemas.android.com/apk/res/android"
- android:drawable="@drawable/ic_speaker_mute" />
+ android:drawable="@drawable/ic_legacy_speaker_mute" />
diff --git a/packages/SystemUI/res/drawable/stat_sys_ringer_vibrate.xml b/packages/SystemUI/res/drawable/stat_sys_ringer_vibrate.xml
index 21a4c17..4d68d67 100644
--- a/packages/SystemUI/res/drawable/stat_sys_ringer_vibrate.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_ringer_vibrate.xml
@@ -16,4 +16,4 @@
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:insetLeft="2.5dp"
android:insetRight="2.5dp"
- android:drawable="@drawable/ic_volume_ringer_vibrate" />
\ No newline at end of file
+ android:drawable="@drawable/ic_legacy_volume_ringer_vibrate" />
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/bluetooth_tile_dialog.xml b/packages/SystemUI/res/layout/bluetooth_tile_dialog.xml
index 1f93717..795b7b4 100644
--- a/packages/SystemUI/res/layout/bluetooth_tile_dialog.xml
+++ b/packages/SystemUI/res/layout/bluetooth_tile_dialog.xml
@@ -121,8 +121,8 @@
android:contentDescription="@string/turn_on_bluetooth"
android:switchMinWidth="@dimen/settingslib_switch_track_width"
android:theme="@style/MainSwitch.Settingslib"
- android:thumb="@drawable/settingslib_thumb_selector"
- android:track="@drawable/settingslib_track_selector"
+ android:thumb="@drawable/settingslib_switch_thumb"
+ android:track="@drawable/settingslib_switch_track"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/bluetooth_toggle_title"
app:layout_constraintTop_toTopOf="parent" />
@@ -163,8 +163,8 @@
android:contentDescription="@string/turn_on_bluetooth_auto_tomorrow"
android:switchMinWidth="@dimen/settingslib_switch_track_width"
android:theme="@style/MainSwitch.Settingslib"
- android:thumb="@drawable/settingslib_thumb_selector"
- android:track="@drawable/settingslib_track_selector"
+ android:thumb="@drawable/settingslib_switch_thumb"
+ android:track="@drawable/settingslib_switch_track"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/bluetooth_auto_on_toggle_title"
app:layout_constraintTop_toBottomOf="@+id/bluetooth_toggle" />
diff --git a/packages/SystemUI/res/layout/internet_connectivity_dialog.xml b/packages/SystemUI/res/layout/internet_connectivity_dialog.xml
index 5922a7d..67e9701 100644
--- a/packages/SystemUI/res/layout/internet_connectivity_dialog.xml
+++ b/packages/SystemUI/res/layout/internet_connectivity_dialog.xml
@@ -131,7 +131,7 @@
style="@style/InternetDialog.Network">
<FrameLayout
- android:layout_width="24dp"
+ android:layout_width="wrap_content"
android:layout_height="24dp"
android:clickable="false"
android:layout_gravity="center_vertical|start">
diff --git a/packages/SystemUI/res/layout/notification_2025_hybrid.xml b/packages/SystemUI/res/layout/notification_2025_hybrid.xml
index 8fd10fb..8c34cd4 100644
--- a/packages/SystemUI/res/layout/notification_2025_hybrid.xml
+++ b/packages/SystemUI/res/layout/notification_2025_hybrid.xml
@@ -29,7 +29,6 @@
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Notification.Title"
- android:textSize="@*android:dimen/notification_2025_title_text_size"
android:paddingEnd="4dp"
/>
<TextView
diff --git a/packages/SystemUI/res/layout/notification_2025_hybrid_conversation.xml b/packages/SystemUI/res/layout/notification_2025_hybrid_conversation.xml
index 35f2ef9..a338e4c 100644
--- a/packages/SystemUI/res/layout/notification_2025_hybrid_conversation.xml
+++ b/packages/SystemUI/res/layout/notification_2025_hybrid_conversation.xml
@@ -54,7 +54,6 @@
android:singleLine="true"
android:paddingEnd="4dp"
android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Notification.Title"
- android:textSize="@*android:dimen/notification_2025_title_text_size"
/>
<TextView
diff --git a/packages/SystemUI/res/layout/volume_dialog.xml b/packages/SystemUI/res/layout/volume_dialog.xml
index 889aefe..f41eaec 100644
--- a/packages/SystemUI/res/layout/volume_dialog.xml
+++ b/packages/SystemUI/res/layout/volume_dialog.xml
@@ -13,14 +13,13 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/volume_dialog"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:alpha="0"
- android:clipChildren="false"
- app:layoutDescription="@xml/volume_dialog_scene">
+ android:clipChildren="false">
<View
android:id="@+id/volume_dialog_background"
@@ -52,7 +51,17 @@
<include
android:id="@+id/volume_dialog_main_slider_container"
- layout="@layout/volume_dialog_slider" />
+ layout="@layout/volume_dialog_slider"
+ android:layout_width="@dimen/volume_dialog_slider_width"
+ android:layout_height="0dp"
+ android:layout_marginTop="@dimen/volume_dialog_slider_vertical_margin"
+ android:layout_marginEnd="@dimen/volume_dialog_window_margin"
+ android:layout_marginBottom="@dimen/volume_dialog_slider_vertical_margin"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintHeight_max="@dimen/volume_dialog_slider_height"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintVertical_bias="0.5" />
<FrameLayout
android:id="@+id/volume_dialog_bottom_section_container"
@@ -88,4 +97,4 @@
app:layout_constraintEnd_toStartOf="@id/volume_dialog_background"
app:layout_constraintTop_toTopOf="@id/volume_dialog_main_slider_container" />
-</androidx.constraintlayout.motion.widget.MotionLayout>
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/packages/SystemUI/res/layout/volume_ringer_drawer_legacy.xml b/packages/SystemUI/res/layout/volume_ringer_drawer_legacy.xml
index 0efbc6d..c7e0f7d 100644
--- a/packages/SystemUI/res/layout/volume_ringer_drawer_legacy.xml
+++ b/packages/SystemUI/res/layout/volume_ringer_drawer_legacy.xml
@@ -67,7 +67,7 @@
android:layout_width="@dimen/volume_ringer_drawer_icon_size"
android:layout_height="@dimen/volume_ringer_drawer_icon_size"
android:layout_gravity="center"
- android:src="@drawable/ic_volume_ringer_vibrate"
+ android:src="@drawable/ic_legacy_volume_ringer_vibrate"
android:tint="?android:attr/textColorPrimary" />
</FrameLayout>
@@ -85,7 +85,7 @@
android:layout_width="@dimen/volume_ringer_drawer_icon_size"
android:layout_height="@dimen/volume_ringer_drawer_icon_size"
android:layout_gravity="center"
- android:src="@drawable/ic_speaker_mute"
+ android:src="@drawable/ic_legacy_speaker_mute"
android:tint="?android:attr/textColorPrimary" />
</FrameLayout>
@@ -103,7 +103,7 @@
android:layout_width="@dimen/volume_ringer_drawer_icon_size"
android:layout_height="@dimen/volume_ringer_drawer_icon_size"
android:layout_gravity="center"
- android:src="@drawable/ic_speaker_on"
+ android:src="@drawable/ic_legacy_speaker_on"
android:tint="?android:attr/textColorPrimary" />
</FrameLayout>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index b8b69b6..538d9e2 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"ontkies legstuk"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Verminder hoogte"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Vermeerder hoogte"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Wys volgende"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Wys vorige"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Sluitskermlegstukke"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Om ’n app met ’n legstuk oop te maak, sal jy moet verifieer dat dit jy is. Hou ook in gedagte dat enigeen dit kan bekyk, selfs wanneer jou tablet gesluit is. Sommige legstukke is moontlik nie vir jou sluitskerm bedoel nie en dit kan onveilig wees om dit hier by te voeg."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Het dit"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> steun nie gesprekskenmerke nie"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Terugvoer"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Maak toe"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Moenie weer wys nie"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Hierdie kennisgewings kan nie gewysig word nie."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Oproepkennisgewings kan nie gewysig word nie."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Hierdie groep kennisgewings kan nie hier opgestel word nie"</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Voubare toestel word ontvou"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Voubare toestel word omgekeer"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Voorste skerm is aangeskakel"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"Gly om binneskerm te gebruik"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"gevou"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"oopgevou"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
diff --git a/packages/SystemUI/res/values-af/tiles_states_strings.xml b/packages/SystemUI/res/values-af/tiles_states_strings.xml
index fbeefc8..3d0dbb5 100644
--- a/packages/SystemUI/res/values-af/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-af/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Af"</item>
<item msgid="5908720590832378783">"Aan"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index c89ea75..f1b9fca 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"ምግብር አትምረጥ"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"ቁመት ቀንስ"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"ቁመት ጨምር"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"ቀጣይ አሳይ"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"ቀዳሚ አሳይ"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"የማያ ገፅ ቁልፍ ምግብሮች"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ምግብር በመጠቀም መተግበሪያ ለመክፈት እርስዎ መሆንዎን ማረጋገጥ አለብዎት። እንዲሁም የእርስዎ ጡባዊ በተቆለፈበት ጊዜ እንኳን ማንኛውም ሰው እነሱን ማየት እንደሚችል ከግምት ውስጥ ያስገቡ። አንዳንድ ምግብሮች ለማያ ገፅ ቁልፍዎ የታሰቡ ላይሆኑ ይችላሉ እና እዚህ ለማከል አስተማማኝ ላይሆኑ ይችላሉ።"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"ገባኝ"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> የውይይት ባህሪያትን አይደግፍም"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"ግብረመልስ"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"አሰናብት"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"ዳግም አታሳይ"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"እነዚህ ማሳወቂያዎች ሊሻሻሉ አይችሉም።"</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"የጥሪ ማሳወቂያዎች ሊቀየሩ አይችሉም።"</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"የማሳወቂያዎች ይህ ቡድን እዚህ ላይ ሊዋቀር አይችልም"</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"መታጠፍ የሚችል መሣሪያ እየተዘረጋ ነው"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"መታጠፍ የሚችል መሣሪያ እየተገለበጠ ነው"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"የፊት ለፊት ማያ ገፅ በርቷል"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"ውስጣዊ ማያ ገፅን ለመጠቀም ያንሸራትቱ"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"የታጠፈ"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"የተዘረጋ"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
diff --git a/packages/SystemUI/res/values-am/tiles_states_strings.xml b/packages/SystemUI/res/values-am/tiles_states_strings.xml
index b98fe57..31a7d96 100644
--- a/packages/SystemUI/res/values-am/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-am/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"ጠፍቷል"</item>
<item msgid="5908720590832378783">"በርቷል"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 962f1c9..7d55b85 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"إلغاء اختيار التطبيق المصغّر"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"تقليل الارتفاع"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"زيادة الارتفاع"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"عرض التالي"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"عرض السابق"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"التطبيقات المصغّرة المصمَّمة لشاشة القفل"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"لفتح تطبيق باستخدام تطبيق مصغَّر، عليك إثبات هويتك. يُرجى ملاحظة أنّ أي شخص يمكنه الاطّلاع محتوى التطبيقات المصغَّرة، حتى وإن كان جهازك اللوحي مُقفلاً. بعض التطبيقات المصغّرة قد لا تكون مُصمَّمة لإضافتها إلى شاشة القفل، وقد يكون هذا الإجراء غير آمن."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"حسنًا"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"لا يدعم تطبيق <xliff:g id="APP_NAME">%1$s</xliff:g> ميزات المحادثات."</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"الملاحظات"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"إغلاق"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"عدم الإظهار مرة أخرى"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"يتعذّر تعديل هذه الإشعارات."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"لا يمكن تعديل إشعارات المكالمات."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"يتعذّر ضبط مجموعة الإشعارات هذه هنا."</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"جهاز قابل للطي يجري فتحه"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"جهاز قابل للطي يجري قلبه"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"تم تفعيل الشاشة الأمامية"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"يُرجى التمرير لاستخدام الشاشة الداخلية"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"مطوي"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"غير مطوي"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1525,7 +1531,7 @@
<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>
- <string name="home_controls_dream_description" msgid="4644150952104035789">"يمكنك إدارة المنزل آليًّا بشكل سريع من شاشة الاستراحة"</string>
+ <string name="home_controls_dream_description" msgid="4644150952104035789">"يمكنك إدارة المنزل آليًّا بسرعة من شاشة الاستراحة."</string>
<string name="volume_undo_action" msgid="5815519725211877114">"تراجع"</string>
<string name="back_edu_toast_content" msgid="4530314597378982956">"للرجوع، مرِّر سريعًا لليمين أو لليسار على لوحة اللمس باستخدام 3 أصابع"</string>
<string name="home_edu_toast_content" msgid="3381071147871955415">"للانتقال إلى الشاشة الرئيسية، مرِّر سريعًا للأعلى على لوحة اللمس باستخدام 3 أصابع"</string>
diff --git a/packages/SystemUI/res/values-ar/tiles_states_strings.xml b/packages/SystemUI/res/values-ar/tiles_states_strings.xml
index 0be4367..abb0d85 100644
--- a/packages/SystemUI/res/values-ar/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ar/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"متوقّفة"</item>
<item msgid="5908720590832378783">"مفعّلة"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index b88e9e9..74c4e3e 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"ৱিজেট বাছনিৰ পৰা আঁতৰাওক"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"উচ্চতা হ্ৰাস কৰক"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"উচ্চতা বৃদ্ধি কৰক"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"পিছৰটো দেখুৱাওক"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"পূৰ্বৰটো দেখুৱাওক"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"লক স্ক্ৰীন ৱিজেট"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"এটা ৱিজেট ব্যৱহাৰ কৰি কোনো এপ্ খুলিবলৈ, এয়া আপুনিয়েই বুলি সত্যাপন পৰীক্ষা কৰিব লাগিব। লগতে, মনত ৰাখিব যে যিকোনো লোকেই সেইবোৰ চাব পাৰে, আনকি আপোনাৰ টেবলেটটো লক হৈ থাকিলেও। কিছুমান ৱিজেট হয়তো আপোনাৰ লক স্ক্ৰীনৰ বাবে কৰা হোৱা নাই আৰু ইয়াত যোগ কৰাটো অসুৰক্ষিত হ’ব পাৰে।"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"বুজি পালোঁ"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g>এ বাৰ্তালাপৰ সুবিধাসমূহ সমৰ্থন নকৰে"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"মতামত"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"অগ্ৰাহ্য কৰক"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"পুনৰাই নেদেখুৱাব"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"এই জাননীসমূহ সংশোধন কৰিব নোৱাৰি।"</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"কলৰ জাননীসমূহ সংশোধন কৰিব নোৱাৰি।"</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"এই ধৰণৰ জাননীবোৰ ইয়াত কনফিগাৰ কৰিব পৰা নাযায়"</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"জপাব পৰা ডিভাইচৰ জাপ খুলি থকা হৈছে"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"জপাব পৰা ডিভাইচৰ ওলোটাই থকা হৈছে"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"সন্মুখৰ স্ক্ৰীনখন অন কৰা হৈছে"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"ভিতৰৰ স্ক্ৰীন ব্যৱহাৰ কৰিবলৈ স্লাইড কৰক"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"ফ’ল্ড কৰা"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"আনফ’ল্ড কৰা"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
diff --git a/packages/SystemUI/res/values-as/tiles_states_strings.xml b/packages/SystemUI/res/values-as/tiles_states_strings.xml
index da237e5..68212e0 100644
--- a/packages/SystemUI/res/values-as/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-as/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"অফ আছে"</item>
<item msgid="5908720590832378783">"অন আছে"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index e629969..4b316b6 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"vidcet seçimini silin"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Hündürlüyü azaldın"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Hündürlüyü artırın"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Növbətini göstərin"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Əvvəlkini göstərin"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Kilid ekranı vidcetləri"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Vidcetdən istifadə edərək tətbiqi açmaq üçün kimliyi doğrulamalısınız. Planşet kilidli olsa da, hər kəs vidcetlərə baxa bilər. Bəzi vidcetlər kilid ekranı üçün nəzərdə tutulmayıb və bura əlavə etmək təhlükəli ola bilər."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Anladım"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> söhbət funksiyalarını dəstəkləmir"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Rəy"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Rədd edin"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Yenidən göstərməyin"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Bu bildirişlər dəyişdirilə bilməz."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Zəng bildirişləri dəyişdirilə bilməz."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Bu bildiriş qrupunu burada konfiqurasiya etmək olmaz"</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Qatlana bilən cihaz açılır"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Qatlana bilən cihaz fırladılır"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Ön ekran aktiv edildi"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"Daxili ekrandan istifadə etmək üçün sürüşdürün"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"qatlanmış"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"açıq"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
diff --git a/packages/SystemUI/res/values-az/tiles_states_strings.xml b/packages/SystemUI/res/values-az/tiles_states_strings.xml
index 0203fb0..696fad2 100644
--- a/packages/SystemUI/res/values-az/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-az/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Deaktiv"</item>
<item msgid="5908720590832378783">"Aktiv"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 1970144..9a5bc49 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"poništi izbor vidžeta"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Smanji visinu"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Povećaj visinu"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Prikažite sledeće"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Prikažite prethodno"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Vidžeti za zaključani ekran"</string>
<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>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ne podržava funkcije konverzacije"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Povratne informacije"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Odbaci"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Ne prikazuj ponovo"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Ova obaveštenja ne mogu da se menjaju."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Obaveštenja o pozivima ne mogu da se menjaju."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Ova grupa obaveštenja ne može da se konfiguriše ovde"</string>
@@ -1370,7 +1377,7 @@
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Promenite izlaz"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Nepoznato"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"s:min"</string>
- <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"č:min"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="log_access_confirmation_title" msgid="4843557604739943395">"Želite da dozvolite da <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> pristupa svim evidencijama uređaja?"</string>
<string name="log_access_confirmation_allow" msgid="752147861593202968">"Dozvoli jednokratan pristup"</string>
<string name="log_access_confirmation_deny" msgid="2389461495803585795">"Ne dozvoli"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml b/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml
index 2401e4a..3b99019 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Isključeno"</item>
<item msgid="5908720590832378783">"Uključeno"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index afbac9f..5fc56bc 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"скасаваць выбар віджэта"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Паменшыць вышыню"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Павялічыць вышыню"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Паказаць наступны"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Паказаць папярэдні"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Віджэты на экране блакіроўкі"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Каб адкрыць праграму з дапамогай віджэта, вам неабходна будзе пацвердзіць сваю асобу. Таксама памятайце, што такія віджэты могуць пабачыць іншыя людзі, нават калі экран планшэта заблакіраваны. Некаторыя віджэты могуць не падыходзіць для выкарыстання на экране блакіроўкі, і дадаваць іх сюды можа быць небяспечна."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Зразумела"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> не падтрымлівае функцыі размовы"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Водгук"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Закрыць"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Больш не паказваць"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Гэтыя апавяшчэнні нельга змяніць."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Апавяшчэнні пра выклікі нельга змяніць."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Тут канфігурыраваць гэту групу апавяшчэнняў забаронена"</string>
diff --git a/packages/SystemUI/res/values-be/tiles_states_strings.xml b/packages/SystemUI/res/values-be/tiles_states_strings.xml
index 2dc7057..9f520da9 100644
--- a/packages/SystemUI/res/values-be/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-be/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Выключана"</item>
<item msgid="5908720590832378783">"Уключана"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 77542de..339d751 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"премахване на избора от приспособлението"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Намаляване на височината"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Увеличаване на височината"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Показване на следващия"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Показване на предишния"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Приспособления за заключения екран"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"За да отворите дадено приложение посредством приспособление, ще трябва да потвърдите, че това сте вие. Също така имайте предвид, че всеки ще вижда приспособленията дори когато таблетът ви е заключен. Възможно е някои от тях да не са предназначени за заключения екран и добавянето им на него може да е опасно."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Разбрах"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> не поддържа функциите за разговор"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Отзиви"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Отхвърляне"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Да не се показва отново"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Тези известия не могат да бъдат променяни."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Известията за обаждания не могат да бъдат променяни."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Тази група от известия не може да бъде конфигурирана тук"</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Разгъване на сгъваемо устройство"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Обръщане на сгъваемо устройство"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Предният екран е включен"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"Плъзнете, за да използвате вътрешния екран"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"затворено"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"отворено"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
diff --git a/packages/SystemUI/res/values-bg/tiles_states_strings.xml b/packages/SystemUI/res/values-bg/tiles_states_strings.xml
index cc632db7..e598f928 100644
--- a/packages/SystemUI/res/values-bg/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-bg/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Изкл."</item>
<item msgid="5908720590832378783">"Вкл."</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 6bd1e0c..ef1253b 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"উইজেট বাদ দিন"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"উচ্চতা কমান"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"উচ্চতা বাড়ান"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"পরেরটি দেখুন"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"আগেরটি দেখুন"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"লক স্ক্রিন উইজেট"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"উইজেট ব্যবহার করে কোনও অ্যাপ খুলতে, আপনাকে নিজের পরিচয় যাচাই করতে হবে। এছাড়াও, মনে রাখবেন, আপনার ট্যাবলেট লক থাকলেও যেকেউ তা দেখতে পারবেন। কিছু উইজেট আপনার লক স্ক্রিনের উদ্দেশ্যে তৈরি করা হয়নি এবং এখানে যোগ করা নিরাপদ নাও হতে পারে।"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"বুঝেছি"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g>-এ কথোপকথন ফিচার কাজ করে না"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"মতামত"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"বাতিল করুন"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"আর দেখতে চাই না"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"এই বিজ্ঞপ্তিগুলি পরিবর্তন করা যাবে না।"</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"কল বিজ্ঞপ্তি পরিবর্তন করা যাবে না।"</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"এই সমস্ত বিজ্ঞপ্তিকে এখানে কনফিগার করা যাবে না"</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ফোল্ড করা যায় এমন ডিভাইস খোলা হচ্ছে"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ফোল্ড করা যায় এমন ডিভাইস উল্টানো হচ্ছে"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"ফ্রন্ট স্ক্রিন চালু আছে"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"ভেতরের স্ক্রিন ব্যবহার করতে স্লাইড করুন"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"ফোল্ড করা রয়েছে"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"ফোল্ড করা নেই"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
diff --git a/packages/SystemUI/res/values-bn/tiles_states_strings.xml b/packages/SystemUI/res/values-bn/tiles_states_strings.xml
index e213928..38d9ee7 100644
--- a/packages/SystemUI/res/values-bn/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-bn/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"বন্ধ আছে"</item>
<item msgid="5908720590832378783">"চালু আছে"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 4ccc38a..aa036d4 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"poništavanje odabira vidžeta"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Smanjenje visine"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Povećanje visine"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Prikaz sljedećeg"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Prikaz prethodnog"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Vidžeti na zaključanom ekranu"</string>
<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>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> ne podržava funkcije razgovora"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Povratne informacije"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Odbaci"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Ne prikazuj ponovo"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Ta obavještenja se ne mogu izmijeniti."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Nije moguće izmijeniti obavještenja o pozivima."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Ovu grupu obavještenja nije moguće konfigurirati ovdje"</string>
@@ -1394,7 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Sklopivi uređaj se rasklapa"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Sklopivi uređaj se obrće"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Prednji ekran je uključen"</string>
- <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"Kliznite za upotrebu unutarnjeg zaslona"</string>
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"Kliznite da koristite unutrašnji ekran"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"sklopljeno"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"otklopljeno"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
diff --git a/packages/SystemUI/res/values-bs/tiles_states_strings.xml b/packages/SystemUI/res/values-bs/tiles_states_strings.xml
index 2401e4a..3b99019 100644
--- a/packages/SystemUI/res/values-bs/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-bs/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Isključeno"</item>
<item msgid="5908720590832378783">"Uključeno"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 80558a9..15d9283 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"desselecciona el widget"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Redueix l\'alçada"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Augmenta l\'alçada"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Mostra el següent"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Mostra l\'anterior"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgets de la pantalla de bloqueig"</string>
<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>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> no admet les funcions de converses"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Suggeriments"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Ignora"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"No ho tornis a mostrar"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Aquestes notificacions no es poden modificar."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Les notificacions de trucades no es poden modificar."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Aquest grup de notificacions no es pot configurar aquí"</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositiu plegable desplegant-se"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositiu plegable girant"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"La pantalla frontal està activada"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"Llisca per utilitzar la pantalla interior"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"plegat"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"desplegat"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1474,7 +1480,7 @@
<string name="shortcut_helper_key_combinations_forward_slash" msgid="1238652537199346970">"barra inclinada"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Ansa per arrossegar"</string>
<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_set_shortcut_button_label" msgid="4754492225010429382">"Configura"</string>
<string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Suprimeix"</string>
<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>
diff --git a/packages/SystemUI/res/values-ca/tiles_states_strings.xml b/packages/SystemUI/res/values-ca/tiles_states_strings.xml
index 94d5545..e0c3fb9 100644
--- a/packages/SystemUI/res/values-ca/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ca/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Desactivat"</item>
<item msgid="5908720590832378783">"Activat"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index ee32107..031e59d 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"zrušit výběr widgetu"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Snížit výšku"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Zvýšit výšku"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Zobrazit další"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Zobrazit předchozí"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgety na obrazovce uzamčení"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"K otevření aplikace pomocí widgetu budete muset ověřit svou totožnost. Také mějte na paměti, že widgety uvidí kdokoli, i když tablet bude uzamčen. Některé widgety nemusí být pro obrazovku uzamčení určeny a nemusí být bezpečné je na ni přidat."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Rozumím"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> funkce konverzace nepodporuje"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Zpětná vazba"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Zavřít"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Už nezobrazovat"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Tato oznámení nelze upravit."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Upozornění na hovor nelze upravit."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Tuto skupinu oznámení tady nelze nakonfigurovat"</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Rozkládání rozkládacího zařízení"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Otáčení rozkládacího zařízení"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Přední obrazovka je zapnutá"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"Pokud chcete použít vnitřní obrazovku, přejeďte prstem"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"složené"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"rozložené"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
diff --git a/packages/SystemUI/res/values-cs/tiles_states_strings.xml b/packages/SystemUI/res/values-cs/tiles_states_strings.xml
index a02ed76..ea62773 100644
--- a/packages/SystemUI/res/values-cs/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-cs/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Vypnuto"</item>
<item msgid="5908720590832378783">"Zapnuto"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 323b9d8..1ddaf8c 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"fjern markering af widget"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Reducer højden"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Forøg højden"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Vis næste"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Vis forrige"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgets på låseskærmen"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Hvis du vil åbne en app ved hjælp af en widget, skal du verificere din identitet. Husk også, at alle kan se dem, også når din tablet er låst. Nogle widgets er muligvis ikke beregnet til låseskærmen, og det kan være usikkert at tilføje dem her."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> understøtter ikke samtalefunktioner"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Feedback"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Luk"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Vis ikke igen"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Disse notifikationer kan ikke redigeres."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Opkaldsnotifikationer kan ikke redigeres."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Du kan ikke konfigurere denne gruppe notifikationer her"</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Foldbar enhed foldes ud"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Foldbar enhed vendes om"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Frontskærmen er aktiveret"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"Skub for at bruge den indre skærm"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"foldet"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"foldet ud"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
diff --git a/packages/SystemUI/res/values-da/tiles_states_strings.xml b/packages/SystemUI/res/values-da/tiles_states_strings.xml
index 8b536a2..2b1dbcf 100644
--- a/packages/SystemUI/res/values-da/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-da/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Fra"</item>
<item msgid="5908720590832378783">"Til"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 3c8be75..16bbea1 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -463,7 +463,7 @@
<string name="zen_mode_off" msgid="1736604456618147306">"Aus"</string>
<string name="zen_mode_set_up" msgid="8231201163894922821">"Nicht festgelegt"</string>
<string name="zen_mode_no_manual_invocation" msgid="1769975741344633672">"In den Einstellungen verwalten"</string>
- <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{Keine aktiven Modi}=1{{mode} aktiv}other{# aktiv}}"</string>
+ <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{Kein Modus aktiv}=1{{mode} aktiv}other{# aktiv}}"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Klingeltöne und die Vibration werden deaktiviert, außer für Weckrufe, Erinnerungen, Termine sowie Anrufe von zuvor von dir festgelegten Personen. Du hörst jedoch weiterhin Sound, wenn du dir Musik anhörst, Videos ansiehst oder Spiele spielst."</string>
<string name="zen_alarms_introduction" msgid="3987266042682300470">"Klingeltöne und die Vibration werden deaktiviert, außer für Weckrufe. Du hörst jedoch weiterhin Sound, wenn du dir Musik anhörst, Videos ansiehst oder Spiele spielst."</string>
<string name="zen_priority_customize_button" msgid="4119213187257195047">"Anpassen"</string>
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"Auswahl für Widget aufheben"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Höhe verringern"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Höhe vergrößern"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Nächstes Element anzeigen"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Vorheriges Element anzeigen"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Sperrbildschirm-Widgets"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Wenn du eine App mit einem Widget öffnen möchtest, musst du deine Identität bestätigen. Beachte auch, dass jeder die Widgets sehen kann, auch wenn dein Tablet gesperrt ist. Einige Widgets sind möglicherweise nicht für den Sperrbildschirm vorgesehen, sodass es unsicher sein kann, sie hier hinzuzufügen."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Ok"</string>
@@ -541,7 +543,7 @@
<string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Hub-Modus entdecken"</string>
<string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Du kannst während des Ladevorgangs auf deine bevorzugten Widgets und Bildschirmschoner zugreifen."</string>
<string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Los gehts"</string>
- <string name="glanceable_hub_to_dream_button_tooltip" msgid="9018287673822335829">"Beim Laden deine bevorzugten Bildschirmschoner anzeigen"</string>
+ <string name="glanceable_hub_to_dream_button_tooltip" msgid="9018287673822335829">"Beim Laden werden deine Lieblings-Bildschirmschoner angezeigt"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Nutzer wechseln"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"Pull-down-Menü"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle Apps und Daten in dieser Sitzung werden gelöscht."</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> unterstützt keine Funktionen für Unterhaltungen"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Feedback"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Schließen"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Nicht mehr anzeigen"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Diese Benachrichtigungen können nicht geändert werden."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Anrufbenachrichtigungen können nicht geändert werden."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Die Benachrichtigungsgruppe kann hier nicht konfiguriert werden"</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Faltbares Gerät wird geöffnet"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Faltbares Gerät wird umgeklappt"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Frontdisplay aktiviert"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"Ziehen, um das innere Display zu verwenden"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"zugeklappt"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"aufgeklappt"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
diff --git a/packages/SystemUI/res/values-de/tiles_states_strings.xml b/packages/SystemUI/res/values-de/tiles_states_strings.xml
index bb39b4e..ded7efd 100644
--- a/packages/SystemUI/res/values-de/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-de/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Aus"</item>
<item msgid="5908720590832378783">"An"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 470dd2c..89c2cd2 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"αποεπιλογή γραφικού στοιχείου"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Μείωση του ύψους"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Αύξηση του ύψους"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Εμφάνιση επόμενου"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Εμφάνιση προηγούμενου"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Γραφικά στοιχεία οθόνης κλειδώματος"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Για να ανοίξετε μια εφαρμογή χρησιμοποιώντας ένα γραφικό στοιχείο, θα πρέπει να επαληθεύσετε την ταυτότητά σας. Επίσης, λάβετε υπόψη ότι η προβολή τους είναι δυνατή από οποιονδήποτε, ακόμα και όταν το tablet σας είναι κλειδωμένο. Ορισμένα γραφικά στοιχεία μπορεί να μην προορίζονται για την οθόνη κλειδώματος και η προσθήκη τους εδώ ενδέχεται να μην είναι ασφαλής."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Το κατάλαβα"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> δεν υποστηρίζει τις λειτουργίες συζήτησης"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Σχόλια"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Παράβλεψη"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Να μην εμφανιστεί ξανά"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Δεν είναι δυνατή η τροποποίηση αυτών των ειδοποιήσεων"</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Δεν είναι δυνατή η τροποποίηση των ειδοποιήσεων κλήσεων."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Δεν είναι δυνατή η διαμόρφωση αυτής της ομάδας ειδοποιήσεων εδώ"</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Αναδιπλούμενη συσκευή που ξεδιπλώνει"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Αναδιπλούμενη συσκευή που διπλώνει"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Η μπροστινή οθόνη ενεργοποιήθηκε"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"Σύρετε για χρήση της εσωτερικής οθόνης"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"διπλωμένη"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"ξεδιπλωμένη"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
diff --git a/packages/SystemUI/res/values-el/tiles_states_strings.xml b/packages/SystemUI/res/values-el/tiles_states_strings.xml
index 5ce4b8c..398bf13 100644
--- a/packages/SystemUI/res/values-el/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-el/tiles_states_strings.xml
@@ -64,7 +64,7 @@
<string-array name="tile_states_rotation">
<item msgid="4578491772376121579">"Μη διαθέσιμο"</item>
<item msgid="5776427577477729185">"Ανενεργό"</item>
- <item msgid="7105052717007227415">"Ενεργό"</item>
+ <item msgid="7105052717007227415">"Ενεργή"</item>
</string-array>
<string-array name="tile_states_bt">
<item msgid="5330252067413512277">"Μη διαθέσιμο"</item>
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Ανενεργό"</item>
<item msgid="5908720590832378783">"Ενεργό"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 0c161a7..af0703c 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"unselect widget"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Decrease height"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Increase height"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Show next"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Show previous"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Lock screen widgets"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"To open an app using a widget, you\'ll need to verify that it\'s you. Also, bear in mind that anyone can view them, even when your tablet\'s locked. Some widgets may not have been intended for your lock screen and may be unsafe to add here."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Got it"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> doesn’t support conversation features"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Feedback"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Dismiss"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Don\'t show again"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"These notifications can\'t be modified."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Call notifications can\'t be modified."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"This group of notifications cannot be configured here"</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Foldable device being unfolded"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Foldable device being flipped around"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Front screen turned on"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"Slide to use inner screen"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"folded"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"unfolded"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml
index 1b60921..d62f2e5 100644
--- a/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Off"</item>
<item msgid="5908720590832378783">"On"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 3a7440b..f171a78 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"unselect widget"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Decrease height"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Increase height"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Show next"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Show previous"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Lock screen widgets"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"To open an app using a widget, you’ll need to verify it’s you. Also, keep in mind that anyone can view them, even when your tablet’s locked. Some widgets may not have been intended for your lock screen and may be unsafe to add here."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Got it"</string>
@@ -806,7 +808,9 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> doesn’t support conversation features"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Feedback"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Dismiss"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Don\'t show again"</string>
+ <string name="notification_inline_disable_promotion" msgid="3551682588314376921">"Don\'t show as pinned"</string>
+ <string name="live_notifications_title" msgid="1586553354601345379">"Showing Live Updates"</string>
+ <string name="live_notifications_desc" msgid="7470787001768372152">"Pinned notifications display live info from apps, and always appear on the status bar and lock screen"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"These notifications can\'t be modified."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Call notifications can\'t be modified."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"This group of notifications cannot be configured here"</string>
diff --git a/packages/SystemUI/res/values-en-rCA/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rCA/tiles_states_strings.xml
index 1b60921..d62f2e5 100644
--- a/packages/SystemUI/res/values-en-rCA/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Off"</item>
<item msgid="5908720590832378783">"On"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 0c161a7..af0703c 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"unselect widget"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Decrease height"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Increase height"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Show next"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Show previous"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Lock screen widgets"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"To open an app using a widget, you\'ll need to verify that it\'s you. Also, bear in mind that anyone can view them, even when your tablet\'s locked. Some widgets may not have been intended for your lock screen and may be unsafe to add here."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Got it"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> doesn’t support conversation features"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Feedback"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Dismiss"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Don\'t show again"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"These notifications can\'t be modified."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Call notifications can\'t be modified."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"This group of notifications cannot be configured here"</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Foldable device being unfolded"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Foldable device being flipped around"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Front screen turned on"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"Slide to use inner screen"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"folded"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"unfolded"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml
index 1b60921..d62f2e5 100644
--- a/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Off"</item>
<item msgid="5908720590832378783">"On"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 0c161a7..af0703c 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"unselect widget"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Decrease height"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Increase height"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Show next"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Show previous"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Lock screen widgets"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"To open an app using a widget, you\'ll need to verify that it\'s you. Also, bear in mind that anyone can view them, even when your tablet\'s locked. Some widgets may not have been intended for your lock screen and may be unsafe to add here."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Got it"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> doesn’t support conversation features"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Feedback"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Dismiss"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Don\'t show again"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"These notifications can\'t be modified."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Call notifications can\'t be modified."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"This group of notifications cannot be configured here"</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Foldable device being unfolded"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Foldable device being flipped around"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Front screen turned on"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"Slide to use inner screen"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"folded"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"unfolded"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml
index 1b60921..d62f2e5 100644
--- a/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Off"</item>
<item msgid="5908720590832378783">"On"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index dd8f735..0e15e45 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"anular la selección del widget"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Reducir la altura"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Aumentar la altura"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Mostrar siguiente"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Mostrar anterior"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgets en la pantalla de bloqueo"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Para abrir una app usando un widget, debes verificar tu identidad. Además, ten en cuenta que cualquier persona podrá verlo, incluso cuando la tablet esté bloqueada. Es posible que algunos widgets no se hayan diseñados para la pantalla de bloqueo y podría ser peligroso agregarlos allí."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Entendido"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> no admite funciones de conversación"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Comentarios"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Descartar"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"No volver a mostrar"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"No se pueden modificar estas notificaciones."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"No se pueden modificar las notificaciones de llamada."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"No se puede configurar aquí este grupo de notificaciones"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml b/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml
index 1c587d6..d835483 100644
--- a/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Desactivado"</item>
<item msgid="5908720590832378783">"Activado"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index a2fcc5c..1670ce6 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"deseleccionar widget"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Reducir altura"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Aumentar altura"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Mostrar siguiente"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Mostrar anterior"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgets para la pantalla de bloqueo"</string>
<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>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> no admite funciones de conversación"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Comentarios"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Cerrar"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"No volver a mostrar"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Estas notificaciones no se pueden modificar."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Las notificaciones de llamada no se pueden modificar."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Este grupo de notificaciones no se puede configurar aquí"</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo plegable desplegándose"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo plegable mostrado desde varios ángulos"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Pantalla frontal encendida"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"Desliza para usar la pantalla interior"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"plegado"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"desplegado"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
diff --git a/packages/SystemUI/res/values-es/tiles_states_strings.xml b/packages/SystemUI/res/values-es/tiles_states_strings.xml
index 5c4f36a..ea75e52 100644
--- a/packages/SystemUI/res/values-es/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-es/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Desactivado"</item>
<item msgid="5908720590832378783">"Activado"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index bca7491..445b540 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -504,8 +504,8 @@
<string name="accessibility_action_open_communal_hub" msgid="3081702792413787849">"Lukustuskuva vidinad"</string>
<string name="accessibility_announcement_communal_widget_added" msgid="6911593106099328271">"Vidin <xliff:g id="WIDGET_NAME">%1$s</xliff:g> lisati lukustuskuvale"</string>
<string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Ühise õpetuse käivitamiseks pühkige vasakule"</string>
- <string name="cta_tile_button_to_open_widget_editor" msgid="3871562362382963878">"Kohandage"</string>
- <string name="cta_tile_button_to_dismiss" msgid="3377597875997861754">"Loobuge"</string>
+ <string name="cta_tile_button_to_open_widget_editor" msgid="3871562362382963878">"Kohanda"</string>
+ <string name="cta_tile_button_to_dismiss" msgid="3377597875997861754">"Loobu"</string>
<string name="cta_label_to_edit_widget" msgid="6496885074209203756">"Lisage ja eemaldage vidinaid ning muutke nende järjestust"</string>
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Lisage rohkem vidinaid"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Vajutage pikalt vidinate kohandamiseks"</string>
@@ -530,10 +530,12 @@
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"eemaldage vidin"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"asetage valitud vidin"</string>
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Lukustuskuva vidinad"</string>
- <string name="communal_widget_picker_description" msgid="490515450110487871">"Igaüks saab vaadata luk.kuval olevaid vidinaid, isegi kui tahvelarvuti on lukus."</string>
+ <string name="communal_widget_picker_description" msgid="490515450110487871">"Igaüks saab vaadata lukustuskuval olevaid vidinaid, isegi kui tahvelarvuti on lukus."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"tühistage vidina valimine"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Vähenda kõrgust"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Suurenda kõrgust"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Kuva järgmine"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Kuva eelmine"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Lukustuskuva vidinad"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Rakenduse avamiseks vidina abil peate kinnitama, et see olete teie. Samuti pidage meeles, et kõik saavad vidinaid vaadata, isegi kui teie tahvelarvuti on lukus. Mõni vidin ei pruugi olla ette nähtud teie lukustuskuva jaoks ja seda pole turvaline siia lisada."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Selge"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ei toeta vestlusfunktsioone"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Tagasiside"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Loobu"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Ära enam näita"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Neid märguandeid ei saa muuta."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Kõnemärguandeid ei saa muuta."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Seda märguannete rühma ei saa siin seadistada"</string>
diff --git a/packages/SystemUI/res/values-et/tiles_states_strings.xml b/packages/SystemUI/res/values-et/tiles_states_strings.xml
index f995128..a9f0880 100644
--- a/packages/SystemUI/res/values-et/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-et/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Väljas"</item>
<item msgid="5908720590832378783">"Sees"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index f447dc6..1f7d697 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"desautatu widgeta"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Txikitu altuera"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Handitu altuera"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Erakutsi hurrengoa"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Erakutsi aurrekoa"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Pantaila blokeatuko widgetak"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Aplikazio bat widget baten bidez irekitzeko, zeu zarela egiaztatu beharko duzu. Gainera, kontuan izan edonork ikusi ahalko dituela halako widgetak, tableta blokeatuta badago ere. Baliteke widget batzuk pantaila blokeaturako egokiak ez izatea, eta agian ez da segurua haiek bertan gehitzea."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Ados"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioak ez ditu onartzen elkarrizketetarako eginbideak"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Iritzia"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Baztertu"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Ez erakutsi berriro"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Jakinarazpen horiek ezin dira aldatu."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Deien jakinarazpenak ezin dira aldatu."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Jakinarazpen talde hau ezin da konfiguratu hemen"</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Gailu tolesgarria zabaltzen"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Gailu tolesgarria biratzen"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Aurreko pantaila piztuta dago"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"Lerratu hau barneko pantaila erabiltzeko"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"tolestuta"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"tolestu gabe"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
diff --git a/packages/SystemUI/res/values-eu/tiles_states_strings.xml b/packages/SystemUI/res/values-eu/tiles_states_strings.xml
index 5d4672f..62bbc27 100644
--- a/packages/SystemUI/res/values-eu/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-eu/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Desaktibatuta"</item>
<item msgid="5908720590832378783">"Aktibatuta"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 800bf78..c9392e3 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -125,7 +125,7 @@
<string name="screenrecord_continue" msgid="4055347133700593164">"شروع"</string>
<string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"درحال ضبط صفحهنمایش"</string>
<string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"درحال ضبط صفحهنمایش و صدا"</string>
- <string name="screenrecord_taps_label" msgid="1595690528298857649">"نمایش قسمتهای لمسشده روی صفحهنمایش"</string>
+ <string name="screenrecord_taps_label" msgid="1595690528298857649">"نمایش نقاط لمس روی صفحهنمایش"</string>
<string name="screenrecord_stop_label" msgid="72699670052087989">"متوقف کردن"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"همرسانی"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"قطعه ضبطشده از صفحهنمایش ذخیره شد"</string>
@@ -133,7 +133,7 @@
<string name="screenrecord_save_error" msgid="5862648532560118815">"خطا در ذخیرهسازی ضبط صفحهنمایش"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"خطا هنگام شروع ضبط صفحهنمایش"</string>
<string name="screenrecord_stop_dialog_title" msgid="8716193661764511095">"ضبط متوقف شود؟"</string>
- <string name="screenrecord_stop_dialog_message" msgid="6262768207331626817">"اکنون درحال ضبط کل صفحهنمایشتان هستید"</string>
+ <string name="screenrecord_stop_dialog_message" msgid="6262768207331626817">"اکنون درحال ضبط کل صفحهنمایش هستید"</string>
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"اکنون درحال ضبط <xliff:g id="APP_NAME">%1$s</xliff:g> هستید"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"توقف ضبط"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"درحال همرسانی صفحه"</string>
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"لغو انتخاب ابزاره"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"کاهش ارتفاع"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"افزایش ارتفاع"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"نمایش بعدی"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"نمایش قبلی"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"ابزارههای صفحه قفل"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"برای باز کردن برنامه بااستفاده از ابزاره، باید هویت خودتان را بهتأیید برسانید. همچنین، بهخاطر داشته باشید که همه میتوانند آنها را مشاهده کنند، حتی وقتی رایانه لوحیتان قفل است. برخیاز ابزارهها ممکن است برای صفحه قفل درنظر گرفته نشده باشند و ممکن است اضافه کردن آنها در اینجا ناامن باشد."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"متوجهم"</string>
@@ -542,7 +544,7 @@
<string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"در حین شارژ، به ابزارهها و محافظهای صفحهنمایش دلخواهتان دسترسی داشته باشید."</string>
<string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"بیایید شروع کنیم"</string>
<string name="glanceable_hub_to_dream_button_tooltip" msgid="9018287673822335829">"نمایش محافظهای صفحهنمایش دلخواه درحین شارژ"</string>
- <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"تغییر کاربر"</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>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"مهمان گرامی، بازگشتتان را خوش آمد میگوییم!"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> از ویژگیهای مکالمه پشتیبانی نمیکند"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"بازخورد"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"بستن"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"دیگر نشان داده نشود"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"این اعلانها قابل اصلاح نیستند."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"این اعلانها قابلاصلاح نیستند."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"نمیتوانید این گروه اعلانها را در اینجا پیکربندی کنید"</string>
diff --git a/packages/SystemUI/res/values-fa/tiles_states_strings.xml b/packages/SystemUI/res/values-fa/tiles_states_strings.xml
index 1f9d6c6..edc2d41 100644
--- a/packages/SystemUI/res/values-fa/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-fa/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"خاموش"</item>
<item msgid="5908720590832378783">"روشن"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index fdf18a3..96162b2 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -536,6 +536,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"poista widgetin valinta"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Vähennä korkeutta"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Lisää korkeutta"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Näytä seuraava"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Näytä edellinen"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Lukitusnäytön widgetit"</string>
<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>
@@ -808,7 +810,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ei tue keskusteluominaisuuksia"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Palaute"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Hylkää"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Älä näytä uudelleen"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Näitä ilmoituksia ei voi muokata"</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Puheluilmoituksia ei voi muokata."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Tätä ilmoitusryhmää ei voi määrittää tässä"</string>
@@ -1396,8 +1403,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Taitettava laite taitetaan"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Taitettava laite käännetään ympäri"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Etunäyttö päällä"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"Liu\'uta käyttääksesi sisäistä näyttöä"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"taitettu"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"taittamaton"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
diff --git a/packages/SystemUI/res/values-fi/tiles_states_strings.xml b/packages/SystemUI/res/values-fi/tiles_states_strings.xml
index 96750ef..6b1a8ed 100644
--- a/packages/SystemUI/res/values-fi/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-fi/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Pois päältä"</item>
<item msgid="5908720590832378783">"Päällä"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index dde9b64..8fd2ed2 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"désélectionner le widget"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Diminuer la hauteur"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Augmenter la hauteur"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Afficher le suivant"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Afficher le précédent"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgets de l\'écran de verrouillage"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Pour ouvrir une appli à l\'aide d\'un widget, vous devrez confirmer votre identité. En outre, gardez à l\'esprit que tout le monde peut voir les widgets, même lorsque votre tablette est verrouillée. Certains widgets n\'ont peut-être pas été conçus pour votre écran de verrouillage, et il pourrait être dangereux de les ajouter ici."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ne prend pas en charge les fonctionnalités de conversation"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Commentaires"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Fermer"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Ne plus afficher"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Ces notifications ne peuvent pas être modifiées"</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Les notifications d\'appel ne peuvent pas être modifiées."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Ce groupe de notifications ne peut pas être configuré ici"</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Appareil pliable en cours de dépliage"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Appareil pliable en train d\'être retourné"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Écran avant activé"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"Faites glisser pour utiliser l\'écran intérieur"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"plié"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"déplié"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml b/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml
index ffacde2..4734d86 100644
--- a/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Désactivée"</item>
<item msgid="5908720590832378783">"Activée"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 53dbfea..89002d4 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"désélectionner le widget"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Diminuer la hauteur"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Augmenter la hauteur"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Afficher le suivant"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Afficher le précédent"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgets pour l\'écran de verrouillage"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Pour ouvrir une appli à l\'aide d\'un widget, vous devez confirmer qu\'il s\'agit bien de vous. N\'oubliez pas non plus que tout le monde peut voir vos widgets, même lorsque votre tablette est verrouillée. Certains d\'entre eux n\'ont pas été conçus pour l\'écran de verrouillage et les ajouter à cet endroit peut s\'avérer dangereux."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> n\'est pas compatible avec les fonctionnalités de conversation"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Commentaires"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Ignorer"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Ne plus afficher"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Impossible de modifier ces notifications."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Impossible de modifier les notifications d\'appel."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Vous ne pouvez pas configurer ce groupe de notifications ici"</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Appareil pliable qui est déplié"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Appareil pliable qui est retourné"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Écran avant activé"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"Faites glisser pour utiliser l\'écran intérieur"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"plié"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"déplié"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
diff --git a/packages/SystemUI/res/values-fr/tiles_states_strings.xml b/packages/SystemUI/res/values-fr/tiles_states_strings.xml
index ffceb0d..cefc9a2 100644
--- a/packages/SystemUI/res/values-fr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-fr/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Désactivé"</item>
<item msgid="5908720590832378783">"Activé"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 03ec2b0..4e801ee 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -125,7 +125,7 @@
<string name="screenrecord_continue" msgid="4055347133700593164">"Iniciar"</string>
<string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"Gravando pantalla"</string>
<string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"Gravando pantalla e audio"</string>
- <string name="screenrecord_taps_label" msgid="1595690528298857649">"Mostrar a localización dos toques na pantalla"</string>
+ <string name="screenrecord_taps_label" msgid="1595690528298857649">"Mostrar localización dos toques na pantalla"</string>
<string name="screenrecord_stop_label" msgid="72699670052087989">"Deter"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Compartir"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Gravación da pantalla gardada"</string>
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"anular a selección do widget"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Reducir a altura"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Aumentar a altura"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Mostrar seguinte"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Mostrar anterior"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgets da pantalla de bloqueo"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Para abrir unha aplicación mediante un widget, tes que verificar a túa identidade. Ten en conta que pode velos calquera persoa, mesmo coa tableta bloqueada. Pode ser que algúns widgets non estean pensados para a túa pantalla de bloqueo, polo que talvez non sexa seguro engadilos aquí."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Entendido"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> non admite funcións de conversa"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Comentarios"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Pechar"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Non volver mostrar"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Estas notificacións non se poden modificar."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"As notificacións de chamadas non se poden modificar."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Aquí non se pode configurar este grupo de notificacións"</string>
@@ -1349,7 +1356,7 @@
<string name="clipboard_image_preview" msgid="2156475174343538128">"Vista previa da imaxe"</string>
<string name="clipboard_edit" msgid="4500155216174011640">"editar"</string>
<string name="add" msgid="81036585205287996">"Engadir"</string>
- <string name="manage_users" msgid="1823875311934643849">"Usuarios"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Xestionar usuarios"</string>
<string name="drag_split_not_supported" msgid="7173481676120546121">"Esta notificación non pode arrastrarse á pantalla dividida"</string>
<string name="dream_overlay_location_active" msgid="6484763493158166618">"Localización activa"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"A wifi non está dispoñible"</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo pregable abríndose"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo pregable xirando"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Activouse a pantalla dianteira"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"Pasa o dedo para usar a pantalla interior"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"dispositivo pregado"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"dispositivo despregado"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
diff --git a/packages/SystemUI/res/values-gl/tiles_states_strings.xml b/packages/SystemUI/res/values-gl/tiles_states_strings.xml
index 7889983..bfd6a12 100644
--- a/packages/SystemUI/res/values-gl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-gl/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Opción desactivada"</item>
<item msgid="5908720590832378783">"Opción activada"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 0c27927..08e1398 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"વિજેટ નાપસંદ કરો"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"ઊંચાઈ ઘટાડો"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"ઊંચાઈ વધારો"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"આગલું બતાવો"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"પાછલું બતાવો"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"લૉક સ્ક્રીન વિજેટ"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"વિજેટનો ઉપયોગ કરીને ઍપ ખોલવા માટે, તમારે એ ચકાસણી કરવાની જરૂર રહેશે કે આ તમે જ છો. તે ઉપરાંત, ધ્યાનમાં રાખો કે તમારું ટૅબ્લેટ લૉક કરેલું હોય તો પણ કોઈપણ વ્યક્તિ તેમને જોઈ શકે છે. અમુક વિજેટ કદાચ તમારી લૉક સ્ક્રીન માટે બનાવવામાં આવ્યા ન હોઈ શકે છે અને તેમને અહીં ઉમેરવાનું અસલામત હોઈ શકે છે."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"સમજાઈ ગયું"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> વાતચીતની સુવિધાઓને સપોર્ટ આપતી નથી"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"પ્રતિસાદ"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"છોડી દો"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"ફરી બતાવશો નહીં"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"આ નોટિફિકેશનમાં કોઈ ફેરફાર થઈ શકશે નહીં."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"કૉલના નોટિફિકેશનમાં કોઈ ફેરફાર કરી શકાતો નથી."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"નોટિફિકેશનના આ ગ્રૂપની ગોઠવણી અહીં કરી શકાશે નહીં"</string>
diff --git a/packages/SystemUI/res/values-gu/tiles_states_strings.xml b/packages/SystemUI/res/values-gu/tiles_states_strings.xml
index 17b47cc..c6e204d 100644
--- a/packages/SystemUI/res/values-gu/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-gu/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"બંધ છે"</item>
<item msgid="5908720590832378783">"ચાલુ"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index f2daffe..d781585 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"विजेट से चुने हुए का निशान हटाएं"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"ऊंचाई घटाएं"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"ऊंचाई बढ़ाएं"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"अगला दिखाएं"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"पिछला दिखाएं"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"लॉक स्क्रीन विजेट"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"किसी विजेट से कोई ऐप्लिकेशन खोलने के लिए, आपको अपनी पहचान की पुष्टि करनी होगी. ध्यान रखें कि आपके टैबलेट के लॉक होने पर भी, कोई व्यक्ति विजेट देख सकता है. ऐसा हो सकता है कि कुछ विजेट, लॉक स्क्रीन पर दिखाने के लिए न बने हों. इन्हें लॉक स्क्रीन पर जोड़ना असुरक्षित हो सकता है."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"ठीक है"</string>
@@ -542,7 +544,7 @@
<string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"चार्जिंग के दौरान, अपने पसंदीदा विजेट और स्क्रीन सेवर को ऐक्सेस करें."</string>
<string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"आइए शुरू करें"</string>
<string name="glanceable_hub_to_dream_button_tooltip" msgid="9018287673822335829">"चार्ज करते समय अपने पसंदीदा स्क्रीन सेवर दिखाएं"</string>
- <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"उपयोगकर्ता बदलें"</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>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"मेहमान, आपका फिर से स्वागत है!"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> पर बातचीत की सुविधाएं काम नहीं करतीं"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"सुझाव/राय दें या शिकायत करें"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"खारिज करें"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"फिर से न दिखाएं"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"ये सूचनाएं नहीं बदली जा सकती हैं."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"कॉल से जुड़ी सूचनाओं को ब्लॉक नहीं किया जा सकता."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"सूचनाओं के इस समूह को यहां कॉन्फ़िगर नहीं किया जा सकता"</string>
diff --git a/packages/SystemUI/res/values-hi/tiles_states_strings.xml b/packages/SystemUI/res/values-hi/tiles_states_strings.xml
index 69a4e4d..65046cc 100644
--- a/packages/SystemUI/res/values-hi/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-hi/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"बंद है"</item>
<item msgid="5908720590832378783">"चालू है"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 5222e80..3a985a9 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"poništavanje odabira widgeta"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Smanjenje visine"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Povećanje visine"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Prikazivanje sljedećeg"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Prikazivanje prethodnog"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgeti na zaključanom zaslonu"</string>
<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>
@@ -731,7 +733,7 @@
<string name="volume_panel_hint_muted" msgid="1124844870181285320">"isključen zvuk"</string>
<string name="volume_panel_hint_vibrate" msgid="4136223145435914132">"vibriranje"</string>
<string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g> se reproducira na"</string>
- <string name="media_output_title_without_playing" msgid="3825663683169305013">"Zvuk će se reproducirati na"</string>
+ <string name="media_output_title_without_playing" msgid="3825663683169305013">"Za reprodukciju zvuka koristi se"</string>
<string name="media_output_title_ongoing_call" msgid="208426888064112006">"Pozivanje na uređaju"</string>
<string name="system_ui_tuner" msgid="1471348823289954729">"Ugađanje korisničkog sučelja sustava"</string>
<string name="status_bar" msgid="4357390266055077437">"Traka statusa"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> ne podržava značajke razgovora"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Povratne informacije"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Odbaci"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Ne prikazuj ponovo"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Te se obavijesti ne mogu izmijeniti."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Obavijesti o pozivima ne mogu se izmijeniti."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Ta se grupa obavijesti ne može konfigurirati ovdje"</string>
diff --git a/packages/SystemUI/res/values-hr/tiles_states_strings.xml b/packages/SystemUI/res/values-hr/tiles_states_strings.xml
index 2401e4a..3b99019 100644
--- a/packages/SystemUI/res/values-hr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-hr/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Isključeno"</item>
<item msgid="5908720590832378783">"Uključeno"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 109c52f..9b17567 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"modul kijelölésének megszüntetése"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Magasság csökkentése"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Magasság növelése"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Következő mutatása"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Előző mutatása"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"A lezárási képernyő moduljai"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Ha modul használatával szeretne megnyitni egy alkalmazást, igazolnia kell a személyazonosságát. Ne felejtse továbbá, hogy bárki megtekintheti a modulokat, még akkor is, amikor zárolva van a táblagép. Előfordulhat, hogy bizonyos modulokat nem a lezárási képernyőn való használatra terveztek, ezért nem biztonságos a hozzáadásuk."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Értem"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> nem támogatja a beszélgetési funkciókat"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Visszajelzés"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Elvetés"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Ne jelenjen meg újra"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Ezeket az értesítéseket nem lehet módosítani."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"A hívásértesítéseket nem lehet módosítani."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Az értesítések jelen csoportját itt nem lehet beállítani"</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Összehajtható eszköz kihajtása"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Összehajtható eszköz körbeforgatása"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Előlapi képernyő bekapcsolva"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"Csúsztatás a belső képernyő használatához"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"összehajtva"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"kihajtva"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
diff --git a/packages/SystemUI/res/values-hu/tiles_states_strings.xml b/packages/SystemUI/res/values-hu/tiles_states_strings.xml
index 8911fe9..06bf4f2 100644
--- a/packages/SystemUI/res/values-hu/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-hu/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Ki"</item>
<item msgid="5908720590832378783">"Be"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 914d2cd..2aa72cc 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"չեղարկել վիջեթի ընտրությունը"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Նվազեցնել բարձրությունը"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Ավելացնել բարձրությունը"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Ցույց տալ հաջորդը"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Ցույց տալ նախորդը"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Կողպէկրանի վիջեթներ"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Վիջեթի միջոցով հավելված բացելու համար դուք պետք է հաստատեք ձեր ինքնությունը։ Նաև նկատի ունեցեք, որ ցանկացած ոք կարող է դիտել վիջեթները, նույնիսկ երբ ձեր պլանշետը կողպված է։ Որոշ վիջեթներ կարող են նախատեսված չլինել ձեր կողպէկրանի համար, և այստեղ դրանց ավելացնելը կարող է վտանգավոր լինել։"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Եղավ"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը զրույցի գործառույթներ չի աջակցում"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Կարծիք հայտնել"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Փակել"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Այլևս ցույց չտալ"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Այս ծանուցումները չեն կարող փոփոխվել:"</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Զանգերի մասին ծանուցումները հնարավոր չէ փոփոխել։"</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Ծանուցումների տվյալ խումբը հնարավոր չէ կարգավորել այստեղ"</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Ծալովի սարք՝ բացված վիճակում"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Ծալովի սարք՝ շրջված վիճակում"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Առջևի էկրանը միացված է"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"Սահեցրեք՝ ներքին էկրանն օգտագործելու համար"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"ծալված"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"բացված"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
diff --git a/packages/SystemUI/res/values-hy/tiles_states_strings.xml b/packages/SystemUI/res/values-hy/tiles_states_strings.xml
index f2b09e0..dc8bbb1 100644
--- a/packages/SystemUI/res/values-hy/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-hy/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Անջատված է"</item>
<item msgid="5908720590832378783">"Միացված է"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 62e3476..c57f40f 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -250,8 +250,8 @@
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Persentase baterai tidak diketahui."</string>
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Terhubung ke <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Terhubung ke <xliff:g id="CAST">%s</xliff:g>."</string>
- <string name="accessibility_expand_group" msgid="521237935987978624">"Meluaskan grup."</string>
- <string name="accessibility_open_application" msgid="1749126077501259712">"Membuka aplikasi."</string>
+ <string name="accessibility_expand_group" msgid="521237935987978624">"Luaskan grup."</string>
+ <string name="accessibility_open_application" msgid="1749126077501259712">"Buka aplikasi."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Tidak terhubung."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
<string name="cell_data_off" msgid="4886198950247099526">"Nonaktif"</string>
@@ -345,7 +345,7 @@
<string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Jaringan tidak tersedia"</string>
<string name="quick_settings_wifi_detail_empty_text" msgid="483130889414601732">"Tidak ada jaringan Wi-Fi yang tersedia"</string>
<string name="quick_settings_wifi_secondary_label_transient" msgid="7501659015509357887">"Mengaktifkan…"</string>
- <string name="quick_settings_cast_title" msgid="3033553249449938182">"Cast"</string>
+ <string name="quick_settings_cast_title" msgid="3033553249449938182">"Transmisikan"</string>
<string name="quick_settings_casting" msgid="1435880708719268055">"Melakukan transmisi"</string>
<string name="quick_settings_cast_device_default_name" msgid="6988469571141331700">"Perangkat tanpa nama"</string>
<string name="quick_settings_cast_detail_empty_text" msgid="2846282280014617785">"Perangkat tak tersedia"</string>
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"batalkan pilihan widget"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Kurangi tinggi"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Tambah tinggi"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Tampilkan berikutnya"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Tampilkan sebelumnya"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widget layar kunci"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Untuk membuka aplikasi menggunakan widget, Anda perlu memverifikasi diri Anda. Selain itu, harap ingat bahwa siapa saja dapat melihatnya, bahkan saat tablet Anda terkunci. Beberapa widget mungkin tidak dirancang untuk layar kunci Anda dan mungkin tidak aman untuk ditambahkan di sini."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Oke"</string>
@@ -542,7 +544,7 @@
<string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Akses widget dan screensaver favorit Anda saat mengisi daya."</string>
<string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Mulai"</string>
<string name="glanceable_hub_to_dream_button_tooltip" msgid="9018287673822335829">"Tampilkan screensaver favorit saat mengisi daya"</string>
- <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Beralih pengguna"</string>
+ <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Ganti pengguna"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu pulldown"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Semua aplikasi dan data dalam sesi ini akan dihapus."</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Selamat datang kembali, tamu!"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak mendukung fitur percakapan"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Masukan"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Tutup"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Jangan tampilkan lagi"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Notifikasi ini tidak dapat diubah."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Notifikasi panggilan tidak dapat diubah."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Grup notifikasi ini tidak dapat dikonfigurasi di sini"</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Perangkat foldable sedang dibentangkan"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Perangkat foldable sedang dibalik"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Layar depan diaktifkan"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"Geser untuk menggunakan layar dalam"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"ditutup"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"dibuka"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
diff --git a/packages/SystemUI/res/values-in/tiles_states_strings.xml b/packages/SystemUI/res/values-in/tiles_states_strings.xml
index 7462ff6..b48a587 100644
--- a/packages/SystemUI/res/values-in/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-in/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Nonaktif"</item>
<item msgid="5908720590832378783">"Aktif"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 4e486d0..ec284c2 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"afturkalla val á græju"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Lækka"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Hækka"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Sýna næsta"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Sýna fyrra"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Græjur fyrir lásskjá"</string>
<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>
@@ -731,7 +733,7 @@
<string name="volume_panel_hint_muted" msgid="1124844870181285320">"þaggað"</string>
<string name="volume_panel_hint_vibrate" msgid="4136223145435914132">"titringur"</string>
<string name="media_output_label_title" msgid="872824698593182505">"Í spilun í <xliff:g id="LABEL">%s</xliff:g>"</string>
- <string name="media_output_title_without_playing" msgid="3825663683169305013">"Hljóð heldur áfram að spilast"</string>
+ <string name="media_output_title_without_playing" msgid="3825663683169305013">"Hljóð heldur áfram að spilast í"</string>
<string name="media_output_title_ongoing_call" msgid="208426888064112006">"Símtal í gangi"</string>
<string name="system_ui_tuner" msgid="1471348823289954729">"Fínstillingar kerfisviðmóts"</string>
<string name="status_bar" msgid="4357390266055077437">"Stöðustika"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> styður ekki samtalseiginleika"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Ábendingar"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Loka"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Ekki sýna aftur"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Ekki er hægt að breyta þessum tilkynningum."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Ekki er hægt að breyta tilkynningum um símtöl."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Ekki er hægt að stilla þessar tilkynningar hér"</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Samanbrjótanlegt tæki opnað"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Samanbrjótanlegu tæki snúið við"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Kveikt á fremri skjá"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"Renndu til að opna innri skjá"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"samanbrotið"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"opið"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
diff --git a/packages/SystemUI/res/values-is/tiles_states_strings.xml b/packages/SystemUI/res/values-is/tiles_states_strings.xml
index df3bcf9..92f07b6 100644
--- a/packages/SystemUI/res/values-is/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-is/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Slökkt"</item>
<item msgid="5908720590832378783">"Kveikt"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 786254b..2391fe2 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"deseleziona widget"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Riduci altezza"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Aumenta altezza"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Mostra successivo"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Mostra precedente"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widget della schermata di blocco"</string>
<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>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> non supporta le funzionalità delle conversazioni"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Feedback"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Ignora"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Non mostrare più"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Impossibile modificare queste notifiche."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Impossibile modificare gli avvisi di chiamata."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Qui non è possibile configurare questo gruppo di notifiche"</string>
@@ -1396,7 +1403,7 @@
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Schermo frontale attivato"</string>
<string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"Scorri per usare lo schermo interno"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"Piegato"</string>
- <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"Non piegato"</string>
+ <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"Aperto"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
<string name="stylus_battery_low_percentage" msgid="2564243323894629626">"Batteria dello stilo: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
<string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Connetti lo stilo a un caricabatterie"</string>
diff --git a/packages/SystemUI/res/values-it/tiles_states_strings.xml b/packages/SystemUI/res/values-it/tiles_states_strings.xml
index 9d26859..7e11d0b 100644
--- a/packages/SystemUI/res/values-it/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-it/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Off"</item>
<item msgid="5908720590832378783">"On"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 5000885..0d7a620 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"ביטול הבחירה בווידג\'ט"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"הקטנת הגובה"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"הגדלת הגובה"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"לפריט הבא"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"לפריט הקודם"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"ווידג\'טים במסך הנעילה"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"כדי לפתוח אפליקציה באמצעות ווידג\'ט, עליך לאמת את זהותך. בנוסף, כדאי לזכור שכל אחד יכול לראות את הווידג\'טים גם כשהטאבלט שלך נעול. יכול להיות שחלק מהווידג\'טים לא נועדו למסך הנעילה ושלא בטוח להוסיף אותם לכאן."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"הבנתי"</string>
@@ -804,10 +806,14 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"מוצגת בחלק העליון של קטע התראות השיחה וכתמונת פרופיל במסך הנעילה, מופיעה בבועה צפה ומפריעה במצב \'נא לא להפריע\'"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"בעדיפות גבוהה"</string>
<string name="no_shortcut" msgid="8257177117568230126">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> לא תומכת בתכונות השיחה"</string>
- <!-- no translation found for notification_guts_bundle_feedback (7581587973879656500) -->
- <skip />
+ <string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"משוב"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"סגירה"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"לא להציג את זה שוב"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"לא ניתן לשנות את ההתראות האלה."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"לא ניתן לשנות את התראות השיחה."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"לא ניתן להגדיר כאן את קבוצת ההתראות הזו"</string>
@@ -1395,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"מכשיר מתקפל עובר למצב לא מקופל"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"מכשיר מתקפל עובר למצב מהופך"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"המסך הקדמי מופעל"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"כדי להשתמש במסך הפנימי, צריך להסיט"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"מצב מקופל"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"מצב לא מקופל"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
diff --git a/packages/SystemUI/res/values-iw/tiles_states_strings.xml b/packages/SystemUI/res/values-iw/tiles_states_strings.xml
index 1a5b8fb..2f8ec0a 100644
--- a/packages/SystemUI/res/values-iw/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-iw/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"מושבת"</item>
<item msgid="5908720590832378783">"מצב פעיל"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index fd98fe8..7867633 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"ウィジェットの選択を解除する"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"高さを低くする"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"高さを高くする"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"次を表示"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"前を表示"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"ロック画面ウィジェット"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ウィジェットを使用してアプリを起動するには、本人確認が必要です。タブレットがロックされた状態でも他のユーザーにウィジェットが表示されますので、注意してください。一部のウィジェットについてはロック画面での使用を想定していないため、ロック画面への追加は危険な場合があります。"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g>は会話機能に対応していません"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"フィードバック"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"閉じる"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"次回から表示しない"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"これらの通知は変更できません。"</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"着信通知は変更できません。"</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"このグループの通知はここでは設定できません"</string>
diff --git a/packages/SystemUI/res/values-ja/tiles_states_strings.xml b/packages/SystemUI/res/values-ja/tiles_states_strings.xml
index 81c10e7..1282f57 100644
--- a/packages/SystemUI/res/values-ja/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ja/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"OFF"</item>
<item msgid="5908720590832378783">"ON"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 18522da..b599220 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"ვიჯეტის არჩევის გაუქმება"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"სიმაღლის შემცირება"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"სიმაღლის გაზრდა"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"შემდეგის ჩვენება"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"წინას ჩვენება"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"დაბლოკილი ეკრანის ვიჯეტები"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"უნდა დაადასტუროთ თქვენი ვინაობა, რათა გახსნათ აპი ვიჯეტის გამოყენებით. გაითვალისწინეთ, რომ ნებისმიერს შეუძლია მათი ნახვა, მაშინაც კი, როცა ტაბლეტი დაბლოკილია. ზოგი ვიჯეტი შეიძლება არ იყოს გათვლილი თქვენი დაბლოკილი ეკრანისთვის და მათი აქ დამატება შეიძლება სახიფათო იყოს."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"გასაგებია"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ს არ აქვს მიმოწერის ფუნქციების მხარდაჭერა"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"გამოხმაურება"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"დახურვა"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"აღარ მაჩვენო"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"ამ შეტყობინებების შეცვლა შეუძლებელია."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"ზარის შეტყობინებების შეცვლა შეუძლებელია."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"შეტყობინებების ამ ჯგუფის კონფიგურირება აქ შეუძლებელია"</string>
diff --git a/packages/SystemUI/res/values-ka/tiles_states_strings.xml b/packages/SystemUI/res/values-ka/tiles_states_strings.xml
index 6e62ed4e..81fc54d 100644
--- a/packages/SystemUI/res/values-ka/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ka/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"გამორთული"</item>
<item msgid="5908720590832378783">"ჩართული"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 83af7c8..bf12aca 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -114,7 +114,7 @@
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="4882406311415082016">"Осы экранды жазу"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="4169494703993148253">"%s экранын жазу"</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_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>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"Аудио жазу"</string>
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"виджетті таңдаудан алу"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Биіктігін төмендету"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Биіктігін арттыру"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Келесіні көрсету"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Алдыңғыны көрсету"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Құлып экранының виджеттері"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Қолданбаны виджет көмегімен ашу үшін жеке басыңызды растауыңыз керек. Сондай-ақ басқалар оларды планшетіңіз құлыптаулы кезде де көре алатынын ескеріңіз. Кейбір виджеттер құлып экранына арналмаған болады, сондықтан оларды мұнда қосу қауіпсіз болмауы мүмкін."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Түсінікті"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> әңгіме функцияларын қолдамайды."</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Пікір"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Жабу"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Қайта көрсетілмесін"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Бұл хабарландыруларды өзгерту мүмкін емес."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Қоңырау туралы хабарландыруларды өзгерту мүмкін емес."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Мұндай хабарландырулар бұл жерде конфигурацияланбайды."</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Бүктемелі құрылғы ашылып жатыр."</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Бүктемелі құрылғы аударылып жатыр."</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Алдыңғы экран қосылды."</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"Ішкі экранды пайдалану үшін жылжытыңыз."</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"жабық"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"ашық"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
diff --git a/packages/SystemUI/res/values-kk/tiles_states_strings.xml b/packages/SystemUI/res/values-kk/tiles_states_strings.xml
index 66deff6..32562c6 100644
--- a/packages/SystemUI/res/values-kk/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-kk/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Өшірулі"</item>
<item msgid="5908720590832378783">"Қосулы"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 569ecd3..e12fd13 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"ដកការជ្រើសរើសធាតុក្រាហ្វិក"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"បន្ថយកម្ពស់"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"បង្កើនកម្ពស់"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"បង្ហាញកម្មវិធីចាក់មេឌៀបន្ទាប់"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"បង្ហាញកម្មវិធីចាក់មេឌៀមុន"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"ធាតុក្រាហ្វិកលើអេក្រង់ចាក់សោ"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ដើម្បីបើកកម្មវិធីដោយប្រើធាតុក្រាហ្វិក អ្នកនឹងត្រូវផ្ទៀងផ្ទាត់ថាជាអ្នក។ ទន្ទឹមនឹងនេះ សូមចងចាំថា នរណាក៏អាចមើលធាតុក្រាហ្វិកបាន សូម្បីពេលថេប្លេតរបស់អ្នកជាប់សោក៏ដោយ។ ធាតុក្រាហ្វិកមួយចំនួនប្រហែលមិនត្រូវបានរចនាឡើងសម្រាប់អេក្រង់ចាក់សោរបស់អ្នកទេ និងមិនមានសុវត្ថិភាពឡើយ បើបញ្ចូលទៅទីនេះ។"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"យល់ហើយ"</string>
@@ -542,7 +544,7 @@
<string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"ចូលប្រើប្រាស់ធាតុក្រាហ្វិក និងធាតុរក្សាអេក្រង់ដែលអ្នកពេញចិត្តពេលសាកថ្ម។"</string>
<string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"ចាប់ផ្ដើម"</string>
<string name="glanceable_hub_to_dream_button_tooltip" msgid="9018287673822335829">"បង្ហាញធាតុរក្សាអេក្រង់សំណព្វរបស់អ្នក ពេលកំពុងសាកថ្ម"</string>
- <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ប្ដូរអ្នកប្រើ"</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>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"សូមស្វាគមន៍ការត្រឡប់មកវិញ, ភ្ញៀវ!"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> មិនអាចប្រើមុខងារសន្ទនាបានទេ"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"មតិកែលម្អ"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"ច្រានចោល"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"កុំបង្ហាញម្ដងទៀត"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"មិនអាចកែប្រែការជូនដំណឹងទាំងនេះបានទេ។"</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"មិនអាចកែប្រែការជូនដំណឹងអំពីការហៅទូរសព្ទបានទេ។"</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"មិនអាចកំណត់រចនាសម្ព័ន្ធក្រុមការជូនដំណឹងនេះនៅទីនេះបានទេ"</string>
diff --git a/packages/SystemUI/res/values-km/tiles_states_strings.xml b/packages/SystemUI/res/values-km/tiles_states_strings.xml
index 71b12ca..0e47250 100644
--- a/packages/SystemUI/res/values-km/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-km/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"បិទ"</item>
<item msgid="5908720590832378783">"បើក"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 5bcd986..3bb4e4d 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"ವಿಜೆಟ್ ಅನ್ನು ಆಯ್ಕೆ ಮಾಡಬೇಡಿ"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"ಎತ್ತರವನ್ನು ಕಡಿಮೆ ಮಾಡಿ"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"ಎತ್ತರವನ್ನು ಹೆಚ್ಚಿಸಿ"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"ಮುಂದಿನದನ್ನು ತೋರಿಸಿ"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"ಹಿಂದಿನದನ್ನು ತೋರಿಸಿ"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"ಲಾಕ್ ಸ್ಕ್ರೀನ್ ವಿಜೆಟ್ಗಳು"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ವಿಜೆಟ್ ಅನ್ನು ಬಳಸಿಕೊಂಡು ಆ್ಯಪ್ ತೆರೆಯಲು, ಇದು ನೀವೇ ಎಂದು ನೀವು ದೃಢೀಕರಿಸಬೇಕಾಗುತ್ತದೆ. ಅಲ್ಲದೆ, ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ ಲಾಕ್ ಆಗಿದ್ದರೂ ಸಹ ಯಾರಾದರೂ ಅವುಗಳನ್ನು ವೀಕ್ಷಿಸಬಹುದು ಎಂಬುದನ್ನು ನೆನಪಿನಲ್ಲಿಡಿ. ಕೆಲವು ವಿಜೆಟ್ಗಳು ನಿಮ್ಮ ಲಾಕ್ ಸ್ಕ್ರೀನ್ಗಾಗಿ ಉದ್ದೇಶಿಸದೇ ಇರಬಹುದು ಮತ್ತು ಇಲ್ಲಿ ಸೇರಿಸುವುದು ಸುರಕ್ಷಿತವಲ್ಲದಿರಬಹುದು."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"ಅರ್ಥವಾಯಿತು"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"ಸಂವಾದ ಫೀಚರ್ಗಳನ್ನು <xliff:g id="APP_NAME">%1$s</xliff:g> ಬೆಂಬಲಿಸುವುದಿಲ್ಲ"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"ಫೀಡ್ಬ್ಯಾಕ್"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"ವಜಾಗೊಳಿಸಿ"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"ಮತ್ತೊಮ್ಮೆ ತೋರಿಸಬೇಡಿ"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"ಈ ಅಧಿಸೂಚನೆಗಳನ್ನು ಮಾರ್ಪಡಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"ಕರೆ ಅಧಿಸೂಚನೆಗಳನ್ನು ಮಾರ್ಪಡಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"ಈ ಗುಂಪಿನ ಅಧಿಸೂಚನೆಗಳನ್ನು ಇಲ್ಲಿ ಕಾನ್ಫಿಗರ್ ಮಾಡಲಾಗಿರುವುದಿಲ್ಲ"</string>
diff --git a/packages/SystemUI/res/values-kn/tiles_states_strings.xml b/packages/SystemUI/res/values-kn/tiles_states_strings.xml
index 49c688a..b3543f9 100644
--- a/packages/SystemUI/res/values-kn/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-kn/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"ಆಫ್ ಆಗಿದೆ"</item>
<item msgid="5908720590832378783">"ಆನ್ ಆಗಿದೆ"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index fd2c62e..33f54b6 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"위젯 선택 해제"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"높이 줄이기"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"높이 늘리기"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"다음 표시"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"이전 표시"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"잠금 화면 위젯"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"위젯을 사용하여 앱을 열려면 본인 인증을 해야 합니다. 또한 태블릿이 잠겨 있더라도 누구나 볼 수 있다는 점을 유의해야 합니다. 일부 위젯은 잠금 화면에 적합하지 않고 여기에 추가하기에 안전하지 않을 수 있습니다."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"확인"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> 앱은 대화 기능을 지원하지 않습니다."</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"의견"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"닫기"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"다시 표시하지 않음"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"이 알림은 수정할 수 없습니다."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"전화 알림은 수정할 수 없습니다."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"이 알림 그룹은 여기에서 설정할 수 없습니다."</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"폴더블 기기를 펼치는 모습"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"폴더블 기기를 뒤집는 모습"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"전면 화면 켜짐"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"슬라이드하여 내부 화면 사용"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"접은 상태"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"펼친 상태"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
diff --git a/packages/SystemUI/res/values-ko/tiles_states_strings.xml b/packages/SystemUI/res/values-ko/tiles_states_strings.xml
index 002d38e..c512435 100644
--- a/packages/SystemUI/res/values-ko/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ko/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"사용 안함"</item>
<item msgid="5908720590832378783">"사용"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 1916cbc..e764bad 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"виджетти тандоодон чыгаруу"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Бийиктигин азайтуу"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Бийиктигин көбөйтүү"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Кийинкини көрсөтүү"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Мурункуну көрсөтүү"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Кулпуланган экрандагы виджеттер"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Колдонмону виджет аркылуу ачуу үчүн өзүңүздү ырасташыңыз керек. Алар кулпуланган планшетиңизде да көрүнүп турат. Кээ бир виджеттерди кулпуланган экранда колдоно албайсыз, андыктан аларды ал жерге кошпой эле койгонуңуз оң."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Түшүндүм"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосунда оозеки сүйлөшкөнгө болбойт"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Пикир билдирүү"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Жабуу"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Экинчи көрсөтүлбөсүн"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Бул билдирмелерди өзгөртүүгө болбойт."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Чалуу билдирмелерин өзгөртүүгө болбойт."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Бул билдирмелердин тобун бул жерде конфигурациялоого болбойт"</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Ачылып турган бүктөлмө түзмөк"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Оодарылып жаткан бүктөлмө түзмөк"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Маңдайкы экран күйгүзүлдү"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"Ички экранды колдонуу үчүн экранды сүрүп коюңуз"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"бүктөлгөн"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"ачылган"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
diff --git a/packages/SystemUI/res/values-ky/tiles_states_strings.xml b/packages/SystemUI/res/values-ky/tiles_states_strings.xml
index 4834dbc..47e36da 100644
--- a/packages/SystemUI/res/values-ky/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ky/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Өчүк"</item>
<item msgid="5908720590832378783">"Күйүк"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index f61186d..3236b2e2 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"ຍົກເລີກການເລືອກວິດເຈັດ"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"ຫຼຸດຄວາມສູງ"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"ເພີ່ມຄວາມສູງ"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"ສະແດງເພງຖັດໄປ"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"ສະແດງເພງກ່ອນໜ້າ"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"ວິດເຈັດໃນໜ້າຈໍລັອກ"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ເພື່ອເປີດແອັບໂດຍໃຊ້ວິດເຈັດ, ທ່ານຈະຕ້ອງຢັ້ງຢືນວ່າແມ່ນທ່ານ. ນອກຈາກນັ້ນ, ກະລຸນາຮັບຊາບວ່າທຸກຄົນສາມາດເບິ່ງຂໍ້ມູນດັ່ງກ່າວໄດ້, ເຖິງແມ່ນວ່າແທັບເລັດຂອງທ່ານຈະລັອກຢູ່ກໍຕາມ. ວິດເຈັດບາງຢ່າງອາດບໍ່ໄດ້ມີໄວ້ສຳລັບໜ້າຈໍລັອກຂອງທ່ານ ແລະ ອາດບໍ່ປອດໄພທີ່ຈະເພີ່ມໃສ່ບ່ອນນີ້."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"ເຂົ້າໃຈແລ້ວ"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ບໍ່ຮອງຮັບຄຸນສົມບັດການສົນທະນາ"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"ຄຳຕິຊົມ"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"ປິດໄວ້"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"ບໍ່ຕ້ອງສະແດງອີກ"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"ບໍ່ສາມາດແກ້ໄຂການແຈ້ງເຕືອນເຫຼົ່ານີ້ໄດ້."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"ບໍ່ສາມາດແກ້ໄຂການແຈ້ງເຕືອນການໂທໄດ້."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"ບໍ່ສາມາດຕັ້ງຄ່າກຸ່ມການແຈ້ງເຕືອນນີ້ຢູ່ບ່ອນນີ້ໄດ້"</string>
diff --git a/packages/SystemUI/res/values-lo/tiles_states_strings.xml b/packages/SystemUI/res/values-lo/tiles_states_strings.xml
index bc63895..71e084a 100644
--- a/packages/SystemUI/res/values-lo/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-lo/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"ປິດ"</item>
<item msgid="5908720590832378783">"ເປີດ"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 88f9399..25208b0 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"atšaukti valdiklio pasirinkimą"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Sumažinti aukštį"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Padidinti aukštį"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Rodyti kitą mediją"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Rodyti ankstesnę mediją"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Užrakinimo ekrano valdikliai"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Kad galėtumėte atidaryti programą naudodami valdiklį, turėsite patvirtinti savo tapatybę. Be to, atminkite, kad bet kas gali peržiūrėti valdiklius net tada, kai planšetinis kompiuteris užrakintas. Kai kurie valdikliai gali būti neskirti jūsų užrakinimo ekranui ir gali būti nesaugu juos čia pridėti."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Supratau"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"Programa „<xliff:g id="APP_NAME">%1$s</xliff:g>“ nepalaiko pokalbių funkcijų"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Atsiliepimai"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Uždaryti"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Neberodyti"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Šių pranešimų keisti negalima."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Skambučių pranešimų keisti negalima."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Šios grupės pranešimai čia nekonfigūruojami"</string>
diff --git a/packages/SystemUI/res/values-lt/tiles_states_strings.xml b/packages/SystemUI/res/values-lt/tiles_states_strings.xml
index 12f8b6c..893d6ae 100644
--- a/packages/SystemUI/res/values-lt/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-lt/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Išjungta"</item>
<item msgid="5908720590832378783">"Įjungta"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index e0e38a1..bf1ef96 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -125,7 +125,7 @@
<string name="screenrecord_continue" msgid="4055347133700593164">"Sākt"</string>
<string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"Notiek ekrāna satura ierakstīšana."</string>
<string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"Notiek ekrāna satura un audio ierakstīšana."</string>
- <string name="screenrecord_taps_label" msgid="1595690528298857649">"Rādīt pieskārienus pie ekrāna"</string>
+ <string name="screenrecord_taps_label" msgid="1595690528298857649">"Rādīt pieskārienus ekrānam"</string>
<string name="screenrecord_stop_label" msgid="72699670052087989">"Pārtraukt"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Kopīgot"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Ekrāna ieraksts ir saglabāts"</string>
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"noņemt logrīka atlasi"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Samazināt augstumu"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Palielināt augstumu"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Rādīt nākamo"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Rādīt iepriekšējo"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Bloķēšanas ekrāna logrīki"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Lai atvērtu lietotni, izmantojot logrīku, jums būs jāapstiprina sava identitāte. Turklāt ņemiet vērā, ka ikviens var skatīt logrīkus, pat ja planšetdators ir bloķēts. Iespējams, daži logrīki nav paredzēti izmantošanai bloķēšanas ekrānā, un var nebūt droši tos šeit pievienot."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Labi"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"Lietotnē <xliff:g id="APP_NAME">%1$s</xliff:g> netiek atbalstītas sarunu funkcijas."</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Atsauksmes"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Nerādīt"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Vairs nerādīt"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Šos paziņojumus nevar modificēt."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Paziņojumus par zvaniem nevar modificēt."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Šeit nevar konfigurēt šo paziņojumu grupu."</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Salokāma ierīce tiek atlocīta"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Salokāma ierīce tiek apgriezta"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Priekšējais ekrāns ir ieslēgts"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"Velciet, lai izmantotu iekšējo ekrānu."</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"aizvērta"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"atvērta"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
diff --git a/packages/SystemUI/res/values-lv/tiles_states_strings.xml b/packages/SystemUI/res/values-lv/tiles_states_strings.xml
index 1494836..7329751 100644
--- a/packages/SystemUI/res/values-lv/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-lv/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Izslēgts"</item>
<item msgid="5908720590832378783">"Ieslēgts"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 0a9ca89..e34d9d8 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"поништи го изборот на виџетот"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Намали ја висината"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Зголеми ја висината"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Прикажи следно"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Прикажи претходно"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Виџети на заклучен екран"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"За да отворите апликација со помош на виџет, ќе треба да потврдите дека сте вие. Покрај тоа, имајте предвид дека секој може да ги гледа виџетите, дури и кога вашиот таблет е заклучен. Некои виџети можеби не се наменети за вашиот заклучен екран, па можеби не е безбедно да се додадат овде."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Сфатив"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> не поддржува функции за разговор"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Повратни информации"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Отфрли"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Не прикажувај повторно"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Овие известувања не може да се изменат"</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Известувањата за повици не може да се изменат."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Оваа група известувања не може да се конфигурира тука"</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Преклопувачки уред се отклопува"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Преклопувачки уред се врти"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Предниот екран е вклучен"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"Лизгајте за да го користите внатрешниот екран"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"затворен"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"отворен"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
diff --git a/packages/SystemUI/res/values-mk/tiles_states_strings.xml b/packages/SystemUI/res/values-mk/tiles_states_strings.xml
index 17545c3..67baf7c 100644
--- a/packages/SystemUI/res/values-mk/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-mk/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Исклучено"</item>
<item msgid="5908720590832378783">"Вклучено"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 8ef9b79..226822a 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"വിജറ്റ് തിരഞ്ഞെടുത്തത് മാറ്റുക"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"ഉയരം കുറയ്ക്കുക"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"ഉയരം കൂട്ടുക"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"അടുത്തത് കാണിക്കുക"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"മുമ്പത്തേത് കാണിക്കുക"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"ലോക്ക് സ്ക്രീൻ വിജറ്റുകൾ"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"വിജറ്റ് ഉപയോഗിച്ച് ഒരു ആപ്പ് തുറക്കാൻ, ഇത് നിങ്ങൾ തന്നെയാണെന്ന് പരിശോധിച്ചുറപ്പിക്കേണ്ടതുണ്ട്. നിങ്ങളുടെ ടാബ്ലെറ്റ് ലോക്കായിരിക്കുമ്പോഴും എല്ലാവർക്കും അത് കാണാനാകുമെന്നതും ഓർക്കുക. ചില വിജറ്റുകൾ നിങ്ങളുടെ ലോക്ക് സ്ക്രീനിന് ഉള്ളതായിരിക്കില്ല, അവ ഇവിടെ ചേർക്കുന്നത് സുരക്ഷിതവുമായിരിക്കില്ല."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"മനസ്സിലായി"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"സംഭാഷണ ഫീച്ചറുകളെ <xliff:g id="APP_NAME">%1$s</xliff:g> പിന്തുണയ്ക്കുന്നില്ല"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"ഫീഡ്ബാക്ക്"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"ഡിസ്മിസ് ചെയ്യുക"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"വീണ്ടും കാണിക്കരുത്"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"ഈ അറിയിപ്പുകൾ പരിഷ്ക്കരിക്കാനാവില്ല."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"കോൾ അറിയിപ്പുകൾ പരിഷ്കരിക്കാനാകുന്നില്ല."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"അറിയിപ്പുകളുടെ ഈ ഗ്രൂപ്പ് ഇവിടെ കോണ്ഫിഗര് ചെയ്യാൻ കഴിയില്ല"</string>
diff --git a/packages/SystemUI/res/values-ml/tiles_states_strings.xml b/packages/SystemUI/res/values-ml/tiles_states_strings.xml
index 689fe85..8639c10 100644
--- a/packages/SystemUI/res/values-ml/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ml/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"ഓഫാണ്"</item>
<item msgid="5908720590832378783">"ഓണാണ്"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index feca241..06b62e9 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"виджетийн сонголтыг болиулах"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Намсгах"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Өндөрсгөх"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Дараагийнхыг харуулах"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Өмнөхийг харуулах"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Түгжээтэй дэлгэцийн виджет"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Виджет ашиглан аппыг нээхийн тулд та өөрийгөө мөн болохыг баталгаажуулах шаардлагатай болно. Мөн таны таблет түгжээтэй байсан ч тэдгээрийг дурын хүн үзэж болохыг санаарай. Зарим виджет таны түгжээтэй дэлгэцэд зориулагдаагүй байж магадгүй ба энд нэмэхэд аюултай байж болзошгүй."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Ойлголоо"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> нь харилцан ярианы онцлогуудыг дэмждэггүй"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Санал хүсэлт"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Хаах"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Дахиж бүү харуул"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Эдгээр мэдэгдлийг өөрчлөх боломжгүй."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Дуудлагын мэдэгдлийг өөрчлөх боломжгүй."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Энэ бүлэг мэдэгдлийг энд тохируулах боломжгүй байна"</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Эвхэгддэг төхөөрөмжийг дэлгэж байна"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Эвхэгддэг төхөөрөмжийг хөнтөрч байна"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Нүүрэн талын дэлгэцийг асаасан"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"Дотоод дэлгэцийг ашиглахын тулд гулсуулна уу"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"эвхсэн"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"дэлгэсэн"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
diff --git a/packages/SystemUI/res/values-mn/tiles_states_strings.xml b/packages/SystemUI/res/values-mn/tiles_states_strings.xml
index 94e3939..678033c 100644
--- a/packages/SystemUI/res/values-mn/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-mn/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Унтраалттай"</item>
<item msgid="5908720590832378783">"Асаалттай"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index a3c45f3..4c2fd29 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"विजेटची निवड रद्द करा"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"उंची कमी करा"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"उंची वाढवा"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"पुढील दाखवा"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"मागील दाखवा"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"लॉक स्क्रीन विजेट"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"विजेट वापरून अॅप उघडण्यासाठी, तुम्हाला हे तुम्हीच असल्याची पडताळणी करावी लागेल. तसेच, लक्षात ठेवा, तुमचा टॅबलेट लॉक असतानादेखील कोणीही ती पाहू शकते. काही विजेट कदाचित तुमच्या लॉक स्क्रीनसाठी नाहीत आणि ती इथे जोडणे असुरक्षित असू शकते."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"समजले"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> हे संभाषण वैशिष्ट्यांना सपोर्ट करत नाही"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"फीडबॅक"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"डिसमिस करा"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"पुन्हा दाखवू नका"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"या सूचनांमध्ये सुधारणा केली जाऊ शकत नाही."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"कॉलशी संबंधित सूचनांमध्ये फेरबदल केला जाऊ शकत नाही."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"या सूचनांचा संच येथे कॉन्फिगर केला जाऊ शकत नाही"</string>
@@ -1523,8 +1530,8 @@
<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">"%2$d पैकी %1$d पातळी"</string>
- <string name="home_controls_dream_label" msgid="6567105701292324257">"होम कंट्रोल"</string>
- <string name="home_controls_dream_description" msgid="4644150952104035789">"स्क्रीनसेव्हर म्हणून होम कंट्रोल झटपट ॲक्सेस करा"</string>
+ <string name="home_controls_dream_label" msgid="6567105701292324257">"होम कंट्रोल्स"</string>
+ <string name="home_controls_dream_description" msgid="4644150952104035789">"स्क्रीनसेव्हर म्हणून होम कंट्रोल्स झटपट ॲक्सेस करा"</string>
<string name="volume_undo_action" msgid="5815519725211877114">"पहिल्यासारखे करा"</string>
<string name="back_edu_toast_content" msgid="4530314597378982956">"मागे जाण्यासाठी, टचपॅडवर तीन बोटांनी डावीकडे किंवा उजवीकडे स्वाइप करा"</string>
<string name="home_edu_toast_content" msgid="3381071147871955415">"होमवर जाण्यासाठी, टचपॅडवर तीन बोटांनी वरती स्वाइप करा"</string>
diff --git a/packages/SystemUI/res/values-mr/tiles_states_strings.xml b/packages/SystemUI/res/values-mr/tiles_states_strings.xml
index cbaefb9..ec87659 100644
--- a/packages/SystemUI/res/values-mr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-mr/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"बंद आहे"</item>
<item msgid="5908720590832378783">"सुरू आहे"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index bb7dcb8..93f25ff 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"nyahpilih widget"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Kurangkan ketinggian"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Tambahkan ketinggian"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Tunjukkan seterusnya"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Tunjukkan sebelumnya"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widget skrin kunci"</string>
<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>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak menyokong ciri perbualan"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Maklum balas"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Ketepikan"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Jangan tunjukkan lagi"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Pemberitahuan ini tidak boleh diubah suai."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Pemberitahuan panggilan tidak boleh diubah suai."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Kumpulan pemberitahuan ini tidak boleh dikonfigurasikan di sini"</string>
diff --git a/packages/SystemUI/res/values-ms/tiles_states_strings.xml b/packages/SystemUI/res/values-ms/tiles_states_strings.xml
index 3c78bcc..6dc9827 100644
--- a/packages/SystemUI/res/values-ms/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ms/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Mati"</item>
<item msgid="5908720590832378783">"Hidup"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 0219f69..bed07ef 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"ဝိဂျက် ပြန်ဖြုတ်ရန်"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"အမြင့်ကို လျှော့ရန်"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"အမြင့်ကို တိုးရန်"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"နောက်တစ်ခု ပြပါ"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"ယခင်တစ်ခု ပြပါ"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"လော့ခ်မျက်နှာပြင် ဝိဂျက်များ"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ဝိဂျက်သုံး၍ အက်ပ်ဖွင့်ရန်အတွက် သင်ဖြစ်ကြောင်း အတည်ပြုရန်လိုသည်။ ထို့ပြင် သင့်တက်ဘလက် လော့ခ်ချထားချိန်၌ပင် မည်သူမဆို ၎င်းတို့ကို ကြည့်နိုင်ကြောင်း သတိပြုပါ။ ဝိဂျက်အချို့ကို လော့ခ်မျက်နှာပြင်အတွက် ရည်ရွယ်ထားခြင်း မရှိသဖြင့် ဤနေရာတွင် ထည့်ပါက မလုံခြုံနိုင်ပါ။"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"နားလည်ပြီ"</string>
@@ -542,7 +544,7 @@
<string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"အားသွင်းနေစဉ် အကြိုက်ဆုံးဝိဂျက်များ၊ စခရင်နားချိန်ပုံများ ကြည့်နိုင်သည်။"</string>
<string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"စကြစို့"</string>
<string name="glanceable_hub_to_dream_button_tooltip" msgid="9018287673822335829">"အားသွင်းနေစဉ် သင့်အကြိုက်ဆုံး စခရင်နားချိန်ပုံများကို ပြသည်"</string>
- <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"အသုံးပြုသူကို ပြောင်းလဲရန်"</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>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"ဧည့်သည်ကို ပြန်လည် ကြိုဆိုပါသည်။"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> က စကားဝိုင်းဝန်ဆောင်မှုများကို မပံ့ပိုးပါ"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"အကြံပြုချက်"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"ပယ်ရန်"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"ထပ်မပြပါနှင့်"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"ဤအကြောင်းကြားချက်များကို ပြုပြင်၍ မရပါ။"</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"ခေါ်ဆိုမှုအကြောင်းကြားချက်များကို ပြင်၍မရပါ။"</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"ဤအကြောင်းကြားချက်အုပ်စုကို ဤနေရာတွင် စီစဉ်သတ်မှတ်၍ မရပါ"</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ခေါက်နိုင်သောစက်ကို ဖြန့်လိုက်သည်"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ခေါက်နိုင်သောစက်ကို တစ်ဘက်သို့ လှန်လိုက်သည်"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"ရှေ့စခရင် ဖွင့်ထားသည်"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"အတွင်းဘက်ဖန်သားပြင် သုံးရန် ဘေးတိုက်ပွတ်ဆွဲပါ"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"ခေါက်ထားသည်"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"ဖြန့်ထားသည်"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
diff --git a/packages/SystemUI/res/values-my/tiles_states_strings.xml b/packages/SystemUI/res/values-my/tiles_states_strings.xml
index 9675cb5..424b4b9 100644
--- a/packages/SystemUI/res/values-my/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-my/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"ပိတ်"</item>
<item msgid="5908720590832378783">"ဖွင့်"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 15e568b..7e87efc 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"velg bort modul"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Reduser høyden"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Øk høyden"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Vis neste"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Vis forrige"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Låseskjermmoduler"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"For å åpne en app ved hjelp av en modul må du bekrefte at det er deg. Husk også at hvem som helst kan se dem, selv om nettbrettet er låst. Noen moduler er kanskje ikke laget for å være på låseskjermen og kan være utrygge å legge til der."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Greit"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> støtter ikke samtalefunksjoner"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Tilbakemelding"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Lukk"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Ikke vis igjen"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Disse varslene kan ikke endres."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Anropsvarsler kan ikke endres."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Denne varselgruppen kan ikke konfigureres her"</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"En foldbar enhet blir brettet ut"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"En foldbar enhet blir snudd"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Frontskjermen er slått på"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"Dra for å bruke den indre skjermen"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"lagt sammen"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"åpen"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
diff --git a/packages/SystemUI/res/values-nb/tiles_states_strings.xml b/packages/SystemUI/res/values-nb/tiles_states_strings.xml
index bd5b692..bbeafd8 100644
--- a/packages/SystemUI/res/values-nb/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-nb/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Av"</item>
<item msgid="5908720590832378783">"På"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 02285f2..cc07b7f 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"विजेटको चयन रद्द गर्नुहोस्"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"उचाइ घटाउनुहोस्"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"उचाइ बढाउनुहोस्"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"अर्को देखाउनुहोस्"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"अघिल्लो देखाउनुहोस्"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"लक स्क्रिन विजेटहरू"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"विजेट प्रयोग गरी एप खोल्न तपाईंले आफ्नो पहिचान पुष्टि गर्नु पर्ने हुन्छ। साथै, तपाईंको ट्याब्लेट लक भएका बेला पनि सबै जनाले तिनलाई देख्न सक्छन् भन्ने कुरा ख्याल गर्नुहोस्। केही विजेटहरू लक स्क्रिनमा प्रयोग गर्ने उद्देश्यले नबनाइएका हुन सक्छन् र तिनलाई यहाँ हाल्नु सुरक्षित नहुन सक्छ।"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"बुझेँ"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> मा वार्तालापसम्बन्धी सुविधा प्रयोग गर्न मिल्दैन"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"प्रतिक्रिया"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"हटाउनुहोस्"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"फेरि नदेखाउनुहोस्"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"यी सूचनाहरू परिमार्जन गर्न मिल्दैन।"</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"कलसम्बन्धी सूचनाहरू परिमार्जन गर्न मिल्दैन।"</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"यहाँबाट सूचनाहरूको यो समूह कन्फिगर गर्न सकिँदैन"</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"फोल्डेबल डिभाइस अनफोल्ड गरेको देखाइएको एनिमेसन"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"फोल्डेबल डिभाइस यताउता पल्टाएर देखाइएको एनिमेसन"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"अगाडिको स्क्रिन अन गरिएको छ"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"भित्री स्क्रिन प्रयोग गर्न स्लाइड गर्नुहोस्"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"फोल्ड गरिएको"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"अनफोल्ड गरिएको"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
diff --git a/packages/SystemUI/res/values-ne/tiles_states_strings.xml b/packages/SystemUI/res/values-ne/tiles_states_strings.xml
index 2dd209d..de3baa0 100644
--- a/packages/SystemUI/res/values-ne/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ne/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"अफ छ"</item>
<item msgid="5908720590832378783">"अन छ"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 99c8838..b778cec 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"widget deselecteren"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Hoogte verkleinen"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Hoogte vergroten"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Volgende tonen"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Vorige tonen"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgets op het vergrendelscherm"</string>
<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>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ondersteunt geen gespreksfuncties"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Feedback"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Sluiten"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Niet meer tonen"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Deze meldingen kunnen niet worden aangepast."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Gespreksmeldingen kunnen niet worden aangepast."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Deze groep meldingen kan hier niet worden ingesteld"</string>
diff --git a/packages/SystemUI/res/values-nl/tiles_states_strings.xml b/packages/SystemUI/res/values-nl/tiles_states_strings.xml
index 221749c..90572b6 100644
--- a/packages/SystemUI/res/values-nl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-nl/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Uit"</item>
<item msgid="5908720590832378783">"Aan"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 5847a9a..0ef622b 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -128,8 +128,8 @@
<string name="screenrecord_taps_label" msgid="1595690528298857649">"ସ୍କ୍ରିନରେ ସ୍ପର୍ଶଗୁଡ଼ିକ ଦେଖାନ୍ତୁ"</string>
<string name="screenrecord_stop_label" msgid="72699670052087989">"ବନ୍ଦ କରନ୍ତୁ"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"ସେୟାର୍ କରନ୍ତୁ"</string>
- <string name="screenrecord_save_title" msgid="1886652605520893850">"ସ୍କ୍ରିନ୍ ରେକର୍ଡିଂ ସେଭ୍ କରାଯାଇଛି"</string>
- <string name="screenrecord_save_text" msgid="3008973099800840163">"ଦେଖିବାକୁ ଟାପ୍ କରନ୍ତୁ"</string>
+ <string name="screenrecord_save_title" msgid="1886652605520893850">"ସ୍କ୍ରିନ ରେକର୍ଡିଂ ସେଭ କରାଯାଇଛି"</string>
+ <string name="screenrecord_save_text" msgid="3008973099800840163">"ଦେଖିବାକୁ ଟାପ କରନ୍ତୁ"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"ସ୍କ୍ରିନ ରେକର୍ଡିଂ ସେଭ କରିବାରେ ତ୍ରୁଟି"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"ସ୍କ୍ରିନ୍ ରେକର୍ଡିଂ ଆରମ୍ଭ କରିବାରେ ତ୍ରୁଟି"</string>
<string name="screenrecord_stop_dialog_title" msgid="8716193661764511095">"ରେକର୍ଡିଂ ବନ୍ଦ କରିବେ?"</string>
@@ -360,7 +360,7 @@
<string name="quick_settings_connected" msgid="3873605509184830379">"ସଂଯୁକ୍ତ"</string>
<string name="quick_settings_connected_battery_level" msgid="1322075669498906959">"କନେକ୍ଟ ରହିଛି, ବ୍ୟାଟେରୀ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="quick_settings_connecting" msgid="2381969772953268809">"ସଂଯୋଗ କରୁଛି..."</string>
- <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"ହଟସ୍ପଟ୍"</string>
+ <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"ହଟସ୍ପଟ"</string>
<string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"ଚାଲୁ ହେଉଛି…"</string>
<string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"ଡାଟା ସେଭର୍ ଅନ୍ ଅଛି"</string>
<string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{#ଟି ଡିଭାଇସ}other{#ଟି ଡିଭାଇସ}}"</string>
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"ୱିଜେଟକୁ ଅଚୟନ କରନ୍ତୁ"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"ଉଚ୍ଚତାକୁ କମ କରନ୍ତୁ"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"ଉଚ୍ଚତାକୁ ବଢ଼ାନ୍ତୁ"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"ପରବର୍ତ୍ତୀ ନେଭିଗେସନ ପଏଣ୍ଟ ଦେଖାନ୍ତୁ"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"ପୂର୍ବବର୍ତ୍ତୀ ଦେଖାନ୍ତୁ"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"ଲକ ସ୍କ୍ରିନ ୱିଜେଟ"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ଏକ ୱିଜେଟ ବ୍ୟବହାର କରି ଗୋଟିଏ ଆପ ଖୋଲିବା ପାଇଁ ଏହା ଆପଣ ଅଟନ୍ତି ବୋଲି ଆପଣଙ୍କୁ ଯାଞ୍ଚ କରିବାକୁ ହେବ। ଆହୁରି ମଧ୍ୟ, ଆପଣଙ୍କ ଟାବଲେଟ ଲକ ଥିଲେ ମଧ୍ୟ ଯେ କୌଣସି ବ୍ୟକ୍ତି ଏହାକୁ ଭ୍ୟୁ କରିପାରିବେ ବୋଲି ମନେ ରଖନ୍ତୁ। କିଛି ୱିଜେଟ ଆପଣଙ୍କ ଲକ ସ୍କ୍ରିନ ପାଇଁ ଉଦ୍ଦିଷ୍ଟ ହୋଇନଥାଇପାରେ ଏବଂ ଏଠାରେ ଯୋଗ କରିବା ଅସୁରକ୍ଷିତ ହୋଇପାରେ।"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"ବୁଝିଗଲି"</string>
@@ -757,7 +759,7 @@
<string name="zen_alarm_warning" msgid="7844303238486849503">"<xliff:g id="WHEN">%1$s</xliff:g>ବେଳେ ଆପଣ ନିଜର ପରବର୍ତ୍ତୀ ଆଲାର୍ମ ଶୁଣିପାରିବେ ନାହିଁ"</string>
<string name="alarm_template" msgid="2234991538018805736">"<xliff:g id="WHEN">%1$s</xliff:g> ହେଲେ"</string>
<string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g> ବେଳେ"</string>
- <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"ହଟସ୍ପଟ୍"</string>
+ <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"ହଟସ୍ପଟ"</string>
<string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"ସାଟେଲାଇଟ, କୌଣସି କନେକ୍ସନ ନାହିଁ"</string>
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"ସାଟେଲାଇଟ, ଦୁର୍ବଳ କନେକ୍ସନ"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ସାଟେଲାଇଟ, ଭଲ କନେକ୍ସନ"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ବାର୍ତ୍ତାଳାପ ଫିଚରଗୁଡ଼ିକୁ ସମର୍ଥନ କରେ ନାହିଁ"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"ମତାମତ"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"ଖାରଜ କରନ୍ତୁ"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"ପୁଣି ଶୋ କରନ୍ତୁ ନାହିଁ"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"ଏହି ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ପରିବର୍ତ୍ତନ କରିହେବ ନାହିଁ।"</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"କଲ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ପରିବର୍ତ୍ତନ କରାଯାଇପାରିବ ନାହିଁ।"</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"ଏଠାରେ ଏହି ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକର ଗ୍ରୁପ୍ କନଫ୍ୟୁଗର୍ କରାଯାଇପାରିବ ନାହିଁ"</string>
@@ -955,7 +962,7 @@
<item msgid="5874146774389433072">"ଡାହାଣକୁ-ଆଉଜେଇବା"</item>
</string-array>
<string name="save" msgid="3392754183673848006">"ସେଭ କରନ୍ତୁ"</string>
- <string name="reset" msgid="8715144064608810383">"ରିସେଟ୍ କରନ୍ତୁ"</string>
+ <string name="reset" msgid="8715144064608810383">"ରିସେଟ କରନ୍ତୁ"</string>
<string name="clipboard" msgid="8517342737534284617">"କ୍ଲିପ୍ବୋର୍ଡ"</string>
<string name="accessibility_key" msgid="3471162841552818281">"କଷ୍ଟମ୍ ନାଭିଗେଶନ୍ ବଟନ୍"</string>
<string name="left_keycode" msgid="8211040899126637342">"ବାମ କୀ\'କୋଡ୍"</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ଫୋଲ୍ଡ କରାଯାଇପାରୁଥିବା ଡିଭାଇସକୁ ଅନଫୋଲ୍ଡ କରାଯାଉଛି"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ଫୋଲ୍ଡ କରାଯାଇପାରୁଥିବା ଡିଭାଇସକୁ ଫ୍ଲିପ କରାଯାଉଛି"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"ସାମ୍ନା ସ୍କ୍ରିନ ଚାଲୁ ଅଛି"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"ଭିତର ସ୍କ୍ରିନକୁ ବ୍ୟବହାର କରିବା ପାଇଁ ସ୍ଲାଇଡ କରନ୍ତୁ"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"ଫୋଲ୍ଡେଡ"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"ଅନଫୋଲ୍ଡେଡ"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
diff --git a/packages/SystemUI/res/values-or/tiles_states_strings.xml b/packages/SystemUI/res/values-or/tiles_states_strings.xml
index 8d23073..c9c3198 100644
--- a/packages/SystemUI/res/values-or/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-or/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"ବନ୍ଦ ଅଛି"</item>
<item msgid="5908720590832378783">"ଚାଲୁ ଅଛି"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 17757b8..4be78a3 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"ਵਿਜੇਟ ਨੂੰ ਅਣਚੁਣਿਆ ਕਰੋ"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"ਉਚਾਈ ਘਟਾਓ"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"ਉਚਾਈ ਵਧਾਓ"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"ਅਗਲਾ ਦਿਖਾਓ"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"ਪਿਛਲਾ ਦਿਖਾਓ"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"ਲਾਕ ਸਕ੍ਰੀਨ ਵਿਜੇਟ"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ਵਿਜੇਟ ਦੀ ਵਰਤੋਂ ਕਰ ਕੇ ਐਪ ਖੋਲ੍ਹਣ ਲਈ, ਤੁਹਾਨੂੰ ਇਹ ਪੁਸ਼ਟੀ ਕਰਨ ਦੀ ਲੋੜ ਪਵੇਗੀ ਕਿ ਇਹ ਤੁਸੀਂ ਹੀ ਹੋ। ਨਾਲ ਹੀ, ਇਹ ਵੀ ਧਿਆਨ ਵਿੱਚ ਰੱਖੋ ਕਿ ਕੋਈ ਵੀ ਉਨ੍ਹਾਂ ਨੂੰ ਦੇਖ ਸਕਦਾ ਹੈ, ਭਾਵੇਂ ਤੁਹਾਡਾ ਟੈਬਲੈੱਟ ਲਾਕ ਹੋਵੇ। ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਕੁਝ ਵਿਜੇਟ ਤੁਹਾਡੀ ਲਾਕ ਸਕ੍ਰੀਨ ਲਈ ਨਾ ਬਣੇ ਹੋਣ ਅਤੇ ਉਨ੍ਹਾਂ ਨੂੰ ਇੱਥੇ ਸ਼ਾਮਲ ਕਰਨਾ ਅਸੁਰੱਖਿਅਤ ਹੋਵੇ।"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"ਸਮਝ ਲਿਆ"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਐਪ ਗੱਲਬਾਤ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੀ"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"ਵਿਚਾਰ"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"ਖਾਰਜ ਕਰੋ"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"ਦੁਬਾਰਾ ਨਾ ਦਿਖਾਓ"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"ਇਹਨਾਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਸੋਧਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ।"</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"ਕਾਲ ਸੰਬੰਧੀ ਸੂਚਨਾਵਾਂ ਨੂੰ ਸੋਧਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ।"</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"ਇਹ ਸੂਚਨਾਵਾਂ ਦਾ ਗਰੁੱਪ ਇੱਥੇ ਸੰਰੂਪਿਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
diff --git a/packages/SystemUI/res/values-pa/tiles_states_strings.xml b/packages/SystemUI/res/values-pa/tiles_states_strings.xml
index 0f53e5d..eeb9a5b 100644
--- a/packages/SystemUI/res/values-pa/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pa/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"ਬੰਦ"</item>
<item msgid="5908720590832378783">"ਚਾਲੂ"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index c0a2831..d358b9f 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -391,7 +391,7 @@
<string name="quick_settings_nfc_label" msgid="1054317416221168085">"Komunikacja NFC"</string>
<string name="quick_settings_nfc_off" msgid="3465000058515424663">"Komunikacja NFC jest wyłączona"</string>
<string name="quick_settings_nfc_on" msgid="1004976611203202230">"Komunikacja NFC jest włączona"</string>
- <string name="quick_settings_screen_record_label" msgid="8650355346742003694">"Nagraj ekran"</string>
+ <string name="quick_settings_screen_record_label" msgid="8650355346742003694">"Nagrywanie ekranu"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Rozpocznij"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Zatrzymaj"</string>
<string name="qs_record_issue_label" msgid="8166290137285529059">"Zarejestruj problem"</string>
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"odznacz widżet"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Zmniejsz wysokość"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Zwiększ wysokość"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Pokaż następny"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Pokaż poprzedni"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widżety na ekranie blokady"</string>
<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>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> nie obsługuje funkcji rozmów"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Opinia"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Zamknij"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Nie pokazuj ponownie"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Tych powiadomień nie można zmodyfikować."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Powiadomień o połączeniach nie można modyfikować."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Tej grupy powiadomień nie można tu skonfigurować"</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Składane urządzenie jest rozkładane"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Składane urządzenie jest obracane"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Ekran przedni jest włączony"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"Przesuń palcem, aby używać wewnętrznego ekranu"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"po zamknięciu"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"po otwarciu"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
diff --git a/packages/SystemUI/res/values-pl/tiles_states_strings.xml b/packages/SystemUI/res/values-pl/tiles_states_strings.xml
index c9eb500..bc59a90 100644
--- a/packages/SystemUI/res/values-pl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pl/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Wyłączony"</item>
<item msgid="5908720590832378783">"Włączony"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index c1a8ec4..3a7d1f2 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -333,8 +333,8 @@
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Giro automático da tela"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Localização"</string>
<string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Protetor de tela"</string>
- <string name="quick_settings_camera_label" msgid="5612076679385269339">"Acesso à câmera"</string>
- <string name="quick_settings_mic_label" msgid="8392773746295266375">"Acesso ao microfone"</string>
+ <string name="quick_settings_camera_label" msgid="5612076679385269339">"Câmera"</string>
+ <string name="quick_settings_mic_label" msgid="8392773746295266375">"Microfone"</string>
<string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Disponível"</string>
<string name="quick_settings_camera_mic_blocked" msgid="4710884905006788281">"Bloqueada"</string>
<string name="quick_settings_media_device_label" msgid="8034019242363789941">"Dispositivo de mídia"</string>
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"desmarcar widget"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Diminuir altura"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Aumentar altura"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Mostrar próximo"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Mostrar anterior"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgets da tela de bloqueio"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Para abrir um app usando um widget, você precisa confirmar sua identidade. E não se esqueça que qualquer pessoa pode ver os widgets, mesmo com o tablet bloqueado. Além disso, alguns apps não foram criados para a tela de bloqueio, é melhor manter a segurança."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Entendi"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> não é compatível com recursos de conversa"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Enviar feedback"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Dispensar"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Não mostrar novamente"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Não é possível modificar essas notificações."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Não é possível modificar as notificações de chamada."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Não é possível configurar esse grupo de notificações aqui"</string>
@@ -1524,7 +1531,7 @@
<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>
- <string name="home_controls_dream_description" msgid="4644150952104035789">"Controles de automação residencial no protetor de tela"</string>
+ <string name="home_controls_dream_description" msgid="4644150952104035789">"Controle de automação no protetor de tela"</string>
<string name="volume_undo_action" msgid="5815519725211877114">"Desfazer"</string>
<string name="back_edu_toast_content" msgid="4530314597378982956">"Se quiser voltar, deslize para a esquerda ou direita com três dedos no touchpad"</string>
<string name="home_edu_toast_content" msgid="3381071147871955415">"Se quiser acessar a tela inicial, deslize para cima com três dedos no touchpad"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml b/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml
index 9ddc41c..3e75cdd 100644
--- a/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Desativado"</item>
<item msgid="5908720590832378783">"Ativado"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 36384bc..ff0ba36 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -128,7 +128,7 @@
<string name="screenrecord_taps_label" msgid="1595690528298857649">"Mostrar toques no ecrã"</string>
<string name="screenrecord_stop_label" msgid="72699670052087989">"Parar"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Partilhar"</string>
- <string name="screenrecord_save_title" msgid="1886652605520893850">"Gravação de ecrã guardada."</string>
+ <string name="screenrecord_save_title" msgid="1886652605520893850">"Gravação de ecrã guardada"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Toque para ver"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Erro ao guardar a gravação de ecrã"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Ocorreu um erro ao iniciar a gravação do ecrã."</string>
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"desmarcar widget"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Diminuir altura"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Aumentar altura"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Mostrar próximo"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Mostrar anterior"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgets do ecrã de bloqueio"</string>
<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>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> não suporta funcionalidades de conversa."</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Feedback"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Ignorar"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Não mostrar novamente"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Não é possível modificar estas notificações."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Não é possível modificar as notificações de chamadas."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Não é possível configurar este grupo de notificações aqui."</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml b/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml
index 5baa61c..7e7e673 100644
--- a/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Desativado"</item>
<item msgid="5908720590832378783">"Ativado"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index c1a8ec4..3a7d1f2 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -333,8 +333,8 @@
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Giro automático da tela"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Localização"</string>
<string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Protetor de tela"</string>
- <string name="quick_settings_camera_label" msgid="5612076679385269339">"Acesso à câmera"</string>
- <string name="quick_settings_mic_label" msgid="8392773746295266375">"Acesso ao microfone"</string>
+ <string name="quick_settings_camera_label" msgid="5612076679385269339">"Câmera"</string>
+ <string name="quick_settings_mic_label" msgid="8392773746295266375">"Microfone"</string>
<string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Disponível"</string>
<string name="quick_settings_camera_mic_blocked" msgid="4710884905006788281">"Bloqueada"</string>
<string name="quick_settings_media_device_label" msgid="8034019242363789941">"Dispositivo de mídia"</string>
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"desmarcar widget"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Diminuir altura"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Aumentar altura"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Mostrar próximo"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Mostrar anterior"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgets da tela de bloqueio"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Para abrir um app usando um widget, você precisa confirmar sua identidade. E não se esqueça que qualquer pessoa pode ver os widgets, mesmo com o tablet bloqueado. Além disso, alguns apps não foram criados para a tela de bloqueio, é melhor manter a segurança."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Entendi"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> não é compatível com recursos de conversa"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Enviar feedback"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Dispensar"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Não mostrar novamente"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Não é possível modificar essas notificações."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Não é possível modificar as notificações de chamada."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Não é possível configurar esse grupo de notificações aqui"</string>
@@ -1524,7 +1531,7 @@
<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>
- <string name="home_controls_dream_description" msgid="4644150952104035789">"Controles de automação residencial no protetor de tela"</string>
+ <string name="home_controls_dream_description" msgid="4644150952104035789">"Controle de automação no protetor de tela"</string>
<string name="volume_undo_action" msgid="5815519725211877114">"Desfazer"</string>
<string name="back_edu_toast_content" msgid="4530314597378982956">"Se quiser voltar, deslize para a esquerda ou direita com três dedos no touchpad"</string>
<string name="home_edu_toast_content" msgid="3381071147871955415">"Se quiser acessar a tela inicial, deslize para cima com três dedos no touchpad"</string>
diff --git a/packages/SystemUI/res/values-pt/tiles_states_strings.xml b/packages/SystemUI/res/values-pt/tiles_states_strings.xml
index 9ddc41c..3e75cdd 100644
--- a/packages/SystemUI/res/values-pt/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pt/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Desativado"</item>
<item msgid="5908720590832378783">"Ativado"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index beb3c116..2417c84 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"deselectează widgetul"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Redu înălțimea"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Crește înălțimea"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Afișează elementul următor"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Afișează elementul anterior"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgeturi pe ecranul de blocare"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Pentru a deschide o aplicație folosind un widget, va trebui să-ți confirmi identitatea. În plus, reține că oricine poate să vadă widgeturile, chiar dacă tableta este blocată. Este posibil ca unele widgeturi să nu fi fost create pentru ecranul de blocare și poate fi nesigur să le adaugi aici."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> nu acceptă funcții pentru conversații"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Feedback"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Închide"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Nu mai afișa"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Aceste notificări nu pot fi modificate."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Notificările pentru apeluri nu pot fi modificate."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Acest grup de notificări nu poate fi configurat aici"</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispozitiv pliabil care este desfăcut"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispozitiv pliabil care este întors"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Ecranul frontal este activat"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"Glisează pentru a folosi ecranul interior"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"închis"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"deschis"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
diff --git a/packages/SystemUI/res/values-ro/tiles_states_strings.xml b/packages/SystemUI/res/values-ro/tiles_states_strings.xml
index 528b112..6dcb0d3 100644
--- a/packages/SystemUI/res/values-ro/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ro/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Dezactivat"</item>
<item msgid="5908720590832378783">"Activat"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index e3f852c..f6968d5 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -129,7 +129,7 @@
<string name="screenrecord_stop_label" msgid="72699670052087989">"Остановить"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Поделиться"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Видео с экрана сохранено"</string>
- <string name="screenrecord_save_text" msgid="3008973099800840163">"Нажмите, чтобы посмотреть."</string>
+ <string name="screenrecord_save_text" msgid="3008973099800840163">"Нажмите, чтобы посмотреть"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Не удалось сохранить запись видео с экрана."</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Не удалось начать запись видео с экрана."</string>
<string name="screenrecord_stop_dialog_title" msgid="8716193661764511095">"Остановить запись?"</string>
@@ -162,7 +162,7 @@
<string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Записываем проблему на видео"</string>
<string name="issuerecord_share_label" msgid="3992657993619876199">"Поделиться"</string>
<string name="issuerecord_save_title" msgid="4161043023696751591">"Запись сохранена."</string>
- <string name="issuerecord_save_text" msgid="1205985304551521495">"Нажмите, чтобы посмотреть."</string>
+ <string name="issuerecord_save_text" msgid="1205985304551521495">"Нажмите, чтобы посмотреть"</string>
<string name="issuerecord_save_error" msgid="6913040083446722726">"Не удалось сохранить запись."</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Не удалось начать запись."</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Полноэкранный режим"</string>
@@ -335,7 +335,7 @@
<string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Заставка"</string>
<string name="quick_settings_camera_label" msgid="5612076679385269339">"Доступ к камере"</string>
<string name="quick_settings_mic_label" msgid="8392773746295266375">"Доступ к микрофону"</string>
- <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Есть"</string>
+ <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Разрешен"</string>
<string name="quick_settings_camera_mic_blocked" msgid="4710884905006788281">"Заблокировано"</string>
<string name="quick_settings_media_device_label" msgid="8034019242363789941">"Режим медиа"</string>
<string name="quick_settings_user_title" msgid="8673045967216204537">"Пользователь"</string>
@@ -381,7 +381,7 @@
<string name="quick_settings_night_secondary_label_on_at" msgid="3584738542293528235">"Включить в <xliff:g id="TIME">%s</xliff:g>"</string>
<string name="quick_settings_secondary_label_until" msgid="1883981263191927372">"До <xliff:g id="TIME">%s</xliff:g>"</string>
<string name="quick_settings_ui_mode_night_label" msgid="1398928270610780470">"Тёмная тема"</string>
- <string name="quick_settings_dark_mode_secondary_label_battery_saver" msgid="4990712734503013251">"Режим энергосбер."</string>
+ <string name="quick_settings_dark_mode_secondary_label_battery_saver" msgid="4990712734503013251">"Энергосбережение"</string>
<string name="quick_settings_dark_mode_secondary_label_on_at_sunset" msgid="6017379738102015710">"Вкл. на закате"</string>
<string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"До рассвета"</string>
<string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Включить в <xliff:g id="TIME">%s</xliff:g>"</string>
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"отменить выбор виджета"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Уменьшить высоту"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Увеличить высоту"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Показать следующий"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Показать предыдущий"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Виджеты на заблокированном экране"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Чтобы открыть приложение, используя виджет, вам нужно будет подтвердить свою личность. Обратите внимание, что виджеты видны всем, даже если планшет заблокирован. Некоторые виджеты не предназначены для использования на заблокированном экране. Добавлять их туда может быть небезопасно."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"ОК"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" не поддерживает функции разговоров."</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Оставить отзыв"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Закрыть"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Больше не показывать"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Эти уведомления нельзя изменить."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Уведомления о звонках нельзя изменить."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Эту группу уведомлений нельзя настроить здесь."</string>
diff --git a/packages/SystemUI/res/values-ru/tiles_states_strings.xml b/packages/SystemUI/res/values-ru/tiles_states_strings.xml
index 43d3e2a..e7ff74d 100644
--- a/packages/SystemUI/res/values-ru/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ru/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Отключено"</item>
<item msgid="5908720590832378783">"Включено"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 9ff6747..eb816b8 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"විජට් නොතෝරන්න"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"උස අඩු කරන්න"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"උස වැඩි කරන්න"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"මීළග පෙන්වන්න"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"පෙර එක පෙන්වන්න"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"අගුළු තිර විජට්"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"විජට් එකක් භාවිතයෙන් යෙදුමක් විවෘත කිරීමට, ඔබට ඒ ඔබ බව සත්යාපනය කිරීමට අවශ්ය වනු ඇත. එසේම, ඔබේ ටැබ්ලටය අගුළු දමා ඇති විට පවා ඕනෑම කෙනෙකුට ඒවා බැලිය හැකි බව මතක තබා ගන්න. සමහර විජට් ඔබේ අගුළු තිරය සඳහා අදහස් කර නොතිබිය හැකි අතර මෙහි එක් කිරීමට අනාරක්ෂිත විය හැක."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"තේරුණා"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> සංවාද විශේෂාංගවලට සහාය නොදක්වයි"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"ප්රතිපෝෂණය"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"අස් කරන්න"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"නැවත නොපෙන්වන්න"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"මෙම දැනුම්දීම් වෙනස් කළ නොහැක."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"ඇමතුම් දැනුම්දීම් වෙනස් කළ නොහැකිය."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"මෙම දැනුම්දීම් සමූහය මෙහි වින්යාස කළ නොහැක"</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"දිග හැරෙමින් පවතින නැමිය හැකි උපාංගය"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"වටා පෙරළෙමින් තිබෙන නැමිය හැකි උපාංගය"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"ඉදිරිපස තිරය ක්රියාත්මකයි"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"අභ්යන්තර තිරය භාවිතා කිරීමට ස්ලයිඩ් කරන්න"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"නැවූ"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"නොනැවූ"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
diff --git a/packages/SystemUI/res/values-si/tiles_states_strings.xml b/packages/SystemUI/res/values-si/tiles_states_strings.xml
index 91280e1..710e9aa 100644
--- a/packages/SystemUI/res/values-si/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-si/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"ක්රියාවිරහිතයි"</item>
<item msgid="5908720590832378783">"ක්රියාත්මකයි"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index a42eb1e..fcb281d 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -354,7 +354,7 @@
<string name="quick_settings_inversion_label" msgid="3501527749494755688">"Inverzia farieb"</string>
<string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Úprava farieb"</string>
<string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Veľkosť písma"</string>
- <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Spravovať použ."</string>
+ <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Spravovať používateľov"</string>
<string name="quick_settings_done" msgid="2163641301648855793">"Hotovo"</string>
<string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Zavrieť"</string>
<string name="quick_settings_connected" msgid="3873605509184830379">"Pripojené"</string>
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"zrušiť výber miniaplikácie"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Znížiť výšku"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Zväčšiť výšku"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Zobraziť ďalší"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Zobraziť predchádzajúci"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Miniaplikácie na uzamknutej obrazovke"</string>
<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>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> nepodporuje funkcie konverzácie"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Spätná väzba"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Zavrieť"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Nabudúce nezobrazovať"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Tieto upozornenia sa nedajú upraviť."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Upozornenia na hovory sa nedajú upraviť."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Túto skupinu upozornení nejde na tomto mieste konfigurovať"</string>
@@ -1349,7 +1356,7 @@
<string name="clipboard_image_preview" msgid="2156475174343538128">"Ukážka obrázka"</string>
<string name="clipboard_edit" msgid="4500155216174011640">"upraviť"</string>
<string name="add" msgid="81036585205287996">"Pridať"</string>
- <string name="manage_users" msgid="1823875311934643849">"Spravovať použ."</string>
+ <string name="manage_users" msgid="1823875311934643849">"Spravovať používateľov"</string>
<string name="drag_split_not_supported" msgid="7173481676120546121">"Toto upozornenie nepodporuje presun na rozdelenú obrazovku"</string>
<string name="dream_overlay_location_active" msgid="6484763493158166618">"Aktívne miesto"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi nie je k dispozícii"</string>
@@ -1524,7 +1531,7 @@
<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>
- <string name="home_controls_dream_description" msgid="4644150952104035789">"Rýchly prístup k ovládaniu domácnosti z šetriča obrazovky"</string>
+ <string name="home_controls_dream_description" msgid="4644150952104035789">"Rýchle ovládanie domácnosti z šetriča obrazovky"</string>
<string name="volume_undo_action" msgid="5815519725211877114">"Vrátiť späť"</string>
<string name="back_edu_toast_content" msgid="4530314597378982956">"Ak chcete prejsť späť, potiahnite po touchpade troma prstami doľava alebo doprava"</string>
<string name="home_edu_toast_content" msgid="3381071147871955415">"Ak sa chcete vrátiť na plochu, potiahnite po touchpade troma prstami nahor."</string>
diff --git a/packages/SystemUI/res/values-sk/tiles_states_strings.xml b/packages/SystemUI/res/values-sk/tiles_states_strings.xml
index 0b0b894..8323506 100644
--- a/packages/SystemUI/res/values-sk/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sk/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Vypnuté"</item>
<item msgid="5908720590832378783">"Zapnuté"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index c0e751b..e999065 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"preklic izbire pripomočka"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Zmanjšanje višine"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Povečanje višine"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Prikaz naslednjega"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Prikaz prejšnjega"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Pripomočki na zaklenjenem zaslonu"</string>
<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>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> ne podpira pogovornih funkcij."</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Povratne informacije"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Opusti"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Tega ne prikaži več"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Za ta obvestila ni mogoče spremeniti nastavitev."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Obvestil o klicih ni mogoče spreminjati."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Te skupine obvestil ni mogoče konfigurirati tukaj"</string>
diff --git a/packages/SystemUI/res/values-sl/tiles_states_strings.xml b/packages/SystemUI/res/values-sl/tiles_states_strings.xml
index f9ccbb1..d644038 100644
--- a/packages/SystemUI/res/values-sl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sl/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Izklopljeno"</item>
<item msgid="5908720590832378783">"Vklopljeno"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 06cefd9c..7e2b698 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"anulo zgjedhjen e miniaplikacionit"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Zvogëlo lartësinë"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Rrit lartësinë"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Shfaq tjetrin"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Shfaq të mëparshmin"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Miniaplikacionet në ekranin e kyçjes"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Për të hapur një aplikacion duke përdorur një miniaplikacion, do të duhet të verifikosh që je ti. Ki parasysh gjithashtu që çdo person mund t\'i shikojë, edhe kur tableti yt është i kyçur. Disa miniaplikacione mund të mos jenë planifikuar për ekranin tënd të kyçjes dhe mund të mos jetë e sigurt t\'i shtosh këtu."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"E kuptova"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> nuk mbështet veçoritë e bisedës"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Koment"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Hiq"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Mos e shfaq më"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Këto njoftime nuk mund të modifikohen."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Njoftimet e telefonatave nuk mund të modifikohen."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Ky grup njoftimesh nuk mund të konfigurohet këtu"</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Pajisja e palosshme duke u hapur"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Pajisja e palosshme duke u rrotulluar"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Ekrani i përparmë është aktivizuar"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"Rrëshqit për të përdorur ekranin e brendshëm"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"palosur"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"shpalosur"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
diff --git a/packages/SystemUI/res/values-sq/tiles_states_strings.xml b/packages/SystemUI/res/values-sq/tiles_states_strings.xml
index 1ab4f01..1b1a62f 100644
--- a/packages/SystemUI/res/values-sq/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sq/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Joaktive"</item>
<item msgid="5908720590832378783">"Aktive"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 3977058..1e44e0c 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"поништи избор виџета"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Смањи висину"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Повећај висину"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Прикажите следеће"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Прикажите претходно"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Виџети за закључани екран"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Да бисте отворили апликацију која користи виџет, треба да потврдите да сте то ви. Имајте у виду да свако може да га види, чак и када је таблет закључан. Неки виџети можда нису намењени за закључани екран и можда није безбедно да их тамо додате."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Важи"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> не подржава функције конверзације"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Повратне информације"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Одбаци"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Не приказуј поново"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Ова обавештења не могу да се мењају."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Обавештења о позивима не могу да се мењају."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Ова група обавештења не може да се конфигурише овде"</string>
@@ -1370,7 +1377,7 @@
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Промените излаз"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Непознато"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"с:мин"</string>
- <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"ч:мин"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="log_access_confirmation_title" msgid="4843557604739943395">"Желите да дозволите да <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> приступа свим евиденцијама уређаја?"</string>
<string name="log_access_confirmation_allow" msgid="752147861593202968">"Дозволи једнократан приступ"</string>
<string name="log_access_confirmation_deny" msgid="2389461495803585795">"Не дозволи"</string>
diff --git a/packages/SystemUI/res/values-sr/tiles_states_strings.xml b/packages/SystemUI/res/values-sr/tiles_states_strings.xml
index ec5f10f..e1bd7b1 100644
--- a/packages/SystemUI/res/values-sr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sr/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Искључено"</item>
<item msgid="5908720590832378783">"Укључено"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 7051a2a..d613922 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"avmarkera widget"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Minska höjden"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Öka höjden"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Visa nästa"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Visa föregående"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgetar för låsskärm"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Du måste verifiera din identitet innan du öppnar en app med en widget. Tänk också på att alla kan se dem, även när surfplattan är låst. Vissa widgetar kanske inte är avsedda för låsskärmen och det kan vara osäkert att lägga till dem här."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> har inte stöd för konversationsfunktioner"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Feedback"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Stäng"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Visa inte igen"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Det går inte att ändra de här aviseringarna."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Det går inte att ändra samtalsaviseringarna."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Den här aviseringsgruppen kan inte konfigureras här"</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"En vikbar enhet viks upp"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"En vikbar enhet vänds"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Den främre skärmen har aktiverats"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"Dra för att använda den inre skärmen"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"hopvikt"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"uppvikt"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
diff --git a/packages/SystemUI/res/values-sv/tiles_states_strings.xml b/packages/SystemUI/res/values-sv/tiles_states_strings.xml
index e9da805..37d757e 100644
--- a/packages/SystemUI/res/values-sv/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sv/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Av"</item>
<item msgid="5908720590832378783">"På"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 2ead01a..33d8511 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -335,7 +335,7 @@
<string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Taswira ya skrini"</string>
<string name="quick_settings_camera_label" msgid="5612076679385269339">"Ufikiaji wa kamera"</string>
<string name="quick_settings_mic_label" msgid="8392773746295266375">"Ufikiaji wa maikrofoni"</string>
- <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Unapatikana"</string>
+ <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Inapatikana"</string>
<string name="quick_settings_camera_mic_blocked" msgid="4710884905006788281">"Umezuiwa"</string>
<string name="quick_settings_media_device_label" msgid="8034019242363789941">"Kifaa cha faili"</string>
<string name="quick_settings_user_title" msgid="8673045967216204537">"Mtumiaji"</string>
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"acha kuchagua wijeti"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Punguza urefu"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Ongeza urefu"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Onyesha inayofuata"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Onyesha iliyotangulia"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Wijeti zinazoonekana kwenye skrini iliyofungwa"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Utahitaji kuthibitisha kuwa ni wewe ili ufungue programu ukitumia wijeti. Pia, kumbuka kuwa mtu yeyote anaweza kuziona, hata kishikwambi chako kikiwa kimefungwa. Huenda baadhi ya wijeti hazikukusudiwa kutumika kwenye skrini yako iliyofungwa na huenda si salama kuziweka hapa."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Nimeelewa"</string>
@@ -573,7 +575,7 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Unaporuhusu ufikiaji wa programu, chochote kinachoonyeshwa au kuchezwa katika programu hiyo kitaonekana kwa <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Kwa hivyo kuwa mwangalifu na vitu kama vile manenosiri, maelezo ya malipo, ujumbe, picha, sauti na video."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Ruhusu ufikiaji wa skrini"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> imezima chaguo hili"</string>
- <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Kuchagua programu utakayoruhusu ifikiwe"</string>
+ <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Chagua programu utakayoruhusu ifikiwe"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Ungependa kutuma maudhui yaliyo katika skrini yako?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Tuma maudhui ya programu moja"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_entire_screen" msgid="8389508187954155307">"Tuma maudhui katika skrini nzima"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> haitumii vipengele vya mazungumzo"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Maoni"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Ondoa"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Usionyeshe tena"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Arifa hizi haziwezi kubadilishwa."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Arifa za simu haziwezi kubadilishwa."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Kikundi hiki cha arifa hakiwezi kuwekewa mipangilio hapa"</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Kifaa kinachokunjwa kikikunjuliwa"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Kifaa kinachokunjwa kikigeuzwa"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Umewasha skrini ya mbele"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"Telezesha kidole ili utumie skrini ya ndani"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"kimekunjwa"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"kimefunguliwa"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
diff --git a/packages/SystemUI/res/values-sw/tiles_states_strings.xml b/packages/SystemUI/res/values-sw/tiles_states_strings.xml
index 702af45..fae42c3 100644
--- a/packages/SystemUI/res/values-sw/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sw/tiles_states_strings.xml
@@ -64,12 +64,12 @@
<string-array name="tile_states_rotation">
<item msgid="4578491772376121579">"Hakipatikani"</item>
<item msgid="5776427577477729185">"Kimezimwa"</item>
- <item msgid="7105052717007227415">"Kimewashwa"</item>
+ <item msgid="7105052717007227415">"Imewashwa"</item>
</string-array>
<string-array name="tile_states_bt">
<item msgid="5330252067413512277">"Hakipatikani"</item>
<item msgid="5315121904534729843">"Kimezimwa"</item>
- <item msgid="503679232285959074">"Kimewashwa"</item>
+ <item msgid="503679232285959074">"Imewashwa"</item>
</string-array>
<string-array name="tile_states_airplane">
<item msgid="1985366811411407764">"Hakipatikani"</item>
@@ -93,7 +93,7 @@
</string-array>
<string-array name="tile_states_inversion">
<item msgid="3638187931191394628">"Hakipatikani"</item>
- <item msgid="9103697205127645916">"Kimezimwa"</item>
+ <item msgid="9103697205127645916">"Umezimwa"</item>
<item msgid="8067744885820618230">"Kimewashwa"</item>
</string-array>
<string-array name="tile_states_saver">
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Limezimwa"</item>
<item msgid="5908720590832378783">"Limewashwa"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index b37350c..aa312c7 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"விட்ஜெட்டைத் தேர்வுநீக்கும்"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"உயரத்தைக் குறைக்கும்"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"உயரத்தை அதிகரிக்கும்"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"அடுத்ததைக் காட்டும்"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"முந்தையதைக் காட்டும்"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"பூட்டுத் திரை விட்ஜெட்கள்"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"விட்ஜெட்டைப் பயன்படுத்தி ஆப்ஸைத் திறக்க, அது நீங்கள்தான் என்பதை உறுதிசெய்ய வேண்டும். அத்துடன், உங்கள் டேப்லெட் பூட்டப்பட்டிருந்தாலும்கூட அவற்றை யார் வேண்டுமானாலும் பார்க்கலாம் என்பதை நினைவில்கொள்ளுங்கள். சில விட்ஜெட்கள் உங்கள் பூட்டுத் திரைக்காக உருவாக்கப்பட்டவை அல்ல என்பதையும் அவற்றை இங்கே சேர்ப்பது பாதுகாப்பற்றதாக இருக்கக்கூடும் என்பதையும் நினைவில்கொள்ளுங்கள்."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"சரி"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"உரையாடல் அம்சங்களை <xliff:g id="APP_NAME">%1$s</xliff:g> ஆதரிக்காது"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"கருத்து"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"மூடுக"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"மீண்டும் காட்டாதே"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"இந்த அறிவிப்புகளை மாற்ற இயலாது."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"அழைப்பு அறிவிப்புகளை மாற்ற முடியாது."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"இந்த அறிவுப்புக் குழுக்களை இங்கே உள்ளமைக்க இயலாது"</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"மடக்கத்தக்க சாதனம் திறக்கப்படுகிறது"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"மடக்கத்தக்க சாதனம் ஃபிளிப் செய்யப்பட்டு திருப்பப்படுகிறது"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"முன்பக்கத் திரை இயக்கப்பட்டுள்ளது"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"உட்புறத் திரையைப் பயன்படுத்த ஸ்லைடு செய்யுங்கள்"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"மடக்கப்பட்டது"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"விரிக்கப்பட்டது"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
diff --git a/packages/SystemUI/res/values-ta/tiles_states_strings.xml b/packages/SystemUI/res/values-ta/tiles_states_strings.xml
index 17cc570..b09b17f 100644
--- a/packages/SystemUI/res/values-ta/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ta/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"முடக்கப்பட்டுள்ளது"</item>
<item msgid="5908720590832378783">"இயக்கப்பட்டுள்ளது"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index f64c737..fc5361b 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"విడ్జెట్ ఎంపిక రద్దు చేయండి"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"ఎత్తును తగ్గించండి"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"ఎత్తును పెంచండి"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"తర్వాతది చూడండి"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"మునుపటి దాన్ని చూడండి"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"లాక్ స్క్రీన్ విడ్జెట్లు"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"విడ్జెట్ను ఉపయోగించి యాప్ను తెరవడానికి, ఇది మీరేనని వెరిఫై చేయాల్సి ఉంటుంది. అలాగే, మీ టాబ్లెట్ లాక్ చేసి ఉన్నప్పటికీ, ఎవరైనా వాటిని చూడగలరని గుర్తుంచుకోండి. కొన్ని విడ్జెట్లు మీ లాక్ స్క్రీన్కు తగినవి కాకపోవచ్చు, వాటిని ఇక్కడ జోడించడం సురక్షితం కాకపోవచ్చు."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"అర్థమైంది"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> సంభాషణ ఫీచర్లను సపోర్ట్ చేయదు"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"ఫీడ్బ్యాక్"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"విస్మరించండి"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"మళ్లీ చూపవద్దు"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"ఈ నోటిఫికేషన్లను ఎడిట్ చేయడం వీలుపడదు."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"కాల్ నోటిఫికేషన్లను ఎడిట్ చేయడం సాధ్యం కాదు."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"ఈ నోటిఫికేషన్ల గ్రూప్ను ఇక్కడ కాన్ఫిగర్ చేయలేము"</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"మడవగల పరికరం విప్పబడుతోంది"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"మడవగల పరికరం చుట్టూ తిప్పబడుతోంది"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"ముందు వైపు స్క్రీన్ ఆన్ అయింది"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"లోపలి స్క్రీన్ను ఉపయోగించడానికి స్లయిడ్ చేయండి"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"మడిచే సదుపాయం గల పరికరం"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"మడిచే సదుపాయం లేని పరికరం"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
diff --git a/packages/SystemUI/res/values-te/tiles_states_strings.xml b/packages/SystemUI/res/values-te/tiles_states_strings.xml
index 8a0ab484..7562aae 100644
--- a/packages/SystemUI/res/values-te/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-te/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"ఆఫ్లో ఉంది"</item>
<item msgid="5908720590832378783">"ఆన్లో ఉంది"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 316aab0..873635d 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"ยกเลิกการเลือกวิดเจ็ต"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"ลดความสูง"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"เพิ่มความสูง"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"แสดงมีเดียเพลเยอร์ถัดไป"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"แสดงมีเดียเพลเยอร์ก่อนหน้า"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"วิดเจ็ตในหน้าจอล็อก"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"หากต้องการเปิดแอปโดยใช้วิดเจ็ต คุณจะต้องยืนยันตัวตนของคุณ นอกจากนี้ โปรดทราบว่าผู้อื่นจะดูวิดเจ็ตเหล่านี้ได้แม้ว่าแท็บเล็ตจะล็อกอยู่ก็ตาม วิดเจ็ตบางอย่างอาจไม่ได้มีไว้สำหรับหน้าจอล็อกของคุณ และอาจไม่ปลอดภัยที่จะเพิ่มที่นี่"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"รับทราบ"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ไม่รองรับฟีเจอร์การสนทนา"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"ความคิดเห็น"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"ปิด"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"ไม่ต้องแสดงอีก"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"แก้ไขการแจ้งเตือนเหล่านี้ไม่ได้"</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"แก้ไขการแจ้งเตือนสายเรียกเข้าไม่ได้"</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"การแจ้งเตือนกลุ่มนี้กำหนดค่าที่นี่ไม่ได้"</string>
diff --git a/packages/SystemUI/res/values-th/tiles_states_strings.xml b/packages/SystemUI/res/values-th/tiles_states_strings.xml
index 4db59c0..6d36036 100644
--- a/packages/SystemUI/res/values-th/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-th/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"ปิด"</item>
<item msgid="5908720590832378783">"เปิด"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 04dc6c7..e6aa410 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"i-unselect ang widget"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Bawasan ang taas"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Dagdagan ang taas"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Ipakita ang susunod"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Ipakita ang mga nakaraan"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Mga widget ng lock screen"</string>
<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>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"Hindi sinusuportahan ng <xliff:g id="APP_NAME">%1$s</xliff:g> ang mga feature ng pag-uusap"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Feedback"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"I-dismiss"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Huwag nang ipakita ulit"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Hindi puwedeng baguhin ang mga notification na ito."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Hindi mabago ang mga notification ng tawag."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Hindi mako-configure dito ang pangkat na ito ng mga notification"</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Ina-unfold na foldable na device"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Fini-flip na foldable na device"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Na-on ang screen sa harap"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"I-slide para gamitin ang inner screen"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"naka-fold"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"hindi naka-fold"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
diff --git a/packages/SystemUI/res/values-tl/tiles_states_strings.xml b/packages/SystemUI/res/values-tl/tiles_states_strings.xml
index 4832d1d..112c0bf 100644
--- a/packages/SystemUI/res/values-tl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-tl/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Naka-off"</item>
<item msgid="5908720590832378783">"Naka-on"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index f4a2c92..05fc1f2 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"widget\'ın seçimini kaldırın"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Yüksekliği azalt"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Yüksekliği artır"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Sonrakini göster"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Öncekini göster"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Kilit ekranı widget\'ları"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Widget kullanarak bir uygulamayı açmak için kimliğinizi doğrulamanız gerekir. Ayrıca, tabletiniz kilitliyken bile widget\'ların herkes tarafından görüntülenebileceğini unutmayın. Bazı widget\'lar kilit ekranınız için tasarlanmamış olabileceğinden buraya eklenmeleri güvenli olmayabilir."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Anladım"</string>
@@ -542,7 +544,7 @@
<string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Cihazınız şarj olurken en sevdiğiniz widget\'lara ve ekran koruyuculara erişin."</string>
<string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Başlayalım"</string>
<string name="glanceable_hub_to_dream_button_tooltip" msgid="9018287673822335829">"Cihazınız şarj olurken en sevdiğiniz ekran koruyucuları gösterin"</string>
- <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Kullanıcı değiştirme"</string>
+ <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Kullanıcı değiştir"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"açılır menü"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Bu oturumdaki tüm uygulamalar ve veriler silinecek."</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Misafir kullanıcı, tekrar hoşgeldiniz"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g>, sohbet özelliklerini desteklemiyor"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Geri bildirim"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Kapat"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Tekrar gösterme"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Bu bildirimler değiştirilemez."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Arama bildirimleri değiştirilemez."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Bu bildirim grubu burada yapılandırılamaz"</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Katlanabilir cihaz açılıyor"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Katlanabilir cihaz döndürülüyor"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Ön ekran açıldı"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"İç taraftaki ekranı kullanmak için kaydırın"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"katlanmış"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"katlanmamış"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
diff --git a/packages/SystemUI/res/values-tr/tiles_states_strings.xml b/packages/SystemUI/res/values-tr/tiles_states_strings.xml
index 1c0c110..f3c51c0 100644
--- a/packages/SystemUI/res/values-tr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-tr/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Kapalı"</item>
<item msgid="5908720590832378783">"Açık"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 7dab3db..0b0d6dc 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"скасувати вибір віджета"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Зменшити висоту"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Збільшити висоту"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Показати наступний"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Показати попередній"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Віджети для заблокованого екрана"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Щоб відкрити додаток за допомогою віджета, вам потрібно буде підтвердити особу. Пам’ятайте також, що бачити віджети можуть усі, навіть коли планшет заблоковано. Можливо, деякі віджети не призначені для заблокованого екрана, і додавати їх на нього може бути небезпечно."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> не підтримує функції розмов"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Надіслати відгук"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Закрити"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Більше не показувати"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Ці сповіщення не можна змінити."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Сповіщення про виклик не можна змінити."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Цю групу сповіщень не можна налаштувати тут"</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Розкладний пристрій у розкладеному стані"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Розкладний пристрій обертається"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Передній екран увімкнено"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"Проведіть пальцем, щоб використовувати внутрішній екран"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"складений"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"розкладений"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
diff --git a/packages/SystemUI/res/values-uk/tiles_states_strings.xml b/packages/SystemUI/res/values-uk/tiles_states_strings.xml
index 656ccd4..4fac740 100644
--- a/packages/SystemUI/res/values-uk/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-uk/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Вимкнено"</item>
<item msgid="5908720590832378783">"Увімкнено"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 6460721..ab4dd77 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"ویجیٹ غیر منتخب کریں"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"اونچائی کم کریں"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"اونچائی بڑھائیں"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"اگلا دکھائیں"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"سابقہ دکھائیں"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"مقفل اسکرین کے ویجیٹس"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ویجیٹ کے ذریعے ایپ کھولنے کے لیے آپ کو تصدیق کرنی ہوگی کہ یہ آپ ہی ہیں۔ نیز، ذہن میں رکھیں کہ کوئی بھی انہیں دیکھ سکتا ہے، یہاں تک کہ جب آپ کا ٹیبلیٹ مقفل ہو۔ ہو سکتا ہے کچھ ویجٹس آپ کی لاک اسکرین کے لیے نہ بنائے گئے ہوں اور یہاں شامل کرنا غیر محفوظ ہو سکتا ہے۔"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"سمجھ آ گئی"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ایپ گفتگو کی خصوصیات کو سپورٹ نہیں کرتی ہے"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"تاثرات"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"برخاست کریں"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"دوبارہ نہ دکھائیں"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"ان اطلاعات کی ترمیم نہیں کی جا سکتی۔"</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"کال کی اطلاعات میں ترمیم نہیں کی جا سکتی۔"</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"اطلاعات کے اس گروپ کو یہاں کنفیگر نہیں کیا جا سکتا"</string>
diff --git a/packages/SystemUI/res/values-ur/tiles_states_strings.xml b/packages/SystemUI/res/values-ur/tiles_states_strings.xml
index 4aa490d..06e213b 100644
--- a/packages/SystemUI/res/values-ur/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ur/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"آف"</item>
<item msgid="5908720590832378783">"آن"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 6bcd9d6..55caf25 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -60,12 +60,12 @@
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Tilni almashtirish"</string>
<string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Joriy tilni qoldirish"</string>
<string name="share_wifi_button_text" msgid="1285273973812029240">"Wi‑Fi ulashuv"</string>
- <string name="wifi_debugging_title" msgid="7300007687492186076">"Wi-Fi orqali debagging uchun ruxsat berilsinmi?"</string>
+ <string name="wifi_debugging_title" msgid="7300007687492186076">"Wi-Fi orqali debaging uchun ruxsat berilsinmi?"</string>
<string name="wifi_debugging_message" msgid="5461204211731802995">"Tarmoq nomi (SSID):\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi‑Fi Manzil (BSSID):\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string>
<string name="wifi_debugging_always" msgid="2968383799517975155">"Bu tarmoqda doim ruxsat etilsin"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Ruxsat"</string>
- <string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Wi-Fi orqali debagging taqiqlandi"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"Ayni paytda ushbu qurilmaga oʻz hisobi bilan kirgan foydalanuvchi Wi-Fi orqali debagging funksiyasini yoqa olmaydi. Bu funksiyadan foydalanish uchun administrator profiliga oʻting."</string>
+ <string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Wi-Fi orqali debaging taqiqlandi"</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"Ayni paytda ushbu qurilmaga oʻz hisobi bilan kirgan foydalanuvchi Wi-Fi orqali debaging funksiyasini yoqa olmaydi. Bu funksiyadan foydalanish uchun administrator profiliga oʻting."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB port faolsizlashtirildi"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"Qurilmangizni suyuqlik va turli parchalardan himoya qilish uchun USB port faolsizlashtiriladi va hech qanday aksessuarni aniqlay olmaydi.\n\nUSB portdan xavfsiz foydalanish mumkin boʻlganda, sizga xabar beriladi."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"Quvvatlash moslamalari va aksessuarlarni aniqlash uchun USB port yoqildi"</string>
@@ -354,7 +354,7 @@
<string name="quick_settings_inversion_label" msgid="3501527749494755688">"Ranglarni akslantirish"</string>
<string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Ranglarni tuzatish"</string>
<string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Shrift hajmi"</string>
- <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Foyd-ni boshqarish"</string>
+ <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Foydalanuvchilarni boshqarish"</string>
<string name="quick_settings_done" msgid="2163641301648855793">"Tayyor"</string>
<string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Yopish"</string>
<string name="quick_settings_connected" msgid="3873605509184830379">"Ulangan"</string>
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"vidjetni bekor qilish"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Balandligini kichraytirish"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Balandligini oshirish"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Keyingisi"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Avvalgisi"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Ekran qulfi vidjetlari"</string>
<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>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilovasida suhbat funksiyalari ishlamaydi"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Fikr-mulohaza"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Yopish"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Boshqa chiqmasin"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Bu bildirishnomalarni tahrirlash imkonsiz."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Chaqiruv bildirishnomalarini tahrirlash imkonsiz."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Ushbu bildirishnomalar guruhi bu yerda sozlanmaydi"</string>
@@ -1349,7 +1356,7 @@
<string name="clipboard_image_preview" msgid="2156475174343538128">"Rasmga razm solish"</string>
<string name="clipboard_edit" msgid="4500155216174011640">"tahrir"</string>
<string name="add" msgid="81036585205287996">"Kiritish"</string>
- <string name="manage_users" msgid="1823875311934643849">"Foyd-ni boshqarish"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Foydalanuvchilarni boshqarish"</string>
<string name="drag_split_not_supported" msgid="7173481676120546121">"Bu bildirishnoma ikkiga ajratilgan ekranda ishlamaydi."</string>
<string name="dream_overlay_location_active" msgid="6484763493158166618">"Joylashuv faol"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi ishlamayapti"</string>
@@ -1394,10 +1401,9 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Buklanadigan qurilma ochilmoqda"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Buklanadigan qurilma aylantirilmoqda"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Old ekran yoqildi"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"Ichki ekranni ishlatish uchun surish"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"buklangan"</string>
- <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"buklanmagan"</string>
+ <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"yoyib ochilgan"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
<string name="stylus_battery_low_percentage" msgid="2564243323894629626">"Stilus batareyasi: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
<string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Stilusni quvvat manbaiga ulang"</string>
diff --git a/packages/SystemUI/res/values-uz/tiles_states_strings.xml b/packages/SystemUI/res/values-uz/tiles_states_strings.xml
index 1c32e9fb..f636bc6 100644
--- a/packages/SystemUI/res/values-uz/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-uz/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Yoqilmagan"</item>
<item msgid="5908720590832378783">"Yoniq"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index a9f24ed..35fe2f2 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"bỏ chọn tiện ích"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Giảm chiều cao"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Tăng chiều cao"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Hiện trình phát nội dung nghe nhìn tiếp theo"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Hiện trình phát nội dung nghe nhìn trước"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Tiện ích trên màn hình khoá"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Để dùng tiện ích mở một ứng dụng, bạn cần xác minh danh tính của mình. Ngoài ra, hãy lưu ý rằng bất kỳ ai cũng có thể xem các tiện ích này, ngay cả khi máy tính bảng của bạn được khoá. Một số tiện ích có thể không dành cho màn hình khoá và không an toàn khi thêm vào đây."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Tôi hiểu"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> không hỗ trợ các tính năng trò chuyện"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Phản hồi"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Đóng"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Không hiện lại"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Không thể sửa đổi các thông báo này."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Không thể sửa đổi các thông báo cuộc gọi."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Không thể định cấu hình nhóm thông báo này tại đây"</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Thiết bị có thể gập lại đang được mở ra"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Thiết bị có thể gập lại đang được lật ngược"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Đã bật màn hình trước"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"Trượt để dùng màn hình bên trong"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"gập"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"mở"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
diff --git a/packages/SystemUI/res/values-vi/tiles_states_strings.xml b/packages/SystemUI/res/values-vi/tiles_states_strings.xml
index 466eb3d6..d8e6887 100644
--- a/packages/SystemUI/res/values-vi/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-vi/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Đang tắt"</item>
<item msgid="5908720590832378783">"Đang bật"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 0f28d92..530017c 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"取消选中微件"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"减小高度"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"增加高度"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"显示下一个"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"显示上一个"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"锁屏微件"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"若要使用微件打开应用,您需要验证是您本人在操作。另外请注意,任何人都可以查看此类微件,即使您的平板电脑已锁定。有些微件可能不适合显示在锁定的屏幕中,因此添加到这里可能不安全。"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"知道了"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g>不支持对话功能"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"反馈"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"关闭"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"不再显示"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"无法修改这些通知。"</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"无法修改来电通知。"</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"您无法在此处配置这组通知"</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"正在展开可折叠设备"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"正在翻转可折叠设备"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"前屏已开启"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"滑动即可使用内屏"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"折叠状态"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"展开状态"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml b/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml
index 65415f6..6f36065 100644
--- a/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"关闭"</item>
<item msgid="5908720590832378783">"开启"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 6a29d86..496cbdb 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"取消揀小工具"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"調低高度"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"調高高度"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"顯示下一個"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"顯示上一個"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"上鎖畫面小工具"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"如要使用小工具開啟應用程式,系統會要求你驗證身分。請注意,所有人都能查看小工具,即使平板電腦已鎖定亦然。部分小工具可能不適用於上鎖畫面,新增至這裡可能會有安全疑慮。"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"知道了"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」不支援對話功能"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"意見反映"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"關閉"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"不要再顯示"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"無法修改這些通知。"</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"無法修改通話通知。"</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"無法在此設定這組通知"</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"正在展開折疊式裝置"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"正在翻轉折疊式裝置"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"正面螢幕已開啟"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"滑動即可使用內部螢幕"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"已摺疊"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"已打開"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml b/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml
index 0882be7..25548e2 100644
--- a/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"關閉"</item>
<item msgid="5908720590832378783">"開啟"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index a931304..c63473f 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -534,6 +534,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"取消選取小工具"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"調低"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"調高"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"顯示下一個"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"顯示上一個"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"螢幕鎖定小工具"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"如要使用小工具開啟應用程式,需先驗證身分。請留意,即使平板電腦已鎖定,所有人都還是能查看小工具。某些小工具可能不適用於螢幕鎖定畫面,新增到此可能會有安全疑慮。"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"我知道了"</string>
@@ -806,7 +808,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」不支援對話功能"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"意見回饋"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"關閉"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"不要再顯示"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"無法修改這些通知。"</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"無法修改來電通知。"</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"無法在這裡設定這個通知群組"</string>
@@ -1394,8 +1401,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"正在展開的折疊式裝置"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"正在翻轉折疊式裝置"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"正面螢幕已開啟"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"滑動即可使用內螢幕"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"已摺疊"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"已展開"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml b/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml
index f94b044..3a192ba 100644
--- a/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"關閉"</item>
<item msgid="5908720590832378783">"開啟"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 08e6852..2aad788 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -536,6 +536,8 @@
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"yeka ukukhetha iwijethi"</string>
<string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Nciphisa ubude"</string>
<string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Khuphula ubude"</string>
+ <string name="accessibility_action_label_umo_show_next" msgid="8033581654789193281">"Bonisa okulandelayo"</string>
+ <string name="accessibility_action_label_umo_show_previous" msgid="5935831384525173810">"Bonisa okwangaphambili"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Amawijethi wesikrini esikhiyiwe"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Ukuze uvule i-app usebenzisa iwijethi, uzodinga ukuqinisekisa ukuthi nguwe. Futhi, khumbula ukuthi noma ubani angakwazi ukuzibuka, nanoma ithebhulethi yakho ikhiyiwe. Amanye amawijethi kungenzeka abengahloselwe ukukhiya isikrini sakho futhi kungenzeka awaphephile ukuthi angafakwa lapha."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Ngiyezwa"</string>
@@ -808,7 +810,12 @@
<string name="no_shortcut" msgid="8257177117568230126">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> ayisekeli izici zengxoxo"</string>
<string name="notification_guts_bundle_feedback" msgid="7581587973879656500">"Impendulo"</string>
<string name="notification_inline_dismiss" msgid="88423586921134258">"Chitha"</string>
- <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Ungabonisi futhi"</string>
+ <!-- no translation found for notification_inline_disable_promotion (3551682588314376921) -->
+ <skip />
+ <!-- no translation found for live_notifications_title (1586553354601345379) -->
+ <skip />
+ <!-- no translation found for live_notifications_desc (7470787001768372152) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Lezi zaziso azikwazi ukushintshwa."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Izaziso zekholi azikwazi ukushintshwa."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Leli qembu lezaziso alikwazi ukulungiselelwa lapha"</string>
@@ -1396,8 +1403,7 @@
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Idivayisi egoqekayo iyembulwa"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Idivayisi egoqekayo iphendulwa nxazonke"</string>
<string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Isikrini sangaphambili sivuliwe"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on_slide_to_cancel (1455192420423012859) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on_slide_to_cancel" msgid="1455192420423012859">"Slayida ukuze usebenzise isikrini esingaphakathi"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"kugoqiwe"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"kuvuliwe"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
diff --git a/packages/SystemUI/res/values-zu/tiles_states_strings.xml b/packages/SystemUI/res/values-zu/tiles_states_strings.xml
index be5c6d8..f9f27bd 100644
--- a/packages/SystemUI/res/values-zu/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-zu/tiles_states_strings.xml
@@ -196,4 +196,7 @@
<item msgid="6419996398343291862">"Valiwe"</item>
<item msgid="5908720590832378783">"Vuliwe"</item>
</string-array>
+ <!-- no translation found for tile_states_desktopeffects:0 (6253480000354287321) -->
+ <!-- no translation found for tile_states_desktopeffects:1 (6641673879029894995) -->
+ <!-- no translation found for tile_states_desktopeffects:2 (5806682401126108403) -->
</resources>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 8665fd6..f4c6904 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -198,6 +198,7 @@
<!-- media -->
<color name="media_seamless_border">?android:attr/colorAccent</color>
<color name="media_paging_indicator">@color/material_dynamic_neutral_variant80</color>
+ <color name="media_on_background">#FFFFFF</color>
<!-- media output dialog-->
<color name="media_dialog_background" android:lstar="98">@color/material_dynamic_neutral90</color>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 09aa224..8d10e39 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -119,7 +119,7 @@
<!-- Tiles native to System UI. Order should match "quick_settings_tiles_default" -->
<string name="quick_settings_tiles_stock" translatable="false">
- internet,bt,flashlight,dnd,alarm,airplane,controls,wallet,rotation,battery,cast,screenrecord,mictoggle,cameratoggle,location,hotspot,inversion,saver,dark,work,night,reverse,reduce_brightness,qr_code_scanner,onehanded,color_correction,dream,font_scaling,record_issue,hearing_devices,notes
+ internet,bt,flashlight,dnd,alarm,airplane,controls,wallet,rotation,battery,cast,screenrecord,mictoggle,cameratoggle,location,hotspot,inversion,saver,dark,work,night,reverse,reduce_brightness,qr_code_scanner,onehanded,color_correction,dream,font_scaling,record_issue,hearing_devices,notes,desktopeffects
</string>
<!-- The tiles to display in QuickSettings -->
@@ -175,6 +175,9 @@
<!-- Minimum display time for a heads up notification if throttling is enabled, in milliseconds. -->
<integer name="heads_up_notification_minimum_time_with_throttling">500</integer>
+ <!-- Minimum display time for a heads up notification that was shown from a user action (like tapping on a different part of the UI), in milliseconds. -->
+ <integer name="heads_up_notification_minimum_time_for_user_initiated">3000</integer>
+
<!-- Display time for a sticky heads up notification, in milliseconds. -->
<integer name="sticky_heads_up_notification_time">60000</integer>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 8cd4c1b..17a89b3 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -204,15 +204,31 @@
match the core/status_bar_system_icon_size and change to sp unit -->
<dimen name="status_bar_mobile_signal_size">15sp</dimen>
<dimen name="status_bar_mobile_signal_size_updated">12sp</dimen>
+
<!-- Size of the view displaying the mobile signal icon in the status bar. This value should
- match the viewport height of mobile signal drawables such as ic_lte_mobiledata -->
+ match the viewport height of mobile signal drawables such as ic_lte_mobiledata
+ Note: can be removed once new_status_bar_icons is rolled out -->
<dimen name="status_bar_mobile_type_size">16sp</dimen>
<!-- Size of the view that contains the network type. Should be equal to
- status_bar_mobile_type_size + 2, to account for 1sp top and bottom padding -->
+ status_bar_mobile_type_size + 2, to account for 1sp top and bottom padding
+ Note: can be removed once new_status_bar_icons is rolled out -->
<dimen name="status_bar_mobile_container_height">18sp</dimen>
<!-- Corner radius for the background of the network type indicator. Should be equal to
- status_bar_mobile_container_height / 2 -->
+ status_bar_mobile_container_height / 2
+ Note: can be removed once new_status_bar_icons is rolled out -->
<dimen name="status_bar_mobile_container_corner_radius">9sp</dimen>
+
+ <!-- Size of the view displaying the mobile signal icon in the status bar. This value should
+ match the viewport height of mobile signal drawables such as ic_lte_mobiledata -->
+ <dimen name="status_bar_mobile_type_size_updated">12sp</dimen>
+ <!-- Size of the view that contains the network type. Should be equal to
+ status_bar_mobile_type_size + 2, to account for 1sp top and bottom padding -->
+ <dimen name="status_bar_mobile_container_height_updated">14sp</dimen>
+ <dimen name="status_bar_mobile_container_margin_end">2sp</dimen>
+ <!-- Corner radius for the background of the network type indicator. Should be equal to
+ status_bar_mobile_container_height / 2 -->
+ <dimen name="status_bar_mobile_container_corner_radius_updated">7sp</dimen>
+
<!-- Size of the view displaying the mobile roam icon in the status bar. This value should
match the viewport size of drawable stat_sys_roaming -->
<dimen name="status_bar_mobile_roam_size">8sp</dimen>
@@ -1806,7 +1822,8 @@
<!-- The activity chip side padding, used with the default phone icon. -->
<dimen name="ongoing_activity_chip_side_padding">12dp</dimen>
<!-- The activity chip side padding, used with an icon that has embedded padding (e.g. if the icon comes from the notification's smallIcon field). If the icon has padding, the chip itself can have less padding. -->
- <dimen name="ongoing_activity_chip_side_padding_for_embedded_padding_icon">6dp</dimen>
+ <dimen name="ongoing_activity_chip_side_padding_for_embedded_padding_icon">2dp</dimen>
+ <dimen name="ongoing_activity_chip_side_padding_for_embedded_padding_icon_legacy">6dp</dimen>
<!-- The icon size, used with the default phone icon. -->
<dimen name="ongoing_activity_chip_icon_size">16dp</dimen>
<!-- The icon size, used with an icon that has embedded padding. (If the icon has embedded padding, we need to make the whole icon larger so the icon itself doesn't look small.) -->
@@ -2166,9 +2183,7 @@
orientation when the vertical space is limited
-->
<dimen name="volume_dialog_slider_vertical_margin">124dp</dimen>
-
- <fraction name="volume_dialog_half_opened_bias">0.2</fraction>
-
+ <dimen name="volume_dialog_half_opened_offset">-128dp</dimen>
<dimen name="volume_dialog_slider_max_deviation">56dp</dimen>
<dimen name="volume_dialog_background_square_corner_radius">12dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index e077b41..87c4282 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -574,11 +574,12 @@
<!-- Content description of the bluetooth device settings gear icon. [CHAR LIMIT=NONE] -->
<string name="accessibility_bluetooth_device_settings_gear">Click to configure device detail</string>
+ <!-- Content description of the bluetooth device settings gear icon. [CHAR LIMIT=NONE] [BACKUP_MESSAGE_ID=3314916468105272540] -->
+ <string name="accessibility_bluetooth_device_settings_gear_with_name"><xliff:g id="device_name">%s</xliff:g>. Configure device detail</string>
<!-- Content description of the bluetooth device settings see all. [CHAR LIMIT=NONE] -->
- <string name="accessibility_bluetooth_device_settings_see_all">Click to see all devices</string>
+ <string name="accessibility_bluetooth_device_settings_see_all">See all devices</string>
<!-- Content description of the bluetooth device settings pair new device. [CHAR LIMIT=NONE] -->
- <string name="accessibility_bluetooth_device_settings_pair_new_device">Click to pair new device</string>
-
+ <string name="accessibility_bluetooth_device_settings_pair_new_device">Pair new device</string>
<!-- Content description of the battery when battery state is unknown for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_battery_unknown">Battery percentage unknown.</string>
@@ -2341,7 +2342,9 @@
<!-- 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 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 to full screen</string>
+ <string name="system_multitasking_full_screen">Use full screen</string>
+ <!-- User visible title for the keyboard shortcut that switches to desktop view [CHAR LIMIT=70] -->
+ <string name="system_multitasking_desktop_view">Use desktop view</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] -->
@@ -4007,6 +4010,8 @@
<string name="touchpad_tutorial_switch_apps_gesture_button">Switch apps</string>
<!-- Label for button finishing touchpad tutorial [CHAR LIMIT=NONE] -->
<string name="touchpad_tutorial_done_button">Done</string>
+ <!-- Label for button proceeding touchpad tutorial [CHAR LIMIT=NONE] -->
+ <string name="touchpad_tutorial_next_button">Next</string>
<!-- Screen title after gesture was not done correctly [CHAR LIMIT=NONE] -->
<string name="gesture_error_title">Try again!</string>
<!-- BACK GESTURE -->
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 8f808d3..8a6b3af 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -186,7 +186,7 @@
</style>
<style name="TextAppearance.QS.Status.Build">
- <item name="android:textColor">?attr/onSurfaceVariant</item>
+ <item name="android:textColor">?attr/onShadeInactiveVariant</item>
</style>
<style name="TextAppearance.DeviceManagementDialog.Title" parent="@android:style/TextAppearance.DeviceDefault.DialogWindowTitle"/>
@@ -828,23 +828,23 @@
<item name="android:elevation">10dp</item>
</style>
- <!-- Media controls always have light background -->
+ <!-- Media controls always have dark background -->
<style name="MediaPlayer" parent="@*android:style/Theme.DeviceDefault.Light">
- <item name="android:textColor">?android:attr/textColorPrimary</item>
- <item name="android:backgroundTint">@color/material_dynamic_secondary95</item>
+ <item name="android:textColor">@color/media_on_background</item>
+ <item name="android:backgroundTint">@android:color/system_on_surface_light</item>
</style>
<style name="MediaPlayer.ProgressBar" parent="@android:style/Widget.ProgressBar.Horizontal">
<item name="android:thumb">@drawable/media_seekbar_thumb</item>
- <item name="android:thumbTint">?android:attr/textColorPrimary</item>
+ <item name="android:thumbTint">@color/media_on_background</item>
<item name="android:progressDrawable">@drawable/media_squiggly_progress</item>
- <item name="android:progressTint">?android:attr/textColorPrimary</item>
- <item name="android:progressBackgroundTint">?android:attr/textColorTertiary</item>
+ <item name="android:progressTint">@color/media_on_background</item>
+ <item name="android:progressBackgroundTint">@android:color/system_primary_dark</item>
<item name="android:splitTrack">false</item>
</style>
<style name="MediaPlayer.Subtitle" parent="MediaPlayer">
- <item name="android:textColor">?android:attr/textColorSecondary</item>
+ <item name="android:textColor">@color/media_on_background</item>
</style>
<style name="MediaPlayer.ScrubbingTime">
@@ -853,21 +853,10 @@
<item name="android:gravity">center</item>
</style>
- <style name="MediaPlayer.Action" parent="@android:style/Widget.Material.Button.Borderless.Small">
- <item name="android:background">@drawable/qs_media_light_source</item>
- <item name="android:tint">?android:attr/textColorPrimary</item>
- <item name="android:stateListAnimator">@anim/media_button_state_list_animator</item>
- <item name="android:paddingTop">8dp</item>
- <item name="android:paddingStart">12dp</item>
- <item name="android:paddingEnd">12dp</item>
- <item name="android:paddingBottom">16dp</item>
- <item name="android:scaleType">centerInside</item>
- </style>
-
<style name="MediaPlayer.SessionAction"
parent="@android:style/Widget.Material.Button.Borderless.Small">
<item name="android:background">@drawable/qs_media_light_source</item>
- <item name="android:tint">?android:attr/textColorPrimary</item>
+ <item name="android:tint">@color/media_on_background</item>
<item name="android:paddingTop">12dp</item>
<item name="android:paddingStart">12dp</item>
<item name="android:paddingEnd">12dp</item>
@@ -886,8 +875,8 @@
<style name="MediaPlayer.OutlineButton">
<item name="android:background">@drawable/qs_media_outline_button</item>
- <item name="android:textColor">?android:attr/textColorPrimary</item>
- <item name="android:backgroundTint">@color/media_player_outline_button_bg</item>
+ <item name="android:textColor">@color/media_on_background</item>
+ <item name="android:backgroundTint">@android:color/system_primary_dark</item>
<item name="android:fontFamily">@*android:string/config_headlineFontFamilyMedium</item>
<item name="android:layout_gravity">center</item>
<item name="android:singleLine">true</item>
@@ -895,8 +884,8 @@
<style name="MediaPlayer.SolidButton">
<item name="android:backgroundTint">@color/media_player_solid_button_bg</item>
- <item name="android:tint">?android:attr/colorPrimary</item>
- <item name="android:textColor">?android:attr/textColorPrimary</item>
+ <item name="android:tint">@android:color/system_on_primary_dark</item>
+ <item name="android:textColor">@android:color/system_on_primary_dark</item>
</style>
<style name="MediaPlayer.Recommendation"/>
diff --git a/packages/SystemUI/res/values/tiles_states_strings.xml b/packages/SystemUI/res/values/tiles_states_strings.xml
index d885e00..faf06f3 100644
--- a/packages/SystemUI/res/values/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values/tiles_states_strings.xml
@@ -358,4 +358,14 @@
<item>Off</item>
<item>On</item>
</string-array>
+
+ <!-- State names for desktop effects tile: unavailable, off, on.
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as
+ if they could appear. [CHAR LIMIT=32] -->
+ <string-array name="tile_states_desktopeffects">
+ <item>Unavailable</item>
+ <item>Off</item>
+ <item>On</item>
+ </string-array>
</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/res/xml/volume_dialog_constraint_set.xml b/packages/SystemUI/res/xml/volume_dialog_constraint_set.xml
deleted file mode 100644
index dcc5d4f..0000000
--- a/packages/SystemUI/res/xml/volume_dialog_constraint_set.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<ConstraintSet xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:id="@+id/volume_dialog_constraint_set">
-
- <Constraint
- android:id="@id/volume_dialog_main_slider_container"
- android:layout_width="@dimen/volume_dialog_slider_width"
- android:layout_height="0dp"
- android:layout_marginTop="@dimen/volume_dialog_slider_vertical_margin"
- android:layout_marginEnd="@dimen/volume_dialog_window_margin"
- android:layout_marginBottom="@dimen/volume_dialog_slider_vertical_margin"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintHeight_max="@dimen/volume_dialog_slider_height"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintVertical_bias="0.5" />
-</ConstraintSet>
\ No newline at end of file
diff --git a/packages/SystemUI/res/xml/volume_dialog_half_folded_constraint_set.xml b/packages/SystemUI/res/xml/volume_dialog_half_folded_constraint_set.xml
deleted file mode 100644
index 3a5e41d..0000000
--- a/packages/SystemUI/res/xml/volume_dialog_half_folded_constraint_set.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<ConstraintSet xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:id="@+id/volume_dialog_half_folded_constraint_set">
-
- <Constraint
- android:id="@id/volume_dialog_main_slider_container"
- android:layout_width="@dimen/volume_dialog_slider_width"
- android:layout_height="0dp"
- android:layout_marginTop="@dimen/volume_dialog_slider_vertical_margin"
- android:layout_marginEnd="@dimen/volume_dialog_window_margin"
- android:layout_marginBottom="@dimen/volume_dialog_slider_vertical_margin"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintHeight_max="@dimen/volume_dialog_slider_height"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintVertical_bias="@fraction/volume_dialog_half_opened_bias" />
-</ConstraintSet>
\ No newline at end of file
diff --git a/packages/SystemUI/res/xml/volume_dialog_scene.xml b/packages/SystemUI/res/xml/volume_dialog_scene.xml
deleted file mode 100644
index b813474..0000000
--- a/packages/SystemUI/res/xml/volume_dialog_scene.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- ~ Copyright (C) 2024 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<MotionScene xmlns:motion="http://schemas.android.com/apk/res-auto">
-
- <Transition
- motion:autoTransition="none"
- motion:constraintSetEnd="@id/volume_dialog_half_folded_constraint_set"
- motion:constraintSetStart="@id/volume_dialog_constraint_set"
- motion:duration="150" />
-
- <Include motion:constraintSet="@xml/volume_dialog_constraint_set" />
- <Include motion:constraintSet="@xml/volume_dialog_half_folded_constraint_set" />
-</MotionScene>
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardMessageAreaController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardMessageAreaController.java
index f528ec8..860a496 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardMessageAreaController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardMessageAreaController.java
@@ -20,22 +20,16 @@
import android.content.res.Configuration;
import android.hardware.biometrics.BiometricSourceType;
import android.os.SystemClock;
-import android.text.Editable;
-import android.text.TextUtils;
-import android.text.TextWatcher;
import android.util.Log;
import android.util.Pair;
import android.view.View;
import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
import com.android.systemui.util.ViewController;
-import java.lang.ref.WeakReference;
-
import javax.inject.Inject;
/**
@@ -54,39 +48,8 @@
private Pair<BiometricSourceType, Long> mMessageBiometricSource = null;
private static final Long SKIP_SHOWING_FACE_MESSAGE_AFTER_FP_MESSAGE_MS = 3500L;
- /**
- * Delay before speaking an accessibility announcement. Used to prevent
- * lift-to-type from interrupting itself.
- */
- private static final long ANNOUNCEMENT_DELAY = 250;
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
private final ConfigurationController mConfigurationController;
- private final AnnounceRunnable mAnnounceRunnable;
- private final TextWatcher mTextWatcher = new TextWatcher() {
- @Override
- public void afterTextChanged(Editable editable) {
- CharSequence msg = editable;
- if (!TextUtils.isEmpty(msg)) {
- mView.removeCallbacks(mAnnounceRunnable);
- mAnnounceRunnable.setTextToAnnounce(msg);
- mView.postDelayed(() -> {
- if (msg == mView.getText()) {
- mAnnounceRunnable.run();
- }
- }, ANNOUNCEMENT_DELAY);
- }
- }
-
- @Override
- public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
- /* no-op */
- }
-
- @Override
- public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
- /* no-op */
- }
- };
private KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
public void onFinishedGoingToSleep(int why) {
@@ -122,7 +85,6 @@
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mConfigurationController = configurationController;
- mAnnounceRunnable = new AnnounceRunnable(mView);
}
@Override
@@ -131,14 +93,12 @@
mKeyguardUpdateMonitor.registerCallback(mInfoCallback);
mView.setSelected(mKeyguardUpdateMonitor.isDeviceInteractive());
mView.onThemeChanged();
- mView.addTextChangedListener(mTextWatcher);
}
@Override
protected void onViewDetached() {
mConfigurationController.removeCallback(mConfigurationListener);
mKeyguardUpdateMonitor.removeCallback(mInfoCallback);
- mView.removeTextChangedListener(mTextWatcher);
}
/**
@@ -232,30 +192,4 @@
view, mKeyguardUpdateMonitor, mConfigurationController);
}
}
-
- /**
- * Runnable used to delay accessibility announcements.
- */
- @VisibleForTesting
- public static class AnnounceRunnable implements Runnable {
- private final WeakReference<View> mHost;
- private CharSequence mTextToAnnounce;
-
- AnnounceRunnable(View host) {
- mHost = new WeakReference<>(host);
- }
-
- /** Sets the text to announce. */
- public void setTextToAnnounce(CharSequence textToAnnounce) {
- mTextToAnnounce = textToAnnounce;
- }
-
- @Override
- public void run() {
- final View host = mHost.get();
- if (host != null && host.isVisibleToUser()) {
- host.announceForAccessibility(mTextToAnnounce);
- }
- }
- }
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
index 5d63c2a..4a4cb7a 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
@@ -43,6 +43,8 @@
import com.android.settingslib.animation.AppearAnimationCreator;
import com.android.settingslib.animation.AppearAnimationUtils;
import com.android.settingslib.animation.DisappearAnimationUtils;
+import com.android.systemui.Flags;
+import com.android.systemui.bouncer.shared.constants.PatternBouncerConstants.ColorId;
import com.android.systemui.res.R;
import com.android.systemui.statusbar.policy.DevicePostureController.DevicePostureInt;
@@ -227,6 +229,18 @@
super.onFinishInflate();
mLockPatternView = findViewById(R.id.lockPatternView);
+ if (Flags.bouncerUiRevamp2()) {
+ mLockPatternView.setDotColors(mContext.getColor(ColorId.dotColor), mContext.getColor(
+ ColorId.activatedDotColor));
+ mLockPatternView.setColors(mContext.getColor(ColorId.pathColor), 0, 0);
+ mLockPatternView.setDotSizes(
+ getResources().getDimensionPixelSize(R.dimen.keyguard_pattern_dot_size),
+ getResources().getDimensionPixelSize(
+ R.dimen.keyguard_pattern_activated_dot_size));
+ mLockPatternView.setPathWidth(
+ getResources().getDimensionPixelSize(R.dimen.keyguard_pattern_stroke_width));
+ mLockPatternView.setKeepDotActivated(true);
+ }
mEcaView = findViewById(R.id.keyguard_selector_fade_container);
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java
index 245283d..04d4c2a 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java
@@ -184,7 +184,9 @@
}
mDeleteButton = findViewById(R.id.delete_button);
if (Flags.bouncerUiRevamp2()) {
- mDeleteButton.setImageResource(R.drawable.pin_bouncer_delete);
+ mDeleteButton.setDrawableForTransparentMode(R.drawable.pin_bouncer_delete_filled);
+ mDeleteButton.setDefaultDrawable(R.drawable.pin_bouncer_delete_outline);
+ mDeleteButton.setImageResource(R.drawable.pin_bouncer_delete_outline);
}
mDeleteButton.setVisibility(View.VISIBLE);
diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadButton.java b/packages/SystemUI/src/com/android/keyguard/NumPadButton.java
index 0ff9323..584ebb50 100644
--- a/packages/SystemUI/src/com/android/keyguard/NumPadButton.java
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadButton.java
@@ -25,6 +25,7 @@
import android.view.MotionEvent;
import android.view.accessibility.AccessibilityNodeInfo;
+import androidx.annotation.DrawableRes;
import androidx.annotation.Nullable;
import com.android.systemui.Flags;
@@ -42,6 +43,12 @@
private int mStyleAttr;
private boolean mIsTransparentMode;
+ @DrawableRes
+ private int mDrawableForTransparentMode = 0;
+
+ @DrawableRes
+ private int mDefaultDrawable = 0;
+
public NumPadButton(Context context, AttributeSet attrs) {
super(context, attrs);
mStyleAttr = attrs.getStyleAttribute();
@@ -123,8 +130,14 @@
mIsTransparentMode = isTransparentMode;
if (isTransparentMode) {
+ if (mDrawableForTransparentMode != 0) {
+ setImageResource(mDrawableForTransparentMode);
+ }
setBackgroundColor(getResources().getColor(android.R.color.transparent));
} else {
+ if (mDefaultDrawable != 0) {
+ setImageResource(mDefaultDrawable);
+ }
Drawable bgDrawable = getContext().getDrawable(R.drawable.num_pad_key_background);
if (Flags.bouncerUiRevamp2() && bgDrawable != null) {
bgDrawable.setTint(Color.actionBg);
@@ -154,4 +167,19 @@
super.onInitializeAccessibilityNodeInfo(info);
info.setTextEntryKey(true);
}
+
+ /**
+ * Drawable to use when transparent mode is enabled
+ */
+ public void setDrawableForTransparentMode(@DrawableRes int drawableResId) {
+ mDrawableForTransparentMode = drawableResId;
+ }
+
+ /**
+ * Drawable to use when transparent mode is not enabled.
+ */
+ public void setDefaultDrawable(@DrawableRes int drawableResId) {
+ mDefaultDrawable = drawableResId;
+ setImageResource(mDefaultDrawable);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
index 42896a4..b2cb357 100644
--- a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
@@ -167,7 +167,7 @@
public void setHeight(float h) {
if (DEBUG_SCALE) Log.v(TAG, "SetHeight: setting to " + h);
- mView.setActualHeight((int) h);
+ mView.setFinalActualHeight((int) h);
mCurrentHeight = h;
}
public float getHeight() {
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 438184d..22ecb0a 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java
@@ -30,7 +30,6 @@
import android.content.res.Resources;
import android.media.AudioManager;
import android.os.Bundle;
-import android.os.Handler;
import android.provider.Settings;
import android.util.Log;
import android.view.LayoutInflater;
@@ -49,6 +48,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
+import androidx.annotation.WorkerThread;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
@@ -57,7 +57,6 @@
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
-import com.android.settingslib.utils.ThreadUtils;
import com.android.systemui.accessibility.hearingaid.HearingDevicesListAdapter.HearingDeviceItemCallback;
import com.android.systemui.animation.DialogTransitionAnimator;
import com.android.systemui.bluetooth.qsdialog.ActiveHearingDeviceItemFactory;
@@ -67,6 +66,7 @@
import com.android.systemui.bluetooth.qsdialog.DeviceItemFactory;
import com.android.systemui.bluetooth.qsdialog.DeviceItemType;
import com.android.systemui.bluetooth.qsdialog.SavedHearingDeviceItemFactory;
+import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.res.R;
@@ -79,6 +79,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
+import java.util.concurrent.Executor;
import java.util.stream.Collectors;
/**
@@ -101,7 +102,8 @@
private final DialogTransitionAnimator mDialogTransitionAnimator;
private final ActivityStarter mActivityStarter;
private final LocalBluetoothManager mLocalBluetoothManager;
- private final Handler mMainHandler;
+ private final Executor mMainExecutor;
+ private final Executor mBgExecutor;
private final AudioManager mAudioManager;
private final LocalBluetoothProfileManager mProfileManager;
private final HearingDevicesUiEventLogger mUiEventLogger;
@@ -109,8 +111,6 @@
private final int mLaunchSourceId;
private SystemUIDialog mDialog;
-
- private List<DeviceItem> mHearingDeviceItemList;
private HearingDevicesListAdapter mDeviceListAdapter;
private View mPresetLayout;
@@ -122,14 +122,14 @@
@Override
public void onPresetInfoUpdated(List<BluetoothHapPresetInfo> presetInfos,
int activePresetIndex) {
- mMainHandler.post(
+ mMainExecutor.execute(
() -> refreshPresetUi(presetInfos, activePresetIndex));
}
@Override
public void onPresetCommandFailed(int reason) {
mPresetController.refreshPresetInfo();
- mMainHandler.post(() -> {
+ mMainExecutor.execute(() -> {
showErrorToast(R.string.hearing_devices_presets_error);
});
}
@@ -166,7 +166,8 @@
ActivityStarter activityStarter,
DialogTransitionAnimator dialogTransitionAnimator,
@Nullable LocalBluetoothManager localBluetoothManager,
- @Main Handler handler,
+ @Main Executor mainExecutor,
+ @Background Executor bgExecutor,
AudioManager audioManager,
HearingDevicesUiEventLogger uiEventLogger) {
mShowPairNewDevice = showPairNewDevice;
@@ -174,7 +175,8 @@
mActivityStarter = activityStarter;
mDialogTransitionAnimator = dialogTransitionAnimator;
mLocalBluetoothManager = localBluetoothManager;
- mMainHandler = handler;
+ mMainExecutor = mainExecutor;
+ mBgExecutor = bgExecutor;
mAudioManager = audioManager;
mProfileManager = localBluetoothManager.getProfileManager();
mUiEventLogger = uiEventLogger;
@@ -227,9 +229,10 @@
@Override
public void onActiveDeviceChanged(@Nullable CachedBluetoothDevice activeDevice,
int bluetoothProfile) {
- refreshDeviceUi();
- mMainHandler.post(() -> {
- CachedBluetoothDevice device = getActiveHearingDevice();
+ List<DeviceItem> hearingDeviceItemList = getHearingDeviceItemList();
+ refreshDeviceUi(hearingDeviceItemList);
+ mMainExecutor.execute(() -> {
+ CachedBluetoothDevice device = getActiveHearingDevice(hearingDeviceItemList);
if (mPresetController != null) {
mPresetController.setDevice(device);
mPresetLayout.setVisibility(
@@ -244,13 +247,15 @@
@Override
public void onProfileConnectionStateChanged(@NonNull CachedBluetoothDevice cachedDevice,
int state, int bluetoothProfile) {
- refreshDeviceUi();
+ List<DeviceItem> hearingDeviceItemList = getHearingDeviceItemList();
+ refreshDeviceUi(hearingDeviceItemList);
}
@Override
public void onAclConnectionStateChanged(@NonNull CachedBluetoothDevice cachedDevice,
int state) {
- refreshDeviceUi();
+ List<DeviceItem> hearingDeviceItemList = getHearingDeviceItemList();
+ refreshDeviceUi(hearingDeviceItemList);
}
@Override
@@ -280,18 +285,25 @@
mUiEventLogger.log(HearingDevicesUiEvent.HEARING_DEVICES_DIALOG_SHOW, mLaunchSourceId);
- setupDeviceListView(dialog);
- setupPairNewDeviceButton(dialog);
- setupPresetSpinner(dialog);
- if (com.android.settingslib.flags.Flags.hearingDevicesAmbientVolumeControl()) {
- setupAmbientControls();
- }
- setupRelatedToolsView(dialog);
+ mBgExecutor.execute(() -> {
+ List<DeviceItem> hearingDeviceItemList = getHearingDeviceItemList();
+ CachedBluetoothDevice activeHearingDevice = getActiveHearingDevice(
+ hearingDeviceItemList);
+ mMainExecutor.execute(() -> {
+ setupDeviceListView(dialog, hearingDeviceItemList);
+ setupPairNewDeviceButton(dialog);
+ setupPresetSpinner(dialog, activeHearingDevice);
+ if (com.android.settingslib.flags.Flags.hearingDevicesAmbientVolumeControl()) {
+ setupAmbientControls(activeHearingDevice);
+ }
+ setupRelatedToolsView(dialog);
+ });
+ });
}
@Override
public void onStart(@NonNull SystemUIDialog dialog) {
- ThreadUtils.postOnBackgroundThread(() -> {
+ mBgExecutor.execute(() -> {
if (mLocalBluetoothManager != null) {
mLocalBluetoothManager.getEventManager().registerCallback(this);
}
@@ -306,7 +318,7 @@
@Override
public void onStop(@NonNull SystemUIDialog dialog) {
- ThreadUtils.postOnBackgroundThread(() -> {
+ mBgExecutor.execute(() -> {
if (mLocalBluetoothManager != null) {
mLocalBluetoothManager.getEventManager().unregisterCallback(this);
}
@@ -319,17 +331,18 @@
});
}
- private void setupDeviceListView(SystemUIDialog dialog) {
+ private void setupDeviceListView(SystemUIDialog dialog,
+ List<DeviceItem> hearingDeviceItemList) {
final RecyclerView deviceList = dialog.requireViewById(R.id.device_list);
deviceList.setLayoutManager(new LinearLayoutManager(dialog.getContext()));
- mHearingDeviceItemList = getHearingDeviceItemList();
- mDeviceListAdapter = new HearingDevicesListAdapter(mHearingDeviceItemList, this);
+ mDeviceListAdapter = new HearingDevicesListAdapter(hearingDeviceItemList, this);
deviceList.setAdapter(mDeviceListAdapter);
}
- private void setupPresetSpinner(SystemUIDialog dialog) {
+ private void setupPresetSpinner(SystemUIDialog dialog,
+ CachedBluetoothDevice activeHearingDevice) {
mPresetController = new HearingDevicesPresetsController(mProfileManager, mPresetCallback);
- mPresetController.setDevice(getActiveHearingDevice());
+ mPresetController.setDevice(activeHearingDevice);
mPresetSpinner = dialog.requireViewById(R.id.preset_spinner);
mPresetInfoAdapter = new HearingDevicesSpinnerAdapter(dialog.getContext());
@@ -367,12 +380,12 @@
mPresetLayout.setVisibility(mPresetController.isPresetControlAvailable() ? VISIBLE : GONE);
}
- private void setupAmbientControls() {
+ private void setupAmbientControls(CachedBluetoothDevice activeHearingDevice) {
final AmbientVolumeLayout ambientLayout = mDialog.requireViewById(R.id.ambient_layout);
mAmbientController = new AmbientVolumeUiController(
mDialog.getContext(), mLocalBluetoothManager, ambientLayout);
mAmbientController.setShowUiWhenLocalDataExist(false);
- mAmbientController.loadDevice(getActiveHearingDevice());
+ mAmbientController.loadDevice(activeHearingDevice);
}
private void setupPairNewDeviceButton(SystemUIDialog dialog) {
@@ -429,10 +442,11 @@
}
}
- private void refreshDeviceUi() {
- mHearingDeviceItemList = getHearingDeviceItemList();
- mMainHandler.post(() -> {
- mDeviceListAdapter.refreshDeviceItemList(mHearingDeviceItemList);
+ private void refreshDeviceUi(List<DeviceItem> hearingDeviceItemList) {
+ mMainExecutor.execute(() -> {
+ if (mDeviceListAdapter != null) {
+ mDeviceListAdapter.refreshDeviceItemList(hearingDeviceItemList);
+ }
});
}
@@ -463,21 +477,27 @@
}
@Nullable
- private CachedBluetoothDevice getActiveHearingDevice() {
- return mHearingDeviceItemList.stream()
+ private static CachedBluetoothDevice getActiveHearingDevice(
+ List<DeviceItem> hearingDeviceItemList) {
+ return hearingDeviceItemList.stream()
.filter(item -> item.getType() == DeviceItemType.ACTIVE_MEDIA_BLUETOOTH_DEVICE)
.map(DeviceItem::getCachedBluetoothDevice)
.findFirst()
.orElse(null);
}
+ @WorkerThread
private DeviceItem createHearingDeviceItem(CachedBluetoothDevice cachedDevice) {
final Context context = mDialog.getContext();
if (cachedDevice == null) {
return null;
}
+ int mode = mAudioManager.getMode();
+ boolean isOngoingCall = mode == AudioManager.MODE_RINGTONE
+ || mode == AudioManager.MODE_IN_CALL
+ || mode == AudioManager.MODE_IN_COMMUNICATION;
for (DeviceItemFactory itemFactory : mHearingDeviceItemFactoryList) {
- if (itemFactory.isFilterMatched(context, cachedDevice, mAudioManager)) {
+ if (itemFactory.isFilterMatched(context, cachedDevice, isOngoingCall)) {
return itemFactory.create(context, cachedDevice);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothDetailsContentManager.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothDetailsContentManager.kt
index eebcf0b..576acd2 100644
--- a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothDetailsContentManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothDetailsContentManager.kt
@@ -383,6 +383,11 @@
actionIcon.setImageResource(item.actionIconRes)
actionIcon.drawable?.setTint(tintColor)
+ actionIconView.contentDescription =
+ resources.getString(
+ R.string.accessibility_bluetooth_device_settings_gear_with_name,
+ item.deviceName,
+ )
divider.setBackgroundColor(tintColor)
diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothDetailsContentViewModel.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothDetailsContentViewModel.kt
index ff2d9ef..1c9cf8d 100644
--- a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothDetailsContentViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothDetailsContentViewModel.kt
@@ -31,6 +31,7 @@
import com.android.internal.jank.InteractionJankMonitor
import com.android.internal.logging.UiEventLogger
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast
+import com.android.settingslib.volume.domain.interactor.AudioModeInteractor
import com.android.systemui.Prefs
import com.android.systemui.animation.DialogCuj
import com.android.systemui.animation.DialogTransitionAnimator
@@ -71,6 +72,7 @@
private val bluetoothStateInteractor: BluetoothStateInteractor,
private val bluetoothAutoOnInteractor: BluetoothAutoOnInteractor,
private val audioSharingInteractor: AudioSharingInteractor,
+ private val audioModeInteractor: AudioModeInteractor,
private val audioSharingButtonViewModelFactory: AudioSharingButtonViewModel.Factory,
private val bluetoothDeviceMetadataInteractor: BluetoothDeviceMetadataInteractor,
private val dialogTransitionAnimator: DialogTransitionAnimator,
@@ -167,6 +169,7 @@
// the device item list and animate the progress bar.
merge(
deviceItemInteractor.deviceItemUpdateRequest,
+ audioModeInteractor.isOngoingCall,
bluetoothDeviceMetadataInteractor.metadataUpdate,
if (
audioSharingInteractor.audioSharingAvailable() &&
diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemFactory.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemFactory.kt
index 095e6e7..bfbc27d 100644
--- a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemFactory.kt
@@ -18,7 +18,6 @@
import android.bluetooth.BluetoothDevice
import android.content.Context
-import android.media.AudioManager
import com.android.settingslib.bluetooth.BluetoothUtils
import com.android.settingslib.bluetooth.CachedBluetoothDevice
import com.android.settingslib.bluetooth.LocalBluetoothManager
@@ -43,7 +42,7 @@
abstract fun isFilterMatched(
context: Context,
cachedDevice: CachedBluetoothDevice,
- audioManager: AudioManager,
+ isOngoingCall: Boolean,
audioSharingAvailable: Boolean,
): Boolean
@@ -51,8 +50,8 @@
fun isFilterMatched(
context: Context,
cachedDevice: CachedBluetoothDevice,
- audioManager: AudioManager,
- ): Boolean = isFilterMatched(context, cachedDevice, audioManager, false)
+ isOngoingCall: Boolean,
+ ): Boolean = isFilterMatched(context, cachedDevice, isOngoingCall, false)
abstract fun create(context: Context, cachedDevice: CachedBluetoothDevice): DeviceItem
@@ -88,11 +87,11 @@
override fun isFilterMatched(
context: Context,
cachedDevice: CachedBluetoothDevice,
- audioManager: AudioManager,
+ isOngoingCall: Boolean,
audioSharingAvailable: Boolean,
): Boolean {
return BluetoothUtils.isActiveMediaDevice(cachedDevice) &&
- BluetoothUtils.isAvailableMediaBluetoothDevice(cachedDevice, audioManager)
+ BluetoothUtils.isAvailableMediaBluetoothDevice(cachedDevice, isOngoingCall)
}
override fun create(context: Context, cachedDevice: CachedBluetoothDevice): DeviceItem {
@@ -113,10 +112,11 @@
override fun isFilterMatched(
context: Context,
cachedDevice: CachedBluetoothDevice,
- audioManager: AudioManager,
+ isOngoingCall: Boolean,
audioSharingAvailable: Boolean,
): Boolean {
return audioSharingAvailable &&
+ !isOngoingCall &&
BluetoothUtils.hasConnectedBroadcastSource(cachedDevice, localBluetoothManager)
}
@@ -140,11 +140,12 @@
override fun isFilterMatched(
context: Context,
cachedDevice: CachedBluetoothDevice,
- audioManager: AudioManager,
+ isOngoingCall: Boolean,
audioSharingAvailable: Boolean,
): Boolean {
return audioSharingAvailable &&
- super.isFilterMatched(context, cachedDevice, audioManager, true) &&
+ !isOngoingCall &&
+ super.isFilterMatched(context, cachedDevice, false, true) &&
BluetoothUtils.isAvailableAudioSharingMediaBluetoothDevice(
cachedDevice,
localBluetoothManager,
@@ -170,7 +171,7 @@
override fun isFilterMatched(
context: Context,
cachedDevice: CachedBluetoothDevice,
- audioManager: AudioManager,
+ isOngoingCall: Boolean,
audioSharingAvailable: Boolean,
): Boolean {
return BluetoothUtils.isActiveMediaDevice(cachedDevice) &&
@@ -182,11 +183,11 @@
override fun isFilterMatched(
context: Context,
cachedDevice: CachedBluetoothDevice,
- audioManager: AudioManager,
+ isOngoingCall: Boolean,
audioSharingAvailable: Boolean,
): Boolean {
return !BluetoothUtils.isActiveMediaDevice(cachedDevice) &&
- BluetoothUtils.isAvailableMediaBluetoothDevice(cachedDevice, audioManager)
+ BluetoothUtils.isAvailableMediaBluetoothDevice(cachedDevice, isOngoingCall)
}
override fun create(context: Context, cachedDevice: CachedBluetoothDevice): DeviceItem {
@@ -206,7 +207,7 @@
override fun isFilterMatched(
context: Context,
cachedDevice: CachedBluetoothDevice,
- audioManager: AudioManager,
+ isOngoingCall: Boolean,
audioSharingAvailable: Boolean,
): Boolean {
return !BluetoothUtils.isActiveMediaDevice(cachedDevice) &&
@@ -218,14 +219,14 @@
override fun isFilterMatched(
context: Context,
cachedDevice: CachedBluetoothDevice,
- audioManager: AudioManager,
+ isOngoingCall: Boolean,
audioSharingAvailable: Boolean,
): Boolean {
return if (Flags.enableHideExclusivelyManagedBluetoothDevice()) {
!BluetoothUtils.isExclusivelyManagedBluetoothDevice(context, cachedDevice.device) &&
- BluetoothUtils.isConnectedBluetoothDevice(cachedDevice, audioManager)
+ BluetoothUtils.isConnectedBluetoothDevice(cachedDevice, isOngoingCall)
} else {
- BluetoothUtils.isConnectedBluetoothDevice(cachedDevice, audioManager)
+ BluetoothUtils.isConnectedBluetoothDevice(cachedDevice, isOngoingCall)
}
}
@@ -246,7 +247,7 @@
override fun isFilterMatched(
context: Context,
cachedDevice: CachedBluetoothDevice,
- audioManager: AudioManager,
+ isOngoingCall: Boolean,
audioSharingAvailable: Boolean,
): Boolean {
return if (Flags.enableHideExclusivelyManagedBluetoothDevice()) {
@@ -275,7 +276,7 @@
override fun isFilterMatched(
context: Context,
cachedDevice: CachedBluetoothDevice,
- audioManager: AudioManager,
+ isOngoingCall: Boolean,
audioSharingAvailable: Boolean,
): Boolean {
return if (Flags.enableHideExclusivelyManagedBluetoothDevice()) {
diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemInteractor.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemInteractor.kt
index 1e0ba8e..b606c19 100644
--- a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemInteractor.kt
@@ -19,10 +19,10 @@
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
import android.content.Context
-import android.media.AudioManager
import com.android.settingslib.bluetooth.BluetoothCallback
import com.android.settingslib.bluetooth.CachedBluetoothDevice
import com.android.settingslib.bluetooth.LocalBluetoothManager
+import com.android.settingslib.volume.domain.interactor.AudioModeInteractor
import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
import com.android.systemui.dagger.SysUISingleton
@@ -39,6 +39,7 @@
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.shareIn
import kotlinx.coroutines.isActive
@@ -51,7 +52,6 @@
constructor(
private val bluetoothTileDialogRepository: BluetoothTileDialogRepository,
private val audioSharingInteractor: AudioSharingInteractor,
- private val audioManager: AudioManager,
private val bluetoothAdapter: BluetoothAdapter? = BluetoothAdapter.getDefaultAdapter(),
private val localBluetoothManager: LocalBluetoothManager?,
private val systemClock: SystemClock,
@@ -60,6 +60,7 @@
private val deviceItemDisplayPriority: List<@JvmSuppressWildcards DeviceItemType>,
@Application private val coroutineScope: CoroutineScope,
@Background private val backgroundDispatcher: CoroutineDispatcher,
+ private val audioModeInteractor: AudioModeInteractor,
) {
private val mutableDeviceItemUpdate: MutableSharedFlow<List<DeviceItem>> =
@@ -118,8 +119,12 @@
internal suspend fun updateDeviceItems(context: Context, trigger: DeviceFetchTrigger) {
withContext(backgroundDispatcher) {
+ if (!isActive) {
+ return@withContext
+ }
val start = systemClock.elapsedRealtime()
val audioSharingAvailable = audioSharingInteractor.audioSharingAvailable()
+ val isOngoingCall = audioModeInteractor.isOngoingCall.first()
val deviceItems =
bluetoothTileDialogRepository.cachedDevices
.mapNotNull { cachedDevice ->
@@ -128,7 +133,7 @@
it.isFilterMatched(
context,
cachedDevice,
- audioManager,
+ isOngoingCall,
audioSharingAvailable,
)
}
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 149efcd..3ef50f6 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
@@ -87,6 +87,14 @@
}
}
+object PatternBouncerConstants {
+ object ColorId {
+ @JvmField val dotColor = colors.materialColorOnSurfaceVariant
+ @JvmField val activatedDotColor = colors.materialColorOnPrimary
+ @JvmField val pathColor = colors.materialColorPrimary
+ }
+}
+
object PinBouncerConstants {
@JvmField
val pinShapes = c(old = R.array.bouncer_pin_shapes, new = R.array.updated_bouncer_pin_shapes)
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/KeyguardBouncerViewBinder.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/KeyguardBouncerViewBinder.kt
index 434a9ce..7d8945a 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/KeyguardBouncerViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/KeyguardBouncerViewBinder.kt
@@ -191,7 +191,6 @@
.filter { it == EXPANSION_VISIBLE }
.collect {
securityContainerController.onResume(KeyguardSecurityView.SCREEN_ON)
- view.announceForAccessibility(securityContainerController.title)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSceneRepository.kt b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSceneRepository.kt
index 0a9bd42..bf4445b 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSceneRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSceneRepository.kt
@@ -151,5 +151,7 @@
override fun instantlyShowOverlay(overlay: OverlayKey) = Unit
override fun instantlyHideOverlay(overlay: OverlayKey) = Unit
+
+ override fun freezeAndAnimateToCurrentState() = Unit
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalTransitionKeys.kt b/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalTransitionKeys.kt
index ca49de3..a84c457 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalTransitionKeys.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalTransitionKeys.kt
@@ -31,4 +31,6 @@
val ToEditMode = TransitionKey("ToEditMode")
/** Transition to the glanceable hub after exiting edit mode */
val FromEditMode = TransitionKey("FromEditMode")
+ /** Swipes the glanceable hub in/out of view */
+ val Swipe = TransitionKey("Swipe")
}
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 2169881..cce1ae1 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
@@ -359,7 +359,13 @@
/** See [CommunalSettingsInteractor.isV2FlagEnabled] */
fun v2FlagEnabled(): Boolean = communalSettingsInteractor.isV2FlagEnabled()
- fun swipeToHubEnabled(): Boolean = swipeToHub
+ val swipeToHubEnabled: StateFlow<Boolean> by lazy {
+ if (v2FlagEnabled()) {
+ communalInteractor.shouldShowCommunal
+ } else {
+ MutableStateFlow(swipeToHub)
+ }
+ }
companion object {
const val POPUP_AUTO_HIDE_TIMEOUT_MS = 12000L
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/TouchpadTutorialScreensProvider.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/TouchpadTutorialScreensProvider.kt
index bd3e771..7d2492a 100644
--- a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/TouchpadTutorialScreensProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/TouchpadTutorialScreensProvider.kt
@@ -20,7 +20,9 @@
interface TouchpadTutorialScreensProvider {
- @Composable fun BackGesture(onDoneButtonClicked: () -> Unit, onBack: () -> Unit)
+ @Composable
+ fun BackGesture(onDoneButtonClicked: () -> Unit, onBack: () -> Unit, isAutoProceed: Boolean)
- @Composable fun HomeGesture(onDoneButtonClicked: () -> Unit, onBack: () -> Unit)
+ @Composable
+ fun HomeGesture(onDoneButtonClicked: () -> Unit, onBack: () -> Unit, isAutoProceed: Boolean)
}
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialSchedulerInteractor.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialSchedulerInteractor.kt
index b712fde..0d57a57 100644
--- a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialSchedulerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialSchedulerInteractor.kt
@@ -102,10 +102,9 @@
}
// This flow is used by the notification updater once an initial notification is launched. It
- // listens to the device connection changes for both keyboard and touchpad. When either of the
- // device is disconnected, resolve the tutorial type base on the latest connection state.
- // Dropping the initial state because it's the existing notification. Filtering out BOTH because
- // we only care about disconnections.
+ // listens to the changes of keyboard and touchpad connection and resolve the tutorial type base
+ // on the latest connection state.
+ // Dropping the initial state because it represents the existing notification.
val tutorialTypeUpdates: Flow<TutorialType> =
keyboardRepository.isAnyKeyboardConnected
.combine(touchpadRepository.isAnyTouchpadConnected, ::Pair)
@@ -118,7 +117,6 @@
}
}
.drop(1)
- .filter { it != TutorialType.BOTH }
private suspend fun waitForDeviceConnection(deviceType: DeviceType) =
isAnyDeviceConnected[deviceType]!!.filter { it }.first()
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/composable/ActionTutorialContent.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/composable/ActionTutorialContent.kt
index 8cbcba2..ee875c4 100644
--- a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/composable/ActionTutorialContent.kt
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/composable/ActionTutorialContent.kt
@@ -137,6 +137,7 @@
onDoneButtonClicked = onDoneButtonClicked,
modifier = Modifier.padding(horizontal = 60.dp).graphicsLayer { alpha = buttonAlpha },
enabled = actionState is Finished,
+ isNext = config.hasNextButton,
)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/composable/TutorialComponents.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/composable/TutorialComponents.kt
index 202dba3..d92e48e 100644
--- a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/composable/TutorialComponents.kt
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/composable/TutorialComponents.kt
@@ -32,6 +32,7 @@
onDoneButtonClicked: () -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
+ isNext: Boolean = false,
) {
Row(
horizontalArrangement = Arrangement.End,
@@ -39,7 +40,10 @@
modifier = modifier.fillMaxWidth(),
) {
Button(onClick = onDoneButtonClicked, enabled = enabled) {
- Text(stringResource(R.string.touchpad_tutorial_done_button))
+ val text =
+ if (isNext) R.string.touchpad_tutorial_next_button
+ else R.string.touchpad_tutorial_done_button
+ Text(stringResource(text))
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/composable/TutorialScreenConfig.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/composable/TutorialScreenConfig.kt
index eda23a5..65adc14 100644
--- a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/composable/TutorialScreenConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/composable/TutorialScreenConfig.kt
@@ -28,6 +28,7 @@
val colors: Colors,
val strings: Strings,
val animations: Animations,
+ val hasNextButton: Boolean = false,
) {
data class Colors(
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/view/KeyboardTouchpadTutorialActivity.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/view/KeyboardTouchpadTutorialActivity.kt
index 639e9b1..086705f 100644
--- a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/view/KeyboardTouchpadTutorialActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/view/KeyboardTouchpadTutorialActivity.kt
@@ -93,17 +93,29 @@
}
}
}
+ val entryPointExtra = intent.getStringExtra(INTENT_TUTORIAL_ENTRY_POINT_KEY)
+ val isAutoProceed =
+ if (entryPointExtra == null) true
+ else entryPointExtra.equals(INTENT_TUTORIAL_ENTRY_POINT_SCHEDULER)
+ val scopeExtra = intent.getStringExtra(INTENT_TUTORIAL_SCOPE_KEY)
+ val isScopeAll = INTENT_TUTORIAL_SCOPE_ALL.equals(scopeExtra)
setContent {
- PlatformTheme { KeyboardTouchpadTutorialContainer(vm, touchpadTutorialScreensProvider) }
+ PlatformTheme {
+ KeyboardTouchpadTutorialContainer(
+ vm,
+ touchpadTutorialScreensProvider,
+ isAutoProceed,
+ isScopeAll,
+ )
+ }
}
if (savedInstanceState == null) {
logger.logOpenTutorial(TutorialContext.KEYBOARD_TOUCHPAD_TUTORIAL)
- val entryPointExtra = intent.getStringExtra(INTENT_TUTORIAL_ENTRY_POINT_KEY)
val tutorialTypeExtra = intent.getStringExtra(INTENT_TUTORIAL_SCOPE_KEY)
metricsLogger.logPeripheralTutorialLaunched(entryPointExtra, tutorialTypeExtra)
// We only update launched info when the tutorial is triggered by the scheduler
- if (entryPointExtra.equals(INTENT_TUTORIAL_ENTRY_POINT_SCHEDULER))
+ if (INTENT_TUTORIAL_ENTRY_POINT_SCHEDULER.equals(entryPointExtra))
updateLaunchInfo(tutorialTypeExtra)
}
}
@@ -124,17 +136,27 @@
fun KeyboardTouchpadTutorialContainer(
vm: KeyboardTouchpadTutorialViewModel,
touchpadScreens: Optional<TouchpadTutorialScreensProvider>,
+ isAutoProceed: Boolean = false,
+ isScopeAll: Boolean = false,
) {
val activeScreen by vm.screen.collectAsStateWithLifecycle(STARTED)
when (activeScreen) {
BACK_GESTURE ->
touchpadScreens
.get()
- .BackGesture(onDoneButtonClicked = vm::onDoneButtonClicked, onBack = vm::onBack)
+ .BackGesture(
+ onDoneButtonClicked = vm::onDoneButtonClicked,
+ onBack = vm::onBack,
+ isAutoProceed = isAutoProceed,
+ )
HOME_GESTURE ->
touchpadScreens
.get()
- .HomeGesture(onDoneButtonClicked = vm::onDoneButtonClicked, onBack = vm::onBack)
+ .HomeGesture(
+ onDoneButtonClicked = vm::onDoneButtonClicked,
+ onBack = vm::onBack,
+ isAutoProceed = isScopeAll,
+ )
ACTION_KEY ->
ActionKeyTutorialScreen(
onDoneButtonClicked = vm::onDoneButtonClicked,
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 464201f..b787fc2 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
@@ -19,6 +19,7 @@
import android.content.Context
import android.content.res.Resources
import android.view.KeyEvent.KEYCODE_D
+import android.view.KeyEvent.KEYCODE_DPAD_DOWN
import android.view.KeyEvent.KEYCODE_DPAD_LEFT
import android.view.KeyEvent.KEYCODE_DPAD_RIGHT
import android.view.KeyEvent.KEYCODE_DPAD_UP
@@ -73,6 +74,15 @@
command(META_META_ON or META_CTRL_ON, KEYCODE_DPAD_UP)
}
)
+ if (DesktopModeStatus.canEnterDesktopMode(context)) {
+ // Switch to desktop view
+ // - Meta + Ctrl + Down arrow
+ add(
+ shortcutInfo(resources.getString(R.string.system_multitasking_desktop_view)) {
+ command(META_META_ON or META_CTRL_ON, KEYCODE_DPAD_DOWN)
+ }
+ )
+ }
if (enableMoveToNextDisplayShortcut()) {
// Move a window to the next display:
// - Meta + Ctrl + D
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractor.kt
index 61d11f4..f89421f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractor.kt
@@ -17,19 +17,16 @@
package com.android.systemui.keyboard.shortcut.domain.interactor
import android.content.Context
-import android.view.KeyEvent.META_META_ON
import com.android.systemui.Flags.keyboardShortcutHelperShortcutCustomizer
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.keyboard.shortcut.data.repository.ShortcutCategoriesRepository
-import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperKeys
-import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperKeys.metaModifierIconResId
+import com.android.systemui.keyboard.shortcut.extensions.toContentDescription
import com.android.systemui.keyboard.shortcut.qualifiers.CustomShortcutCategories
import com.android.systemui.keyboard.shortcut.qualifiers.DefaultShortcutCategories
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.ShortcutCommand
-import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutSubCategory
import com.android.systemui.res.R
import dagger.Lazy
@@ -105,8 +102,6 @@
context.getString(R.string.shortcut_helper_key_combinations_and_conjunction)
val orConjunction =
context.getString(R.string.shortcut_helper_key_combinations_or_separator)
- val forwardSlash =
- context.getString(R.string.shortcut_helper_key_combinations_forward_slash)
return buildString {
append("$label, $pressKey")
commands.forEachIndexed { i, shortcutCommand ->
@@ -117,29 +112,7 @@
if (j > 0) {
append(" $andConjunction")
}
- if (shortcutKey is ShortcutKey.Text) {
- // Special handling for "/" as TalkBack will not read punctuation by
- // default.
- if (shortcutKey.value.equals("/")) {
- append(" $forwardSlash")
- } else {
- append(" ${shortcutKey.value}")
- }
- } else if (shortcutKey is ShortcutKey.Icon.ResIdIcon) {
- val keyLabel =
- if (shortcutKey.drawableResId == metaModifierIconResId) {
- ShortcutHelperKeys.modifierLabels[META_META_ON]
- } else {
- val keyCode =
- ShortcutHelperKeys.keyIcons.entries
- .firstOrNull { it.value == shortcutKey.drawableResId }
- ?.key
- ShortcutHelperKeys.specialKeyLabels[keyCode]
- }
- if (keyLabel != null) {
- append(" ${keyLabel.invoke(context)}")
- }
- } // No-Op when shortcutKey is ShortcutKey.Icon.DrawableIcon
+ shortcutKey.toContentDescription(context)?.let { append(" $it") }
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/extensions/ShortcutKeyExtensions.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/extensions/ShortcutKeyExtensions.kt
new file mode 100644
index 0000000..5637747
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/extensions/ShortcutKeyExtensions.kt
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2025 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.extensions
+
+import android.content.Context
+import android.view.KeyEvent.META_META_ON
+import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperKeys
+import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperKeys.metaModifierIconResId
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey
+import com.android.systemui.res.R
+
+fun ShortcutKey.toContentDescription(context: Context): String? {
+ val forwardSlash = context.getString(R.string.shortcut_helper_key_combinations_forward_slash)
+ when (this) {
+ is ShortcutKey.Text -> {
+ // Special handling for "/" as TalkBack will not read punctuation by
+ // default.
+ return if (this.value == "/") {
+ forwardSlash
+ } else {
+ this.value
+ }
+ }
+
+ is ShortcutKey.Icon.ResIdIcon -> {
+ val keyLabel =
+ if (this.drawableResId == metaModifierIconResId) {
+ ShortcutHelperKeys.modifierLabels[META_META_ON]
+ } else {
+ val keyCode =
+ ShortcutHelperKeys.keyIcons.entries
+ .firstOrNull { it.value == this.drawableResId }
+ ?.key
+ ShortcutHelperKeys.specialKeyLabels[keyCode]
+ }
+
+ if (keyLabel != null) {
+ return keyLabel.invoke(context)
+ }
+ }
+
+ is ShortcutKey.Icon.DrawableIcon -> {
+ // No-Op when shortcutKey is ShortcutKey.Icon.DrawableIcon
+ }
+ }
+
+ return null
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutCustomizer.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutCustomizer.kt
index 66e4505..7e0fa2f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutCustomizer.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutCustomizer.kt
@@ -60,6 +60,7 @@
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.LiveRegionMode
import androidx.compose.ui.semantics.contentDescription
+import androidx.compose.ui.semantics.hideFromAccessibility
import androidx.compose.ui.semantics.liveRegion
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.font.FontWeight
@@ -127,6 +128,7 @@
shouldShowError = uiState.errorMessage.isNotEmpty(),
onShortcutKeyCombinationSelected = onShortcutKeyCombinationSelected,
pressedKeys = uiState.pressedKeys,
+ contentDescription = uiState.pressedKeysDescription,
onConfirmSetShortcut = onConfirmSetShortcut,
onClearSelectedKeyCombination = onClearSelectedKeyCombination,
)
@@ -267,6 +269,7 @@
shouldShowError: Boolean,
onShortcutKeyCombinationSelected: (KeyEvent) -> Boolean,
pressedKeys: List<ShortcutKey>,
+ contentDescription: String,
onConfirmSetShortcut: () -> Unit,
onClearSelectedKeyCombination: () -> Unit,
) {
@@ -313,6 +316,7 @@
} else {
null
},
+ contentDescription = contentDescription,
)
}
@@ -331,8 +335,7 @@
@Composable
private fun PressedKeysTextContainer(pressedKeys: List<ShortcutKey>) {
Row(
- modifier =
- Modifier.semantics(mergeDescendants = true) { liveRegion = LiveRegionMode.Polite },
+ modifier = Modifier.semantics { hideFromAccessibility() },
verticalAlignment = Alignment.CenterVertically,
) {
pressedKeys.forEachIndexed { keyIndex, key ->
@@ -495,6 +498,7 @@
trailingIcon: @Composable () -> Unit,
isError: Boolean,
modifier: Modifier = Modifier,
+ contentDescription: String,
) {
OutlinedTextField(
value = "",
@@ -502,7 +506,10 @@
placeholder = if (content == null) placeholder else null,
prefix = content,
singleLine = true,
- modifier = modifier,
+ modifier =
+ modifier.semantics(mergeDescendants = true) {
+ this.contentDescription = contentDescription
+ },
trailingIcon = trailingIcon,
colors =
OutlinedTextFieldDefaults.colors()
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/model/ShortcutCustomizationUiState.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/model/ShortcutCustomizationUiState.kt
index 36c5ae0..688573d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/model/ShortcutCustomizationUiState.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/model/ShortcutCustomizationUiState.kt
@@ -24,6 +24,7 @@
val errorMessage: String = "",
val defaultCustomShortcutModifierKey: ShortcutKey.Icon.ResIdIcon,
val pressedKeys: List<ShortcutKey> = emptyList(),
+ val pressedKeysDescription: String = "",
) : ShortcutCustomizationUiState
data object DeleteShortcutDialog : ShortcutCustomizationUiState
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModel.kt
index f4ba99c..aeedc4b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModel.kt
@@ -26,6 +26,7 @@
import androidx.compose.ui.input.key.type
import com.android.systemui.keyboard.shared.model.ShortcutCustomizationRequestResult
import com.android.systemui.keyboard.shortcut.domain.interactor.ShortcutCustomizationInteractor
+import com.android.systemui.keyboard.shortcut.extensions.toContentDescription
import com.android.systemui.keyboard.shortcut.shared.model.KeyCombination
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCustomizationRequestInfo
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey
@@ -185,7 +186,11 @@
_shortcutCustomizationUiState.update { uiState ->
if (uiState is AddShortcutDialog) {
- uiState.copy(pressedKeys = keys, errorMessage = errorMessage)
+ uiState.copy(
+ pressedKeys = keys,
+ errorMessage = errorMessage,
+ pressedKeysDescription = getAccessibilityDescForPressedKeys(keys),
+ )
} else {
uiState
}
@@ -193,11 +198,25 @@
}
}
+ private fun getAccessibilityDescForPressedKeys(keys: List<ShortcutKey>): String {
+ val andConjunction =
+ context.getString(R.string.shortcut_helper_key_combinations_and_conjunction)
+ return buildString {
+ keys.forEach { key ->
+ key.toContentDescription(context)?.let {
+ if (isNotEmpty()) {
+ append(", $andConjunction ")
+ }
+ append(it)
+ }
+ }
+ }
+ }
+
private suspend fun getErrorMessageForPressedKeys(keys: List<ShortcutKey>): String {
return if (keys.isEmpty() or isSelectedKeyCombinationAvailable()) {
""
- }
- else {
+ } else {
context.getString(R.string.shortcut_customizer_key_combination_in_use_error_message)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/LockscreenSceneTransitionRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/LockscreenSceneTransitionRepository.kt
index 80bdc65..f692292 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/LockscreenSceneTransitionRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/LockscreenSceneTransitionRepository.kt
@@ -25,11 +25,17 @@
class LockscreenSceneTransitionRepository @Inject constructor() {
/**
- * This [KeyguardState] will indicate which sub state within KTF should be navigated to when the
- * next transition into the Lockscreen scene is started. It will be consumed exactly once and
- * after that the state will be set back to [DEFAULT_STATE].
+ * This [KeyguardState] will indicate which sub-state within KTF should be navigated to next.
+ *
+ * This can be either starting a transition to the `Lockscreen` scene or cancelling a transition
+ * from the `Lockscreen` scene and returning back to it.
+ *
+ * A `null` value means that no explicit target state was set and therefore the [DEFAULT_STATE]
+ * should be used.
+ *
+ * Once consumed, this state should be reset to `null`.
*/
- val nextLockscreenTargetState: MutableStateFlow<KeyguardState> = MutableStateFlow(DEFAULT_STATE)
+ val nextLockscreenTargetState: MutableStateFlow<KeyguardState?> = MutableStateFlow(null)
companion object {
val DEFAULT_STATE = KeyguardState.LOCKSCREEN
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
index 0700ec6..6f5f662 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
@@ -159,7 +159,6 @@
val isKeyguardOccludedLegacy = keyguardInteractor.isKeyguardOccluded.value
val primaryBouncerShowing = keyguardInteractor.primaryBouncerShowing.value
val isKeyguardGoingAway = keyguardInteractor.isKeyguardGoingAway.value
- val canStartDreaming = dreamManager.canStartDreaming(false)
if (!deviceEntryInteractor.isLockscreenEnabled()) {
if (!SceneContainerFlag.isEnabled) {
@@ -192,13 +191,6 @@
if (!SceneContainerFlag.isEnabled) {
transitionToGlanceableHub()
}
- } else if (canStartDreaming) {
- // If we're waking up to dream, transition directly to dreaming without
- // showing the lockscreen.
- startTransitionTo(
- KeyguardState.DREAMING,
- ownerReason = "moving from doze to dream",
- )
} else {
startTransitionTo(KeyguardState.LOCKSCREEN)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractor.kt
index 5f82102..1b70ff8 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractor.kt
@@ -119,7 +119,8 @@
} else {
val targetState =
if (idle.currentScene == Scenes.Lockscreen) {
- transitionInteractor.startedKeyguardTransitionStep.value.from
+ repository.nextLockscreenTargetState.value
+ ?: transitionInteractor.startedKeyguardTransitionStep.value.from
} else {
UNDEFINED
}
@@ -197,11 +198,11 @@
TransitionInfo(
ownerName = this::class.java.simpleName,
from = UNDEFINED,
- to = repository.nextLockscreenTargetState.value,
+ to = repository.nextLockscreenTargetState.value ?: DEFAULT_STATE,
animator = null,
modeOnCanceled = TransitionModeOnCanceled.RESET,
)
- repository.nextLockscreenTargetState.value = DEFAULT_STATE
+ repository.nextLockscreenTargetState.value = null
startTransition(newTransition)
}
@@ -215,7 +216,7 @@
animator = null,
modeOnCanceled = TransitionModeOnCanceled.RESET,
)
- repository.nextLockscreenTargetState.value = DEFAULT_STATE
+ repository.nextLockscreenTargetState.value = null
startTransition(newTransition)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt
index 8e38538..c7791cd 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt
@@ -26,6 +26,8 @@
import android.view.InputDevice
import android.view.MotionEvent
import android.view.View
+import android.view.View.GONE
+import android.view.View.INVISIBLE
import android.view.View.OnLayoutChangeListener
import android.view.View.VISIBLE
import android.view.ViewGroup
@@ -304,8 +306,9 @@
if (isVisible.value) {
blueprintViewModel.refreshBlueprint()
}
- childViews[aodPromotedNotificationId]
- ?.setAodNotifIconContainerIsVisible(isVisible)
+ childViews[aodPromotedNotificationId]?.setAodPromotedNotifIsVisible(
+ isVisible
+ )
}
}
@@ -313,7 +316,7 @@
shadeInteractor.isAnyFullyExpanded.collect { isFullyAnyExpanded ->
view.visibility =
if (isFullyAnyExpanded) {
- View.INVISIBLE
+ INVISIBLE
} else {
View.VISIBLE
}
@@ -370,6 +373,14 @@
repeatOnLifecycle(Lifecycle.State.STARTED) {
if (wallpaperFocalAreaViewModel.hasFocalArea.value) {
launch {
+ wallpaperFocalAreaViewModel.wallpaperFocalAreaBounds.collect {
+ wallpaperFocalAreaBounds ->
+ wallpaperFocalAreaViewModel.setFocalAreaBounds(
+ wallpaperFocalAreaBounds
+ )
+ }
+ }
+ launch {
wallpaperFocalAreaViewModel.wallpaperFocalAreaBounds
.filterNotNull()
.collect { wallpaperFocalAreaViewModel.setFocalAreaBounds(it) }
@@ -516,10 +527,10 @@
visibility =
if (isVisible.value) {
alpha = 1f
- View.VISIBLE
+ VISIBLE
} else {
alpha = 0f
- View.INVISIBLE
+ INVISIBLE
}
}
@@ -533,6 +544,36 @@
}
}
+ private fun View.setAodPromotedNotifIsVisible(isVisible: AnimatedValue<Boolean>) {
+ animate().cancel()
+ val animatorListener =
+ object : AnimatorListenerAdapter() {
+ override fun onAnimationEnd(animation: Animator) {
+ isVisible.stopAnimating()
+ }
+ }
+
+ if (isVisible.isAnimating) {
+ if (isVisible.value) {
+ alpha = 0f
+ visibility = VISIBLE
+ CrossFadeHelper.fadeIn(this, animatorListener)
+ } else {
+ CrossFadeHelper.fadeOut(this, animatorListener)
+ }
+ } else {
+ if (isVisible.value) {
+ alpha = 1f
+ visibility = VISIBLE
+ } else {
+ // Hide with GONE, not INVISIBLE, so there won't be a redundant bottom
+ // margin between the smart space and the shelf.
+ alpha = 0f
+ visibility = GONE
+ }
+ }
+ }
+
private fun MotionEvent.isTouchscreenSource(): Boolean {
return device?.supportsSource(InputDevice.SOURCE_TOUCHSCREEN) == true
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToDreamingTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToDreamingTransitionViewModel.kt
index 9018c58..e6a85c6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToDreamingTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToDreamingTransitionViewModel.kt
@@ -39,6 +39,4 @@
)
val lockscreenAlpha: Flow<Float> = transitionAnimation.immediatelyTransitionTo(0f)
- // Notifications should not be shown while transitioning to dream.
- val notificationAlpha = transitionAnimation.immediatelyTransitionTo(0f)
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataManager.kt
index c3182bf..1466d8b 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataManager.kt
@@ -143,6 +143,12 @@
* place immediately.
*/
override fun onSmartspaceMediaDataRemoved(key: String, immediately: Boolean) {}
+
+ /**
+ * Called whenever the current active media notification changes. Should only be used if
+ * [SceneContainerFlag] is disabled
+ */
+ override fun onCurrentActiveMediaChanged(key: String?, data: MediaData?) {}
}
companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataProcessor.kt b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataProcessor.kt
index 1464849..59f98d8 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataProcessor.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataProcessor.kt
@@ -1434,6 +1434,9 @@
* place immediately.
*/
fun onSmartspaceMediaDataRemoved(key: String, immediately: Boolean = true) {}
+
+ /** Called whenever the current active media notification changes */
+ fun onCurrentActiveMediaChanged(key: String?, data: MediaData?) {}
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/animation/ColorSchemeTransition.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/animation/ColorSchemeTransition.kt
index 21407f3..9badf85 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/animation/ColorSchemeTransition.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/animation/ColorSchemeTransition.kt
@@ -27,6 +27,7 @@
import com.android.internal.R
import com.android.internal.annotations.VisibleForTesting
import com.android.settingslib.Utils
+import com.android.systemui.Flags
import com.android.systemui.media.controls.ui.view.MediaViewHolder
import com.android.systemui.monet.ColorScheme
import com.android.systemui.surfaceeffects.loadingeffect.LoadingEffect
@@ -51,7 +52,7 @@
open class AnimatingColorTransition(
private val defaultColor: Int,
private val extractColor: (ColorScheme) -> Int,
- private val applyColor: (Int) -> Unit
+ private val applyColor: (Int) -> Unit,
) : AnimatorUpdateListener, ColorTransition {
private val argbEvaluator = ArgbEvaluator()
@@ -105,24 +106,60 @@
private val mediaViewHolder: MediaViewHolder,
private val multiRippleController: MultiRippleController,
private val turbulenceNoiseController: TurbulenceNoiseController,
- animatingColorTransitionFactory: AnimatingColorTransitionFactory
+ animatingColorTransitionFactory: AnimatingColorTransitionFactory,
) {
constructor(
context: Context,
mediaViewHolder: MediaViewHolder,
multiRippleController: MultiRippleController,
- turbulenceNoiseController: TurbulenceNoiseController
+ turbulenceNoiseController: TurbulenceNoiseController,
) : this(
context,
mediaViewHolder,
multiRippleController,
turbulenceNoiseController,
- ::AnimatingColorTransition
+ ::AnimatingColorTransition,
)
+
var loadingEffect: LoadingEffect? = null
- val bgColor = context.getColor(com.google.android.material.R.color.material_dynamic_neutral20)
- val surfaceColor =
+ // Defaults may be briefly visible before loading a new player's colors
+ private val backgroundDefault = context.getColor(R.color.system_on_surface_light)
+ private val primaryDefault = context.getColor(R.color.system_primary_dark)
+ private val onPrimaryDefault = context.getColor(R.color.system_on_primary_dark)
+
+ private val backgroundColor: AnimatingColorTransition by lazy {
+ animatingColorTransitionFactory(backgroundDefault, ::backgroundFromScheme) { color ->
+ mediaViewHolder.albumView.backgroundTintList = ColorStateList.valueOf(color)
+ }
+ }
+
+ private val primaryColor: AnimatingColorTransition by lazy {
+ animatingColorTransitionFactory(primaryDefault, ::primaryFromScheme) { primaryColor ->
+ val primaryColorList = ColorStateList.valueOf(primaryColor)
+ mediaViewHolder.actionPlayPause.backgroundTintList = primaryColorList
+ mediaViewHolder.seamlessButton.backgroundTintList = primaryColorList
+ (mediaViewHolder.seamlessButton.background as? RippleDrawable)?.let {
+ it.setColor(primaryColorList)
+ it.effectColor = primaryColorList
+ }
+ mediaViewHolder.seekBar.progressBackgroundTintList = primaryColorList
+ }
+ }
+
+ private val onPrimaryColor: AnimatingColorTransition by lazy {
+ animatingColorTransitionFactory(onPrimaryDefault, ::onPrimaryFromScheme) { onPrimaryColor ->
+ val onPrimaryColorList = ColorStateList.valueOf(onPrimaryColor)
+ mediaViewHolder.actionPlayPause.imageTintList = onPrimaryColorList
+ mediaViewHolder.seamlessText.setTextColor(onPrimaryColor)
+ mediaViewHolder.seamlessIcon.imageTintList = onPrimaryColorList
+ }
+ }
+
+ // TODO(media_controls_a11y_colors): remove the below color definitions
+ private val bgColor =
+ context.getColor(com.google.android.material.R.color.material_dynamic_neutral20)
+ private val surfaceColor: AnimatingColorTransition by lazy {
animatingColorTransitionFactory(bgColor, ::surfaceFromScheme) { surfaceColor ->
val colorList = ColorStateList.valueOf(surfaceColor)
mediaViewHolder.seamlessIcon.imageTintList = colorList
@@ -130,10 +167,12 @@
mediaViewHolder.albumView.backgroundTintList = colorList
mediaViewHolder.gutsViewHolder.setSurfaceColor(surfaceColor)
}
- val accentPrimary =
+ }
+
+ private val accentPrimary: AnimatingColorTransition by lazy {
animatingColorTransitionFactory(
loadDefaultColor(R.attr.textColorPrimary),
- ::accentPrimaryFromScheme
+ ::accentPrimaryFromScheme,
) { accentPrimary ->
val accentColorList = ColorStateList.valueOf(accentPrimary)
mediaViewHolder.actionPlayPause.backgroundTintList = accentColorList
@@ -142,11 +181,12 @@
turbulenceNoiseController.updateNoiseColor(accentPrimary)
loadingEffect?.updateColor(accentPrimary)
}
+ }
- val accentSecondary =
+ private val accentSecondary: AnimatingColorTransition by lazy {
animatingColorTransitionFactory(
loadDefaultColor(R.attr.textColorPrimary),
- ::accentSecondaryFromScheme
+ ::accentSecondaryFromScheme,
) { accentSecondary ->
val colorList = ColorStateList.valueOf(accentSecondary)
(mediaViewHolder.seamlessButton.background as? RippleDrawable)?.let {
@@ -154,8 +194,9 @@
it.effectColor = colorList
}
}
+ }
- val colorSeamless =
+ private val colorSeamless: AnimatingColorTransition by lazy {
animatingColorTransitionFactory(
loadDefaultColor(R.attr.textColorPrimary),
{ colorScheme: ColorScheme ->
@@ -170,13 +211,14 @@
{ seamlessColor: Int ->
val accentColorList = ColorStateList.valueOf(seamlessColor)
mediaViewHolder.seamlessButton.backgroundTintList = accentColorList
- }
+ },
)
+ }
- val textPrimary =
+ private val textPrimary: AnimatingColorTransition by lazy {
animatingColorTransitionFactory(
loadDefaultColor(R.attr.textColorPrimary),
- ::textPrimaryFromScheme
+ ::textPrimaryFromScheme,
) { textPrimary ->
mediaViewHolder.titleText.setTextColor(textPrimary)
val textColorList = ColorStateList.valueOf(textPrimary)
@@ -189,44 +231,81 @@
}
mediaViewHolder.gutsViewHolder.setTextPrimaryColor(textPrimary)
}
+ }
- val textPrimaryInverse =
+ private val textPrimaryInverse: AnimatingColorTransition by lazy {
animatingColorTransitionFactory(
loadDefaultColor(R.attr.textColorPrimaryInverse),
- ::textPrimaryInverseFromScheme
+ ::textPrimaryInverseFromScheme,
) { textPrimaryInverse ->
mediaViewHolder.actionPlayPause.imageTintList =
ColorStateList.valueOf(textPrimaryInverse)
}
+ }
- val textSecondary =
+ private val textSecondary: AnimatingColorTransition by lazy {
animatingColorTransitionFactory(
loadDefaultColor(R.attr.textColorSecondary),
- ::textSecondaryFromScheme
+ ::textSecondaryFromScheme,
) { textSecondary ->
mediaViewHolder.artistText.setTextColor(textSecondary)
}
+ }
- val textTertiary =
+ private val textTertiary: AnimatingColorTransition by lazy {
animatingColorTransitionFactory(
loadDefaultColor(R.attr.textColorTertiary),
- ::textTertiaryFromScheme
+ ::textTertiaryFromScheme,
) { textTertiary ->
mediaViewHolder.seekBar.progressBackgroundTintList =
ColorStateList.valueOf(textTertiary)
}
+ }
- val colorTransitions =
- arrayOf(
- surfaceColor,
- colorSeamless,
- accentPrimary,
- accentSecondary,
- textPrimary,
- textPrimaryInverse,
- textSecondary,
- textTertiary,
- )
+ fun getDeviceIconColor(): Int {
+ if (Flags.mediaControlsA11yColors()) {
+ return onPrimaryColor.targetColor
+ }
+ return surfaceColor.targetColor
+ }
+
+ fun getAppIconColor(): Int {
+ if (Flags.mediaControlsA11yColors()) {
+ return primaryColor.targetColor
+ }
+ return accentPrimary.targetColor
+ }
+
+ fun getSurfaceEffectColor(): Int {
+ if (Flags.mediaControlsA11yColors()) {
+ return primaryColor.targetColor
+ }
+ return accentPrimary.targetColor
+ }
+
+ fun getGutsTextColor(): Int {
+ if (Flags.mediaControlsA11yColors()) {
+ return context.getColor(com.android.systemui.res.R.color.media_on_background)
+ }
+ return textPrimary.targetColor
+ }
+
+ private fun getColorTransitions(): Array<AnimatingColorTransition> {
+ return if (Flags.mediaControlsA11yColors()) {
+ arrayOf(backgroundColor, primaryColor, onPrimaryColor)
+ } else {
+ arrayOf(
+ surfaceColor,
+ colorSeamless,
+ accentPrimary,
+ accentSecondary,
+ textPrimary,
+ textPrimaryInverse,
+ textSecondary,
+ textTertiary,
+ )
+ }
+ }
private fun loadDefaultColor(id: Int): Int {
return Utils.getColorAttr(context, id).defaultColor
@@ -234,15 +313,26 @@
fun updateColorScheme(colorScheme: ColorScheme?): Boolean {
var anyChanged = false
- colorTransitions.forEach {
+ getColorTransitions().forEach {
val isChanged = it.updateColorScheme(colorScheme)
// Ignore changes to colorSeamless, since that is expected when toggling dark mode
+ // TODO(media_controls_a11y_colors): remove, not necessary
if (it == colorSeamless) return@forEach
anyChanged = isChanged || anyChanged
}
- colorScheme?.let { mediaViewHolder.gutsViewHolder.colorScheme = colorScheme }
+ if (Flags.mediaControlsA11yColors()) {
+ getSurfaceEffectColor().let {
+ multiRippleController.updateColor(it)
+ turbulenceNoiseController.updateNoiseColor(it)
+ loadingEffect?.updateColor(it)
+ }
+ mediaViewHolder.gutsViewHolder.setTextColor(getGutsTextColor())
+ colorScheme?.let { mediaViewHolder.gutsViewHolder.setColors(it) }
+ } else {
+ colorScheme?.let { mediaViewHolder.gutsViewHolder.colorScheme = colorScheme }
+ }
return anyChanged
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/animation/MediaColorSchemes.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/animation/MediaColorSchemes.kt
index 3c57c83..67113a4 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/animation/MediaColorSchemes.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/animation/MediaColorSchemes.kt
@@ -19,28 +19,43 @@
import com.android.systemui.monet.ColorScheme
/** Returns the surface color for media controls based on the scheme. */
+@Deprecated("Remove with media_controls_a11y_colors")
internal fun surfaceFromScheme(scheme: ColorScheme) = scheme.accent2.s800 // A2-800
/** Returns the primary accent color for media controls based on the scheme. */
+@Deprecated("Remove with media_controls_a11y_colors")
internal fun accentPrimaryFromScheme(scheme: ColorScheme) = scheme.accent1.s100 // A1-100
/** Returns the secondary accent color for media controls based on the scheme. */
+@Deprecated("Remove with media_controls_a11y_colors")
internal fun accentSecondaryFromScheme(scheme: ColorScheme) = scheme.accent1.s200 // A1-200
/** Returns the primary text color for media controls based on the scheme. */
+@Deprecated("Remove with media_controls_a11y_colors")
internal fun textPrimaryFromScheme(scheme: ColorScheme) = scheme.neutral1.s50 // N1-50
/** Returns the inverse of the primary text color for media controls based on the scheme. */
+@Deprecated("Remove with media_controls_a11y_colors")
internal fun textPrimaryInverseFromScheme(scheme: ColorScheme) = scheme.neutral1.s900 // N1-900
/** Returns the secondary text color for media controls based on the scheme. */
+@Deprecated("Remove with media_controls_a11y_colors")
internal fun textSecondaryFromScheme(scheme: ColorScheme) = scheme.neutral2.s200 // N2-200
/** Returns the tertiary text color for media controls based on the scheme. */
+@Deprecated("Remove with media_controls_a11y_colors")
internal fun textTertiaryFromScheme(scheme: ColorScheme) = scheme.neutral2.s400 // N2-400
/** Returns the color for the start of the background gradient based on the scheme. */
+@Deprecated("Remove with media_controls_a11y_colors")
internal fun backgroundStartFromScheme(scheme: ColorScheme) = scheme.accent2.s700 // A2-700
/** Returns the color for the end of the background gradient based on the scheme. */
+@Deprecated("Remove with media_controls_a11y_colors")
internal fun backgroundEndFromScheme(scheme: ColorScheme) = scheme.accent1.s700 // A1-700
+
+internal fun backgroundFromScheme(scheme: ColorScheme) = scheme.materialScheme.getOnSurface()
+
+internal fun primaryFromScheme(scheme: ColorScheme) = scheme.materialScheme.getPrimaryFixed()
+
+internal fun onPrimaryFromScheme(scheme: ColorScheme) = scheme.materialScheme.getOnPrimaryFixed()
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaControlViewBinder.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaControlViewBinder.kt
index 910d3a8..6d796d9 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaControlViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaControlViewBinder.kt
@@ -36,6 +36,7 @@
import androidx.lifecycle.repeatOnLifecycle
import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.settingslib.widget.AdaptiveIcon
+import com.android.systemui.Flags
import com.android.systemui.animation.Expandable
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.dagger.qualifiers.Background
@@ -48,6 +49,7 @@
import com.android.systemui.media.controls.ui.view.MediaViewHolder
import com.android.systemui.media.controls.ui.viewmodel.MediaActionViewModel
import com.android.systemui.media.controls.ui.viewmodel.MediaControlViewModel
+import com.android.systemui.media.controls.ui.viewmodel.MediaControlViewModel.Companion.MEDIA_PLAYER_SCRIM_CENTER_ALPHA
import com.android.systemui.media.controls.ui.viewmodel.MediaControlViewModel.Companion.MEDIA_PLAYER_SCRIM_END_ALPHA
import com.android.systemui.media.controls.ui.viewmodel.MediaControlViewModel.Companion.MEDIA_PLAYER_SCRIM_START_ALPHA
import com.android.systemui.media.controls.ui.viewmodel.MediaControlViewModel.Companion.SEMANTIC_ACTIONS_ALL
@@ -198,7 +200,9 @@
is Icon.Loaded -> {
val icon = viewModel.deviceIcon.drawable
if (icon is AdaptiveIcon) {
- icon.setBackgroundColor(viewController.colorSchemeTransition.bgColor)
+ icon.setBackgroundColor(
+ viewController.colorSchemeTransition.getDeviceIconColor()
+ )
}
viewHolder.seamlessIcon.setImageDrawable(icon)
}
@@ -431,11 +435,16 @@
TAG,
)
val isArtworkBound = wallpaperColors != null
+ val darkTheme = !Flags.mediaControlsA11yColors()
val scheme =
- wallpaperColors?.let { ColorScheme(it, true, Style.CONTENT) }
+ wallpaperColors?.let { ColorScheme(it, darkTheme, Style.CONTENT) }
?: let {
if (viewModel.launcherIcon is Icon.Loaded) {
- MediaArtworkHelper.getColorScheme(viewModel.launcherIcon.drawable, TAG)
+ MediaArtworkHelper.getColorScheme(
+ viewModel.launcherIcon.drawable,
+ TAG,
+ darkTheme,
+ )
} else {
null
}
@@ -496,7 +505,7 @@
}
} else {
viewHolder.appIcon.setColorFilter(
- viewController.colorSchemeTransition.accentPrimary.targetColor
+ viewController.colorSchemeTransition.getAppIconColor()
)
viewHolder.appIcon.setImageIcon(viewModel.appIcon)
}
@@ -528,11 +537,17 @@
height: Int,
): LayerDrawable {
val albumArt = MediaArtworkHelper.getScaledBackground(context, artworkIcon, width, height)
+ val alpha =
+ if (Flags.mediaControlsA11yColors()) {
+ MEDIA_PLAYER_SCRIM_CENTER_ALPHA
+ } else {
+ MEDIA_PLAYER_SCRIM_START_ALPHA
+ }
return MediaArtworkHelper.setUpGradientColorOnDrawable(
albumArt,
context.getDrawable(R.drawable.qs_media_scrim)?.mutate() as GradientDrawable,
mutableColorScheme,
- MEDIA_PLAYER_SCRIM_START_ALPHA,
+ alpha,
MEDIA_PLAYER_SCRIM_END_ALPHA,
)
}
@@ -572,7 +587,7 @@
maxSize,
maxSize,
button.context.resources.displayMetrics.density,
- colorSchemeTransition.accentPrimary.currentColor,
+ colorSchemeTransition.getSurfaceEffectColor(),
opacity = 100,
sparkleStrength = 0f,
baseRingFadeParams = null,
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt
index 173b600..93c4baf 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt
@@ -87,6 +87,7 @@
import com.android.systemui.shared.system.SysUiStatsLog.SMART_SPACE_CARD_REPORTED__DISPLAY_SURFACE__DREAM_OVERLAY as SSPACE_CARD_REPORTED__DREAM_OVERLAY
import com.android.systemui.shared.system.SysUiStatsLog.SMART_SPACE_CARD_REPORTED__DISPLAY_SURFACE__LOCKSCREEN as SSPACE_CARD_REPORTED__LOCKSCREEN
import com.android.systemui.shared.system.SysUiStatsLog.SMART_SPACE_CARD_REPORTED__DISPLAY_SURFACE__SHADE
+import com.android.systemui.statusbar.featurepods.media.domain.interactor.MediaControlChipInteractor
import com.android.systemui.statusbar.notification.collection.provider.OnReorderingAllowedListener
import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider
import com.android.systemui.statusbar.policy.ConfigurationController
@@ -155,6 +156,7 @@
private val mediaCarouselViewModel: MediaCarouselViewModel,
private val mediaViewControllerFactory: Provider<MediaViewController>,
private val deviceEntryInteractor: DeviceEntryInteractor,
+ private val mediaControlChipInteractor: MediaControlChipInteractor,
) : Dumpable {
/** The current width of the carousel */
var currentCarouselWidth: Int = 0
@@ -957,6 +959,9 @@
}
}
mediaCarouselScrollHandler.onPlayersChanged()
+ mediaControlChipInteractor.updateMediaControlChipModelLegacy(
+ MediaPlayerData.getFirstActiveMediaData()
+ )
MediaPlayerData.updateVisibleMediaPlayers()
// Automatically scroll to the active player if needed
if (shouldScrollToKey) {
@@ -1015,6 +1020,9 @@
)
updatePageIndicator()
mediaCarouselScrollHandler.onPlayersChanged()
+ mediaControlChipInteractor.updateMediaControlChipModelLegacy(
+ MediaPlayerData.getFirstActiveMediaData()
+ )
mediaFrame.requiresRemeasuring = true
onUiExecutionEnd?.run()
}
@@ -1023,6 +1031,9 @@
updatePlayer(key, data, isSsReactivated, curVisibleMediaKey, existingPlayer)
updatePageIndicator()
mediaCarouselScrollHandler.onPlayersChanged()
+ mediaControlChipInteractor.updateMediaControlChipModelLegacy(
+ MediaPlayerData.getFirstActiveMediaData()
+ )
mediaFrame.requiresRemeasuring = true
onUiExecutionEnd?.run()
}
@@ -1036,6 +1047,9 @@
}
updatePageIndicator()
mediaCarouselScrollHandler.onPlayersChanged()
+ mediaControlChipInteractor.updateMediaControlChipModelLegacy(
+ MediaPlayerData.getFirstActiveMediaData()
+ )
mediaFrame.requiresRemeasuring = true
onUiExecutionEnd?.run()
}
@@ -1194,6 +1208,9 @@
mediaContent.removeView(removed.recommendationViewHolder?.recommendations)
removed.onDestroy()
mediaCarouselScrollHandler.onPlayersChanged()
+ mediaControlChipInteractor.updateMediaControlChipModelLegacy(
+ MediaPlayerData.getFirstActiveMediaData()
+ )
updatePageIndicator()
if (dismissMediaData) {
@@ -1928,6 +1945,16 @@
fun visiblePlayerKeys() = visibleMediaPlayers.values
+ /** Returns the [MediaData] associated with the first mediaPlayer in the mediaCarousel. */
+ fun getFirstActiveMediaData(): MediaData? {
+ mediaPlayers.entries.forEach { entry ->
+ if (!entry.key.isSsMediaRec && entry.key.data.active) {
+ return entry.key.data
+ }
+ }
+ return null
+ }
+
/** Returns the index of the first non-timeout media. */
fun firstActiveMediaIndex(): Int {
mediaPlayers.entries.forEachIndexed { index, e ->
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaControlPanel.java
index 2bf6a10..f36b089 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaControlPanel.java
@@ -23,6 +23,7 @@
import static com.android.systemui.Flags.mediaLockscreenLaunchAnimation;
import static com.android.systemui.media.controls.domain.pipeline.MediaActionsKt.getNotificationActions;
import static com.android.systemui.media.controls.shared.model.SmartspaceMediaDataKt.NUM_REQUIRED_RECOMMENDATIONS;
+import static com.android.systemui.media.controls.ui.viewmodel.MediaControlViewModel.MEDIA_PLAYER_SCRIM_CENTER_ALPHA;
import android.animation.Animator;
import android.animation.AnimatorInflater;
@@ -730,7 +731,7 @@
Drawable icon = device.getIcon();
if (icon instanceof AdaptiveIcon) {
AdaptiveIcon aIcon = (AdaptiveIcon) icon;
- aIcon.setBackgroundColor(mColorSchemeTransition.getBgColor());
+ aIcon.setBackgroundColor(mColorSchemeTransition.getDeviceIconColor());
iconView.setImageDrawable(aIcon);
} else {
iconView.setImageDrawable(icon);
@@ -921,8 +922,9 @@
boolean isArtworkBound;
Icon artworkIcon = data.getArtwork();
WallpaperColors wallpaperColors = getWallpaperColor(artworkIcon);
+ boolean darkTheme = !Flags.mediaControlsA11yColors();
if (wallpaperColors != null) {
- mutableColorScheme = new ColorScheme(wallpaperColors, true, Style.CONTENT);
+ mutableColorScheme = new ColorScheme(wallpaperColors, darkTheme, Style.CONTENT);
artwork = addGradientToPlayerAlbum(artworkIcon, mutableColorScheme, finalWidth,
finalHeight);
isArtworkBound = true;
@@ -933,8 +935,8 @@
try {
Drawable icon = mContext.getPackageManager()
.getApplicationIcon(data.getPackageName());
- mutableColorScheme = new ColorScheme(WallpaperColors.fromDrawable(icon), true,
- Style.CONTENT);
+ mutableColorScheme = new ColorScheme(WallpaperColors.fromDrawable(icon),
+ darkTheme, Style.CONTENT);
} catch (PackageManager.NameNotFoundException e) {
Log.w(TAG, "Cannot find icon for package " + data.getPackageName(), e);
}
@@ -950,7 +952,8 @@
mArtworkBoundId = reqId;
// Transition Colors to current color scheme
- boolean colorSchemeChanged = mColorSchemeTransition.updateColorScheme(colorScheme);
+ boolean colorSchemeChanged;
+ colorSchemeChanged = mColorSchemeTransition.updateColorScheme(colorScheme);
// Bind the album view to the artwork or a transition drawable
ImageView albumView = mMediaViewHolder.getAlbumView();
@@ -973,7 +976,6 @@
transitionDrawable.setLayerGravity(0, Gravity.CENTER);
transitionDrawable.setLayerGravity(1, Gravity.CENTER);
transitionDrawable.setCrossFadeEnabled(true);
-
albumView.setImageDrawable(transitionDrawable);
transitionDrawable.startTransition(isArtworkBound ? 333 : 80);
}
@@ -986,8 +988,7 @@
appIconView.clearColorFilter();
if (data.getAppIcon() != null && !data.getResumption()) {
appIconView.setImageIcon(data.getAppIcon());
- appIconView.setColorFilter(
- mColorSchemeTransition.getAccentPrimary().getTargetColor());
+ appIconView.setColorFilter(mColorSchemeTransition.getAppIconColor());
} else {
// Resume players use launcher icon
appIconView.setColorFilter(getGrayscaleFilter());
@@ -1092,8 +1093,11 @@
Drawable albumArt = getScaledBackground(artworkIcon, width, height);
GradientDrawable gradient = (GradientDrawable) mContext.getDrawable(
R.drawable.qs_media_scrim).mutate();
+ float startAlpha = (Flags.mediaControlsA11yColors())
+ ? MEDIA_PLAYER_SCRIM_CENTER_ALPHA
+ : MEDIA_SCRIM_START_ALPHA;
return setupGradientColorOnDrawable(albumArt, gradient, mutableColorScheme,
- MEDIA_SCRIM_START_ALPHA, MEDIA_PLAYER_SCRIM_END_ALPHA);
+ startAlpha, MEDIA_PLAYER_SCRIM_END_ALPHA);
}
@VisibleForTesting
@@ -1113,12 +1117,21 @@
private LayerDrawable setupGradientColorOnDrawable(Drawable albumArt, GradientDrawable gradient,
ColorScheme mutableColorScheme, float startAlpha, float endAlpha) {
+ int startColor;
+ int endColor;
+ if (Flags.mediaControlsA11yColors()) {
+ startColor = MediaColorSchemesKt.backgroundFromScheme(mutableColorScheme);
+ endColor = startColor;
+ } else {
+ startColor = MediaColorSchemesKt.backgroundStartFromScheme(mutableColorScheme);
+ endColor = MediaColorSchemesKt.backgroundEndFromScheme(mutableColorScheme);
+ }
gradient.setColors(new int[]{
ColorUtilKt.getColorWithAlpha(
- MediaColorSchemesKt.backgroundStartFromScheme(mutableColorScheme),
+ startColor,
startAlpha),
ColorUtilKt.getColorWithAlpha(
- MediaColorSchemesKt.backgroundEndFromScheme(mutableColorScheme),
+ endColor,
endAlpha),
});
return new LayerDrawable(new Drawable[]{albumArt, gradient});
@@ -1308,7 +1321,7 @@
/* maxWidth= */ maxSize,
/* maxHeight= */ maxSize,
/* pixelDensity= */ getContext().getResources().getDisplayMetrics().density,
- mColorSchemeTransition.getAccentPrimary().getCurrentColor(),
+ /* color= */ mColorSchemeTransition.getSurfaceEffectColor(),
/* opacity= */ 100,
/* sparkleStrength= */ 0f,
/* baseRingFadeParams= */ null,
@@ -1330,10 +1343,13 @@
int width = targetView.getWidth();
int height = targetView.getHeight();
Random random = new Random();
+ float luminosity = (Flags.mediaControlsA11yColors())
+ ? 0.6f
+ : TurbulenceNoiseAnimationConfig.DEFAULT_LUMINOSITY_MULTIPLIER;
return new TurbulenceNoiseAnimationConfig(
/* gridCount= */ 2.14f,
- TurbulenceNoiseAnimationConfig.DEFAULT_LUMINOSITY_MULTIPLIER,
+ /* luminosityMultiplier= */ luminosity,
/* noiseOffsetX= */ random.nextFloat(),
/* noiseOffsetY= */ random.nextFloat(),
/* noiseOffsetZ= */ random.nextFloat(),
@@ -1341,7 +1357,7 @@
/* noiseMoveSpeedY= */ 0f,
TurbulenceNoiseAnimationConfig.DEFAULT_NOISE_SPEED_Z,
// Color will be correctly updated in ColorSchemeTransition.
- /* color= */ mColorSchemeTransition.getAccentPrimary().getCurrentColor(),
+ /* color= */ mColorSchemeTransition.getSurfaceEffectColor(),
/* screenColor= */ Color.BLACK,
width,
height,
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaViewController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaViewController.kt
index 2b36872..6a1ab9f 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaViewController.kt
@@ -1237,9 +1237,15 @@
val width = targetView.width
val height = targetView.height
val random = Random()
+ val luminosity =
+ if (Flags.mediaControlsA11yColors()) {
+ 0.6f
+ } else {
+ TurbulenceNoiseAnimationConfig.DEFAULT_LUMINOSITY_MULTIPLIER
+ }
return TurbulenceNoiseAnimationConfig(
gridCount = 2.14f,
- TurbulenceNoiseAnimationConfig.DEFAULT_LUMINOSITY_MULTIPLIER,
+ luminosity,
random.nextFloat(),
random.nextFloat(),
random.nextFloat(),
@@ -1247,7 +1253,7 @@
noiseMoveSpeedY = 0f,
TurbulenceNoiseAnimationConfig.DEFAULT_NOISE_SPEED_Z,
// Color will be correctly updated in ColorSchemeTransition.
- colorSchemeTransition.accentPrimary.currentColor,
+ colorSchemeTransition.getSurfaceEffectColor(),
screenColor = Color.BLACK,
width.toFloat(),
height.toFloat(),
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/util/MediaArtworkHelper.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/util/MediaArtworkHelper.kt
index 14a4e26..5570325 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/util/MediaArtworkHelper.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/util/MediaArtworkHelper.kt
@@ -25,7 +25,9 @@
import android.graphics.drawable.Icon
import android.graphics.drawable.LayerDrawable
import android.util.Log
+import com.android.systemui.Flags
import com.android.systemui.media.controls.ui.animation.backgroundEndFromScheme
+import com.android.systemui.media.controls.ui.animation.backgroundFromScheme
import com.android.systemui.media.controls.ui.animation.backgroundStartFromScheme
import com.android.systemui.monet.ColorScheme
import com.android.systemui.monet.Style
@@ -89,22 +91,30 @@
startAlpha: Float,
endAlpha: Float,
): LayerDrawable {
+ val startColor =
+ if (Flags.mediaControlsA11yColors()) {
+ backgroundFromScheme(colorScheme)
+ } else {
+ backgroundStartFromScheme(colorScheme)
+ }
+ val endColor =
+ if (Flags.mediaControlsA11yColors()) {
+ startColor
+ } else {
+ backgroundEndFromScheme(colorScheme)
+ }
gradient.colors =
intArrayOf(
- getColorWithAlpha(backgroundStartFromScheme(colorScheme), startAlpha),
- getColorWithAlpha(backgroundEndFromScheme(colorScheme), endAlpha),
+ getColorWithAlpha(startColor, startAlpha),
+ getColorWithAlpha(endColor, endAlpha),
)
return LayerDrawable(arrayOf(albumArt, gradient))
}
/** Returns [ColorScheme] of media app given its [icon]. */
- fun getColorScheme(
- icon: Drawable,
- tag: String,
- @Style.Type style: Int = Style.TONAL_SPOT,
- ): ColorScheme? {
+ fun getColorScheme(icon: Drawable, tag: String, darkTheme: Boolean): ColorScheme? {
return try {
- ColorScheme(WallpaperColors.fromDrawable(icon), true, style)
+ ColorScheme(WallpaperColors.fromDrawable(icon), darkTheme, Style.CONTENT)
} catch (e: PackageManager.NameNotFoundException) {
Log.w(tag, "Fail to get media app info", e)
null
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/util/MediaViewModelListUpdateCallback.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/util/MediaViewModelListUpdateCallback.kt
index 709723f..6022b7b 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/util/MediaViewModelListUpdateCallback.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/util/MediaViewModelListUpdateCallback.kt
@@ -18,6 +18,7 @@
import androidx.recyclerview.widget.ListUpdateCallback
import com.android.systemui.media.controls.ui.viewmodel.MediaCommonViewModel
+import kotlin.math.min
/** A [ListUpdateCallback] to apply media events needed to reach the new state. */
class MediaViewModelListUpdateCallback(
@@ -46,7 +47,7 @@
}
override fun onChanged(position: Int, count: Int, payload: Any?) {
- for (i in position until position + count) {
+ for (i in position until min(position + count, new.size)) {
onUpdated(new[i], position)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/view/GutsViewHolder.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/view/GutsViewHolder.kt
index a667c58..fa500ae 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/view/GutsViewHolder.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/view/GutsViewHolder.kt
@@ -22,7 +22,10 @@
import android.view.ViewGroup
import android.widget.ImageButton
import android.widget.TextView
+import com.android.systemui.Flags
import com.android.systemui.media.controls.ui.animation.accentPrimaryFromScheme
+import com.android.systemui.media.controls.ui.animation.onPrimaryFromScheme
+import com.android.systemui.media.controls.ui.animation.primaryFromScheme
import com.android.systemui.media.controls.ui.animation.surfaceFromScheme
import com.android.systemui.media.controls.ui.animation.textPrimaryFromScheme
import com.android.systemui.monet.ColorScheme
@@ -35,7 +38,7 @@
* Both [MediaViewHolder] and [RecommendationViewHolder] use the same guts menu layout, so this
* class helps share logic between the two.
*/
-class GutsViewHolder constructor(itemView: View) {
+class GutsViewHolder(itemView: View) {
val gutsText: TextView = itemView.requireViewById(R.id.remove_text)
val cancel: View = itemView.requireViewById(R.id.cancel)
val cancelText: TextView = itemView.requireViewById(R.id.cancel_text)
@@ -44,7 +47,9 @@
val settings: ImageButton = itemView.requireViewById(R.id.settings)
private var isDismissible: Boolean = true
+ // TODO(media_controls_a11y_colors): make private
var colorScheme: ColorScheme? = null
+ private var textColorFixed: Int? = null
/** Marquees the main text of the guts menu. */
fun marquee(start: Boolean, delay: Long, tag: String) {
@@ -67,12 +72,43 @@
/** Sets the right colors on all the guts views based on the given [ColorScheme]. */
fun setColors(scheme: ColorScheme) {
colorScheme = scheme
- setSurfaceColor(surfaceFromScheme(scheme))
- setTextPrimaryColor(textPrimaryFromScheme(scheme))
- setAccentPrimaryColor(accentPrimaryFromScheme(scheme))
+
+ if (Flags.mediaControlsA11yColors()) {
+ textColorFixed?.let { setTextColor(it) }
+ setPrimaryColor(primaryFromScheme(scheme))
+ setOnPrimaryColor(onPrimaryFromScheme(scheme))
+ } else {
+ setSurfaceColor(surfaceFromScheme(scheme))
+ setTextPrimaryColor(textPrimaryFromScheme(scheme))
+ setAccentPrimaryColor(accentPrimaryFromScheme(scheme))
+ }
+ }
+
+ private fun setPrimaryColor(color: Int) {
+ val colorList = ColorStateList.valueOf(color)
+ dismissText.backgroundTintList = colorList
+ cancelText.backgroundTintList = colorList
+ }
+
+ private fun setOnPrimaryColor(color: Int) {
+ dismissText.setTextColor(color)
+ if (!isDismissible) {
+ cancelText.setTextColor(color)
+ }
+ }
+
+ fun setTextColor(color: Int) {
+ textColorFixed = color
+ gutsText.setTextColor(color)
+ settings.imageTintList = ColorStateList.valueOf(color)
+
+ if (isDismissible) {
+ cancelText.setTextColor(color)
+ }
}
/** Sets the surface color on all guts views that use it. */
+ @Deprecated("Remove with media_controls_a11y_colors")
fun setSurfaceColor(surfaceColor: Int) {
dismissText.setTextColor(surfaceColor)
if (!isDismissible) {
@@ -81,6 +117,7 @@
}
/** Sets the primary accent color on all guts views that use it. */
+ @Deprecated("Remove with media_controls_a11y_colors")
fun setAccentPrimaryColor(accentPrimary: Int) {
val accentColorList = ColorStateList.valueOf(accentPrimary)
settings.imageTintList = accentColorList
@@ -89,6 +126,7 @@
}
/** Sets the primary text color on all guts views that use it. */
+ @Deprecated("Remove with media_controls_a11y_colors")
fun setTextPrimaryColor(textPrimary: Int) {
val textColorList = ColorStateList.valueOf(textPrimary)
gutsText.setTextColor(textColorList)
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaControlViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaControlViewModel.kt
index 61e4d95..9153e17 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaControlViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaControlViewModel.kt
@@ -418,7 +418,9 @@
)
const val TURBULENCE_NOISE_PLAY_MS_DURATION = 7500L
+ @Deprecated("Remove with media_controls_a11y_colors flag")
const val MEDIA_PLAYER_SCRIM_START_ALPHA = 0.25f
+ const val MEDIA_PLAYER_SCRIM_CENTER_ALPHA = 0.75f
const val MEDIA_PLAYER_SCRIM_END_ALPHA = 1.0f
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
deleted file mode 100644
index f5e6232..0000000
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
+++ /dev/null
@@ -1,585 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.media.dialog;
-
-import static com.android.settingslib.media.MediaDevice.SelectionBehavior.SELECTION_BEHAVIOR_GO_TO_APP;
-import static com.android.settingslib.media.MediaDevice.SelectionBehavior.SELECTION_BEHAVIOR_NONE;
-import static com.android.settingslib.media.MediaDevice.SelectionBehavior.SELECTION_BEHAVIOR_TRANSFER;
-
-import android.annotation.DrawableRes;
-import android.annotation.StringRes;
-import android.content.Context;
-import android.content.res.ColorStateList;
-import android.graphics.drawable.AnimatedVectorDrawable;
-import android.graphics.drawable.Drawable;
-import android.util.Log;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.CheckBox;
-import android.widget.TextView;
-
-import androidx.annotation.DoNotInline;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
-import androidx.core.widget.CompoundButtonCompat;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.media.flags.Flags;
-import com.android.settingslib.media.LocalMediaManager.MediaDeviceState;
-import com.android.settingslib.media.MediaDevice;
-import com.android.systemui.res.R;
-
-import java.util.List;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-/**
- * Adapter for media output dialog.
- */
-public class MediaOutputAdapter extends MediaOutputBaseAdapter {
-
- private static final String TAG = "MediaOutputAdapter";
- private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
- private static final float DEVICE_DISABLED_ALPHA = 0.5f;
- private static final float DEVICE_ACTIVE_ALPHA = 1f;
- protected List<MediaItem> mMediaItemList = new CopyOnWriteArrayList<>();
- private boolean mShouldGroupSelectedMediaItems = Flags.enableOutputSwitcherDeviceGrouping();
-
- public MediaOutputAdapter(MediaSwitchingController controller) {
- super(controller);
- setHasStableIds(true);
- }
-
- @Override
- public void updateItems() {
- mMediaItemList.clear();
- mMediaItemList.addAll(mController.getMediaItemList());
- if (mShouldGroupSelectedMediaItems) {
- if (mController.getSelectedMediaDevice().size() == 1) {
- // Don't group devices if initially there isn't more than one selected.
- mShouldGroupSelectedMediaItems = false;
- }
- }
- notifyDataSetChanged();
- }
-
- @Override
- public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup,
- int viewType) {
- super.onCreateViewHolder(viewGroup, viewType);
- switch (viewType) {
- case MediaItem.MediaItemType.TYPE_GROUP_DIVIDER:
- return new MediaGroupDividerViewHolder(mHolderView);
- case MediaItem.MediaItemType.TYPE_PAIR_NEW_DEVICE:
- case MediaItem.MediaItemType.TYPE_DEVICE:
- default:
- return new MediaDeviceViewHolder(mHolderView);
- }
- }
-
- @Override
- public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
- if (position >= mMediaItemList.size()) {
- if (DEBUG) {
- Log.d(TAG, "Incorrect position: " + position + " list size: "
- + mMediaItemList.size());
- }
- return;
- }
- MediaItem currentMediaItem = mMediaItemList.get(position);
- switch (currentMediaItem.getMediaItemType()) {
- case MediaItem.MediaItemType.TYPE_GROUP_DIVIDER:
- ((MediaGroupDividerViewHolder) viewHolder).onBind(currentMediaItem.getTitle());
- break;
- case MediaItem.MediaItemType.TYPE_PAIR_NEW_DEVICE:
- ((MediaDeviceViewHolder) viewHolder).onBindPairNewDevice();
- break;
- case MediaItem.MediaItemType.TYPE_DEVICE:
- ((MediaDeviceViewHolder) viewHolder).onBind(
- currentMediaItem,
- position);
- break;
- default:
- Log.d(TAG, "Incorrect position: " + position);
- }
- }
-
- @Override
- public long getItemId(int position) {
- if (position >= mMediaItemList.size()) {
- Log.d(TAG, "Incorrect position for item id: " + position);
- return position;
- }
- MediaItem currentMediaItem = mMediaItemList.get(position);
- return currentMediaItem.getMediaDevice().isPresent()
- ? currentMediaItem.getMediaDevice().get().getId().hashCode()
- : position;
- }
-
- @Override
- public int getItemViewType(int position) {
- if (position >= mMediaItemList.size()) {
- Log.d(TAG, "Incorrect position for item type: " + position);
- return MediaItem.MediaItemType.TYPE_GROUP_DIVIDER;
- }
- return mMediaItemList.get(position).getMediaItemType();
- }
-
- @Override
- public int getItemCount() {
- return mMediaItemList.size();
- }
-
- class MediaDeviceViewHolder extends MediaDeviceBaseViewHolder {
-
- MediaDeviceViewHolder(View view) {
- super(view);
- }
-
- void onBind(MediaItem mediaItem, int position) {
- MediaDevice device = mediaItem.getMediaDevice().get();
- super.onBind(device, position);
- boolean isMutingExpectedDeviceExist = mController.hasMutingExpectedDevice();
- final boolean currentlyConnected = isCurrentlyConnected(device);
- boolean isSelected = isDeviceIncluded(mController.getSelectedMediaDevice(), device);
- boolean isDeselectable =
- isDeviceIncluded(mController.getDeselectableMediaDevice(), device);
- boolean isSelectable = isDeviceIncluded(mController.getSelectableMediaDevice(), device);
- boolean isTransferable =
- isDeviceIncluded(mController.getTransferableMediaDevices(), device);
- boolean hasRouteListingPreferenceItem = device.hasRouteListingPreferenceItem();
-
- if (DEBUG) {
- Log.d(
- TAG,
- "["
- + position
- + "] "
- + device.getName()
- + " ["
- + (isDeselectable ? "deselectable" : "")
- + "] ["
- + (isSelected ? "selected" : "")
- + "] ["
- + (isSelectable ? "selectable" : "")
- + "] ["
- + (isTransferable ? "transferable" : "")
- + "] ["
- + (hasRouteListingPreferenceItem ? "hasListingPreference" : "")
- + "]");
- }
-
- boolean isDeviceGroup = false;
- boolean hideGroupItem = false;
- GroupStatus groupStatus = null;
- OngoingSessionStatus ongoingSessionStatus = null;
- ConnectionState connectionState = ConnectionState.DISCONNECTED;
- boolean restrictVolumeAdjustment = mController.hasAdjustVolumeUserRestriction();
- String subtitle = null;
- Drawable deviceStatusIcon = null;
- boolean deviceDisabled = false;
- View.OnClickListener clickListener = null;
-
- if (mCurrentActivePosition == position) {
- mCurrentActivePosition = -1;
- }
- mItemLayout.setVisibility(View.VISIBLE);
-
- if (mController.isAnyDeviceTransferring()) {
- if (device.getState() == MediaDeviceState.STATE_CONNECTING) {
- connectionState = ConnectionState.CONNECTING;
- }
- } else {
- // Set different layout for each device
- if (device.isMutingExpectedDevice()
- && !mController.isCurrentConnectedDeviceRemote()) {
- connectionState = ConnectionState.CONNECTED;
- restrictVolumeAdjustment = true;
- clickListener = v -> onItemClick(v, device);
- } else if (currentlyConnected && isMutingExpectedDeviceExist
- && !mController.isCurrentConnectedDeviceRemote()) {
- // mark as disconnected and set special click listener
- clickListener = v -> cancelMuteAwaitConnection();
- } else if (device.getState() == MediaDeviceState.STATE_GROUPING) {
- connectionState = ConnectionState.CONNECTING;
- } else if (mShouldGroupSelectedMediaItems && hasMultipleSelectedDevices()
- && isSelected) {
- if (mediaItem.isFirstDeviceInGroup()) {
- isDeviceGroup = true;
- } else {
- hideGroupItem = true;
- }
- } else { // A connected or disconnected device.
- subtitle = device.hasSubtext() ? device.getSubtextString() : null;
- ongoingSessionStatus = getOngoingSessionStatus(device);
- groupStatus = getGroupStatus(isSelected, isSelectable, isDeselectable);
-
- if (device.getState() == MediaDeviceState.STATE_CONNECTING_FAILED) {
- deviceStatusIcon = mContext.getDrawable(
- R.drawable.media_output_status_failed);
- subtitle = mContext.getString(R.string.media_output_dialog_connect_failed);
- clickListener = v -> onItemClick(v, device);
- } else if (currentlyConnected || isSelected) {
- connectionState = ConnectionState.CONNECTED;
- } else { // disconnected
- if (isSelectable) { // groupable device
- if (!Flags.disableTransferWhenAppsDoNotSupport() || isTransferable
- || hasRouteListingPreferenceItem) {
- clickListener = v -> onItemClick(v, device);
- }
- } else {
- deviceStatusIcon = getDeviceStatusIcon(device,
- device.hasOngoingSession());
- clickListener = getClickListenerBasedOnSelectionBehavior(device);
- }
- deviceDisabled = clickListener == null;
- }
- }
- }
-
- if (connectionState == ConnectionState.CONNECTED || isDeviceGroup) {
- mCurrentActivePosition = position;
- }
-
- if (isDeviceGroup) {
- renderDeviceGroupItem();
- } else {
- renderDeviceItem(hideGroupItem, device, connectionState, restrictVolumeAdjustment,
- groupStatus, ongoingSessionStatus, clickListener, deviceDisabled, subtitle,
- deviceStatusIcon);
- }
- }
-
- private void renderDeviceItem(boolean hideGroupItem, MediaDevice device,
- ConnectionState connectionState, boolean restrictVolumeAdjustment,
- GroupStatus groupStatus, OngoingSessionStatus ongoingSessionStatus,
- View.OnClickListener clickListener, boolean deviceDisabled, String subtitle,
- Drawable deviceStatusIcon) {
- if (hideGroupItem) {
- mItemLayout.setVisibility(View.GONE);
- return;
- }
- updateTitle(device.getName());
- updateTitleIcon(device, connectionState, restrictVolumeAdjustment);
- updateSeekBar(device, connectionState, restrictVolumeAdjustment,
- getDeviceItemContentDescription(device));
- updateEndArea(device, connectionState, groupStatus, ongoingSessionStatus);
- updateLoadingIndicator(connectionState);
- updateFullItemClickListener(clickListener);
- updateContentAlpha(deviceDisabled);
- updateSubtitle(subtitle);
- updateDeviceStatusIcon(deviceStatusIcon);
- updateItemBackground(connectionState);
- }
-
- private void renderDeviceGroupItem() {
- String sessionName = mController.getSessionName() == null ? ""
- : mController.getSessionName().toString();
- updateTitle(sessionName);
- updateUnmutedVolumeIcon(null /* device */);
- updateGroupSeekBar(getGroupItemContentDescription(sessionName));
- updateEndAreaForDeviceGroup();
- updateItemBackground(ConnectionState.CONNECTED);
- }
-
- private OngoingSessionStatus getOngoingSessionStatus(MediaDevice device) {
- return device.hasOngoingSession() ? new OngoingSessionStatus(
- device.isHostForOngoingSession()) : null;
- }
-
- private GroupStatus getGroupStatus(boolean isSelected, boolean isSelectable,
- boolean isDeselectable) {
- // A device should either be selectable or, when the device selected, the list should
- // have other selectable or selected devices.
- boolean selectedWithOtherGroupDevices =
- isSelected && (hasMultipleSelectedDevices() || hasSelectableDevices());
- if (isSelectable || selectedWithOtherGroupDevices) {
- return new GroupStatus(isSelected, isDeselectable);
- }
- return null;
- }
-
- private boolean hasMultipleSelectedDevices() {
- return mController.getSelectedMediaDevice().size() > 1;
- }
-
- private boolean hasSelectableDevices() {
- return !mController.getSelectableMediaDevice().isEmpty();
- }
-
- /** Renders the right side round pill button / checkbox. */
- private void updateEndArea(@NonNull MediaDevice device, ConnectionState connectionState,
- @Nullable GroupStatus groupStatus,
- @Nullable OngoingSessionStatus ongoingSessionStatus) {
- boolean showEndArea = false;
- boolean isCheckbox = false;
- // If both group status and the ongoing session status are present, only the ongoing
- // session controls are displayed. The current layout design doesn't allow both group
- // and ongoing session controls to be rendered simultaneously.
- if (ongoingSessionStatus != null && connectionState == ConnectionState.CONNECTED) {
- showEndArea = true;
- updateEndAreaForOngoingSession(device, ongoingSessionStatus.host());
- } else if (groupStatus != null && shouldShowGroupCheckbox(groupStatus)) {
- showEndArea = true;
- isCheckbox = true;
- updateEndAreaForGroupCheckBox(device, groupStatus);
- }
- updateEndAreaVisibility(showEndArea, isCheckbox);
- }
-
- private boolean shouldShowGroupCheckbox(@NonNull GroupStatus groupStatus) {
- if (Flags.enableOutputSwitcherDeviceGrouping()) {
- return isGroupCheckboxEnabled(groupStatus);
- }
- return true;
- }
-
- private boolean isGroupCheckboxEnabled(@NonNull GroupStatus groupStatus) {
- boolean disabled = groupStatus.selected() && !groupStatus.deselectable();
- return !disabled;
- }
-
- public void setCheckBoxColor(CheckBox checkBox, int color) {
- int[][] states = {{android.R.attr.state_checked}, {}};
- int[] colors = {color, color};
- CompoundButtonCompat.setButtonTintList(checkBox, new
- ColorStateList(states, colors));
- }
-
- private void updateContentAlpha(boolean deviceDisabled) {
- float alphaValue = deviceDisabled ? DEVICE_DISABLED_ALPHA : DEVICE_ACTIVE_ALPHA;
- mTitleIcon.setAlpha(alphaValue);
- mTitleText.setAlpha(alphaValue);
- mSubTitleText.setAlpha(alphaValue);
- mStatusIcon.setAlpha(alphaValue);
- }
-
- private void updateEndAreaForDeviceGroup() {
- updateEndAreaWithIcon(
- v -> {
- mShouldGroupSelectedMediaItems = false;
- notifyDataSetChanged();
- },
- R.drawable.media_output_item_expand_group,
- R.string.accessibility_expand_group);
- updateEndAreaVisibility(true /* showEndArea */, false /* isCheckbox */);
- }
-
- private void updateEndAreaForOngoingSession(@NonNull MediaDevice device, boolean isHost) {
- updateEndAreaWithIcon(
- v -> mController.tryToLaunchInAppRoutingIntent(device.getId(), v),
- isHost ? R.drawable.media_output_status_edit_session
- : R.drawable.ic_sound_bars_anim,
- R.string.accessibility_open_application);
- }
-
- private void updateEndAreaWithIcon(View.OnClickListener clickListener,
- @DrawableRes int iconDrawableId,
- @StringRes int accessibilityStringId) {
- updateEndAreaColor(mController.getColorSeekbarProgress());
- mEndClickIcon.setImageTintList(
- ColorStateList.valueOf(mController.getColorItemContent()));
- mEndClickIcon.setOnClickListener(clickListener);
- mEndTouchArea.setOnClickListener(v -> mEndClickIcon.performClick());
- Drawable drawable = mContext.getDrawable(iconDrawableId);
- mEndClickIcon.setImageDrawable(drawable);
- if (drawable instanceof AnimatedVectorDrawable) {
- ((AnimatedVectorDrawable) drawable).start();
- }
- if (Flags.enableOutputSwitcherDeviceGrouping()) {
- mEndClickIcon.setContentDescription(mContext.getString(accessibilityStringId));
- }
- }
-
- public void updateEndAreaColor(int color) {
- mEndTouchArea.setBackgroundTintList(
- ColorStateList.valueOf(color));
- }
-
- @Nullable
- private View.OnClickListener getClickListenerBasedOnSelectionBehavior(
- @NonNull MediaDevice device) {
- return Api34Impl.getClickListenerBasedOnSelectionBehavior(
- device, mController, v -> onItemClick(v, device));
- }
-
- @Nullable
- private Drawable getDeviceStatusIcon(MediaDevice device, boolean hasOngoingSession) {
- if (hasOngoingSession) {
- return mContext.getDrawable(R.drawable.ic_sound_bars_anim);
- } else {
- return Api34Impl.getDeviceStatusIconBasedOnSelectionBehavior(device, mContext);
- }
- }
-
- void updateDeviceStatusIcon(@Nullable Drawable deviceStatusIcon) {
- if (deviceStatusIcon == null) {
- mStatusIcon.setVisibility(View.GONE);
- } else {
- mStatusIcon.setImageDrawable(deviceStatusIcon);
- mStatusIcon.setImageTintList(
- ColorStateList.valueOf(mController.getColorItemContent()));
- if (deviceStatusIcon instanceof AnimatedVectorDrawable) {
- ((AnimatedVectorDrawable) deviceStatusIcon).start();
- }
- mStatusIcon.setVisibility(View.VISIBLE);
- }
- }
-
- public void updateEndAreaForGroupCheckBox(@NonNull MediaDevice device,
- @NonNull GroupStatus groupStatus) {
- boolean isEnabled = isGroupCheckboxEnabled(groupStatus);
- mEndTouchArea.setOnClickListener(
- isEnabled ? (v) -> mCheckBox.performClick() : null);
- mEndTouchArea.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
- updateEndAreaColor(groupStatus.selected() ? mController.getColorSeekbarProgress()
- : mController.getColorItemBackground());
- mEndTouchArea.setContentDescription(getDeviceItemContentDescription(device));
- mCheckBox.setOnCheckedChangeListener(null);
- mCheckBox.setChecked(groupStatus.selected());
- mCheckBox.setOnCheckedChangeListener(
- isEnabled ? (buttonView, isChecked) -> onGroupActionTriggered(
- !groupStatus.selected(), device) : null);
- mCheckBox.setEnabled(isEnabled);
- setCheckBoxColor(mCheckBox, mController.getColorItemContent());
- }
-
- private void updateFullItemClickListener(@Nullable View.OnClickListener listener) {
- mContainerLayout.setOnClickListener(listener);
- updateIconAreaClickListener(listener);
- }
-
- /** Binds a ViewHolder for a "Connect a device" item. */
- void onBindPairNewDevice() {
- mTitleText.setTextColor(mController.getColorItemContent());
- mCheckBox.setVisibility(View.GONE);
- updateTitle(mContext.getText(R.string.media_output_dialog_pairing_new));
- updateItemBackground(ConnectionState.DISCONNECTED);
- final Drawable addDrawable = mContext.getDrawable(R.drawable.ic_add);
- mTitleIcon.setImageDrawable(addDrawable);
- mTitleIcon.setImageTintList(
- ColorStateList.valueOf(mController.getColorItemContent()));
- mContainerLayout.setOnClickListener(mController::launchBluetoothPairing);
- }
-
- private void onGroupActionTriggered(boolean isChecked, MediaDevice device) {
- disableSeekBar();
- if (isChecked && isDeviceIncluded(mController.getSelectableMediaDevice(), device)) {
- mController.addDeviceToPlayMedia(device);
- } else if (!isChecked && isDeviceIncluded(mController.getDeselectableMediaDevice(),
- device)) {
- mController.removeDeviceFromPlayMedia(device);
- }
- }
-
- private void onItemClick(View view, MediaDevice device) {
- if (mController.isCurrentOutputDeviceHasSessionOngoing()) {
- showCustomEndSessionDialog(device);
- } else {
- transferOutput(device);
- }
- }
-
- private void transferOutput(MediaDevice device) {
- if (mController.isAnyDeviceTransferring()) {
- return;
- }
- if (isCurrentlyConnected(device)) {
- Log.d(TAG, "This device is already connected! : " + device.getName());
- return;
- }
- mController.setTemporaryAllowListExceptionIfNeeded(device);
- mCurrentActivePosition = -1;
- mController.connectDevice(device);
- device.setState(MediaDeviceState.STATE_CONNECTING);
- notifyDataSetChanged();
- }
-
- @VisibleForTesting
- void showCustomEndSessionDialog(MediaDevice device) {
- MediaSessionReleaseDialog mediaSessionReleaseDialog = new MediaSessionReleaseDialog(
- mContext, () -> transferOutput(device), mController.getColorButtonBackground(),
- mController.getColorItemContent());
- mediaSessionReleaseDialog.show();
- }
-
- private void cancelMuteAwaitConnection() {
- mController.cancelMuteAwaitConnection();
- notifyDataSetChanged();
- }
-
- private String getDeviceItemContentDescription(@NonNull MediaDevice device) {
- return mContext.getString(
- device.getDeviceType() == MediaDevice.MediaDeviceType.TYPE_BLUETOOTH_DEVICE
- ? R.string.accessibility_bluetooth_name
- : R.string.accessibility_cast_name, device.getName());
- }
-
- private String getGroupItemContentDescription(String sessionName) {
- return mContext.getString(R.string.accessibility_cast_name, sessionName);
- }
- }
-
- class MediaGroupDividerViewHolder extends RecyclerView.ViewHolder {
- final TextView mTitleText;
-
- MediaGroupDividerViewHolder(@NonNull View itemView) {
- super(itemView);
- mTitleText = itemView.requireViewById(R.id.title);
- }
-
- void onBind(String groupDividerTitle) {
- mTitleText.setTextColor(mController.getColorItemContent());
- mTitleText.setText(groupDividerTitle);
- }
- }
-
- @RequiresApi(34)
- private static class Api34Impl {
- @DoNotInline
- static View.OnClickListener getClickListenerBasedOnSelectionBehavior(
- MediaDevice device,
- MediaSwitchingController controller,
- View.OnClickListener defaultTransferListener) {
- switch (device.getSelectionBehavior()) {
- case SELECTION_BEHAVIOR_NONE:
- return null;
- case SELECTION_BEHAVIOR_TRANSFER:
- return defaultTransferListener;
- case SELECTION_BEHAVIOR_GO_TO_APP:
- return v -> controller.tryToLaunchInAppRoutingIntent(device.getId(), v);
- }
- return defaultTransferListener;
- }
-
- @DoNotInline
- @Nullable
- static Drawable getDeviceStatusIconBasedOnSelectionBehavior(MediaDevice device,
- Context context) {
- switch (device.getSelectionBehavior()) {
- case SELECTION_BEHAVIOR_NONE:
- return context.getDrawable(R.drawable.media_output_status_failed);
- case SELECTION_BEHAVIOR_TRANSFER:
- return null;
- case SELECTION_BEHAVIOR_GO_TO_APP:
- return context.getDrawable(R.drawable.media_output_status_help);
- }
- return null;
- }
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapterBase.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapterBase.java
new file mode 100644
index 0000000..c58ba37
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapterBase.java
@@ -0,0 +1,409 @@
+/*
+ * 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.systemui.media.dialog;
+
+import static com.android.settingslib.media.MediaDevice.SelectionBehavior.SELECTION_BEHAVIOR_GO_TO_APP;
+import static com.android.settingslib.media.MediaDevice.SelectionBehavior.SELECTION_BEHAVIOR_NONE;
+import static com.android.settingslib.media.MediaDevice.SelectionBehavior.SELECTION_BEHAVIOR_TRANSFER;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.View;
+
+import androidx.annotation.DoNotInline;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.media.flags.Flags;
+import com.android.settingslib.media.LocalMediaManager.MediaDeviceState;
+import com.android.settingslib.media.MediaDevice;
+import com.android.systemui.res.R;
+
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/**
+ * A parent RecyclerView adapter for the media output dialog device list. This class doesn't
+ * manipulate the layout directly.
+ */
+public abstract class MediaOutputAdapterBase extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
+ record OngoingSessionStatus(boolean host) {}
+
+ record GroupStatus(Boolean selected, Boolean deselectable) {}
+
+ enum ConnectionState {
+ CONNECTED,
+ CONNECTING,
+ DISCONNECTED,
+ }
+
+ protected final MediaSwitchingController mController;
+ private int mCurrentActivePosition;
+ private boolean mIsDragging;
+ private static final String TAG = "MediaOutputAdapterBase";
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+ protected final List<MediaItem> mMediaItemList = new CopyOnWriteArrayList<>();
+ private boolean mShouldGroupSelectedMediaItems = Flags.enableOutputSwitcherDeviceGrouping();
+
+ public MediaOutputAdapterBase(MediaSwitchingController controller) {
+ mController = controller;
+ mCurrentActivePosition = -1;
+ mIsDragging = false;
+ setHasStableIds(true);
+ }
+
+ boolean isCurrentlyConnected(MediaDevice device) {
+ return TextUtils.equals(device.getId(),
+ mController.getCurrentConnectedMediaDevice().getId())
+ || (mController.getSelectedMediaDevice().size() == 1
+ && isDeviceIncluded(mController.getSelectedMediaDevice(), device));
+ }
+
+ boolean isDeviceIncluded(List<MediaDevice> deviceList, MediaDevice targetDevice) {
+ for (MediaDevice device : deviceList) {
+ if (TextUtils.equals(device.getId(), targetDevice.getId())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ boolean isDragging() {
+ return mIsDragging;
+ }
+
+ void setIsDragging(boolean isDragging) {
+ mIsDragging = isDragging;
+ }
+
+ int getCurrentActivePosition() {
+ return mCurrentActivePosition;
+ }
+
+ /** Refreshes the RecyclerView dataset and forces re-render. */
+ public void updateItems() {
+ mMediaItemList.clear();
+ mMediaItemList.addAll(mController.getMediaItemList());
+ if (mShouldGroupSelectedMediaItems) {
+ if (mController.getSelectedMediaDevice().size() == 1) {
+ // Don't group devices if initially there isn't more than one selected.
+ mShouldGroupSelectedMediaItems = false;
+ }
+ }
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public long getItemId(int position) {
+ if (position >= mMediaItemList.size()) {
+ Log.d(TAG, "Incorrect position for item id: " + position);
+ return position;
+ }
+ MediaItem currentMediaItem = mMediaItemList.get(position);
+ return currentMediaItem.getMediaDevice().isPresent()
+ ? currentMediaItem.getMediaDevice().get().getId().hashCode()
+ : position;
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ if (position >= mMediaItemList.size()) {
+ Log.d(TAG, "Incorrect position for item type: " + position);
+ return MediaItem.MediaItemType.TYPE_GROUP_DIVIDER;
+ }
+ return mMediaItemList.get(position).getMediaItemType();
+ }
+
+ @Override
+ public int getItemCount() {
+ return mMediaItemList.size();
+ }
+
+ abstract class MediaDeviceViewHolderBase extends RecyclerView.ViewHolder {
+
+ Context mContext;
+
+ MediaDeviceViewHolderBase(View view, Context context) {
+ super(view);
+ mContext = context;
+ }
+
+ void renderItem(MediaItem mediaItem, int position) {
+ MediaDevice device = mediaItem.getMediaDevice().get();
+ boolean isMutingExpectedDeviceExist = mController.hasMutingExpectedDevice();
+ final boolean currentlyConnected = isCurrentlyConnected(device);
+ boolean isSelected = isDeviceIncluded(mController.getSelectedMediaDevice(), device);
+ boolean isDeselectable =
+ isDeviceIncluded(mController.getDeselectableMediaDevice(), device);
+ boolean isSelectable = isDeviceIncluded(mController.getSelectableMediaDevice(), device);
+ boolean isTransferable =
+ isDeviceIncluded(mController.getTransferableMediaDevices(), device);
+ boolean hasRouteListingPreferenceItem = device.hasRouteListingPreferenceItem();
+
+ if (DEBUG) {
+ Log.d(
+ TAG,
+ "["
+ + position
+ + "] "
+ + device.getName()
+ + " ["
+ + (isDeselectable ? "deselectable" : "")
+ + "] ["
+ + (isSelected ? "selected" : "")
+ + "] ["
+ + (isSelectable ? "selectable" : "")
+ + "] ["
+ + (isTransferable ? "transferable" : "")
+ + "] ["
+ + (hasRouteListingPreferenceItem ? "hasListingPreference" : "")
+ + "]");
+ }
+
+ boolean isDeviceGroup = false;
+ boolean hideGroupItem = false;
+ GroupStatus groupStatus = null;
+ OngoingSessionStatus ongoingSessionStatus = null;
+ ConnectionState connectionState = ConnectionState.DISCONNECTED;
+ boolean restrictVolumeAdjustment = mController.hasAdjustVolumeUserRestriction();
+ String subtitle = null;
+ Drawable deviceStatusIcon = null;
+ boolean deviceDisabled = false;
+ View.OnClickListener clickListener = null;
+
+ if (mCurrentActivePosition == position) {
+ mCurrentActivePosition = -1;
+ }
+
+ if (mController.isAnyDeviceTransferring()) {
+ if (device.getState() == MediaDeviceState.STATE_CONNECTING) {
+ connectionState = ConnectionState.CONNECTING;
+ }
+ } else {
+ // Set different layout for each device
+ if (device.isMutingExpectedDevice()
+ && !mController.isCurrentConnectedDeviceRemote()) {
+ connectionState = ConnectionState.CONNECTED;
+ restrictVolumeAdjustment = true;
+ clickListener = v -> onItemClick(v, device);
+ } else if (currentlyConnected && isMutingExpectedDeviceExist
+ && !mController.isCurrentConnectedDeviceRemote()) {
+ // mark as disconnected and set special click listener
+ clickListener = v -> cancelMuteAwaitConnection();
+ } else if (device.getState() == MediaDeviceState.STATE_GROUPING) {
+ connectionState = ConnectionState.CONNECTING;
+ } else if (mShouldGroupSelectedMediaItems && hasMultipleSelectedDevices()
+ && isSelected) {
+ if (mediaItem.isFirstDeviceInGroup()) {
+ isDeviceGroup = true;
+ } else {
+ hideGroupItem = true;
+ }
+ } else { // A connected or disconnected device.
+ subtitle = device.hasSubtext() ? device.getSubtextString() : null;
+ ongoingSessionStatus = getOngoingSessionStatus(device);
+ groupStatus = getGroupStatus(isSelected, isSelectable, isDeselectable);
+
+ if (device.getState() == MediaDeviceState.STATE_CONNECTING_FAILED) {
+ deviceStatusIcon = mContext.getDrawable(
+ R.drawable.media_output_status_failed);
+ subtitle = mContext.getString(R.string.media_output_dialog_connect_failed);
+ clickListener = v -> onItemClick(v, device);
+ } else if (currentlyConnected || isSelected) {
+ connectionState = ConnectionState.CONNECTED;
+ } else { // disconnected
+ if (isSelectable) { // groupable device
+ if (!Flags.disableTransferWhenAppsDoNotSupport() || isTransferable
+ || hasRouteListingPreferenceItem) {
+ clickListener = v -> onItemClick(v, device);
+ }
+ } else {
+ deviceStatusIcon = getDeviceStatusIcon(device,
+ device.hasOngoingSession());
+ clickListener = getClickListenerBasedOnSelectionBehavior(device);
+ }
+ deviceDisabled = clickListener == null;
+ }
+ }
+ }
+
+ if (connectionState == ConnectionState.CONNECTED || isDeviceGroup) {
+ mCurrentActivePosition = position;
+ }
+
+ if (isDeviceGroup) {
+ renderDeviceGroupItem();
+ } else {
+ renderDeviceItem(hideGroupItem, device, connectionState, restrictVolumeAdjustment,
+ groupStatus, ongoingSessionStatus, clickListener, deviceDisabled, subtitle,
+ deviceStatusIcon);
+ }
+ }
+
+ protected abstract void renderDeviceItem(boolean hideGroupItem, MediaDevice device,
+ ConnectionState connectionState, boolean restrictVolumeAdjustment,
+ GroupStatus groupStatus, OngoingSessionStatus ongoingSessionStatus,
+ View.OnClickListener clickListener, boolean deviceDisabled, String subtitle,
+ Drawable deviceStatusIcon);
+
+ protected abstract void renderDeviceGroupItem();
+
+ protected abstract void disableSeekBar();
+
+ private OngoingSessionStatus getOngoingSessionStatus(MediaDevice device) {
+ return device.hasOngoingSession() ? new OngoingSessionStatus(
+ device.isHostForOngoingSession()) : null;
+ }
+
+ private GroupStatus getGroupStatus(boolean isSelected, boolean isSelectable,
+ boolean isDeselectable) {
+ // A device should either be selectable or, when the device selected, the list should
+ // have other selectable or selected devices.
+ boolean selectedWithOtherGroupDevices =
+ isSelected && (hasMultipleSelectedDevices() || hasSelectableDevices());
+ if (isSelectable || selectedWithOtherGroupDevices) {
+ return new GroupStatus(isSelected, isDeselectable);
+ }
+ return null;
+ }
+
+ private boolean hasMultipleSelectedDevices() {
+ return mController.getSelectedMediaDevice().size() > 1;
+ }
+
+ private boolean hasSelectableDevices() {
+ return !mController.getSelectableMediaDevice().isEmpty();
+ }
+
+ @Nullable
+ private View.OnClickListener getClickListenerBasedOnSelectionBehavior(
+ @NonNull MediaDevice device) {
+ return Api34Impl.getClickListenerBasedOnSelectionBehavior(
+ device, mController, v -> onItemClick(v, device));
+ }
+
+ @Nullable
+ private Drawable getDeviceStatusIcon(MediaDevice device, boolean hasOngoingSession) {
+ if (hasOngoingSession) {
+ return mContext.getDrawable(R.drawable.ic_sound_bars_anim);
+ } else {
+ return Api34Impl.getDeviceStatusIconBasedOnSelectionBehavior(device, mContext);
+ }
+ }
+
+ protected void onExpandGroupButtonClicked() {
+ mShouldGroupSelectedMediaItems = false;
+ notifyDataSetChanged();
+ }
+
+ protected void onGroupActionTriggered(boolean isChecked, MediaDevice device) {
+ disableSeekBar();
+ if (isChecked && isDeviceIncluded(mController.getSelectableMediaDevice(), device)) {
+ mController.addDeviceToPlayMedia(device);
+ } else if (!isChecked && isDeviceIncluded(mController.getDeselectableMediaDevice(),
+ device)) {
+ mController.removeDeviceFromPlayMedia(device);
+ }
+ }
+
+ private void onItemClick(View view, MediaDevice device) {
+ if (mController.isCurrentOutputDeviceHasSessionOngoing()) {
+ showCustomEndSessionDialog(device);
+ } else {
+ transferOutput(device);
+ }
+ }
+
+ private void transferOutput(MediaDevice device) {
+ if (mController.isAnyDeviceTransferring()) {
+ return;
+ }
+ if (isCurrentlyConnected(device)) {
+ Log.d(TAG, "This device is already connected! : " + device.getName());
+ return;
+ }
+ mController.setTemporaryAllowListExceptionIfNeeded(device);
+ mCurrentActivePosition = -1;
+ mController.connectDevice(device);
+ device.setState(MediaDeviceState.STATE_CONNECTING);
+ notifyDataSetChanged();
+ }
+
+ @VisibleForTesting
+ void showCustomEndSessionDialog(MediaDevice device) {
+ MediaSessionReleaseDialog mediaSessionReleaseDialog = new MediaSessionReleaseDialog(
+ mContext, () -> transferOutput(device), mController.getColorButtonBackground(),
+ mController.getColorItemContent());
+ mediaSessionReleaseDialog.show();
+ }
+
+ private void cancelMuteAwaitConnection() {
+ mController.cancelMuteAwaitConnection();
+ notifyDataSetChanged();
+ }
+
+ protected String getDeviceItemContentDescription(@NonNull MediaDevice device) {
+ return mContext.getString(
+ device.getDeviceType() == MediaDevice.MediaDeviceType.TYPE_BLUETOOTH_DEVICE
+ ? R.string.accessibility_bluetooth_name
+ : R.string.accessibility_cast_name, device.getName());
+ }
+
+ protected String getGroupItemContentDescription(String sessionName) {
+ return mContext.getString(R.string.accessibility_cast_name, sessionName);
+ }
+ }
+
+ @RequiresApi(34)
+ private static class Api34Impl {
+ @DoNotInline
+ static View.OnClickListener getClickListenerBasedOnSelectionBehavior(
+ MediaDevice device,
+ MediaSwitchingController controller,
+ View.OnClickListener defaultTransferListener) {
+ switch (device.getSelectionBehavior()) {
+ case SELECTION_BEHAVIOR_NONE:
+ return null;
+ case SELECTION_BEHAVIOR_TRANSFER:
+ return defaultTransferListener;
+ case SELECTION_BEHAVIOR_GO_TO_APP:
+ return v -> controller.tryToLaunchInAppRoutingIntent(device.getId(), v);
+ }
+ return defaultTransferListener;
+ }
+
+ @DoNotInline
+ @Nullable
+ static Drawable getDeviceStatusIconBasedOnSelectionBehavior(MediaDevice device,
+ Context context) {
+ switch (device.getSelectionBehavior()) {
+ case SELECTION_BEHAVIOR_NONE:
+ return context.getDrawable(R.drawable.media_output_status_failed);
+ case SELECTION_BEHAVIOR_TRANSFER:
+ return null;
+ case SELECTION_BEHAVIOR_GO_TO_APP:
+ return context.getDrawable(R.drawable.media_output_status_help);
+ }
+ return null;
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapterLegacy.java
similarity index 64%
rename from packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
rename to packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapterLegacy.java
index f97b3d3..ea44184 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapterLegacy.java
@@ -18,14 +18,18 @@
import android.animation.Animator;
import android.animation.ValueAnimator;
-import android.app.WallpaperColors;
+import android.annotation.DrawableRes;
+import android.annotation.StringRes;
import android.content.Context;
import android.content.res.ColorStateList;
+import android.graphics.drawable.AnimatedVectorDrawable;
import android.graphics.drawable.ClipDrawable;
+import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.Icon;
import android.graphics.drawable.LayerDrawable;
import android.text.TextUtils;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -40,6 +44,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
+import androidx.core.widget.CompoundButtonCompat;
import androidx.recyclerview.widget.RecyclerView;
import com.android.media.flags.Flags;
@@ -48,82 +53,67 @@
import com.android.settingslib.utils.ThreadUtils;
import com.android.systemui.res.R;
-import java.util.List;
-
/**
- * Base adapter for media output dialog.
+ * A RecyclerView adapter for the legacy UI media output dialog device list.
*/
-public abstract class MediaOutputBaseAdapter extends
- RecyclerView.Adapter<RecyclerView.ViewHolder> {
-
- record OngoingSessionStatus(boolean host) {}
-
- record GroupStatus(Boolean selected, Boolean deselectable) {}
-
- enum ConnectionState {
- CONNECTED,
- CONNECTING,
- DISCONNECTED,
- }
-
- protected final MediaSwitchingController mController;
+public class MediaOutputAdapterLegacy extends MediaOutputAdapterBase {
+ private static final String TAG = "MediaOutputAdapterL";
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private static final int UNMUTE_DEFAULT_VOLUME = 2;
-
- Context mContext;
+ private static final float DEVICE_DISABLED_ALPHA = 0.5f;
+ private static final float DEVICE_ACTIVE_ALPHA = 1f;
View mHolderView;
- boolean mIsDragging;
- int mCurrentActivePosition;
private boolean mIsInitVolumeFirstTime;
- public MediaOutputBaseAdapter(MediaSwitchingController controller) {
- mController = controller;
- mIsDragging = false;
- mCurrentActivePosition = -1;
+ public MediaOutputAdapterLegacy(MediaSwitchingController controller) {
+ super(controller);
mIsInitVolumeFirstTime = true;
}
- /**
- * Refresh current dataset
- */
- public abstract void updateItems();
-
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup,
int viewType) {
- mContext = viewGroup.getContext();
- mHolderView = LayoutInflater.from(mContext).inflate(MediaItem.getMediaLayoutId(viewType),
+
+ Context context = viewGroup.getContext();
+ mHolderView = LayoutInflater.from(viewGroup.getContext()).inflate(
+ MediaItem.getMediaLayoutId(viewType),
viewGroup, false);
- return null;
- }
-
- void updateColorScheme(WallpaperColors wallpaperColors, boolean isDarkTheme) {
- mController.setCurrentColorScheme(wallpaperColors, isDarkTheme);
- }
-
- boolean isCurrentlyConnected(MediaDevice device) {
- return TextUtils.equals(device.getId(),
- mController.getCurrentConnectedMediaDevice().getId())
- || (mController.getSelectedMediaDevice().size() == 1
- && isDeviceIncluded(mController.getSelectedMediaDevice(), device));
- }
-
- boolean isDeviceIncluded(List<MediaDevice> deviceList, MediaDevice targetDevice) {
- for (MediaDevice device : deviceList) {
- if (TextUtils.equals(device.getId(), targetDevice.getId())) {
- return true;
- }
+ switch (viewType) {
+ case MediaItem.MediaItemType.TYPE_GROUP_DIVIDER:
+ return new MediaGroupDividerViewHolderLegacy(mHolderView);
+ case MediaItem.MediaItemType.TYPE_PAIR_NEW_DEVICE:
+ case MediaItem.MediaItemType.TYPE_DEVICE:
+ default:
+ return new MediaDeviceViewHolderLegacy(mHolderView, context);
}
- return false;
}
- boolean isDragging() {
- return mIsDragging;
- }
-
- int getCurrentActivePosition() {
- return mCurrentActivePosition;
+ @Override
+ public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
+ if (position >= getItemCount()) {
+ if (DEBUG) {
+ Log.d(TAG, "Incorrect position: " + position + " list size: "
+ + getItemCount());
+ }
+ return;
+ }
+ MediaItem currentMediaItem = mMediaItemList.get(position);
+ switch (currentMediaItem.getMediaItemType()) {
+ case MediaItem.MediaItemType.TYPE_GROUP_DIVIDER:
+ ((MediaGroupDividerViewHolderLegacy) viewHolder).onBind(
+ currentMediaItem.getTitle());
+ break;
+ case MediaItem.MediaItemType.TYPE_PAIR_NEW_DEVICE:
+ ((MediaDeviceViewHolderLegacy) viewHolder).onBindPairNewDevice();
+ break;
+ case MediaItem.MediaItemType.TYPE_DEVICE:
+ ((MediaDeviceViewHolderLegacy) viewHolder).onBindDevice(currentMediaItem, position);
+ break;
+ default:
+ Log.d(TAG, "Incorrect position: " + position);
+ }
}
public MediaSwitchingController getController() {
@@ -133,7 +123,7 @@
/**
* ViewHolder for binding device view.
*/
- abstract class MediaDeviceBaseViewHolder extends RecyclerView.ViewHolder {
+ class MediaDeviceViewHolderLegacy extends MediaDeviceViewHolderBase {
private static final int ANIM_DURATION = 500;
@@ -158,8 +148,8 @@
private ValueAnimator mVolumeAnimator;
private int mLatestUpdateVolume = -1;
- MediaDeviceBaseViewHolder(View view) {
- super(view);
+ MediaDeviceViewHolderLegacy(View view, Context context) {
+ super(view, context);
mContainerLayout = view.requireViewById(R.id.device_container);
mItemLayout = view.requireViewById(R.id.item_layout);
mTitleText = view.requireViewById(R.id.title);
@@ -180,8 +170,10 @@
initAnimator();
}
- void onBind(MediaDevice device, int position) {
+ void onBindDevice(MediaItem mediaItem, int position) {
+ MediaDevice device = mediaItem.getMediaDevice().get();
mDeviceId = device.getId();
+ mItemLayout.setVisibility(View.VISIBLE);
mCheckBox.setVisibility(View.GONE);
mStatusIcon.setVisibility(View.GONE);
mEndTouchArea.setVisibility(View.GONE);
@@ -193,9 +185,58 @@
mSubTitleText.setTextColor(mController.getColorItemContent());
mVolumeValueText.setTextColor(mController.getColorItemContent());
mIconAreaLayout.setBackground(null);
+ updateIconAreaClickListener(null);
mSeekBar.setProgressTintList(
ColorStateList.valueOf(mController.getColorSeekbarProgress()));
enableFocusPropertyForView(mContainerLayout);
+ renderItem(mediaItem, position);
+ }
+
+ /** Binds a ViewHolder for a "Connect a device" item. */
+ void onBindPairNewDevice() {
+ mTitleText.setTextColor(mController.getColorItemContent());
+ mCheckBox.setVisibility(View.GONE);
+ updateTitle(mContext.getText(R.string.media_output_dialog_pairing_new));
+ updateItemBackground(ConnectionState.DISCONNECTED);
+ final Drawable addDrawable = mContext.getDrawable(R.drawable.ic_add);
+ mTitleIcon.setImageDrawable(addDrawable);
+ mTitleIcon.setImageTintList(
+ ColorStateList.valueOf(mController.getColorItemContent()));
+ mContainerLayout.setOnClickListener(mController::launchBluetoothPairing);
+ }
+
+ @Override
+ protected void renderDeviceItem(boolean hideGroupItem, MediaDevice device,
+ ConnectionState connectionState, boolean restrictVolumeAdjustment,
+ GroupStatus groupStatus, OngoingSessionStatus ongoingSessionStatus,
+ View.OnClickListener clickListener, boolean deviceDisabled, String subtitle,
+ Drawable deviceStatusIcon) {
+ if (hideGroupItem) {
+ mItemLayout.setVisibility(View.GONE);
+ return;
+ }
+ updateTitle(device.getName());
+ updateTitleIcon(device, connectionState, restrictVolumeAdjustment);
+ updateSeekBar(device, connectionState, restrictVolumeAdjustment,
+ getDeviceItemContentDescription(device));
+ updateEndArea(device, connectionState, groupStatus, ongoingSessionStatus);
+ updateLoadingIndicator(connectionState);
+ updateFullItemClickListener(clickListener);
+ updateContentAlpha(deviceDisabled);
+ updateSubtitle(subtitle);
+ updateDeviceStatusIcon(deviceStatusIcon);
+ updateItemBackground(connectionState);
+ }
+
+ @Override
+ protected void renderDeviceGroupItem() {
+ String sessionName = mController.getSessionName() == null ? ""
+ : mController.getSessionName().toString();
+ updateTitle(sessionName);
+ updateUnmutedVolumeIcon(null /* device */);
+ updateGroupSeekBar(getGroupItemContentDescription(sessionName));
+ updateEndAreaForDeviceGroup();
+ updateItemBackground(ConnectionState.CONNECTED);
}
void updateTitle(CharSequence title) {
@@ -303,7 +344,7 @@
private void initializeSeekbarVolume(
@Nullable MediaDevice device, int currentVolume,
boolean isCurrentSeekbarInvisible) {
- if (!mIsDragging) {
+ if (!isDragging()) {
if (mSeekBar.getVolume() != currentVolume && (mLatestUpdateVolume == -1
|| currentVolume == mLatestUpdateVolume)) {
// Update only if volume of device and value of volume bar doesn't match.
@@ -352,6 +393,11 @@
@Override
public void onMute() {
+ mController.logInteractionMuteDevice(device);
+ }
+
+ @Override
+ public void onUnmute() {
mController.logInteractionUnmuteDevice(device);
}
};
@@ -390,6 +436,9 @@
@Override
public void onMute() {}
+
+ @Override
+ public void onUnmute() {}
};
if (!mController.isVolumeControlEnabledForSession()) {
@@ -459,8 +508,136 @@
: R.drawable.media_output_icon_volume;
}
+ private void updateContentAlpha(boolean deviceDisabled) {
+ float alphaValue = deviceDisabled ? DEVICE_DISABLED_ALPHA : DEVICE_ACTIVE_ALPHA;
+ mTitleIcon.setAlpha(alphaValue);
+ mTitleText.setAlpha(alphaValue);
+ mSubTitleText.setAlpha(alphaValue);
+ mStatusIcon.setAlpha(alphaValue);
+ }
+
+ private void updateDeviceStatusIcon(@Nullable Drawable deviceStatusIcon) {
+ if (deviceStatusIcon == null) {
+ mStatusIcon.setVisibility(View.GONE);
+ } else {
+ mStatusIcon.setImageDrawable(deviceStatusIcon);
+ mStatusIcon.setImageTintList(
+ ColorStateList.valueOf(mController.getColorItemContent()));
+ if (deviceStatusIcon instanceof AnimatedVectorDrawable) {
+ ((AnimatedVectorDrawable) deviceStatusIcon).start();
+ }
+ mStatusIcon.setVisibility(View.VISIBLE);
+ }
+ }
+
+
+ /** Renders the right side round pill button / checkbox. */
+ private void updateEndArea(@NonNull MediaDevice device, ConnectionState connectionState,
+ @Nullable GroupStatus groupStatus,
+ @Nullable OngoingSessionStatus ongoingSessionStatus) {
+ boolean showEndArea = false;
+ boolean isCheckbox = false;
+ // If both group status and the ongoing session status are present, only the ongoing
+ // session controls are displayed. The current layout design doesn't allow both group
+ // and ongoing session controls to be rendered simultaneously.
+ if (ongoingSessionStatus != null && connectionState == ConnectionState.CONNECTED) {
+ showEndArea = true;
+ updateEndAreaForOngoingSession(device, ongoingSessionStatus.host());
+ } else if (groupStatus != null && shouldShowGroupCheckbox(groupStatus)) {
+ showEndArea = true;
+ isCheckbox = true;
+ updateEndAreaForGroupCheckBox(device, groupStatus);
+ }
+ updateEndAreaVisibility(showEndArea, isCheckbox);
+ }
+
+ private void updateEndAreaForDeviceGroup() {
+ updateEndAreaWithIcon(
+ v -> {
+ onExpandGroupButtonClicked();
+ },
+ R.drawable.media_output_item_expand_group,
+ R.string.accessibility_expand_group);
+ updateEndAreaVisibility(true /* showEndArea */, false /* isCheckbox */);
+ }
+
+ private void updateEndAreaForOngoingSession(@NonNull MediaDevice device, boolean isHost) {
+ updateEndAreaWithIcon(
+ v -> mController.tryToLaunchInAppRoutingIntent(device.getId(), v),
+ isHost ? R.drawable.media_output_status_edit_session
+ : R.drawable.ic_sound_bars_anim,
+ R.string.accessibility_open_application);
+ }
+
+ private void updateEndAreaWithIcon(View.OnClickListener clickListener,
+ @DrawableRes int iconDrawableId,
+ @StringRes int accessibilityStringId) {
+ updateEndAreaColor(mController.getColorSeekbarProgress());
+ mEndClickIcon.setImageTintList(
+ ColorStateList.valueOf(mController.getColorItemContent()));
+ mEndClickIcon.setOnClickListener(clickListener);
+ mEndTouchArea.setOnClickListener(v -> mEndClickIcon.performClick());
+ Drawable drawable = mContext.getDrawable(iconDrawableId);
+ mEndClickIcon.setImageDrawable(drawable);
+ if (drawable instanceof AnimatedVectorDrawable) {
+ ((AnimatedVectorDrawable) drawable).start();
+ }
+ if (Flags.enableOutputSwitcherDeviceGrouping()) {
+ mEndClickIcon.setContentDescription(mContext.getString(accessibilityStringId));
+ }
+ }
+
+ private void updateEndAreaForGroupCheckBox(@NonNull MediaDevice device,
+ @NonNull GroupStatus groupStatus) {
+ boolean isEnabled = isGroupCheckboxEnabled(groupStatus);
+ mEndTouchArea.setOnClickListener(
+ isEnabled ? (v) -> mCheckBox.performClick() : null);
+ mEndTouchArea.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
+ updateEndAreaColor(groupStatus.selected() ? mController.getColorSeekbarProgress()
+ : mController.getColorItemBackground());
+ mEndTouchArea.setContentDescription(getDeviceItemContentDescription(device));
+ mCheckBox.setOnCheckedChangeListener(null);
+ mCheckBox.setChecked(groupStatus.selected());
+ mCheckBox.setOnCheckedChangeListener(
+ isEnabled ? (buttonView, isChecked) -> onGroupActionTriggered(
+ !groupStatus.selected(), device) : null);
+ mCheckBox.setEnabled(isEnabled);
+ setCheckBoxColor(mCheckBox, mController.getColorItemContent());
+ }
+
+ private void setCheckBoxColor(CheckBox checkBox, int color) {
+ int[][] states = {{android.R.attr.state_checked}, {}};
+ int[] colors = {color, color};
+ CompoundButtonCompat.setButtonTintList(checkBox, new
+ ColorStateList(states, colors));
+ }
+
+ private boolean shouldShowGroupCheckbox(@NonNull GroupStatus groupStatus) {
+ if (Flags.enableOutputSwitcherDeviceGrouping()) {
+ return isGroupCheckboxEnabled(groupStatus);
+ }
+ return true;
+ }
+
+ private boolean isGroupCheckboxEnabled(@NonNull GroupStatus groupStatus) {
+ boolean disabled = groupStatus.selected() && !groupStatus.deselectable();
+ return !disabled;
+ }
+
+ private void updateEndAreaColor(int color) {
+ mEndTouchArea.setBackgroundTintList(
+ ColorStateList.valueOf(color));
+ }
+
+ private void updateFullItemClickListener(@Nullable View.OnClickListener listener) {
+ mContainerLayout.setOnClickListener(listener);
+ }
+
void updateIconAreaClickListener(@Nullable View.OnClickListener listener) {
mIconAreaLayout.setOnClickListener(listener);
+ if (listener == null) {
+ mIconAreaLayout.setClickable(false); // clickable is not removed automatically.
+ }
}
private void initAnimator() {
@@ -498,6 +675,7 @@
});
}
+ @Override
protected void disableSeekBar() {
mSeekBar.setEnabled(false);
mSeekBar.setOnTouchListener((v, event) -> true);
@@ -510,6 +688,7 @@
mSeekBar.setOnTouchListener((v, event) -> false);
updateIconAreaClickListener((v) -> {
if (volumeControl.getVolume() == 0) {
+ volumeControl.onUnmute();
mSeekBar.setVolume(UNMUTE_DEFAULT_VOLUME);
volumeControl.setVolume(UNMUTE_DEFAULT_VOLUME);
updateUnmutedVolumeIcon(null);
@@ -546,6 +725,7 @@
int getVolume();
void setVolume(int volume);
void onMute();
+ void onUnmute();
}
private abstract class MediaSeekBarChangedListener
@@ -589,7 +769,7 @@
int currentVolume = MediaOutputSeekbar.scaleProgressToVolume(
seekBar.getProgress());
mStartFromMute = (currentVolume == 0);
- mIsDragging = true;
+ setIsDragging(true);
}
@Override
@@ -604,11 +784,25 @@
}
mTitleIcon.setVisibility(View.VISIBLE);
mVolumeValueText.setVisibility(View.GONE);
- mIsDragging = false;
+ setIsDragging(false);
}
protected boolean shouldHandleProgressChanged() {
return mMediaDevice != null;
}
};
}
+
+ class MediaGroupDividerViewHolderLegacy extends RecyclerView.ViewHolder {
+ final TextView mTitleText;
+
+ MediaGroupDividerViewHolderLegacy(@NonNull View itemView) {
+ super(itemView);
+ mTitleText = itemView.requireViewById(R.id.title);
+ }
+
+ void onBind(String groupDividerTitle) {
+ mTitleText.setTextColor(mController.getColorItemContent());
+ mTitleText.setText(groupDividerTitle);
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
index 64256f9..d791361 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
@@ -105,7 +105,7 @@
private boolean mIsLeBroadcastCallbackRegistered;
private boolean mDismissing;
- MediaOutputBaseAdapter mAdapter;
+ MediaOutputAdapterBase mAdapter;
protected Executor mExecutor;
@@ -342,7 +342,7 @@
WallpaperColors wallpaperColors = WallpaperColors.fromBitmap(icon.getBitmap());
colorSetUpdated = !wallpaperColors.equals(mWallpaperColors);
if (colorSetUpdated) {
- mAdapter.updateColorScheme(wallpaperColors, isDarkThemeOn);
+ mMediaSwitchingController.setCurrentColorScheme(wallpaperColors, isDarkThemeOn);
updateButtonBackgroundColorFilter();
updateDialogBackgroundColor();
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialog.java
index 9b5b872a..9ade9e2 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialog.java
@@ -245,7 +245,7 @@
broadcastSender,
mediaSwitchingController, /* includePlaybackAndAppMetadata */
true);
- mAdapter = new MediaOutputAdapter(mMediaSwitchingController);
+ mAdapter = new MediaOutputAdapterLegacy(mMediaSwitchingController);
// TODO(b/226710953): Move the part to MediaOutputBaseDialog for every class
// that extends MediaOutputBaseDialog
if (!aboveStatusbar) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java
index c9af7b3..2e602be 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java
@@ -53,7 +53,7 @@
super(context, broadcastSender, mediaSwitchingController, includePlaybackAndAppMetadata);
mDialogTransitionAnimator = dialogTransitionAnimator;
mUiEventLogger = uiEventLogger;
- mAdapter = new MediaOutputAdapter(mMediaSwitchingController);
+ mAdapter = new MediaOutputAdapterLegacy(mMediaSwitchingController);
if (!aboveStatusbar) {
getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY);
}
diff --git a/packages/SystemUI/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayContentViewModel.kt b/packages/SystemUI/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayContentViewModel.kt
index c7b1654..c43c1a99 100644
--- a/packages/SystemUI/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayContentViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayContentViewModel.kt
@@ -20,12 +20,15 @@
import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.systemui.lifecycle.ExclusiveActivatable
import com.android.systemui.lifecycle.Hydrator
+import com.android.systemui.media.controls.domain.pipeline.interactor.MediaCarouselInteractor
import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.shade.ui.viewmodel.ShadeHeaderViewModel
+import com.android.systemui.statusbar.disableflags.domain.interactor.DisableFlagsInteractor
import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor
import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel
+import com.android.systemui.utils.coroutines.flow.flatMapLatestConflated
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import kotlinx.coroutines.awaitCancellation
@@ -33,6 +36,7 @@
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter
+import kotlinx.coroutines.flow.flowOf
/**
* Models UI state used to render the content of the notifications shade overlay.
@@ -47,6 +51,8 @@
val notificationsPlaceholderViewModelFactory: NotificationsPlaceholderViewModel.Factory,
val sceneInteractor: SceneInteractor,
private val shadeInteractor: ShadeInteractor,
+ disableFlagsInteractor: DisableFlagsInteractor,
+ mediaCarouselInteractor: MediaCarouselInteractor,
activeNotificationsInteractor: ActiveNotificationsInteractor,
) : ExclusiveActivatable() {
@@ -69,6 +75,22 @@
),
)
+ val showMedia: Boolean by
+ hydrator.hydratedStateOf(
+ traceName = "showMedia",
+ initialValue =
+ disableFlagsInteractor.disableFlags.value.isQuickSettingsEnabled() &&
+ mediaCarouselInteractor.hasActiveMediaOrRecommendation.value,
+ source =
+ disableFlagsInteractor.disableFlags.flatMapLatestConflated {
+ if (it.isQuickSettingsEnabled()) {
+ mediaCarouselInteractor.hasActiveMediaOrRecommendation
+ } else {
+ flowOf(false)
+ }
+ },
+ )
+
override suspend fun onActivated(): Nothing {
coroutineScope {
launch { hydrator.activate() }
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 28540d4..6ad8bae 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt
@@ -53,6 +53,7 @@
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
@@ -287,7 +288,7 @@
private fun CollapsableQuickSettingsSTL() {
val sceneState =
rememberMutableSceneTransitionLayoutState(
- viewModel.expansionState.toIdleSceneKey(),
+ initialScene = remember { viewModel.expansionState.toIdleSceneKey() },
transitions =
transitions {
from(QuickQuickSettings, QuickSettings) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/Tile.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/Tile.kt
index 47238d1..d73dc87 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/Tile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/Tile.kt
@@ -245,6 +245,7 @@
color = color(),
shape = shape,
modifier = modifier.clip(shape).verticalSquish(squishiness),
+ useModifierBasedImplementation = true,
) {
content(hapticsViewModel?.createStateAwareExpandable(it) ?: it)
}
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
index 59c554c..7a2c51a 100644
--- 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
@@ -32,18 +32,25 @@
Row(modifier = modifier, verticalAlignment = Alignment.CenterVertically) {
viewModel.userSwitcherViewModel?.let {
- IconButton(it, Modifier.sysuiResTag("multi_user_switch"))
+ IconButton(
+ it,
+ useModifierBasedExpandable = true,
+ Modifier.sysuiResTag("multi_user_switch"),
+ )
}
EditModeButton(viewModel.editModeButtonViewModelFactory)
IconButton(
viewModel.settingsButtonViewModel,
+ useModifierBasedExpandable = true,
Modifier.sysuiResTag("settings_button_container"),
)
Spacer(modifier = Modifier.weight(1f))
- viewModel.powerButtonViewModel?.let { IconButton(it, Modifier.sysuiResTag("pm_lite")) }
+ viewModel.powerButtonViewModel?.let {
+ IconButton(it, useModifierBasedExpandable = true, Modifier.sysuiResTag("pm_lite"))
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/dialog/QSResetDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/dialog/QSResetDialogDelegate.kt
index cbece2c..d266600 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/dialog/QSResetDialogDelegate.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/dialog/QSResetDialogDelegate.kt
@@ -28,6 +28,7 @@
import com.android.systemui.dialog.ui.composable.AlertDialogContent
import com.android.systemui.qs.panels.domain.interactor.EditTilesResetInteractor
import com.android.systemui.res.R
+import com.android.systemui.shade.domain.interactor.ShadeDialogContextInteractor
import com.android.systemui.statusbar.phone.ComponentSystemUIDialog
import com.android.systemui.statusbar.phone.SystemUIDialog
import com.android.systemui.statusbar.phone.SystemUIDialogFactory
@@ -40,6 +41,7 @@
@Inject
constructor(
private val sysuiDialogFactory: SystemUIDialogFactory,
+ private val shadeDialogContextInteractor: ShadeDialogContextInteractor,
private val resetInteractor: EditTilesResetInteractor,
) : SystemUIDialog.Delegate {
private var currentDialog: ComponentSystemUIDialog? = null
@@ -53,7 +55,9 @@
currentDialog =
sysuiDialogFactory
- .create { ResetConfirmationDialog(it) }
+ .create(context = shadeDialogContextInteractor.context) {
+ ResetConfirmationDialog(it)
+ }
.also {
it.lifecycle.addObserver(
object : DefaultLifecycleObserver {
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 2082423..31323c7 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
@@ -42,6 +42,8 @@
import javax.inject.Named
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
@@ -53,6 +55,7 @@
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
+@OptIn(ExperimentalCoroutinesApi::class)
@SysUISingleton
class EditModeViewModel
@Inject
@@ -73,11 +76,9 @@
private val _isEditing = MutableStateFlow(false)
/**
- * Whether we should be editing right now. Use [startEditing] and [stopEditing] to change this
+ * Whether we should be editing right now. Use [startEditing] and [stopEditing] to change this.
*/
val isEditing = _isEditing.asStateFlow()
- private val minimumTiles: Int
- get() = minTilesInteractor.minNumberOfTiles
val gridLayout: StateFlow<GridLayout> =
gridLayoutTypeInteractor.layout
@@ -99,7 +100,7 @@
* * Tiles that are not available will be filtered out. None of them can be current (as they
* cannot be created), and they won't be able to be added.
*/
- val tiles =
+ val tiles: Flow<List<EditTileViewModel>> =
isEditing.flatMapLatest {
if (it) {
val editTilesData = editTilesListInteractor.getTilesToEdit()
@@ -114,10 +115,10 @@
currentTilesInteractor.currentTiles
.map { tiles ->
val currentSpecs = tiles.map { it.spec }
- val canRemoveTiles = currentSpecs.size > minimumTiles
+ val canRemoveTiles = currentSpecs.size > minTilesInteractor.minNumberOfTiles
val allTiles = editTilesData.stockTiles + editTilesData.customTiles
- val allTilesMap = allTiles.associate { it.tileSpec to it }
- val currentTiles = currentSpecs.map { allTilesMap.get(it) }.filterNotNull()
+ val allTilesMap = allTiles.associateBy { it.tileSpec }
+ val currentTiles = currentSpecs.mapNotNull { allTilesMap[it] }
val nonCurrentTiles = allTiles.filter { it.tileSpec !in currentSpecs }
(currentTiles + nonCurrentTiles)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SubtitleArrayMapping.kt b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SubtitleArrayMapping.kt
index c9a0635..61a8fa3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SubtitleArrayMapping.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SubtitleArrayMapping.kt
@@ -55,6 +55,7 @@
subtitleIdsMap["font_scaling"] = R.array.tile_states_font_scaling
subtitleIdsMap["hearing_devices"] = R.array.tile_states_hearing_devices
subtitleIdsMap["notes"] = R.array.tile_states_notes
+ subtitleIdsMap["desktopeffects"] = R.array.tile_states_desktopeffects
}
/** Get the subtitle resource id of the given tile */
diff --git a/packages/SystemUI/src/com/android/systemui/scene/data/repository/SceneContainerRepository.kt b/packages/SystemUI/src/com/android/systemui/scene/data/repository/SceneContainerRepository.kt
index caa7bba..e357f63 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/data/repository/SceneContainerRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/data/repository/SceneContainerRepository.kt
@@ -163,4 +163,12 @@
fun setTransitionState(transitionState: Flow<ObservableTransitionState>?) {
_transitionState.value = transitionState
}
+
+ /**
+ * If currently in a transition between contents, cancel that transition and go back to the
+ * pre-transition state.
+ */
+ fun freezeAndAnimateToCurrentState() {
+ dataSource.freezeAndAnimateToCurrentState()
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt
index e9e7dec..0118085 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt
@@ -234,6 +234,10 @@
* The change is animated. Therefore, it will be some time before the UI will switch to the
* desired scene. Once enough of the transition has occurred, the [currentScene] will become
* [toScene] (unless the transition is canceled by user action or another call to this method).
+ *
+ * If [forceSettleToTargetScene] is `true` and the target scene is the same as the current
+ * scene, any current transition will be canceled and an animation to the target scene will be
+ * started.
*/
@JvmOverloads
fun changeScene(
@@ -241,9 +245,19 @@
loggingReason: String,
transitionKey: TransitionKey? = null,
sceneState: Any? = null,
+ forceSettleToTargetScene: Boolean = false,
) {
val currentSceneKey = currentScene.value
val resolvedScene = sceneFamilyResolvers.get()[toScene]?.resolvedScene?.value ?: toScene
+
+ if (resolvedScene == currentSceneKey && forceSettleToTargetScene) {
+ logger.logSceneChangeCancellation(scene = resolvedScene, sceneState = sceneState)
+ onSceneAboutToChangeListener.forEach {
+ it.onSceneAboutToChange(resolvedScene, sceneState)
+ }
+ repository.freezeAndAnimateToCurrentState()
+ }
+
if (
!validateSceneChange(
from = currentSceneKey,
@@ -523,14 +537,32 @@
}
if (from == to) {
+ logger.logSceneChangeRejection(
+ from = from,
+ to = to,
+ originalChangeReason = loggingReason,
+ rejectionReason = "${from.debugName} is the same as ${to.debugName}",
+ )
return false
}
if (to !in repository.allContentKeys) {
+ logger.logSceneChangeRejection(
+ from = from,
+ to = to,
+ originalChangeReason = loggingReason,
+ rejectionReason = "${to.debugName} isn't present in allContentKeys",
+ )
return false
}
if (disabledContentInteractor.isDisabled(to)) {
+ logger.logSceneChangeRejection(
+ from = from,
+ to = to,
+ originalChangeReason = loggingReason,
+ rejectionReason = "${to.debugName} is currently disabled",
+ )
return false
}
@@ -580,14 +612,58 @@
}
if (to != null && disabledContentInteractor.isDisabled(to)) {
+ logger.logSceneChangeRejection(
+ from = from,
+ to = to,
+ originalChangeReason = loggingReason,
+ rejectionReason = "${to.debugName} is currently disabled",
+ )
return false
}
- val isFromValid = (from == null) || (from in currentOverlays.value)
- val isToValid =
- (to == null) || (to !in currentOverlays.value && to in repository.allContentKeys)
+ return when {
+ to != null && from != null && to == from -> {
+ logger.logSceneChangeRejection(
+ from = from,
+ to = to,
+ originalChangeReason = loggingReason,
+ rejectionReason = "${from.debugName} is the same as ${to.debugName}",
+ )
+ false
+ }
- return isFromValid && isToValid && from != to
+ to != null && to !in repository.allContentKeys -> {
+ logger.logSceneChangeRejection(
+ from = from,
+ to = to,
+ originalChangeReason = loggingReason,
+ rejectionReason = "${to.debugName} is not in allContentKeys",
+ )
+ false
+ }
+
+ from != null && from !in currentOverlays.value -> {
+ logger.logSceneChangeRejection(
+ from = from,
+ to = to,
+ originalChangeReason = loggingReason,
+ rejectionReason = "${from.debugName} is not a current overlay",
+ )
+ false
+ }
+
+ to != null && to in currentOverlays.value -> {
+ logger.logSceneChangeRejection(
+ from = from,
+ to = to,
+ originalChangeReason = loggingReason,
+ rejectionReason = "${to.debugName} is already a current overlay",
+ )
+ false
+ }
+
+ else -> true
+ }
}
/** Returns a flow indicating if the currently visible scene can be resolved from [family]. */
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
index 16adf5e..218ad47 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
@@ -554,6 +554,7 @@
targetSceneKey = Scenes.Lockscreen,
loggingReason = "device is starting to sleep",
sceneState = keyguardInteractor.asleepKeyguardState.value,
+ freezeAndAnimateToCurrentState = true,
)
} else {
val canSwipeToEnter = deviceEntryInteractor.canSwipeToEnter.value
@@ -933,11 +934,13 @@
targetSceneKey: SceneKey,
loggingReason: String,
sceneState: Any? = null,
+ freezeAndAnimateToCurrentState: Boolean = false,
) {
sceneInteractor.changeScene(
toScene = targetSceneKey,
loggingReason = loggingReason,
sceneState = sceneState,
+ forceSettleToTargetScene = freezeAndAnimateToCurrentState,
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/scene/shared/logger/SceneLogger.kt b/packages/SystemUI/src/com/android/systemui/scene/shared/logger/SceneLogger.kt
index d005858..73c71f6 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/shared/logger/SceneLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/shared/logger/SceneLogger.kt
@@ -16,6 +16,7 @@
package com.android.systemui.scene.shared.logger
+import com.android.compose.animation.scene.ContentKey
import com.android.compose.animation.scene.ObservableTransitionState
import com.android.compose.animation.scene.OverlayKey
import com.android.compose.animation.scene.SceneKey
@@ -74,6 +75,50 @@
)
}
+ fun logSceneChangeCancellation(scene: SceneKey, sceneState: Any?) {
+ logBuffer.log(
+ tag = TAG,
+ level = LogLevel.INFO,
+ messageInitializer = {
+ str1 = scene.debugName
+ str2 = sceneState?.toString()
+ },
+ messagePrinter = { "CANCELED scene change. scene: $str1, sceneState: $str2" },
+ )
+ }
+
+ fun logSceneChangeRejection(
+ from: ContentKey?,
+ to: ContentKey?,
+ originalChangeReason: String,
+ rejectionReason: String,
+ ) {
+ logBuffer.log(
+ tag = TAG,
+ level = LogLevel.INFO,
+ messageInitializer = {
+ str1 = "${from?.debugName ?: "<none>"} → ${to?.debugName ?: "<none>"}"
+ str2 = rejectionReason
+ str3 = originalChangeReason
+ bool1 = to is OverlayKey
+ },
+ messagePrinter = {
+ buildString {
+ append("REJECTED ")
+ append(
+ if (bool1) {
+ "overlay "
+ } else {
+ "scene "
+ }
+ )
+ append("change $str1 because \"$str2\" ")
+ append("(original change reason: \"$str3\")")
+ }
+ },
+ )
+ }
+
fun logSceneTransition(transitionState: ObservableTransitionState) {
when (transitionState) {
is ObservableTransitionState.Transition -> {
diff --git a/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneDataSource.kt b/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneDataSource.kt
index daf2d7f..42c4b24 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneDataSource.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneDataSource.kt
@@ -83,4 +83,10 @@
/** Asks for [overlay] to be instantly hidden, without an animated transition of any kind. */
fun instantlyHideOverlay(overlay: OverlayKey)
+
+ /**
+ * If currently in a transition between contents, cancel that transition and go back to the
+ * pre-transition state.
+ */
+ fun freezeAndAnimateToCurrentState()
}
diff --git a/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneDataSourceDelegator.kt b/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneDataSourceDelegator.kt
index dcb6995..d6dce38 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneDataSourceDelegator.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneDataSourceDelegator.kt
@@ -82,6 +82,10 @@
delegateMutable.value.instantlyHideOverlay(overlay)
}
+ override fun freezeAndAnimateToCurrentState() {
+ delegateMutable.value.freezeAndAnimateToCurrentState()
+ }
+
/**
* Binds the current, dependency injection provided [SceneDataSource] to the given object.
*
@@ -120,5 +124,7 @@
override fun instantlyShowOverlay(overlay: OverlayKey) = Unit
override fun instantlyHideOverlay(overlay: OverlayKey) = Unit
+
+ override fun freezeAndAnimateToCurrentState() = Unit
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt b/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt
index 305e71e..3be2f1b 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt
@@ -231,6 +231,9 @@
*/
private var isDreaming = false
+ /** True if we should allow swiping open the glanceable hub. */
+ private var swipeToHubEnabled = false
+
/** Observes and logs state when the lifecycle that controls the [touchMonitor] updates. */
private val touchLifecycleLogger: LifecycleObserver = LifecycleEventObserver { _, event ->
logger.d({
@@ -438,6 +441,7 @@
},
)
collectFlow(containerView, keyguardInteractor.isDreaming, { isDreaming = it })
+ collectFlow(containerView, communalViewModel.swipeToHubEnabled, { swipeToHubEnabled = it })
communalContainerWrapper = CommunalWrapper(containerView.context)
communalContainerWrapper?.addView(communalContainerView)
@@ -520,10 +524,7 @@
val glanceableHubV2 = communalSettingsInteractor.isV2FlagEnabled()
if (
!hubShowing &&
- (touchOnNotifications ||
- touchOnUmo ||
- touchOnSmartspace ||
- !communalViewModel.swipeToHubEnabled())
+ (touchOnNotifications || touchOnUmo || touchOnSmartspace || !swipeToHubEnabled)
) {
logger.d({
"Lockscreen touch ignored: touchOnNotifications: $bool1, touchOnUmo: $bool2, " +
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index 5746cef..131efaa 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -2201,7 +2201,7 @@
@Override
@Deprecated
public void onStatusBarLongPress(MotionEvent event) {
- mShadeLog.d("Status Bar was long pressed.");
+ Log.i(TAG, "Status Bar was long pressed.");
ShadeExpandsOnStatusBarLongPress.assertInNewMode();
mStatusBarLongPressDowntime = event.getDownTime();
if (isTracking()) {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeDisplaysRepository.kt b/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeDisplaysRepository.kt
index 4eb7072..2a14ca4 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeDisplaysRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeDisplaysRepository.kt
@@ -20,6 +20,7 @@
import android.view.Display
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.display.data.repository.DisplayRepository
import com.android.systemui.keyguard.data.repository.KeyguardRepository
import com.android.systemui.shade.ShadeOnDefaultDisplayWhenLocked
import com.android.systemui.shade.display.ShadeDisplayPolicy
@@ -45,7 +46,12 @@
val currentPolicy: ShadeDisplayPolicy
}
-/** Keeps the policy and propagates the display id for the shade from it. */
+/**
+ * Keeps the policy and propagates the display id for the shade from it.
+ *
+ * If the display set by the policy is not available (e.g. after the cable is disconnected), this
+ * falls back to the [Display.DEFAULT_DISPLAY].
+ */
@SysUISingleton
class ShadeDisplaysRepositoryImpl
@Inject
@@ -56,6 +62,7 @@
policies: Set<@JvmSuppressWildcards ShadeDisplayPolicy>,
@ShadeOnDefaultDisplayWhenLocked private val shadeOnDefaultDisplayWhenLocked: Boolean,
keyguardRepository: KeyguardRepository,
+ displayRepository: DisplayRepository,
) : ShadeDisplaysRepository {
private val policy: StateFlow<ShadeDisplayPolicy> =
@@ -73,7 +80,12 @@
.distinctUntilChanged()
.stateIn(bgScope, SharingStarted.Eagerly, defaultPolicy)
- private val displayIdFromPolicy: Flow<Int> = policy.flatMapLatest { it.displayId }
+ private val displayIdFromPolicy: Flow<Int> =
+ policy
+ .flatMapLatest { it.displayId }
+ .combine(displayRepository.displayIds) { policyDisplayId, availableIds ->
+ if (policyDisplayId !in availableIds) Display.DEFAULT_DISPLAY else policyDisplayId
+ }
private val keyguardAwareDisplayPolicy: Flow<Int> =
if (!shadeOnDefaultDisplayWhenLocked) {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/display/ShadeDisplayPolicy.kt b/packages/SystemUI/src/com/android/systemui/shade/display/ShadeDisplayPolicy.kt
index 677e41a..0002fba 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/display/ShadeDisplayPolicy.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/display/ShadeDisplayPolicy.kt
@@ -57,7 +57,7 @@
@Module(includes = [AllShadeDisplayPoliciesModule::class])
interface ShadeDisplayPolicyModule {
- @Binds fun provideDefaultPolicy(impl: DefaultDisplayShadePolicy): ShadeDisplayPolicy
+ @Binds fun provideDefaultPolicy(impl: StatusBarTouchShadeDisplayPolicy): ShadeDisplayPolicy
@Binds
fun provideShadeExpansionIntent(impl: StatusBarTouchShadeDisplayPolicy): ShadeExpansionIntent
diff --git a/packages/SystemUI/src/com/android/systemui/shade/display/StatusBarTouchShadeDisplayPolicy.kt b/packages/SystemUI/src/com/android/systemui/shade/display/StatusBarTouchShadeDisplayPolicy.kt
index 1f534a5..4ebdb60 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/display/StatusBarTouchShadeDisplayPolicy.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/display/StatusBarTouchShadeDisplayPolicy.kt
@@ -26,7 +26,6 @@
import com.android.systemui.shade.domain.interactor.NotificationShadeElement
import com.android.systemui.shade.domain.interactor.QSShadeElement
import com.android.systemui.shade.domain.interactor.ShadeExpandedStateInteractor.ShadeElement
-import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.shade.shared.flag.ShadeWindowGoesAround
import dagger.Lazy
import java.util.concurrent.atomic.AtomicReference
@@ -53,7 +52,6 @@
constructor(
displayRepository: DisplayRepository,
@Background private val backgroundScope: CoroutineScope,
- private val shadeInteractor: Lazy<ShadeInteractor>,
private val qsShadeElement: Lazy<QSShadeElement>,
private val notificationElement: Lazy<NotificationShadeElement>,
) : ShadeDisplayPolicy, ShadeExpansionIntent {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeModeInteractor.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeModeInteractor.kt
index 8f4e870..1ab0b93 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeModeInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeModeInteractor.kt
@@ -22,6 +22,7 @@
import com.android.systemui.log.table.TableLogBuffer
import com.android.systemui.log.table.logDiffsForTable
import com.android.systemui.scene.domain.SceneFrameworkTableLog
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.shade.data.repository.ShadeRepository
import com.android.systemui.shade.shared.model.ShadeMode
import com.android.systemui.shared.settings.data.repository.SecureSettingsRepository
@@ -32,6 +33,7 @@
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.stateIn
/**
@@ -89,10 +91,14 @@
) : ShadeModeInteractor {
private val isDualShadeEnabled: Flow<Boolean> =
- secureSettingsRepository.boolSetting(
- Settings.Secure.DUAL_SHADE,
- defaultValue = DUAL_SHADE_ENABLED_DEFAULT,
- )
+ if (SceneContainerFlag.isEnabled) {
+ secureSettingsRepository.boolSetting(
+ Settings.Secure.DUAL_SHADE,
+ defaultValue = DUAL_SHADE_ENABLED_DEFAULT,
+ )
+ } else {
+ flowOf(false)
+ }
override val isShadeLayoutWide: StateFlow<Boolean> = repository.isShadeLayoutWide
diff --git a/packages/SystemUI/src/com/android/systemui/shade/shared/flag/ShadeWindowGoesAround.kt b/packages/SystemUI/src/com/android/systemui/shade/shared/flag/ShadeWindowGoesAround.kt
index c23ff53..dc444ff 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/shared/flag/ShadeWindowGoesAround.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/shared/flag/ShadeWindowGoesAround.kt
@@ -16,6 +16,7 @@
package com.android.systemui.shade.shared.flag
+import android.window.DesktopExperienceFlags
import com.android.systemui.Flags
import com.android.systemui.flags.FlagToken
import com.android.systemui.flags.RefactorFlagUtils
@@ -30,10 +31,26 @@
val token: FlagToken
get() = FlagToken(FLAG_NAME, isEnabled)
+ /**
+ * This is defined as [DesktopExperienceFlags] to make it possible to enable it together with
+ * all the other desktop experience flags from the dev settings.
+ *
+ * Alternatively, using adb:
+ * ```bash
+ * adb shell aflags enable com.android.window.flags.show_desktop_experience_dev_option && \
+ * adb shell setprop persist.wm.debug.desktop_experience_devopts 1
+ * ```
+ */
+ val FLAG =
+ DesktopExperienceFlags.DesktopExperienceFlag(
+ Flags::shadeWindowGoesAround,
+ /* shouldOverrideByDevOption= */ true,
+ )
+
/** Is the refactor enabled */
@JvmStatic
inline val isEnabled: Boolean
- get() = Flags.shadeWindowGoesAround()
+ get() = FLAG.isTrue
/**
* Called to ensure code is only run when the flag is enabled. This protects users from the
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
index 10f61c6..5b5058f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
@@ -798,6 +798,7 @@
initialTouchY = y
initialTouchX = x
}
+
MotionEvent.ACTION_MOVE -> {
val h = y - initialTouchY
// Adjust the touch slop if another gesture may be being performed.
@@ -852,6 +853,7 @@
}
return true
}
+
MotionEvent.ACTION_UP ->
if (
!falsingManager.isUnlockingDisabled &&
@@ -871,6 +873,7 @@
stopDragging()
return false
}
+
MotionEvent.ACTION_CANCEL -> {
stopDragging()
return false
@@ -910,7 +913,7 @@
overshoot *= 1 - RUBBERBAND_FACTOR_STATIC
rubberband -= overshoot
}
- child.actualHeight = (child.collapsedHeight + rubberband).toInt()
+ child.setFinalActualHeight((child.collapsedHeight + rubberband).toInt())
}
@VisibleForTesting
@@ -927,7 +930,7 @@
anim.duration = animationDuration
anim.addUpdateListener { animation: ValueAnimator ->
// don't use reflection, because the `actualHeight` field may be obfuscated
- child.actualHeight = animation.animatedValue as Int
+ child.setFinalActualHeight(animation.animatedValue as Int)
}
anim.addListener(
object : AnimatorListenerAdapter() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt b/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt
index 85b8bf9..3be7682 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt
@@ -140,8 +140,8 @@
private fun canHandleMotionEvent(): Boolean {
return wakeUpCoordinator.canShowPulsingHuns &&
- !shadeInteractor.isQsExpanded.value &&
- !bouncerShowing
+ !shadeInteractor.isQsExpanded.value &&
+ !bouncerShowing
}
private fun startExpansion(event: MotionEvent): Boolean {
@@ -194,7 +194,7 @@
override fun onTouchEvent(event: MotionEvent): Boolean {
val finishExpanding =
(event.action == MotionEvent.ACTION_CANCEL || event.action == MotionEvent.ACTION_UP) &&
- isExpanding
+ isExpanding
val isDraggingNotificationOrCanBypass =
mStartingChild?.showingPulsing() == true || bypassController.canBypass()
@@ -218,8 +218,8 @@
velocityTracker!!.computeCurrentVelocity(/* units= */ 1000)
val canExpand =
moveDistance > 0 &&
- velocityTracker!!.getYVelocity() > -1000 &&
- statusBarStateController.state != StatusBarState.SHADE
+ velocityTracker!!.getYVelocity() > -1000 &&
+ statusBarStateController.state != StatusBarState.SHADE
if (!falsingManager.isUnlockingDisabled && !isFalseTouch && canExpand) {
finishExpansion()
} else {
@@ -266,11 +266,11 @@
val child = mStartingChild!!
val newHeight =
Math.min((child.collapsedHeight + expansionHeight).toInt(), child.maxContentHeight)
- child.actualHeight = newHeight
+ child.setFinalActualHeight(newHeight)
} else {
wakeUpCoordinator.setNotificationsVisibleForExpansion(
height >
- lockscreenShadeTransitionController.distanceUntilShowingPulsingNotifications,
+ lockscreenShadeTransitionController.distanceUntilShowingPulsingNotifications,
/*animate= */ true,
/*increaseSpeed= */ true,
)
@@ -301,7 +301,7 @@
anim.duration = animationDuration
anim.addUpdateListener { animation: ValueAnimator ->
// don't use reflection, because the `actualHeight` field may be obfuscated
- child.actualHeight = animation.animatedValue as Int
+ child.setFinalActualHeight(animation.animatedValue as Int)
}
anim.addListener(
object : AnimatorListenerAdapter() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/interactor/StatusBarNotificationChipsInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/interactor/StatusBarNotificationChipsInteractor.kt
index d20a2d1..edb4418 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/interactor/StatusBarNotificationChipsInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/interactor/StatusBarNotificationChipsInteractor.kt
@@ -145,7 +145,7 @@
* Emits all notifications that are eligible to show as chips in the status bar. This is
* different from which chips will *actually* show, see [shownNotificationChips] for that.
*/
- private val allNotificationChips: Flow<List<NotificationChipModel>> =
+ val allNotificationChips: Flow<List<NotificationChipModel>> =
if (StatusBarNotifChips.isEnabled) {
// For all our current interactors...
// TODO(b/364653005): When a promoted notification is added or removed, each individual
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 3ecbdf8..994357f 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
@@ -35,6 +35,7 @@
import com.android.systemui.statusbar.notification.headsup.PinnedStatus
import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel
import com.android.systemui.statusbar.phone.ongoingcall.StatusBarChipsModernization
+import com.android.systemui.util.time.SystemClock
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
@@ -51,6 +52,7 @@
@Application private val applicationScope: CoroutineScope,
private val notifChipsInteractor: StatusBarNotificationChipsInteractor,
headsUpNotificationInteractor: HeadsUpNotificationInteractor,
+ private val systemClock: SystemClock,
) {
/**
* A flow modeling the notification chips that should be shown. Emits an empty list if there are
@@ -158,34 +160,46 @@
clickBehavior,
)
}
- when (this.promotedContent.time.mode) {
- PromotedNotificationContentModel.When.Mode.BasicTime -> {
- return OngoingActivityChipModel.Active.ShortTimeDelta(
- this.key,
- icon,
- colors,
- time = this.promotedContent.time.time,
- onClickListenerLegacy,
- clickBehavior,
- )
+
+ when (this.promotedContent.time) {
+ is PromotedNotificationContentModel.When.Time -> {
+ return if (
+ this.promotedContent.time.currentTimeMillis >=
+ systemClock.currentTimeMillis() + FUTURE_TIME_THRESHOLD_MILLIS
+ ) {
+ OngoingActivityChipModel.Active.ShortTimeDelta(
+ this.key,
+ icon,
+ colors,
+ time = this.promotedContent.time.currentTimeMillis,
+ onClickListenerLegacy,
+ clickBehavior,
+ )
+ } else {
+ // Don't show a `when` time that's close to now or in the past because it's
+ // likely that the app didn't intentionally set the `when` time to be shown in
+ // the status bar chip.
+ // TODO(b/393369213): If a notification sets a `when` time in the future and
+ // then that time comes and goes, the chip *will* start showing times in the
+ // past. Not going to fix this right now because the Compose implementation
+ // automatically handles this for us and we're hoping to launch the notification
+ // chips at the same time as the Compose chips.
+ return OngoingActivityChipModel.Active.IconOnly(
+ this.key,
+ icon,
+ colors,
+ onClickListenerLegacy,
+ clickBehavior,
+ )
+ }
}
- PromotedNotificationContentModel.When.Mode.CountUp -> {
+ is PromotedNotificationContentModel.When.Chronometer -> {
+ // TODO(b/364653005): Check isCountDown and support CountDown.
return OngoingActivityChipModel.Active.Timer(
this.key,
icon,
colors,
- startTimeMs = this.promotedContent.time.time,
- onClickListenerLegacy,
- clickBehavior,
- )
- }
- PromotedNotificationContentModel.When.Mode.CountDown -> {
- // TODO(b/364653005): Support CountDown.
- return OngoingActivityChipModel.Active.Timer(
- this.key,
- icon,
- colors,
- startTimeMs = this.promotedContent.time.time,
+ startTimeMs = this.promotedContent.time.elapsedRealtimeMillis,
onClickListenerLegacy,
clickBehavior,
)
@@ -204,4 +218,12 @@
)
)
}
+
+ companion object {
+ /**
+ * Notifications must have a `when` time of at least 1 minute in the future in order for the
+ * status bar chip to show the time.
+ */
+ private const val FUTURE_TIME_THRESHOLD_MILLIS = 60 * 1000
+ }
}
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 d41353b..20dec11 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
@@ -408,11 +408,13 @@
private fun View.setBackgroundPaddingForEmbeddedPaddingIcon() {
val sidePadding =
if (StatusBarNotifChips.isEnabled) {
- 0
- } else {
context.resources.getDimensionPixelSize(
R.dimen.ongoing_activity_chip_side_padding_for_embedded_padding_icon
)
+ } else {
+ context.resources.getDimensionPixelSize(
+ R.dimen.ongoing_activity_chip_side_padding_for_embedded_padding_icon_legacy
+ )
}
setPaddingRelative(sidePadding, paddingTop, sidePadding, paddingBottom)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChip.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChip.kt
index 4a999d5..efd402e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChip.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChip.kt
@@ -41,7 +41,6 @@
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
-import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import com.android.compose.animation.Expandable
import com.android.compose.modifiers.thenIf
@@ -160,7 +159,10 @@
.padding(
horizontal =
if (hasEmbeddedIcon) {
- 0.dp
+ dimensionResource(
+ R.dimen
+ .ongoing_activity_chip_side_padding_for_embedded_padding_icon
+ )
} else {
dimensionResource(id = R.dimen.ongoing_activity_chip_side_padding)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChips.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChips.kt
index 4017c43..3b8c0f4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChips.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChips.kt
@@ -24,7 +24,8 @@
import androidx.compose.runtime.key
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import androidx.compose.ui.unit.dp
+import androidx.compose.ui.res.dimensionResource
+import com.android.systemui.res.R
import com.android.systemui.statusbar.chips.ui.model.MultipleOngoingActivityChipsModel
import com.android.systemui.statusbar.notification.icon.ui.viewbinder.NotificationIconContainerViewBinder
@@ -35,10 +36,13 @@
modifier: Modifier = Modifier,
) {
Row(
- // TODO(b/372657935): Remove magic numbers for padding and spacing.
- modifier = modifier.fillMaxHeight().padding(horizontal = 6.dp),
+ modifier =
+ modifier
+ .fillMaxHeight()
+ .padding(start = dimensionResource(R.dimen.ongoing_activity_chip_margin_start)),
verticalAlignment = Alignment.CenterVertically,
- horizontalArrangement = Arrangement.spacedBy(8.dp),
+ horizontalArrangement =
+ Arrangement.spacedBy(dimensionResource(R.dimen.ongoing_activity_chip_margin_start)),
) {
chips.active
.filter { !it.isHidden }
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 6cb8a53..cf0342b 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
@@ -128,7 +128,10 @@
override val key: String,
override val icon: ChipIcon,
override val colors: ColorsModel,
- /** The time of the event that this chip represents. */
+ /**
+ * The time of the event that this chip represents, relative to
+ * [com.android.systemui.util.time.SystemClock.currentTimeMillis].
+ */
val time: Long,
override val onClickListenerLegacy: View.OnClickListener?,
override val clickBehavior: ClickBehavior,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiIcons.java
index dbcda41..cfc0055 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiIcons.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiIcons.java
@@ -32,12 +32,16 @@
*/
private static int[] getIconsBasedOnFlag() {
if (newStatusBarIcons()) {
+ // TODO(b/396664075):
+ // The new wifi icons only define a range of [0, 3]. Since this array is indexed on
+ // level, we can simulate the range squash by mapping both level 3 to drawn-level 2, and
+ // level 4 to drawn-level 3
return new int[] {
R.drawable.ic_wifi_0,
R.drawable.ic_wifi_1,
R.drawable.ic_wifi_2,
- R.drawable.ic_wifi_3,
- R.drawable.ic_wifi_4
+ R.drawable.ic_wifi_2,
+ R.drawable.ic_wifi_3
};
} else {
return new int[] {
@@ -54,12 +58,13 @@
private static int [] getErrorIconsBasedOnFlag() {
if (newStatusBarIcons()) {
+ // See above note, new wifi icons only have 3 bars, so levels 2 and 3 are the same
return new int[] {
R.drawable.ic_wifi_0_error,
R.drawable.ic_wifi_1_error,
R.drawable.ic_wifi_2_error,
+ R.drawable.ic_wifi_2_error,
R.drawable.ic_wifi_3_error,
- R.drawable.ic_wifi_4_error
};
} else {
return new int[] {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/media/MediaControlChipStartable.kt b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/media/MediaControlChipStartable.kt
new file mode 100644
index 0000000..e7bc052
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/media/MediaControlChipStartable.kt
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2025 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.featurepods.media
+
+import com.android.systemui.CoreStartable
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.statusbar.featurepods.media.domain.interactor.MediaControlChipInteractor
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
+
+/**
+ * A [CoreStartable] that initializes and starts the media control chip functionality. The media
+ * chip is limited to large screen devices currently. Therefore, this [CoreStartable] should not be
+ * used for phones or smaller form factor devices.
+ */
+@SysUISingleton
+class MediaControlChipStartable
+@Inject
+constructor(
+ @Background val bgScope: CoroutineScope,
+ private val mediaControlChipInteractor: MediaControlChipInteractor,
+) : CoreStartable {
+
+ override fun start() {
+ bgScope.launch { mediaControlChipInteractor.initialize() }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/media/domain/interactor/MediaControlChipInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/media/domain/interactor/MediaControlChipInteractor.kt
index e3e77e1..f439bb2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/media/domain/interactor/MediaControlChipInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/media/domain/interactor/MediaControlChipInteractor.kt
@@ -22,13 +22,15 @@
import com.android.systemui.media.controls.shared.model.MediaCommonModel
import com.android.systemui.media.controls.shared.model.MediaData
import com.android.systemui.res.R
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.statusbar.featurepods.media.shared.model.MediaControlChipModel
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
-import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
/**
@@ -37,6 +39,8 @@
* Provides a [StateFlow] of [MediaControlChipModel] representing the current state of the media
* control chip. Emits a new [MediaControlChipModel] when there is an active media session and the
* corresponding user preference is found, otherwise emits null.
+ *
+ * This functionality is only enabled on large screen devices.
*/
@SysUISingleton
class MediaControlChipInteractor
@@ -45,30 +49,57 @@
@Background private val backgroundScope: CoroutineScope,
mediaFilterRepository: MediaFilterRepository,
) {
- private val currentMediaControls: StateFlow<List<MediaCommonModel.MediaControl>> =
- mediaFilterRepository.currentMedia
- .map { mediaList -> mediaList.filterIsInstance<MediaCommonModel.MediaControl>() }
- .stateIn(
- scope = backgroundScope,
- started = SharingStarted.WhileSubscribed(),
- initialValue = emptyList(),
- )
+ private val isEnabled = MutableStateFlow(false)
+
+ private val mediaControlChipModelForScene: Flow<MediaControlChipModel?> =
+ combine(mediaFilterRepository.currentMedia, mediaFilterRepository.selectedUserEntries) {
+ mediaList,
+ userEntries ->
+ mediaList
+ .filterIsInstance<MediaCommonModel.MediaControl>()
+ .mapNotNull { userEntries[it.mediaLoadedModel.instanceId] }
+ .firstOrNull { it.active }
+ ?.toMediaControlChipModel()
+ }
+
+ /**
+ * A flow of [MediaControlChipModel] representing the current state of the media controls chip.
+ * This flow emits null when no active media is playing or when playback information is
+ * unavailable. This flow is only active when [SceneContainerFlag] is disabled.
+ */
+ private val mediaControlChipModelLegacy = MutableStateFlow<MediaControlChipModel?>(null)
+
+ fun updateMediaControlChipModelLegacy(mediaData: MediaData?) {
+ if (!SceneContainerFlag.isEnabled) {
+ mediaControlChipModelLegacy.value = mediaData?.toMediaControlChipModel()
+ }
+ }
+
+ private val _mediaControlChipModel: Flow<MediaControlChipModel?> =
+ if (SceneContainerFlag.isEnabled) {
+ mediaControlChipModelForScene
+ } else {
+ mediaControlChipModelLegacy
+ }
/** The currently active [MediaControlChipModel] */
- val mediaControlModel: StateFlow<MediaControlChipModel?> =
- combine(currentMediaControls, mediaFilterRepository.selectedUserEntries) {
- mediaControls,
- userEntries ->
- mediaControls
- .mapNotNull { userEntries[it.mediaLoadedModel.instanceId] }
- .firstOrNull { it.active }
- ?.toMediaControlChipModel()
+ val mediaControlChipModel: StateFlow<MediaControlChipModel?> =
+ combine(_mediaControlChipModel, isEnabled) { mediaControlChipModel, isEnabled ->
+ if (isEnabled) {
+ mediaControlChipModel
+ } else {
+ null
+ }
}
- .stateIn(
- scope = backgroundScope,
- started = SharingStarted.WhileSubscribed(),
- initialValue = null,
- )
+ .stateIn(backgroundScope, SharingStarted.WhileSubscribed(), null)
+
+ /**
+ * The media control chip may not be enabled on all form factors, so only the relevant form
+ * factors should initialize the interactor. This must be called from a CoreStartable.
+ */
+ fun initialize() {
+ isEnabled.value = true
+ }
}
private fun MediaData.toMediaControlChipModel(): MediaControlChipModel {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/media/ui/viewmodel/MediaControlChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/media/ui/viewmodel/MediaControlChipViewModel.kt
index 19acb2e..90f97df 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/media/ui/viewmodel/MediaControlChipViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/media/ui/viewmodel/MediaControlChipViewModel.kt
@@ -55,8 +55,8 @@
* whenever the underlying [MediaControlChipModel] changes.
*/
override val chip: StateFlow<PopupChipModel> =
- mediaControlChipInteractor.mediaControlModel
- .map { mediaControlModel -> toPopupChipModel(mediaControlModel) }
+ mediaControlChipInteractor.mediaControlChipModel
+ .map { mediaControlChipModel -> toPopupChipModel(mediaControlChipModel) }
.stateIn(
backgroundScope,
SharingStarted.WhileSubscribed(),
@@ -82,10 +82,6 @@
chipId = PopupChipId.MediaControl,
icon = defaultIcon,
chipText = model.songName.toString(),
- isToggled = false,
- // TODO(b/385202114): Show a popup containing the media carousal when the chip is
- // toggled.
- onToggle = {},
hoverBehavior = createHoverBehavior(model),
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/shared/model/PopupChipModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/shared/model/PopupChipModel.kt
index 683b9716..6061553 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/shared/model/PopupChipModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/shared/model/PopupChipModel.kt
@@ -53,10 +53,11 @@
/** Default icon displayed on the chip */
val icon: Icon,
val chipText: String,
- val isToggled: Boolean = false,
- val onToggle: () -> Unit,
+ val isPopupShown: Boolean = false,
+ val showPopup: () -> Unit = {},
+ val hidePopup: () -> Unit = {},
val hoverBehavior: HoverBehavior = HoverBehavior.None,
) : PopupChipModel() {
- override val logName = "Shown(id=$chipId, toggled=$isToggled)"
+ override val logName = "Shown(id=$chipId, toggled=$isPopupShown)"
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/ui/compose/StatusBarPopup.kt b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/ui/compose/StatusBarPopup.kt
new file mode 100644
index 0000000..8a66904
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/ui/compose/StatusBarPopup.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.statusbar.featurepods.popups.ui.compose
+
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.wrapContentSize
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.res.dimensionResource
+import androidx.compose.ui.unit.Density
+import androidx.compose.ui.unit.IntOffset
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.window.Popup
+import androidx.compose.ui.window.PopupProperties
+import com.android.systemui.res.R
+import com.android.systemui.statusbar.featurepods.popups.shared.model.PopupChipId
+import com.android.systemui.statusbar.featurepods.popups.shared.model.PopupChipModel
+
+/**
+ * Displays a popup in the status bar area. The offset is calculated to draw the popup below the
+ * status bar.
+ */
+@Composable
+fun StatusBarPopup(viewModel: PopupChipModel.Shown) {
+ val density = Density(LocalContext.current)
+ Popup(
+ properties =
+ PopupProperties(
+ focusable = false,
+ dismissOnBackPress = true,
+ dismissOnClickOutside = true,
+ ),
+ offset =
+ IntOffset(
+ x = 0,
+ y = with(density) { dimensionResource(R.dimen.status_bar_height).roundToPx() },
+ ),
+ onDismissRequest = { viewModel.hidePopup() },
+ ) {
+ Box(modifier = Modifier.padding(8.dp).wrapContentSize()) {
+ when (viewModel.chipId) {
+ is PopupChipId.MediaControl -> {
+ // TODO(b/385202114): Populate MediaControlPopup contents.
+ }
+ }
+ // Future popup types will be handled here.
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/ui/compose/StatusBarPopupChip.kt b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/ui/compose/StatusBarPopupChip.kt
index 34bef9d..eb85d2f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/ui/compose/StatusBarPopupChip.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/ui/compose/StatusBarPopupChip.kt
@@ -52,14 +52,14 @@
* the chip can show text containing contextual information.
*/
@Composable
-fun StatusBarPopupChip(model: PopupChipModel.Shown, modifier: Modifier = Modifier) {
- val hasHoverBehavior = model.hoverBehavior !is HoverBehavior.None
+fun StatusBarPopupChip(viewModel: PopupChipModel.Shown, modifier: Modifier = Modifier) {
+ val hasHoverBehavior = viewModel.hoverBehavior !is HoverBehavior.None
val hoverInteractionSource = remember { MutableInteractionSource() }
val isHovered by hoverInteractionSource.collectIsHoveredAsState()
- val isToggled = model.isToggled
+ val isPopupShown = viewModel.isPopupShown
val chipBackgroundColor =
- if (isToggled) {
+ if (isPopupShown) {
MaterialTheme.colorScheme.primaryContainer
} else {
MaterialTheme.colorScheme.surfaceContainerHighest
@@ -72,7 +72,7 @@
.padding(vertical = 4.dp)
.animateContentSize()
.thenIf(hasHoverBehavior) { Modifier.hoverable(hoverInteractionSource) }
- .clickable { model.onToggle() },
+ .thenIf(!isPopupShown) { Modifier.clickable { viewModel.showPopup() } },
color = chipBackgroundColor,
) {
Row(
@@ -82,14 +82,14 @@
) {
val iconColor =
if (isHovered) chipBackgroundColor else contentColorFor(chipBackgroundColor)
- val hoverBehavior = model.hoverBehavior
+ val hoverBehavior = viewModel.hoverBehavior
val iconBackgroundColor = contentColorFor(chipBackgroundColor)
val iconInteractionSource = remember { MutableInteractionSource() }
Icon(
icon =
when {
isHovered && hoverBehavior is HoverBehavior.Button -> hoverBehavior.icon
- else -> model.icon
+ else -> viewModel.icon
},
modifier =
Modifier.thenIf(isHovered) {
@@ -109,7 +109,7 @@
)
Text(
- text = model.chipText,
+ text = viewModel.chipText,
style = MaterialTheme.typography.labelLarge,
softWrap = false,
overflow = TextOverflow.Ellipsis,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/ui/compose/StatusBarPopupChipsContainer.kt b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/ui/compose/StatusBarPopupChipsContainer.kt
index d35674d..16538c9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/ui/compose/StatusBarPopupChipsContainer.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/ui/compose/StatusBarPopupChipsContainer.kt
@@ -31,10 +31,15 @@
// TODO(b/385353140): Add padding and spacing for this container according to UX specs.
Box {
Row(
- modifier = Modifier.padding(horizontal = 8.dp),
+ modifier = modifier.padding(horizontal = 8.dp),
verticalAlignment = Alignment.CenterVertically,
) {
- chips.forEach { chip -> StatusBarPopupChip(chip) }
+ chips.forEach { chip ->
+ StatusBarPopupChip(chip)
+ if (chip.isPopupShown) {
+ StatusBarPopup(chip)
+ }
+ }
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/ui/viewmodel/StatusBarPopupChipsViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/ui/viewmodel/StatusBarPopupChipsViewModel.kt
index caa8e6c..33bf90d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/ui/viewmodel/StatusBarPopupChipsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/ui/viewmodel/StatusBarPopupChipsViewModel.kt
@@ -16,49 +16,65 @@
package com.android.systemui.statusbar.featurepods.popups.ui.viewmodel
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Background
+import androidx.compose.runtime.derivedStateOf
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.setValue
+import com.android.systemui.lifecycle.ExclusiveActivatable
+import com.android.systemui.lifecycle.Hydrator
import com.android.systemui.statusbar.featurepods.media.ui.viewmodel.MediaControlChipViewModel
import com.android.systemui.statusbar.featurepods.popups.StatusBarPopupChips
import com.android.systemui.statusbar.featurepods.popups.shared.model.PopupChipId
import com.android.systemui.statusbar.featurepods.popups.shared.model.PopupChipModel
-import javax.inject.Inject
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.asStateFlow
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.stateIn
/**
* View model deciding which system process chips to show in the status bar. Emits a list of
* PopupChipModels.
*/
-@SysUISingleton
class StatusBarPopupChipsViewModel
-@Inject
-constructor(
- @Background scope: CoroutineScope,
- mediaControlChipViewModel: MediaControlChipViewModel,
-) {
+@AssistedInject
+constructor(mediaControlChip: MediaControlChipViewModel) : ExclusiveActivatable() {
+ private val hydrator: Hydrator = Hydrator("StatusBarPopupChipsViewModel.hydrator")
+
+ /** The ID of the current chip that is showing its popup, or `null` if no chip is shown. */
+ private var currentShownPopupChipId by mutableStateOf<PopupChipId?>(null)
+
+ private val incomingPopupChipBundle: PopupChipBundle by
+ hydrator.hydratedStateOf(
+ traceName = "incomingPopupChipBundle",
+ initialValue = PopupChipBundle(),
+ source = mediaControlChip.chip.map { chip -> PopupChipBundle(media = chip) },
+ )
+
+ val shownPopupChips: List<PopupChipModel.Shown> by derivedStateOf {
+ if (StatusBarPopupChips.isEnabled) {
+ val bundle = incomingPopupChipBundle
+
+ listOfNotNull(bundle.media).filterIsInstance<PopupChipModel.Shown>().map { chip ->
+ chip.copy(
+ isPopupShown = chip.chipId == currentShownPopupChipId,
+ showPopup = { currentShownPopupChipId = chip.chipId },
+ hidePopup = { currentShownPopupChipId = null },
+ )
+ }
+ } else {
+ emptyList()
+ }
+ }
+
+ override suspend fun onActivated(): Nothing {
+ hydrator.activate()
+ }
+
private data class PopupChipBundle(
val media: PopupChipModel = PopupChipModel.Hidden(chipId = PopupChipId.MediaControl)
)
- private val incomingPopupChipBundle: StateFlow<PopupChipBundle?> =
- mediaControlChipViewModel.chip
- .map { chip -> PopupChipBundle(media = chip) }
- .stateIn(scope, SharingStarted.WhileSubscribed(), PopupChipBundle())
-
- val shownPopupChips: StateFlow<List<PopupChipModel.Shown>> =
- if (StatusBarPopupChips.isEnabled) {
- incomingPopupChipBundle
- .map { bundle ->
- listOfNotNull(bundle?.media).filterIsInstance<PopupChipModel.Shown>()
- }
- .stateIn(scope, SharingStarted.WhileSubscribed(), emptyList())
- } else {
- MutableStateFlow(emptyList<PopupChipModel.Shown>()).asStateFlow()
- }
+ @AssistedFactory
+ interface Factory {
+ fun create(): StatusBarPopupChipsViewModel
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationUtils.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationUtils.java
index eb1be67..c6775d6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationUtils.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationUtils.java
@@ -24,6 +24,7 @@
import com.android.internal.util.ContrastColorUtil;
import com.android.systemui.res.R;
+import com.android.systemui.statusbar.notification.collection.EntryAdapter;
import com.android.systemui.statusbar.notification.collection.ListEntry;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.util.Compile;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/PhysicsPropertyAnimator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/PhysicsPropertyAnimator.kt
new file mode 100644
index 0000000..74faf25
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/PhysicsPropertyAnimator.kt
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+package com.android.systemui.statusbar.notification
+
+import android.util.Property
+import android.view.View
+import androidx.dynamicanimation.animation.DynamicAnimation
+import androidx.dynamicanimation.animation.FloatPropertyCompat
+import androidx.dynamicanimation.animation.SpringAnimation
+import androidx.dynamicanimation.animation.SpringForce
+import com.android.systemui.res.R
+import com.android.systemui.statusbar.notification.PhysicsPropertyAnimator.Companion.createDefaultSpring
+import com.android.systemui.statusbar.notification.stack.AnimationProperties
+
+/**
+ * A physically animatable property of a view.
+ *
+ * @param tag the view tag to safe this property in
+ * @param property the property to animate.
+ */
+data class PhysicsProperty(val tag: Int, val property: Property<View, Float>) {
+ val offsetProperty =
+ object : FloatPropertyCompat<View>(property.name) {
+ override fun getValue(view: View): Float {
+ return property.get(view)
+ }
+
+ override fun setValue(view: View, offset: Float) {
+ val propertyData = view.getTag(tag) as PropertyData? ?: return
+ propertyData.offset = offset
+ property.set(view, propertyData.finalValue + offset)
+ }
+ }
+
+ fun setFinalValue(view: View, finalValue: Float) {
+ val propertyData = obtainPropertyData(view, this)
+ val previousValue = propertyData.finalValue
+ if (previousValue != finalValue) {
+ propertyData.finalValue = finalValue
+ property.set(view, propertyData.finalValue + propertyData.offset)
+ }
+ }
+}
+
+/** The propertyData associated with each animation running */
+data class PropertyData(
+ var finalValue: Float = 0f,
+ var offset: Float = 0f,
+ var animator: SpringAnimation? = null,
+ var delayRunnable: Runnable? = null,
+)
+
+/**
+ * A utility that can run physics based animations in a simple way. It properly handles overlapping
+ * calls where sometimes a property can be set without animation, while also having instances where
+ * it's supposed to start animations.
+ *
+ * This overall helps making sure that physics based animations complete and don't constantly start
+ * new transitions which can lead to a feeling of lagging behind.
+ *
+ * Overall it is achieved by starting offset animations to an end value as soon as an animation is
+ * requested and updating the end value immediately when no animation is needed. With the offset
+ * always going to 0, this ensures that animations complete within a short time after an animation
+ * has been requested.
+ */
+class PhysicsPropertyAnimator {
+ companion object {
+ @JvmField val TAG_ANIMATOR_TRANSLATION_Y = R.id.translation_y_animator_tag
+
+ @JvmField
+ val Y_TRANSLATION: PhysicsProperty =
+ PhysicsProperty(TAG_ANIMATOR_TRANSLATION_Y, View.TRANSLATION_Y)
+
+ // Uses the standard spatial material spring by default
+ @JvmStatic
+ fun createDefaultSpring(): SpringForce {
+ return SpringForce()
+ .setStiffness(380f) // MEDIUM LOW STIFFNESS
+ .setDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY) // LOW BOUNCINESS
+ }
+
+ @JvmStatic
+ @JvmOverloads
+ /**
+ * Set a property on a view, updating its value, even if it's already animating. The @param
+ * animated can be used to request an animation. If the view isn't animated, this utility
+ * will update the current animation if existent, such that the end value will point
+ * to @param newEndValue or apply it directly if there's no animation.
+ */
+ fun setProperty(
+ view: View,
+ animatableProperty: PhysicsProperty,
+ newEndValue: Float,
+ properties: AnimationProperties? = null,
+ animated: Boolean = false,
+ endListener: DynamicAnimation.OnAnimationEndListener? = null,
+ ) {
+ if (animated) {
+ startAnimation(view, animatableProperty, newEndValue, properties, endListener)
+ } else {
+ animatableProperty.setFinalValue(view, newEndValue)
+ }
+ }
+
+ fun isAnimating(view: View, property: PhysicsProperty): Boolean {
+ val (_, _, animator, _) = obtainPropertyData(view, property)
+ return animator?.isRunning ?: false
+ }
+ }
+}
+
+private fun startAnimation(
+ view: View,
+ animatableProperty: PhysicsProperty,
+ newEndValue: Float,
+ properties: AnimationProperties?,
+ endListener: DynamicAnimation.OnAnimationEndListener?,
+) {
+ val property = animatableProperty.property
+ val propertyData = obtainPropertyData(view, animatableProperty)
+ val previousEndValue = propertyData.finalValue
+ if (previousEndValue == newEndValue) {
+ return
+ }
+ propertyData.finalValue = newEndValue
+ var animator = propertyData.animator
+ if (animator == null) {
+ animator = SpringAnimation(view, animatableProperty.offsetProperty)
+ propertyData.animator = animator
+ animator.setSpring(createDefaultSpring())
+ val listener = properties?.getAnimationEndListener(animatableProperty.property)
+ if (listener != null) {
+ animator.addEndListener(listener)
+ // We always notify things as started even if we have a delay
+ properties.getAnimationStartListener(animatableProperty.property)?.accept(animator)
+ }
+ // remove the tag when the animation is finished
+ animator.addEndListener { _, _, _, _ -> propertyData.animator = null }
+ }
+ // TODO(b/393581344): look at custom spring
+ endListener?.let { animator.addEndListener(it) }
+ val newOffset = previousEndValue - newEndValue + propertyData.offset
+
+ // Immedialely set the new offset that compensates for the immediate end value change
+ propertyData.offset = newOffset
+ property.set(view, newEndValue + newOffset)
+
+ // cancel previous starters still pending
+ view.removeCallbacks(propertyData.delayRunnable)
+ animator.setStartValue(newOffset)
+ val startRunnable = Runnable {
+ animator.animateToFinalPosition(0f)
+ propertyData.delayRunnable = null
+ }
+ if (properties != null && properties.delay > 0 && !animator.isRunning) {
+ propertyData.delayRunnable = startRunnable
+ view.postDelayed(propertyData.delayRunnable, properties.delay)
+ } else {
+ startRunnable.run()
+ }
+}
+
+private fun obtainPropertyData(view: View, animatableProperty: PhysicsProperty): PropertyData {
+ var propertyData = view.getTag(animatableProperty.tag) as PropertyData?
+ if (propertyData == null) {
+ propertyData =
+ PropertyData(finalValue = animatableProperty.property.get(view), offset = 0f, null)
+ view.setTag(animatableProperty.tag, propertyData)
+ }
+ return propertyData
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/BundleEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/BundleEntry.java
index 37485fe..0e3f103 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/BundleEntry.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/BundleEntry.java
@@ -16,11 +16,74 @@
package com.android.systemui.statusbar.notification.collection;
+import static android.app.NotificationChannel.NEWS_ID;
+import static android.app.NotificationChannel.PROMOTIONS_ID;
+import static android.app.NotificationChannel.RECS_ID;
+import static android.app.NotificationChannel.SOCIAL_MEDIA_ID;
+
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
+
+import java.util.List;
+
/**
* Abstract class to represent notification section bundled by AI.
*/
public class BundleEntry extends PipelineEntry {
- public class BundleEntryAdapter implements EntryAdapter {
+ private final String mKey;
+ private final BundleEntryAdapter mEntryAdapter;
+
+ // TODO (b/389839319): implement the row
+ private ExpandableNotificationRow mRow;
+
+ public BundleEntry(String key) {
+ mKey = key;
+ mEntryAdapter = new BundleEntryAdapter();
}
+
+ @VisibleForTesting
+ public BundleEntryAdapter getEntryAdapter() {
+ return mEntryAdapter;
+ }
+
+ public class BundleEntryAdapter implements EntryAdapter {
+
+ /**
+ * TODO (b/394483200): convert to PipelineEntry.ROOT_ENTRY when pipeline is migrated?
+ */
+ @Override
+ public GroupEntry getParent() {
+ return GroupEntry.ROOT_ENTRY;
+ }
+
+ @Override
+ public boolean isTopLevelEntry() {
+ return true;
+ }
+
+ @Override
+ public String getKey() {
+ return mKey;
+ }
+
+ @Override
+ public ExpandableNotificationRow getRow() {
+ return mRow;
+ }
+
+ @Nullable
+ @Override
+ public EntryAdapter getGroupRoot() {
+ return this;
+ }
+ }
+
+ public static final List<BundleEntry> ROOT_BUNDLES = List.of(
+ new BundleEntry(PROMOTIONS_ID),
+ new BundleEntry(SOCIAL_MEDIA_ID),
+ new BundleEntry(NEWS_ID),
+ new BundleEntry(RECS_ID));
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/EntryAdapter.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/EntryAdapter.java
index b12b1c5..4df81c9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/EntryAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/EntryAdapter.java
@@ -16,8 +16,52 @@
package com.android.systemui.statusbar.notification.collection;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
+
/**
* Adapter interface for UI to get relevant info.
*/
public interface EntryAdapter {
+
+ /**
+ * Gets the parent of this entry, or null if the entry's view is not attached
+ */
+ @Nullable PipelineEntry getParent();
+
+ /**
+ * Returns whether the entry is attached and appears at the top level of the shade
+ */
+ boolean isTopLevelEntry();
+
+ /**
+ * @return the unique identifier for this entry
+ */
+ @NonNull String getKey();
+
+ /**
+ * Gets the view that this entry is backing.
+ */
+ @NonNull
+ ExpandableNotificationRow getRow();
+
+ /**
+ * Gets the EntryAdapter that is the nearest root of the collection of rows the given entry
+ * belongs to. If the given entry is a BundleEntry or an isolated child of a BundleEntry, the
+ * BundleEntry will be returned. If the given notification is a group summary NotificationEntry,
+ * or a child of a group summary, the summary NotificationEntry will be returned, even if that
+ * summary belongs to a BundleEntry. If the entry is a notification that does not belong to any
+ * group or bundle grouping, null will be returned.
+ */
+ @Nullable
+ EntryAdapter getGroupRoot();
+
+ /**
+ * Returns whether the entry is attached to the current shade list
+ */
+ default boolean isAttached() {
+ return getParent() != null;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifInflaterImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifInflaterImpl.java
index fc47dc1..8f3c357 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifInflaterImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifInflaterImpl.java
@@ -24,6 +24,7 @@
import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl;
import com.android.systemui.statusbar.notification.row.NotifInflationErrorManager;
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder;
+import com.android.systemui.statusbar.notification.shared.NotificationBundleUi;
import javax.inject.Inject;
@@ -78,7 +79,7 @@
requireBinder().inflateViews(
entry,
params,
- wrapInflationCallback(callback));
+ wrapInflationCallback(entry, callback));
} catch (InflationException e) {
mLogger.logInflationException(entry, e);
mNotifErrorManager.setInflationError(entry, e);
@@ -101,17 +102,26 @@
}
private NotificationRowContentBinder.InflationCallback wrapInflationCallback(
+ final NotificationEntry entry,
InflationCallback callback) {
return new NotificationRowContentBinder.InflationCallback() {
@Override
public void handleInflationException(
NotificationEntry entry,
Exception e) {
+ if (NotificationBundleUi.isEnabled()) {
+ handleInflationException(e);
+ } else {
+ mNotifErrorManager.setInflationError(entry, e);
+ }
+ }
+ @Override
+ public void handleInflationException(Exception e) {
mNotifErrorManager.setInflationError(entry, e);
}
@Override
- public void onAsyncInflationFinished(NotificationEntry entry) {
+ public void onAsyncInflationFinished() {
mNotifErrorManager.clearInflationError(entry);
if (callback != null) {
callback.onInflationFinished(entry, entry.getRowController());
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
index 7dd82a6..90f9525 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
@@ -29,6 +29,8 @@
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK;
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_STATUS_BAR;
+import static com.android.systemui.statusbar.notification.collection.BundleEntry.ROOT_BUNDLES;
+import static com.android.systemui.statusbar.notification.collection.GroupEntry.ROOT_ENTRY;
import static com.android.systemui.statusbar.notification.collection.NotifCollection.REASON_NOT_CANCELED;
import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_ALERTING;
@@ -107,6 +109,7 @@
private final String mKey;
private StatusBarNotification mSbn;
private Ranking mRanking;
+ private final NotifEntryAdapter mEntryAdapter;
/*
* Bookkeeping members
@@ -268,9 +271,48 @@
mKey = sbn.getKey();
setSbn(sbn);
setRanking(ranking);
+ mEntryAdapter = new NotifEntryAdapter();
}
public class NotifEntryAdapter implements EntryAdapter {
+ @Override
+ public PipelineEntry getParent() {
+ return NotificationEntry.this.getParent();
+ }
+
+ @Override
+ public boolean isTopLevelEntry() {
+ return getParent() != null
+ && (getParent() == ROOT_ENTRY || ROOT_BUNDLES.contains(getParent()));
+ }
+
+ @Override
+ public String getKey() {
+ return NotificationEntry.this.getKey();
+ }
+
+ @Override
+ public ExpandableNotificationRow getRow() {
+ return NotificationEntry.this.getRow();
+ }
+
+ @Nullable
+ @Override
+ public EntryAdapter getGroupRoot() {
+ // TODO (b/395857098): for backwards compatibility this will return null if called
+ // on a group summary that's not in a bundles, but it should return itself.
+ if (isTopLevelEntry() || getParent() == null) {
+ return null;
+ }
+ if (NotificationEntry.this.getParent().getSummary() != null) {
+ return NotificationEntry.this.getParent().getSummary().mEntryAdapter;
+ }
+ return null;
+ }
+ }
+
+ public EntryAdapter getEntryAdapter() {
+ return mEntryAdapter;
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/PipelineEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/PipelineEntry.java
index efedfef..c5a4791 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/PipelineEntry.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/PipelineEntry.java
@@ -19,5 +19,5 @@
/**
* Class to represent a notification, group, or bundle in the pipeline.
*/
-public class PipelineEntry {
+public abstract class PipelineEntry {
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinator.java
index 733b986..9df4bf4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinator.java
@@ -23,6 +23,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import com.android.systemui.dagger.qualifiers.Application;
import com.android.systemui.statusbar.notification.collection.ListEntry;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -31,29 +32,50 @@
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner;
import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUi;
+import com.android.systemui.statusbar.notification.promoted.domain.interactor.PromotedNotificationsInteractor;
import com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt;
+import com.android.systemui.util.kotlin.JavaAdapterKt;
-import com.google.common.primitives.Booleans;
+import kotlinx.coroutines.CoroutineScope;
+
+import java.util.Collections;
+import java.util.List;
import javax.inject.Inject;
/**
* Handles sectioning for foreground service notifications.
- * Puts non-min colorized foreground service notifications into the FGS section. See
- * {@link NotifCoordinators} for section ordering priority.
+ * Puts non-min colorized foreground service notifications into the FGS section. See
+ * {@link NotifCoordinators} for section ordering priority.
*/
@CoordinatorScope
public class ColorizedFgsCoordinator implements Coordinator {
private static final String TAG = "ColorizedCoordinator";
+ private final PromotedNotificationsInteractor mPromotedNotificationsInteractor;
+ private final CoroutineScope mMainScope;
+
+ private List<String> mOrderedPromotedNotifKeys = Collections.emptyList();
@Inject
- public ColorizedFgsCoordinator() {
+ public ColorizedFgsCoordinator(
+ @Application CoroutineScope mainScope,
+ PromotedNotificationsInteractor promotedNotificationsInteractor
+ ) {
+ mPromotedNotificationsInteractor = promotedNotificationsInteractor;
+ mMainScope = mainScope;
}
@Override
- public void attach(NotifPipeline pipeline) {
+ public void attach(@NonNull NotifPipeline pipeline) {
if (PromotedNotificationUi.isEnabled()) {
pipeline.addPromoter(mPromotedOngoingPromoter);
+
+ JavaAdapterKt.collectFlow(mMainScope,
+ mPromotedNotificationsInteractor.getOrderedChipNotificationKeys(),
+ (List<String> keys) -> {
+ mOrderedPromotedNotifKeys = keys;
+ mNotifSectioner.invalidateList("updated mOrderedPromotedNotifKeys");
+ });
}
}
@@ -82,12 +104,24 @@
return false;
}
- private NotifComparator mPreferPromoted = new NotifComparator("PreferPromoted") {
+ /** get the sort key for any entry in the ongoing section */
+ private int getSortKey(@Nullable NotificationEntry entry) {
+ if (entry == null) return Integer.MAX_VALUE;
+ // Order all promoted notif keys first, using their order in the list
+ final int index = mOrderedPromotedNotifKeys.indexOf(entry.getKey());
+ if (index >= 0) return index;
+ // Next, prioritize promoted ongoing over other notifications
+ return isPromotedOngoing(entry) ? Integer.MAX_VALUE - 1 : Integer.MAX_VALUE;
+ }
+
+ private final NotifComparator mOngoingComparator = new NotifComparator(
+ "OngoingComparator") {
@Override
public int compare(@NonNull ListEntry o1, @NonNull ListEntry o2) {
- return -1 * Booleans.compare(
- isPromotedOngoing(o1.getRepresentativeEntry()),
- isPromotedOngoing(o2.getRepresentativeEntry()));
+ return Integer.compare(
+ getSortKey(o1.getRepresentativeEntry()),
+ getSortKey(o2.getRepresentativeEntry())
+ );
}
};
@@ -95,7 +129,7 @@
@Override
public NotifComparator getComparator() {
if (PromotedNotificationUi.isEnabled()) {
- return mPreferPromoted;
+ return mOngoingComparator;
} else {
return null;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/HighPriorityProvider.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/HighPriorityProvider.java
index d47fe20..2e3ab92 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/HighPriorityProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/HighPriorityProvider.java
@@ -27,6 +27,7 @@
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
+import com.android.systemui.statusbar.notification.shared.NotificationBundleUi;
import java.util.List;
@@ -129,21 +130,42 @@
>= NotificationManager.IMPORTANCE_DEFAULT);
}
+ /**
+ * Returns whether the given ListEntry has a high priority child or is in a group with a child
+ * that's high priority
+ */
private boolean hasHighPriorityChild(ListEntry entry, boolean allowImplicit) {
- if (entry instanceof NotificationEntry
- && !mGroupMembershipManager.isGroupSummary((NotificationEntry) entry)) {
- return false;
- }
-
- List<NotificationEntry> children = mGroupMembershipManager.getChildren(entry);
- if (children != null) {
- for (NotificationEntry child : children) {
- if (child != entry && isHighPriority(child, allowImplicit)) {
- return true;
+ if (NotificationBundleUi.isEnabled()) {
+ GroupEntry representativeGroupEntry = null;
+ if (entry instanceof GroupEntry) {
+ representativeGroupEntry = (GroupEntry) entry;
+ } else if (entry instanceof NotificationEntry){
+ final NotificationEntry notificationEntry = entry.getRepresentativeEntry();
+ if (notificationEntry.getParent() != null
+ && notificationEntry.getParent().getSummary() != null
+ && notificationEntry.getParent().getSummary() == notificationEntry) {
+ representativeGroupEntry = notificationEntry.getParent();
}
}
+ return representativeGroupEntry != null &&
+ representativeGroupEntry.getChildren().stream().anyMatch(
+ childEntry -> isHighPriority(childEntry, allowImplicit));
+
+ } else {
+ if (entry instanceof NotificationEntry
+ && !mGroupMembershipManager.isGroupSummary((NotificationEntry) entry)) {
+ return false;
+ }
+ List<NotificationEntry> children = mGroupMembershipManager.getChildren(entry);
+ if (children != null) {
+ for (NotificationEntry child : children) {
+ if (child != entry && isHighPriority(child, allowImplicit)) {
+ return true;
+ }
+ }
+ }
+ return false;
}
- return false;
}
private boolean hasHighPriorityCharacteristics(NotificationEntry entry) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManager.java
index 30386ab..ea36946 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManager.java
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.notification.collection.render;
+import com.android.systemui.statusbar.notification.collection.EntryAdapter;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -38,6 +39,20 @@
boolean isGroupExpanded(NotificationEntry entry);
/**
+ * Whether the parent associated with this notification is expanded.
+ * If this notification is not part of a group or bundle, it will always return false.
+ */
+ boolean isGroupExpanded(EntryAdapter entry);
+
+ /**
+ * Set whether the group/bundle associated with this notification is expanded or not.
+ */
+ void setGroupExpanded(EntryAdapter entry, boolean expanded);
+
+ /** @return group/bundle expansion state after toggling. */
+ boolean toggleGroupExpansion(EntryAdapter entry);
+
+ /**
* Set whether the group associated with this notification is expanded or not.
*/
void setGroupExpanded(NotificationEntry entry, boolean expanded);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerImpl.java
index d1aff80..16b98e2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerImpl.java
@@ -23,11 +23,13 @@
import com.android.systemui.Dumpable;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dump.DumpManager;
+import com.android.systemui.statusbar.notification.collection.EntryAdapter;
import com.android.systemui.statusbar.notification.collection.GroupEntry;
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.listbuilder.OnBeforeRenderListListener;
+import com.android.systemui.statusbar.notification.shared.NotificationBundleUi;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -55,6 +57,8 @@
*/
private final Set<NotificationEntry> mExpandedGroups = new HashSet<>();
+ private final Set<EntryAdapter> mExpandedCollections = new HashSet<>();
+
@Inject
public GroupExpansionManagerImpl(DumpManager dumpManager,
GroupMembershipManager groupMembershipManager) {
@@ -63,11 +67,17 @@
}
/**
- * Cleanup entries from mExpandedGroups that no longer exist in the pipeline.
+ * Cleanup entries from internal tracking that no longer exist in the pipeline.
*/
private final OnBeforeRenderListListener mNotifTracker = (entries) -> {
- if (mExpandedGroups.isEmpty()) {
- return; // nothing to do
+ if (NotificationBundleUi.isEnabled()) {
+ if (mExpandedCollections.isEmpty()) {
+ return; // nothing to do
+ }
+ } else {
+ if (mExpandedGroups.isEmpty()) {
+ return; // nothing to do
+ }
}
final Set<NotificationEntry> renderingSummaries = new HashSet<>();
@@ -77,10 +87,25 @@
}
}
- // If a group is in mExpandedGroups but not in the pipeline entries, collapse it.
- final var groupsToRemove = setDifference(mExpandedGroups, renderingSummaries);
- for (NotificationEntry entry : groupsToRemove) {
- setGroupExpanded(entry, false);
+ if (NotificationBundleUi.isEnabled()) {
+ for (EntryAdapter entryAdapter : mExpandedCollections) {
+ boolean isInPipeline = false;
+ for (NotificationEntry entry : renderingSummaries) {
+ if (entry.getKey().equals(entryAdapter.getKey())) {
+ isInPipeline = true;
+ break;
+ }
+ }
+ if (!isInPipeline) {
+ setGroupExpanded(entryAdapter, false);
+ }
+ }
+ } else {
+ // If a group is in mExpandedGroups but not in the pipeline entries, collapse it.
+ final var groupsToRemove = setDifference(mExpandedGroups, renderingSummaries);
+ for (NotificationEntry entry : groupsToRemove) {
+ setGroupExpanded(entry, false);
+ }
}
};
@@ -96,11 +121,13 @@
@Override
public boolean isGroupExpanded(NotificationEntry entry) {
+ NotificationBundleUi.assertInLegacyMode();
return mExpandedGroups.contains(mGroupMembershipManager.getGroupSummary(entry));
}
@Override
public void setGroupExpanded(NotificationEntry entry, boolean expanded) {
+ NotificationBundleUi.assertInLegacyMode();
NotificationEntry groupSummary = mGroupMembershipManager.getGroupSummary(entry);
if (entry.getParent() == null) {
if (expanded) {
@@ -127,14 +154,61 @@
@Override
public boolean toggleGroupExpansion(NotificationEntry entry) {
+ NotificationBundleUi.assertInLegacyMode();
+ setGroupExpanded(entry, !isGroupExpanded(entry));
+ return isGroupExpanded(entry);
+ }
+
+ @Override
+ public boolean isGroupExpanded(EntryAdapter entry) {
+ NotificationBundleUi.assertInNewMode();
+ return mExpandedCollections.contains(mGroupMembershipManager.getGroupRoot(entry));
+ }
+
+ @Override
+ public void setGroupExpanded(EntryAdapter entry, boolean expanded) {
+ NotificationBundleUi.assertInNewMode();
+ EntryAdapter groupParent = mGroupMembershipManager.getGroupRoot(entry);
+ if (!entry.isAttached()) {
+ if (expanded) {
+ Log.wtf(TAG, "Cannot expand group that is not attached");
+ } else {
+ // The entry is no longer attached, but we still want to make sure we don't have
+ // a stale expansion state.
+ groupParent = entry;
+ }
+ }
+
+ boolean changed;
+ if (expanded) {
+ changed = mExpandedCollections.add(groupParent);
+ } else {
+ changed = mExpandedCollections.remove(groupParent);
+ }
+
+ // Only notify listeners if something changed.
+ if (changed) {
+ sendOnGroupExpandedChange(entry, expanded);
+ }
+ }
+
+ @Override
+ public boolean toggleGroupExpansion(EntryAdapter entry) {
+ NotificationBundleUi.assertInNewMode();
setGroupExpanded(entry, !isGroupExpanded(entry));
return isGroupExpanded(entry);
}
@Override
public void collapseGroups() {
- for (NotificationEntry entry : new ArrayList<>(mExpandedGroups)) {
- setGroupExpanded(entry, false);
+ if (NotificationBundleUi.isEnabled()) {
+ for (EntryAdapter entry : new ArrayList<>(mExpandedCollections)) {
+ setGroupExpanded(entry, false);
+ }
+ } else {
+ for (NotificationEntry entry : new ArrayList<>(mExpandedGroups)) {
+ setGroupExpanded(entry, false);
+ }
}
}
@@ -145,9 +219,21 @@
for (NotificationEntry entry : mExpandedGroups) {
pw.println(" * " + entry.getKey());
}
+ pw.println(" mExpandedCollection: " + mExpandedCollections.size());
+ for (EntryAdapter entry : mExpandedCollections) {
+ pw.println(" * " + entry.getKey());
+ }
}
private void sendOnGroupExpandedChange(NotificationEntry entry, boolean expanded) {
+ NotificationBundleUi.assertInLegacyMode();
+ for (OnGroupExpansionChangeListener listener : mOnGroupChangeListeners) {
+ listener.onGroupExpansionChange(entry.getRow(), expanded);
+ }
+ }
+
+ private void sendOnGroupExpandedChange(EntryAdapter entry, boolean expanded) {
+ NotificationBundleUi.assertInNewMode();
for (OnGroupExpansionChangeListener listener : mOnGroupChangeListeners) {
listener.onGroupExpansionChange(entry.getRow(), expanded);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManager.java
index 3158782..69267e5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManager.java
@@ -19,6 +19,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import com.android.systemui.statusbar.notification.collection.EntryAdapter;
import com.android.systemui.statusbar.notification.collection.ListEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -29,6 +30,13 @@
* generally assumes that the notification is attached (aka its parent is not null).
*/
public interface GroupMembershipManager {
+
+ /**
+ * @return whether a given entry is the root (GroupEntry or BundleEntry) in a collection which
+ * has children
+ */
+ boolean isGroupRoot(@NonNull EntryAdapter entry);
+
/**
* @return whether a given notification is the summary in a group which has children
*/
@@ -42,16 +50,15 @@
NotificationEntry getGroupSummary(@NonNull NotificationEntry entry);
/**
- * Similar to {@link #getGroupSummary(NotificationEntry)} but doesn't get the visual summary
- * but the logical summary, i.e when a child is isolated, it still returns the summary as if
- * it wasn't isolated.
- * TODO: remove this when migrating to the new pipeline, this is taken care of in the
- * dismissal logic built into NotifCollection
+ * Gets the EntryAdapter that is the nearest root of the collection of rows the given entry
+ * belongs to. If the given entry is a BundleEntry or an isolated child of a BundleEntry, the
+ * BundleEntry will be returned. If the given notification is a group summary NotificationEntry,
+ * or a child of a group summary, the summary NotificationEntry will be returned, even if that
+ * summary belongs to a BundleEntry. If the entry is a notification that does not belong to any
+ * group or bundle grouping, null will be returned.
*/
@Nullable
- default NotificationEntry getLogicalGroupSummary(@NonNull NotificationEntry entry) {
- return getGroupSummary(entry);
- }
+ EntryAdapter getGroupRoot(@NonNull EntryAdapter entry);
/**
* @return whether a given notification is a child in a group
@@ -59,9 +66,10 @@
boolean isChildInGroup(@NonNull NotificationEntry entry);
/**
- * Whether this is the only child in a group
+ * @return whether a given notification is a child in a group. The group may be a notification
+ * group or a bundle.
*/
- boolean isOnlyChildInGroup(@NonNull NotificationEntry entry);
+ boolean isChildInGroup(@NonNull EntryAdapter entry);
/**
* Get the children that are in the summary's group, not including those isolated.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerImpl.java
index da12479..80a9f8ad 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerImpl.java
@@ -22,9 +22,11 @@
import androidx.annotation.Nullable;
import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.statusbar.notification.collection.EntryAdapter;
import com.android.systemui.statusbar.notification.collection.GroupEntry;
import com.android.systemui.statusbar.notification.collection.ListEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.shared.NotificationBundleUi;
import java.util.List;
@@ -41,6 +43,7 @@
@Override
public boolean isGroupSummary(@NonNull NotificationEntry entry) {
+ NotificationBundleUi.assertInLegacyMode();
if (entry.getParent() == null) {
// The entry is not attached, so it doesn't count.
return false;
@@ -49,33 +52,47 @@
return entry.getParent().getSummary() == entry;
}
+ @Override
+ public boolean isGroupRoot(@NonNull EntryAdapter entry) {
+ NotificationBundleUi.assertInNewMode();
+ return entry == entry.getGroupRoot();
+ }
+
@Nullable
@Override
public NotificationEntry getGroupSummary(@NonNull NotificationEntry entry) {
+ NotificationBundleUi.assertInLegacyMode();
if (isTopLevelEntry(entry) || entry.getParent() == null) {
return null;
}
return entry.getParent().getSummary();
}
+ @Nullable
+ @Override
+ public EntryAdapter getGroupRoot(@NonNull EntryAdapter entry) {
+ NotificationBundleUi.assertInNewMode();
+ return entry.getGroupRoot();
+ }
+
@Override
public boolean isChildInGroup(@NonNull NotificationEntry entry) {
+ NotificationBundleUi.assertInLegacyMode();
// An entry is a child if it's not a summary or top level entry, but it is attached.
return !isGroupSummary(entry) && !isTopLevelEntry(entry) && entry.getParent() != null;
}
@Override
- public boolean isOnlyChildInGroup(@NonNull NotificationEntry entry) {
- if (entry.getParent() == null) {
- return false; // The entry is not attached.
- }
-
- return !isGroupSummary(entry) && entry.getParent().getChildren().size() == 1;
+ public boolean isChildInGroup(@NonNull EntryAdapter entry) {
+ NotificationBundleUi.assertInNewMode();
+ // An entry is a child if it's not a group root or top level entry, but it is attached.
+ return entry.isAttached() && entry != getGroupRoot(entry) && !entry.isTopLevelEntry();
}
@Nullable
@Override
public List<NotificationEntry> getChildren(@NonNull ListEntry entry) {
+ NotificationBundleUi.assertInLegacyMode();
if (entry instanceof GroupEntry) {
return ((GroupEntry) entry).getChildren();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/AvalancheController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/AvalancheController.kt
index ccc2dff..dba8a9a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/AvalancheController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/AvalancheController.kt
@@ -49,7 +49,7 @@
) : Dumpable {
private val tag = "AvalancheController"
- private val debug = Compile.IS_DEBUG && Log.isLoggable(tag, Log.DEBUG)
+ private val debug = false // Compile.IS_DEBUG && Log.isLoggable(tag, Log.DEBUG)
var baseEntryMapStr: () -> String = { "baseEntryMapStr not initialized" }
var enableAtRuntime = true
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImpl.java
index be61dc9..7d74a49 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImpl.java
@@ -46,6 +46,7 @@
import com.android.systemui.shade.domain.interactor.ShadeInteractor;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips;
+import com.android.systemui.statusbar.notification.collection.EntryAdapter;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.coordinator.HeadsUpCoordinator;
import com.android.systemui.statusbar.notification.collection.provider.OnReorderingAllowedListener;
@@ -55,6 +56,7 @@
import com.android.systemui.statusbar.notification.data.repository.HeadsUpRepository;
import com.android.systemui.statusbar.notification.data.repository.HeadsUpRowRepository;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
+import com.android.systemui.statusbar.notification.shared.NotificationBundleUi;
import com.android.systemui.statusbar.notification.shared.NotificationThrottleHun;
import com.android.systemui.statusbar.phone.ExpandHeadsUpOnInlineReply;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
@@ -118,7 +120,8 @@
@VisibleForTesting
final ArrayMap<String, HeadsUpEntry> mHeadsUpEntryMap = new ArrayMap<>();
private final HeadsUpManagerLogger mLogger;
- private final int mMinimumDisplayTime;
+ private final int mMinimumDisplayTimeDefault;
+ private final int mMinimumDisplayTimeForUserInitiated;
private final int mStickyForSomeTimeAutoDismissTime;
private final int mAutoDismissTime;
private final DelayableExecutor mExecutor;
@@ -215,9 +218,11 @@
mGroupMembershipManager = groupMembershipManager;
mVisualStabilityProvider = visualStabilityProvider;
Resources resources = context.getResources();
- mMinimumDisplayTime = NotificationThrottleHun.isEnabled()
+ mMinimumDisplayTimeDefault = NotificationThrottleHun.isEnabled()
? resources.getInteger(R.integer.heads_up_notification_minimum_time_with_throttling)
: resources.getInteger(R.integer.heads_up_notification_minimum_time);
+ mMinimumDisplayTimeForUserInitiated = resources.getInteger(
+ R.integer.heads_up_notification_minimum_time_for_user_initiated);
mStickyForSomeTimeAutoDismissTime = resources.getInteger(
R.integer.sticky_heads_up_notification_time);
mAutoDismissTime = resources.getInteger(R.integer.heads_up_notification_decay);
@@ -871,14 +876,24 @@
if (!hasPinnedHeadsUp() || topEntry == null) {
return null;
} else {
+ ExpandableNotificationRow topRow = topEntry.getRow();
if (topEntry.rowIsChildInGroup()) {
- final NotificationEntry groupSummary =
- mGroupMembershipManager.getGroupSummary(topEntry);
- if (groupSummary != null) {
- topEntry = groupSummary;
+ if (NotificationBundleUi.isEnabled()) {
+ final EntryAdapter adapter = mGroupMembershipManager.getGroupRoot(
+ topRow.getEntryAdapter());
+ if (adapter != null) {
+ topRow = adapter.getRow();
+ }
+ } else {
+ final NotificationEntry groupSummary =
+ mGroupMembershipManager.getGroupSummary(topEntry);
+ if (groupSummary != null) {
+ topEntry = groupSummary;
+ topRow = topEntry.getRow();
+ }
}
}
- ExpandableNotificationRow topRow = topEntry.getRow();
+
int[] tmpArray = new int[2];
topRow.getLocationOnScreen(tmpArray);
int minX = tmpArray[0];
@@ -1358,7 +1373,12 @@
final long now = mSystemClock.elapsedRealtime();
if (updateEarliestRemovalTime) {
- mEarliestRemovalTime = now + mMinimumDisplayTime;
+ if (StatusBarNotifChips.isEnabled()
+ && mPinnedStatus.getValue() == PinnedStatus.PinnedByUser) {
+ mEarliestRemovalTime = now + mMinimumDisplayTimeForUserInitiated;
+ } else {
+ mEarliestRemovalTime = now + mMinimumDisplayTimeDefault;
+ }
}
if (updatePostTime) {
@@ -1377,7 +1397,7 @@
final long now = mSystemClock.elapsedRealtime();
return NotificationThrottleHun.isEnabled()
? Math.max(finishTime, mEarliestRemovalTime) - now
- : Math.max(finishTime - now, mMinimumDisplayTime);
+ : Math.max(finishTime - now, mMinimumDisplayTimeDefault);
};
scheduleAutoRemovalCallback(finishTimeCalculator, "updateEntry (not sticky)");
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpTouchHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpTouchHelper.java
index 3b6b9ed..47e725c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpTouchHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpTouchHelper.java
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.notification.headsup;
+import android.annotation.Nullable;
import android.content.Context;
import android.os.RemoteException;
import android.view.MotionEvent;
@@ -210,10 +211,12 @@
if (mHeadsUpManager.shouldSwallowClick(
mPickedChild.getEntry().getSbn().getKey())) {
endMotion();
+ setTrackingHeadsUp(false);
return true;
}
}
endMotion();
+ setTrackingHeadsUp(false);
return false;
}
return false;
@@ -258,7 +261,7 @@
void setHeadsUpDraggingStartingHeight(int startHeight);
/** Sets notification that is being expanded. */
- void setTrackedHeadsUp(ExpandableNotificationRow expandableNotificationRow);
+ void setTrackedHeadsUp(@Nullable ExpandableNotificationRow expandableNotificationRow);
/** Called when a MotionEvent is about to trigger expansion. */
void startExpand(float newX, float newY, boolean startTracking, float expandedHeight);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleNotificationIdentifier.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleNotificationIdentifier.kt
index 691f1f4..f755dbb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleNotificationIdentifier.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleNotificationIdentifier.kt
@@ -27,6 +27,7 @@
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_IMPORTANT_PERSON
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_NON_PERSON
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_PERSON
+import com.android.systemui.statusbar.notification.shared.NotificationBundleUi
import javax.inject.Inject
import kotlin.math.max
@@ -112,14 +113,26 @@
if (personExtractor.isPersonNotification(sbn)) TYPE_PERSON else TYPE_NON_PERSON
private fun getPeopleTypeOfSummary(entry: NotificationEntry): Int {
- if (!groupManager.isGroupSummary(entry)) {
- return TYPE_NON_PERSON
- }
+ if (NotificationBundleUi.isEnabled) {
+ if (!entry.sbn.notification.isGroupSummary) {
+ return TYPE_NON_PERSON;
+ }
- val childTypes = groupManager.getChildren(entry)
- ?.asSequence()
- ?.map { getPeopleNotificationType(it) }
- ?: return TYPE_NON_PERSON
+ return getPeopleTypeForChildList(entry.parent?.children)
+ } else {
+ if (!groupManager.isGroupSummary(entry)) {
+ return TYPE_NON_PERSON
+ }
+
+ return getPeopleTypeForChildList(groupManager.getChildren(entry))
+ }
+ }
+
+ private fun getPeopleTypeForChildList(children: List<NotificationEntry>?): Int {
+ val childTypes = children
+ ?.asSequence()
+ ?.map { getPeopleNotificationType(it) }
+ ?: return TYPE_NON_PERSON
var groupType = TYPE_NON_PERSON
for (childType in childTypes) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/AODPromotedNotification.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/AODPromotedNotification.kt
index 893570b..9aa5a2e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/AODPromotedNotification.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/AODPromotedNotification.kt
@@ -386,24 +386,21 @@
setTextViewColor(time, SecondaryText)
setTextViewColor(chronometer, SecondaryText)
- val timeValue = content.time
-
- if (timeValue == null) {
- time?.visibility = GONE
- chronometer?.visibility = GONE
- } else if (timeValue.mode == When.Mode.BasicTime) {
- time?.visibility = VISIBLE
- time?.setTime(timeValue.time)
- chronometer?.visibility = GONE
- } else {
- inflateChronometer()
-
- time?.visibility = GONE
- chronometer?.visibility = VISIBLE
- chronometer?.base = timeValue.time
- chronometer?.isCountDown = (timeValue.mode == When.Mode.CountDown)
- chronometer?.setStarted(true)
+ if (content.time is When.Time) {
+ time?.setTime(content.time.currentTimeMillis)
}
+
+ if (content.time is When.Chronometer) {
+ inflateChronometer()
+ chronometer?.base = content.time.elapsedRealtimeMillis
+ chronometer?.isCountDown = content.time.isCountDown
+ chronometer?.setStarted(true)
+ } else {
+ chronometer?.stop()
+ }
+
+ time?.isVisible = (content.time is When.Time)
+ chronometer?.isVisible = (content.time is When.Chronometer)
}
private fun updateSmallIcon(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractor.kt
index 39c7df0..2aafe8c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractor.kt
@@ -48,6 +48,7 @@
import com.android.systemui.statusbar.notification.row.shared.ImageModelProvider.ImageSizeClass.MediumSquare
import com.android.systemui.statusbar.notification.row.shared.ImageModelProvider.ImageSizeClass.SmallSquare
import com.android.systemui.statusbar.notification.row.shared.SkeletonImageTransform
+import com.android.systemui.util.time.SystemClock
import javax.inject.Inject
interface PromotedNotificationContentExtractor {
@@ -64,6 +65,7 @@
constructor(
@ShadeDisplayAware private val context: Context,
private val skeletonImageTransform: SkeletonImageTransform,
+ private val systemClock: SystemClock,
private val logger: PromotedNotificationLogger,
) : PromotedNotificationContentExtractor {
override fun extractContent(
@@ -168,15 +170,17 @@
extras?.getBoolean(EXTRA_PROGRESS_INDETERMINATE)
private fun Notification.extractWhen(): When? {
- val time = `when`
- val showsTime = showsTime()
- val showsChronometer = showsChronometer()
- val countDown = chronometerCountDown()
-
return when {
- showsTime -> When(time, When.Mode.BasicTime)
- showsChronometer ->
- When(time, if (countDown) When.Mode.CountDown else When.Mode.CountUp)
+ showsChronometer() -> {
+ When.Chronometer(
+ elapsedRealtimeMillis =
+ `when` + systemClock.elapsedRealtime() - systemClock.currentTimeMillis(),
+ isCountDown = chronometerCountDown(),
+ )
+ }
+
+ showsTime() -> When.Time(currentTimeMillis = `when`)
+
else -> null
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/AODPromotedNotificationInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/AODPromotedNotificationInteractor.kt
index 393f95d..4bc6854 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/AODPromotedNotificationInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/AODPromotedNotificationInteractor.kt
@@ -18,7 +18,6 @@
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dump.DumpManager
-import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor
import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel
import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel.Style
import com.android.systemui.util.kotlin.FlowDumperImpl
@@ -30,13 +29,12 @@
class AODPromotedNotificationInteractor
@Inject
constructor(
- activeNotificationsInteractor: ActiveNotificationsInteractor,
+ promotedNotificationsInteractor: PromotedNotificationsInteractor,
dumpManager: DumpManager,
) : FlowDumperImpl(dumpManager) {
+ /** The content to show as the promoted notification on AOD */
val content: Flow<PromotedNotificationContentModel?> =
- activeNotificationsInteractor.topLevelRepresentativeNotifications.map { notifs ->
- notifs.firstNotNullOfOrNull { it.promotedContent }
- }
+ promotedNotificationsInteractor.topPromotedNotificationContent
val isPresent: Flow<Boolean> =
content
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PromotedNotificationsInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PromotedNotificationsInteractor.kt
new file mode 100644
index 0000000..1015cfb
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PromotedNotificationsInteractor.kt
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.promoted.domain.interactor
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.statusbar.chips.call.domain.interactor.CallChipInteractor
+import com.android.systemui.statusbar.chips.notification.domain.interactor.StatusBarNotificationChipsInteractor
+import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor
+import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel
+import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallModel
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.flowOn
+import kotlinx.coroutines.flow.map
+
+/**
+ * An interactor that provides details about promoted notification precedence, based on the
+ * presented order of current notification status bar chips.
+ */
+@SysUISingleton
+class PromotedNotificationsInteractor
+@Inject
+constructor(
+ activeNotificationsInteractor: ActiveNotificationsInteractor,
+ callChipInteractor: CallChipInteractor,
+ notifChipsInteractor: StatusBarNotificationChipsInteractor,
+ @Background backgroundDispatcher: CoroutineDispatcher,
+) {
+ /**
+ * This is the ordered list of notifications (and the promoted content) represented as chips in
+ * the status bar.
+ */
+ private val orderedChipNotifications: Flow<List<NotifAndPromotedContent>> =
+ combine(callChipInteractor.ongoingCallState, notifChipsInteractor.allNotificationChips) {
+ callState,
+ notifChips ->
+ buildList {
+ val callData = callState.getNotifData()?.also { add(it) }
+ addAll(
+ notifChips.mapNotNull {
+ when (it.key) {
+ callData?.key -> null // do not re-add the same call
+ else -> NotifAndPromotedContent(it.key, it.promotedContent)
+ }
+ }
+ )
+ }
+ }
+
+ private fun OngoingCallModel.getNotifData(): NotifAndPromotedContent? =
+ when (this) {
+ is OngoingCallModel.InCall -> NotifAndPromotedContent(notificationKey, promotedContent)
+ is OngoingCallModel.InCallWithVisibleApp ->
+ // TODO(b/395989259): support InCallWithVisibleApp when it has notif data
+ null
+ is OngoingCallModel.NoCall -> null
+ }
+
+ /**
+ * The top promoted notification represented by a chip, with the order determined by the order
+ * of the chips, not the notifications.
+ */
+ private val topPromotedChipNotification: Flow<PromotedNotificationContentModel?> =
+ orderedChipNotifications
+ .map { list -> list.firstNotNullOfOrNull { it.promotedContent } }
+ .distinctUntilNewInstance()
+
+ /** This is the top-most promoted notification, which should avoid regular changing. */
+ val topPromotedNotificationContent: Flow<PromotedNotificationContentModel?> =
+ combine(
+ topPromotedChipNotification,
+ activeNotificationsInteractor.topLevelRepresentativeNotifications,
+ ) { topChipNotif, topLevelNotifs ->
+ topChipNotif ?: topLevelNotifs.firstNotNullOfOrNull { it.promotedContent }
+ }
+ // #equals() can be a bit expensive on this object, but this flow will regularly try to
+ // emit the same immutable instance over and over, so just prevent that.
+ .distinctUntilNewInstance()
+
+ /**
+ * This is the ordered list of notifications (and the promoted content) represented as chips in
+ * the status bar. Flows on the background context.
+ */
+ val orderedChipNotificationKeys: Flow<List<String>> =
+ orderedChipNotifications
+ .map { list -> list.map { it.key } }
+ .distinctUntilChanged()
+ .flowOn(backgroundDispatcher)
+
+ /**
+ * Returns flow where all subsequent repetitions of the same object instance are filtered out.
+ */
+ private fun <T> Flow<T>.distinctUntilNewInstance() = distinctUntilChanged { a, b -> a === b }
+
+ /**
+ * A custom pair, but providing clearer semantic names, and implementing equality as being the
+ * same instance of the promoted content model, which allows us to use distinctUntilChanged() on
+ * flows containing this without doing pixel comparisons on the Bitmaps inside Icon objects
+ * provided by the Notification.
+ */
+ private data class NotifAndPromotedContent(
+ val key: String,
+ val promotedContent: PromotedNotificationContentModel?,
+ ) {
+ /**
+ * Define the equals of this object to only check the reference equality of the promoted
+ * content so that we can mark.
+ */
+ override fun equals(other: Any?): Boolean {
+ return when {
+ other == null -> false
+ other === this -> true
+ other !is NotifAndPromotedContent -> return false
+ else -> key == other.key && promotedContent === other.promotedContent
+ }
+ }
+
+ /** Define the hashCode to be very quick, even if it increases collisions. */
+ override fun hashCode(): Int {
+ var result = key.hashCode()
+ result = 31 * result + (promotedContent?.identity?.hashCode() ?: 0)
+ return result
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/shared/model/PromotedNotificationContentModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/shared/model/PromotedNotificationContentModel.kt
index 38d41e3..0c2859f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/shared/model/PromotedNotificationContentModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/shared/model/PromotedNotificationContentModel.kt
@@ -16,7 +16,9 @@
package com.android.systemui.statusbar.notification.promoted.shared.model
+import android.annotation.CurrentTimeMillisLong
import android.annotation.DrawableRes
+import android.annotation.ElapsedRealtimeLong
import android.app.Notification
import android.app.Notification.FLAG_PROMOTED_ONGOING
import androidx.annotation.ColorInt
@@ -120,16 +122,18 @@
data class Identity(val key: String, val style: Style)
/** The timestamp associated with a notification, along with the mode used to display it. */
- data class When(val time: Long, val mode: Mode) {
- /** The mode used to display a notification's `when` value. */
- enum class Mode {
- /** No custom mode requested by the notification. */
- BasicTime,
- /** Show the notification's time as a chronometer that counts down to [time]. */
- CountDown,
- /** Show the notification's time as a chronometer that counts up from [time]. */
- CountUp,
- }
+ sealed class When {
+ /** Show the notification's time as a timestamp. */
+ data class Time(@CurrentTimeMillisLong val currentTimeMillis: Long) : When()
+
+ /**
+ * Show the notification's time as a chronometer that counts up or down (based on
+ * [isCountDown]) to [elapsedRealtimeMillis].
+ */
+ data class Chronometer(
+ @ElapsedRealtimeLong val elapsedRealtimeMillis: Long,
+ val isCountDown: Boolean,
+ ) : When()
}
/** The colors used to display the notification. */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/AsyncRowInflater.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/AsyncRowInflater.kt
new file mode 100644
index 0000000..c3b2411
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/AsyncRowInflater.kt
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2025 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.row
+
+import android.content.Context
+import android.util.Log
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.annotation.LayoutRes
+import androidx.annotation.UiThread
+import com.android.app.tracing.coroutines.launchTraced
+import com.android.app.tracing.coroutines.withContextTraced
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.dagger.qualifiers.NotifInflation
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
+
+@SysUISingleton
+class AsyncRowInflater
+@Inject
+constructor(
+ @Application private val applicationScope: CoroutineScope,
+ @Main private val mainCoroutineDispatcher: CoroutineDispatcher,
+ @NotifInflation private val inflationCoroutineDispatcher: CoroutineDispatcher,
+) {
+ /**
+ * Inflate the layout on the background thread, and invoke the listener on the main thread when
+ * finished.
+ *
+ * If the inflation fails on the background, it will be retried once on the main thread.
+ */
+ @UiThread
+ fun inflate(
+ context: Context,
+ layoutFactory: LayoutInflater.Factory2,
+ @LayoutRes resId: Int,
+ parent: ViewGroup,
+ listener: OnInflateFinishedListener,
+ ): Job {
+ val inflater = BasicRowInflater(context).apply { factory2 = layoutFactory }
+ return applicationScope.launchTraced("AsyncRowInflater-bg", inflationCoroutineDispatcher) {
+ val view =
+ try {
+ inflater.inflate(resId, parent, false)
+ } catch (ex: RuntimeException) {
+ // Probably a Looper failure, retry on the UI thread
+ Log.w(
+ "AsyncRowInflater",
+ "Failed to inflate resource in the background!" +
+ " Retrying on the UI thread",
+ ex,
+ )
+ null
+ }
+ withContextTraced("AsyncRowInflater-ui", mainCoroutineDispatcher) {
+ // If the inflate failed on the inflation thread, try again on the main thread
+ val finalView = view ?: inflater.inflate(resId, parent, false)
+ // Inform the listener of the completion
+ listener.onInflateFinished(finalView, resId, parent)
+ }
+ }
+ }
+
+ /**
+ * Callback interface (identical to the one from AsyncLayoutInflater) for receiving the inflated
+ * view
+ */
+ interface OnInflateFinishedListener {
+ @UiThread fun onInflateFinished(view: View, @LayoutRes resId: Int, parent: ViewGroup?)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/BasicRowInflater.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/BasicRowInflater.kt
new file mode 100644
index 0000000..79d50b8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/BasicRowInflater.kt
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2025 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.row
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.LayoutInflater
+import android.view.View
+
+/**
+ * A [LayoutInflater] that is copy of
+ * [androidx.asynclayoutinflater.view.AsyncLayoutInflater.BasicInflater]
+ */
+internal class BasicRowInflater(context: Context) : LayoutInflater(context) {
+ override fun cloneInContext(newContext: Context): LayoutInflater {
+ return BasicRowInflater(newContext)
+ }
+
+ @Throws(ClassNotFoundException::class)
+ override fun onCreateView(name: String, attrs: AttributeSet): View {
+ for (prefix in sClassPrefixList) {
+ try {
+ val view = createView(name, prefix, attrs)
+ if (view != null) {
+ return view
+ }
+ } catch (e: ClassNotFoundException) {
+ // In this case we want to let the base class take a crack at it.
+ }
+ }
+
+ return super.onCreateView(name, attrs)
+ }
+
+ companion object {
+ private val sClassPrefixList = arrayOf("android.widget.", "android.webkit.", "android.app.")
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index d1d1ea9..66a0fb4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -22,6 +22,7 @@
import static com.android.systemui.Flags.notificationsPinnedHunInShade;
import static com.android.systemui.flags.Flags.ENABLE_NOTIFICATIONS_SIMULATE_SLOW_MEASURE;
+import static com.android.systemui.statusbar.notification.NotificationUtils.logKey;
import static com.android.systemui.statusbar.notification.collection.NotificationEntry.DismissState.PARENT_DISMISSED;
import static com.android.systemui.statusbar.notification.row.NotificationContentView.VISIBLE_TYPE_HEADSUP;
import static com.android.systemui.statusbar.policy.RemoteInputView.FOCUS_ANIMATION_MIN_SCALE;
@@ -105,6 +106,7 @@
import com.android.systemui.statusbar.notification.NotificationTransitionAnimatorController;
import com.android.systemui.statusbar.notification.NotificationUtils;
import com.android.systemui.statusbar.notification.SourceType;
+import com.android.systemui.statusbar.notification.collection.EntryAdapter;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.provider.NotificationDismissibilityProvider;
import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
@@ -120,6 +122,7 @@
import com.android.systemui.statusbar.notification.row.wrapper.NotificationCompactMessagingTemplateViewWrapper;
import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper;
import com.android.systemui.statusbar.notification.shared.NotificationAddXOnHoverToDismiss;
+import com.android.systemui.statusbar.notification.shared.NotificationBundleUi;
import com.android.systemui.statusbar.notification.shared.NotificationContentAlphaOptimization;
import com.android.systemui.statusbar.notification.shared.TransparentHeaderFix;
import com.android.systemui.statusbar.notification.stack.AmbientState;
@@ -268,6 +271,7 @@
private String mLoggingKey;
private NotificationGuts mGuts;
private NotificationEntry mEntry;
+ private EntryAdapter mEntryAdapter;
private String mAppName;
private NotificationRebindingTracker mRebindingTracker;
private FalsingManager mFalsingManager;
@@ -390,11 +394,17 @@
}
private void toggleExpansionState(View v, boolean shouldLogExpandClickMetric) {
- if (!shouldShowPublic() && (!mIsMinimized || isExpanded())
- && mGroupMembershipManager.isGroupSummary(mEntry)) {
+ boolean isGroupRoot = NotificationBundleUi.isEnabled()
+ ? mGroupMembershipManager.isGroupRoot(mEntryAdapter)
+ : mGroupMembershipManager.isGroupSummary(mEntry);
+ if (!shouldShowPublic() && (!mIsMinimized || isExpanded()) && isGroupRoot) {
mGroupExpansionChanging = true;
- final boolean wasExpanded = mGroupExpansionManager.isGroupExpanded(mEntry);
- boolean nowExpanded = mGroupExpansionManager.toggleGroupExpansion(mEntry);
+ final boolean wasExpanded = NotificationBundleUi.isEnabled()
+ ? mGroupExpansionManager.isGroupExpanded(mEntryAdapter)
+ : mGroupExpansionManager.isGroupExpanded(mEntry);
+ boolean nowExpanded = NotificationBundleUi.isEnabled()
+ ? mGroupExpansionManager.toggleGroupExpansion(mEntryAdapter)
+ : mGroupExpansionManager.toggleGroupExpansion(mEntry);
mOnExpandClickListener.onExpandClicked(mEntry, v, nowExpanded);
if (shouldLogExpandClickMetric) {
mMetricsLogger.action(MetricsEvent.ACTION_NOTIFICATION_GROUP_EXPANDER, nowExpanded);
@@ -516,6 +526,10 @@
return mPublicLayout;
}
+ public String getLoggingKey() {
+ return mLoggingKey;
+ }
+
/**
* Sets animations running in the layouts of this row, including public, private, and children.
*
@@ -910,6 +924,12 @@
return mEntry;
}
+ @Nullable
+ public EntryAdapter getEntryAdapter() {
+ NotificationBundleUi.assertInNewMode();
+ return mEntryAdapter;
+ }
+
@Override
public boolean isHeadsUp() {
return mIsHeadsUp;
@@ -1902,15 +1922,15 @@
* Called when a notification which was previously kept in its parent for the
* dismiss animation is finally detached from its parent.
*/
- void logKeepInParentChildDetached(NotificationEntry child, NotificationEntry oldParent);
+ void logKeepInParentChildDetached(String child, String oldParent);
/**
* Called when we want to attach a notification to a new parent,
* but it still has the keepInParent flag set, so we skip it.
*/
void logSkipAttachingKeepInParentChild(
- NotificationEntry child,
- NotificationEntry newParent
+ String child,
+ String newParent
);
/**
@@ -1918,8 +1938,8 @@
* NotificationChildrenContainer
*/
void logRemoveTransientFromContainer(
- NotificationEntry childEntry,
- NotificationEntry containerEntry
+ String childEntry,
+ String containerEntry
);
/**
@@ -1927,7 +1947,7 @@
* NotificationStackScrollLayout
*/
void logRemoveTransientFromNssl(
- NotificationEntry childEntry
+ String childEntry
);
/**
@@ -1935,7 +1955,7 @@
* is not NotificationChildrenContainer or NotificationStackScrollLayout
*/
void logRemoveTransientFromViewGroup(
- NotificationEntry childEntry,
+ String childEntry,
ViewGroup containerView
);
@@ -1944,8 +1964,8 @@
* ExpandableNotificationRow
*/
void logAddTransientRow(
- NotificationEntry childEntry,
- NotificationEntry containerEntry,
+ String childEntry,
+ String containerEntry,
int index
);
@@ -1954,39 +1974,39 @@
* ExpandableNotificationRow
*/
void logRemoveTransientRow(
- NotificationEntry childEntry,
- NotificationEntry containerEntry
+ String childEntry,
+ String containerEntry
);
/**
* Called when resetting the alpha value for content views
*/
void logResetAllContentAlphas(
- NotificationEntry entry
+ String entry
);
/**
* Called when resetting the alpha value for content views is skipped
*/
void logSkipResetAllContentAlphas(
- NotificationEntry entry
+ String entry
);
/** Called when we start an appear animation. */
- void logStartAppearAnimation(NotificationEntry entry, boolean isAppear);
+ void logStartAppearAnimation(String entry, boolean isAppear);
/** Called when we cancel the running appear animation. */
- void logCancelAppearDrawing(NotificationEntry entry, boolean wasDrawing);
+ void logCancelAppearDrawing(String entry, boolean wasDrawing);
/** Called when the animator of the appear animation is started. */
- void logAppearAnimationStarted(NotificationEntry entry, boolean isAppear);
+ void logAppearAnimationStarted(String entry, boolean isAppear);
/** Called when we prepared an appear animation, but the animator was never started. */
- void logAppearAnimationSkipped(NotificationEntry entry, boolean isAppear);
+ void logAppearAnimationSkipped(String entry, boolean isAppear);
/** Called when the animator of the appear animation is finished. */
void logAppearAnimationFinished(
- NotificationEntry entry,
+ String entry,
boolean isAppear,
boolean cancelled
);
@@ -2010,11 +2030,25 @@
*
* @param context context context of the view
* @param attrs attributes used to initialize parent view
+ * @param user the user the row is associated to
+ */
+ public ExpandableNotificationRow(Context context, AttributeSet attrs, UserHandle user) {
+ this(context, attrs, userContextForEntry(context, user));
+ NotificationBundleUi.assertInNewMode();
+ }
+
+ /**
+ * Constructs an ExpandableNotificationRow. Used by layout inflation (with a custom {@code
+ * AsyncLayoutFactory} in {@link RowInflaterTask}.
+ *
+ * @param context context context of the view
+ * @param attrs attributes used to initialize parent view
* @param entry notification that the row will be associated to (determines the user for the
* ImageResolver)
*/
public ExpandableNotificationRow(Context context, AttributeSet attrs, NotificationEntry entry) {
this(context, attrs, userContextForEntry(context, entry));
+ NotificationBundleUi.assertInLegacyMode();
}
private static Context userContextForEntry(Context base, NotificationEntry entry) {
@@ -2025,6 +2059,13 @@
UserHandle.of(entry.getSbn().getNormalizedUserId()), /* flags= */ 0);
}
+ private static Context userContextForEntry(Context base, UserHandle user) {
+ if (base.getUserId() == user.getIdentifier()) {
+ return base;
+ }
+ return base.createContextAsUser(user, /* flags= */ 0);
+ }
+
private ExpandableNotificationRow(Context sysUiContext, AttributeSet attrs,
Context userContext) {
super(sysUiContext, attrs);
@@ -2044,7 +2085,7 @@
NotificationEntry entry,
RemoteInputViewSubcomponent.Factory rivSubcomponentFactory,
String appName,
- String notificationKey,
+ @NonNull String notificationKey,
ExpandableNotificationRowLogger logger,
KeyguardBypassController bypassController,
GroupMembershipManager groupMembershipManager,
@@ -2067,7 +2108,14 @@
IStatusBarService statusBarService,
UiEventLogger uiEventLogger,
NotificationRebindingTracker notificationRebindingTracker) {
- mEntry = entry;
+
+ if (NotificationBundleUi.isEnabled()) {
+ // TODO (b/395857098): remove when all usages are migrated
+ mEntryAdapter = entry.getEntryAdapter();
+ mEntry = entry;
+ } else {
+ mEntry = entry;
+ }
mAppName = appName;
mRebindingTracker = notificationRebindingTracker;
if (mMenuRow == null) {
@@ -2077,7 +2125,7 @@
mMenuRow.setAppName(mAppName);
}
mLogger = logger;
- mLoggingKey = notificationKey;
+ mLoggingKey = logKey(notificationKey);
mBypassController = bypassController;
mGroupMembershipManager = groupMembershipManager;
mGroupExpansionManager = groupExpansionManager;
@@ -2702,7 +2750,7 @@
top = params.getTop();
}
int actualHeight = params.getBottom() - top;
- setActualHeight(actualHeight);
+ setFinalActualHeight(actualHeight);
int notificationStackTop = params.getNotificationParentTop();
top -= notificationStackTop;
@@ -2876,8 +2924,12 @@
public void setUserExpanded(boolean userExpanded, boolean allowChildExpansion) {
if (mIsSummaryWithChildren && !shouldShowPublic() && allowChildExpansion
&& !mChildrenContainer.showingAsLowPriority()) {
- final boolean wasExpanded = mGroupExpansionManager.isGroupExpanded(mEntry);
- mGroupExpansionManager.setGroupExpanded(mEntry, userExpanded);
+ final boolean wasExpanded = isGroupExpanded();
+ if (NotificationBundleUi.isEnabled()) {
+ mGroupExpansionManager.setGroupExpanded(mEntryAdapter, userExpanded);
+ } else {
+ mGroupExpansionManager.setGroupExpanded(mEntry, userExpanded);
+ }
onExpansionChanged(true /* userAction */, wasExpanded);
return;
}
@@ -3031,6 +3083,9 @@
@Override
public boolean isGroupExpanded() {
+ if (NotificationBundleUi.isEnabled()) {
+ return mGroupExpansionManager.isGroupExpanded(mEntryAdapter);
+ }
return mGroupExpansionManager.isGroupExpanded(mEntry);
}
@@ -3187,12 +3242,20 @@
}
public void setSensitive(boolean sensitive, boolean hideSensitive) {
+ if (notificationsRedesignTemplates()
+ && sensitive == mSensitive && hideSensitive == mSensitiveHiddenInGeneral) {
+ return; // nothing has changed
+ }
+
int intrinsicBefore = getIntrinsicHeight();
mSensitive = sensitive;
mSensitiveHiddenInGeneral = hideSensitive;
int intrinsicAfter = getIntrinsicHeight();
if (intrinsicBefore != intrinsicAfter) {
notifyHeightChanged(/* needsAnimation= */ true);
+ } else if (notificationsRedesignTemplates()) {
+ // Just request the correct layout, even if the height hasn't changed
+ getShowingLayout().requestSelectLayout(/* needsAnimation= */ true);
}
}
@@ -3227,11 +3290,14 @@
}
boolean oldShowingPublic = mShowingPublic;
mShowingPublic = mSensitive && hideSensitive;
- if (mShowingPublicInitialized && mShowingPublic == oldShowingPublic) {
+ boolean isShowingLayoutNotChanged = mShowingPublic == oldShowingPublic;
+ if (mShowingPublicInitialized && isShowingLayoutNotChanged) {
return;
}
- if (!animated) {
+ final boolean shouldSkipHideSensitiveAnimation =
+ Flags.skipHideSensitiveNotifAnimation() && isShowingLayoutNotChanged;
+ if (!animated || shouldSkipHideSensitiveAnimation) {
if (!NotificationContentAlphaOptimization.isEnabled()
|| mShowingPublic != oldShowingPublic) {
// Don't reset the alpha or cancel the animation if the showing layout doesn't
@@ -3243,7 +3309,7 @@
}
resetAllContentAlphas();
} else {
- mLogger.logSkipResetAllContentAlphas(getEntry());
+ mLogger.logSkipResetAllContentAlphas(mLoggingKey);
}
mPublicLayout.setVisibility(mShowingPublic ? View.VISIBLE : View.INVISIBLE);
updateChildrenVisibility();
@@ -3342,7 +3408,11 @@
public void makeActionsVisibile() {
setUserExpanded(true, true);
if (isChildInGroup()) {
- mGroupExpansionManager.setGroupExpanded(mEntry, true);
+ if (NotificationBundleUi.isEnabled()) {
+ mGroupExpansionManager.setGroupExpanded(mEntryAdapter, true);
+ } else {
+ mGroupExpansionManager.setGroupExpanded(mEntry, true);
+ }
}
notifyHeightChanged(/* needsAnimation= */ false);
}
@@ -3393,7 +3463,7 @@
@Override
public void performAddAnimation(long delay, long duration, boolean isHeadsUpAppear,
Runnable onFinishRunnable) {
- mLogger.logStartAppearAnimation(getEntry(), /* isAppear = */ true);
+ mLogger.logStartAppearAnimation(mLoggingKey, /* isAppear = */ true);
super.performAddAnimation(delay, duration, isHeadsUpAppear, onFinishRunnable);
}
@@ -3406,7 +3476,7 @@
Runnable onStartedRunnable,
Runnable onFinishedRunnable,
AnimatorListenerAdapter animationListener, ClipSide clipSide) {
- mLogger.logStartAppearAnimation(getEntry(), /* isAppear = */ false);
+ mLogger.logStartAppearAnimation(mLoggingKey, /* isAppear = */ false);
if (mMenuRow != null && mMenuRow.isMenuVisible()) {
Animator anim = getTranslateViewAnimator(0f, null /* listener */);
if (anim != null) {
@@ -3436,20 +3506,20 @@
@Override
protected void onAppearAnimationStarted(boolean isAppear) {
- mLogger.logAppearAnimationStarted(getEntry(), /* isAppear = */ isAppear);
+ mLogger.logAppearAnimationStarted(mLoggingKey, /* isAppear = */ isAppear);
super.onAppearAnimationStarted(isAppear);
}
@Override
protected void onAppearAnimationSkipped(boolean isAppear) {
- mLogger.logAppearAnimationSkipped(getEntry(), /* isAppear = */ isAppear);
+ mLogger.logAppearAnimationSkipped(mLoggingKey, /* isAppear = */ isAppear);
super.onAppearAnimationSkipped(isAppear);
}
@Override
protected void onAppearAnimationFinished(boolean wasAppearing, boolean cancelled) {
mLogger.logAppearAnimationFinished(
- /* entry = */ getEntry(),
+ /* entry = */ mLoggingKey,
/* isAppear = */ wasAppearing,
/* cancelled = */ cancelled
);
@@ -3470,13 +3540,13 @@
@Override
public void cancelAppearDrawing() {
- mLogger.logCancelAppearDrawing(getEntry(), isDrawingAppearAnimation());
+ mLogger.logCancelAppearDrawing(mLoggingKey, isDrawingAppearAnimation());
super.cancelAppearDrawing();
}
@Override
public void resetAllContentAlphas() {
- mLogger.logResetAllContentAlphas(getEntry());
+ mLogger.logResetAllContentAlphas(mLoggingKey);
mPrivateLayout.setAlpha(1f);
mPrivateLayout.setLayerType(LAYER_TYPE_NONE, null);
mPublicLayout.setAlpha(1f);
@@ -3766,7 +3836,9 @@
public void onExpandedByGesture(boolean userExpanded) {
int event = MetricsEvent.ACTION_NOTIFICATION_GESTURE_EXPANDER;
- if (mGroupMembershipManager.isGroupSummary(mEntry)) {
+ if (NotificationBundleUi.isEnabled()
+ ? mGroupMembershipManager.isGroupRoot(mEntryAdapter)
+ : mGroupMembershipManager.isGroupSummary(mEntry)) {
event = MetricsEvent.ACTION_NOTIFICATION_GROUP_GESTURE_EXPANDER;
}
mMetricsLogger.action(event, userExpanded);
@@ -3802,7 +3874,7 @@
private void onExpansionChanged(boolean userAction, boolean wasExpanded) {
boolean nowExpanded = isExpanded();
if (mIsSummaryWithChildren && (!mIsMinimized || wasExpanded)) {
- nowExpanded = mGroupExpansionManager.isGroupExpanded(mEntry);
+ nowExpanded = isGroupExpanded();
}
// Note: nowExpanded is going to be true here on the first expansion of minimized groups,
// even though the group itself is not expanded. Use mGroupExpansionManager to get the real
@@ -4246,13 +4318,13 @@
private void logKeepInParentChildDetached(ExpandableNotificationRow child) {
if (mLogger != null) {
- mLogger.logKeepInParentChildDetached(child.getEntry(), getEntry());
+ mLogger.logKeepInParentChildDetached(child.getLoggingKey(), mLoggingKey);
}
}
private void logSkipAttachingKeepInParentChild(ExpandableNotificationRow child) {
if (mLogger != null) {
- mLogger.logSkipAttachingKeepInParentChild(child.getEntry(), getEntry());
+ mLogger.logSkipAttachingKeepInParentChild(child.getLoggingKey(), mLoggingKey);
}
}
@@ -4308,17 +4380,17 @@
}
if (transientContainer instanceof NotificationChildrenContainer) {
mLogger.logRemoveTransientFromContainer(
- /* childEntry = */ getEntry(),
+ /* childEntry = */ mLoggingKey,
/* containerEntry = */ ((NotificationChildrenContainer) transientContainer)
- .getContainingNotification().getEntry()
+ .getContainingNotification().getLoggingKey()
);
} else if (transientContainer instanceof NotificationStackScrollLayout) {
mLogger.logRemoveTransientFromNssl(
- /* childEntry = */ getEntry()
+ /* childEntry = */ mLoggingKey
);
} else {
mLogger.logRemoveTransientFromViewGroup(
- /* childEntry = */ getEntry(),
+ /* childEntry = */ mLoggingKey,
/* containerView = */ transientContainer
);
}
@@ -4336,7 +4408,7 @@
if (mLogger == null) {
return;
}
- mLogger.logAddTransientRow(row.getEntry(), getEntry(), index);
+ mLogger.logAddTransientRow(row.getLoggingKey(), mLoggingKey, index);
}
@Override
@@ -4351,6 +4423,6 @@
if (mLogger == null) {
return;
}
- mLogger.logRemoveTransientRow(row.getEntry(), getEntry());
+ mLogger.logRemoveTransientRow(row.getLoggingKey(), mLoggingKey);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
index 6262303..b43a387 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
@@ -56,6 +56,7 @@
import com.android.systemui.statusbar.notification.row.dagger.AppName;
import com.android.systemui.statusbar.notification.row.dagger.NotificationKey;
import com.android.systemui.statusbar.notification.row.dagger.NotificationRowScope;
+import com.android.systemui.statusbar.notification.shared.NotificationBundleUi;
import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainerLogger;
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
import com.android.systemui.statusbar.notification.stack.ui.view.NotificationRowStatsLogger;
@@ -145,38 +146,38 @@
@Override
public void logKeepInParentChildDetached(
- NotificationEntry child,
- NotificationEntry oldParent
+ String child,
+ String oldParent
) {
mLogBufferLogger.logKeepInParentChildDetached(child, oldParent);
}
@Override
public void logSkipAttachingKeepInParentChild(
- NotificationEntry child,
- NotificationEntry newParent
+ String child,
+ String newParent
) {
mLogBufferLogger.logSkipAttachingKeepInParentChild(child, newParent);
}
@Override
public void logRemoveTransientFromContainer(
- NotificationEntry childEntry,
- NotificationEntry containerEntry
+ String childEntry,
+ String containerEntry
) {
mLogBufferLogger.logRemoveTransientFromContainer(childEntry, containerEntry);
}
@Override
public void logRemoveTransientFromNssl(
- NotificationEntry childEntry
+ String childEntry
) {
mLogBufferLogger.logRemoveTransientFromNssl(childEntry);
}
@Override
public void logRemoveTransientFromViewGroup(
- NotificationEntry childEntry,
+ String childEntry,
ViewGroup containerView
) {
mLogBufferLogger.logRemoveTransientFromViewGroup(childEntry, containerView);
@@ -184,8 +185,8 @@
@Override
public void logAddTransientRow(
- NotificationEntry childEntry,
- NotificationEntry containerEntry,
+ String childEntry,
+ String containerEntry,
int index
) {
mLogBufferLogger.logAddTransientRow(childEntry, containerEntry, index);
@@ -193,48 +194,48 @@
@Override
public void logRemoveTransientRow(
- NotificationEntry childEntry,
- NotificationEntry containerEntry
+ String childEntry,
+ String containerEntry
) {
mLogBufferLogger.logRemoveTransientRow(childEntry, containerEntry);
}
@Override
public void logResetAllContentAlphas(
- NotificationEntry entry
+ String entry
) {
mLogBufferLogger.logResetAllContentAlphas(entry);
}
@Override
public void logSkipResetAllContentAlphas(
- NotificationEntry entry
+ String entry
) {
mLogBufferLogger.logSkipResetAllContentAlphas(entry);
}
@Override
- public void logStartAppearAnimation(NotificationEntry entry, boolean isAppear) {
+ public void logStartAppearAnimation(String entry, boolean isAppear) {
mLogBufferLogger.logStartAppearAnimation(entry, isAppear);
}
@Override
- public void logCancelAppearDrawing(NotificationEntry entry, boolean wasDrawing) {
+ public void logCancelAppearDrawing(String entry, boolean wasDrawing) {
mLogBufferLogger.logCancelAppearDrawing(entry, wasDrawing);
}
@Override
- public void logAppearAnimationStarted(NotificationEntry entry, boolean isAppear) {
+ public void logAppearAnimationStarted(String entry, boolean isAppear) {
mLogBufferLogger.logAppearAnimationStarted(entry, isAppear);
}
@Override
- public void logAppearAnimationSkipped(NotificationEntry entry, boolean isAppear) {
+ public void logAppearAnimationSkipped(String entry, boolean isAppear) {
mLogBufferLogger.logAppearAnimationSkipped(entry, isAppear);
}
@Override
- public void logAppearAnimationFinished(NotificationEntry entry, boolean isAppear,
+ public void logAppearAnimationFinished(String entry, boolean isAppear,
boolean cancelled) {
mLogBufferLogger.logAppearAnimationFinished(entry, isAppear, cancelled);
}
@@ -405,7 +406,7 @@
@Override
@NonNull
public String getNodeLabel() {
- return logKey(mView.getEntry());
+ return NotificationBundleUi.isEnabled() ? mView.getLoggingKey() : logKey(mView.getEntry());
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
index 2bc4874..da664f8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.notification.row;
import static com.android.systemui.Flags.notificationColorUpdateLogger;
+import static com.android.systemui.Flags.physicalNotificationMovement;
import android.animation.AnimatorListenerAdapter;
import android.content.Context;
@@ -24,6 +25,7 @@
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
+import android.util.FloatProperty;
import android.util.IndentingPrintWriter;
import android.util.Log;
import android.view.View;
@@ -41,6 +43,7 @@
import com.android.systemui.Dumpable;
import com.android.systemui.res.R;
import com.android.systemui.statusbar.StatusBarIconView;
+import com.android.systemui.statusbar.notification.PhysicsProperty;
import com.android.systemui.statusbar.notification.Roundable;
import com.android.systemui.statusbar.notification.RoundableState;
import com.android.systemui.statusbar.notification.headsup.PinnedStatus;
@@ -58,6 +61,20 @@
* An abstract view for expandable views.
*/
public abstract class ExpandableView extends FrameLayout implements Dumpable, Roundable {
+ public static final int TAG_ANIMATOR_HEIGHT = R.id.height_animator_tag;
+ public static final PhysicsProperty HEIGHT_PROPERTY = new PhysicsProperty(TAG_ANIMATOR_HEIGHT,
+ new FloatProperty<>("ActualHeight") {
+
+ @Override
+ public Float get(View view) {
+ return (float) ((ExpandableView) view).getActualHeight();
+ }
+
+ @Override
+ public void setValue(@NonNull View view, float value) {
+ ((ExpandableView) view).setActualHeight((int) value);
+ }
+ });
private static final String TAG = "ExpandableView";
/** whether the dump() for this class should include verbose details */
protected static final boolean DUMP_VERBOSE = Compile.IS_DEBUG
@@ -84,7 +101,8 @@
protected float mContentTransformationAmount;
protected boolean mIsLastChild;
protected int mContentShift;
- @NonNull private final ExpandableViewState mViewState;
+ @NonNull
+ private final ExpandableViewState mViewState;
private float mContentTranslation;
protected boolean mLastInSection;
protected boolean mFirstInSection;
@@ -205,7 +223,7 @@
MeasureSpec.EXACTLY);
}
child.measure(getChildMeasureSpec(
- widthMeasureSpec, viewHorizontalPadding, layoutParams.width),
+ widthMeasureSpec, viewHorizontalPadding, layoutParams.width),
childHeightSpec);
int childHeight = child.getMeasuredHeight();
maxChildHeight = Math.max(maxChildHeight, childHeight);
@@ -223,7 +241,7 @@
// Now that we know our own height, measure the children that are MATCH_PARENT
for (View child : mMatchParentViews) {
child.measure(getChildMeasureSpec(
- widthMeasureSpec, viewHorizontalPadding, child.getLayoutParams().width),
+ widthMeasureSpec, viewHorizontalPadding, child.getLayoutParams().width),
exactlyOwnHeightSpec);
}
mMatchParentViews.clear();
@@ -269,12 +287,29 @@
}
/**
+ * Sets the final value of the actual height, which is to be applied immediately without
+ * animation. This may be different than the current value if we're animating away an offset.
+ */
+ public void setFinalActualHeight(int childHeight) {
+ if (physicalNotificationMovement()) {
+ HEIGHT_PROPERTY.setFinalValue(this, childHeight);
+ } else {
+ setActualHeight(childHeight);
+ }
+ }
+
+ /**
+ * Once the physical notification movement flag is enabled, don't use
+ * this directly as a public method since it may not update the property values and misbehave
+ * during animations. Use #setFinalActualHeight instead.
+ *
* Sets the actual height of this notification. This is different than the laid out
* {@link View#getHeight()}, as we want to avoid layouting during scrolling and expanding.
*
- * @param actualHeight The height of this notification.
+ * @param actualHeight The height of this notification.
* @param notifyListeners Whether the listener should be informed about the change.
*/
+ @Deprecated
public void setActualHeight(int actualHeight, boolean notifyListeners) {
if (mActualHeight != actualHeight) {
mActualHeight = actualHeight;
@@ -285,7 +320,7 @@
}
}
- public void setActualHeight(int actualHeight) {
+ protected void setActualHeight(int actualHeight) {
setActualHeight(actualHeight, true /* notifyListeners */);
}
@@ -748,7 +783,8 @@
*
* @return the ExpandableView's view state.
*/
- @NonNull public ExpandableViewState getViewState() {
+ @NonNull
+ public ExpandableViewState getViewState() {
return mViewState;
}
@@ -840,9 +876,10 @@
* Set how much this notification is transformed into the shelf.
*
* @param contentTransformationAmount A value from 0 to 1 indicating how much we are transformed
- * to the content away
- * @param isLastChild is this the last child in the list. If true, then the transformation is
- * different since its content fades out.
+ * to the content away
+ * @param isLastChild is this the last child in the list. If true, then the
+ * transformation is
+ * different since its content fades out.
*/
public void setContentTransformationAmount(float contentTransformationAmount,
boolean isLastChild) {
@@ -971,8 +1008,9 @@
public interface OnHeightChangedListener {
/**
- * @param view the view for which the height changed, or {@code null} if just the top
- * padding or the padding between the elements changed
+ * @param view the view for which the height changed, or {@code null} if just the
+ * top
+ * padding or the padding between the elements changed
* @param needsAnimation whether the view height needs to be animated
*/
void onHeightChanged(ExpandableView view, boolean needsAnimation);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
index e311b53..0c1dd2e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
@@ -56,6 +56,7 @@
import com.android.systemui.statusbar.notification.ConversationNotificationProcessor;
import com.android.systemui.statusbar.notification.InflationException;
import com.android.systemui.statusbar.notification.NmSummarizationUiFlag;
+import com.android.systemui.statusbar.notification.collection.EntryAdapter;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.promoted.PromotedNotificationContentExtractor;
import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUiForceExpanded;
@@ -1457,12 +1458,12 @@
}
@Override
- public void handleInflationException(NotificationEntry entry, Exception e) {
+ public void handleInflationException(Exception e) {
handleError(e);
}
@Override
- public void onAsyncInflationFinished(NotificationEntry entry) {
+ public void onAsyncInflationFinished() {
mEntry.onInflationTaskFinished();
mRow.onNotificationUpdated();
if (mCallback != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinder.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinder.java
index 0be1d5d..05934e7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinder.java
@@ -24,6 +24,7 @@
import androidx.annotation.VisibleForTesting;
+import com.android.systemui.statusbar.notification.collection.EntryAdapter;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import java.lang.annotation.Retention;
@@ -170,13 +171,29 @@
* @param entry notification which failed to inflate content
* @param e exception
*/
- void handleInflationException(NotificationEntry entry, Exception e);
+ default void handleInflationException(NotificationEntry entry, Exception e) {
+ handleInflationException(e);
+ }
+
+ /**
+ * Callback for when there is an inflation exception
+ *
+ * @param e exception
+ */
+ void handleInflationException(Exception e);
/**
* Callback for after the content views finish inflating.
*
* @param entry the entry with the content views set
*/
- void onAsyncInflationFinished(NotificationEntry entry);
+ default void onAsyncInflationFinished(NotificationEntry entry) {
+ onAsyncInflationFinished();
+ }
+
+ /**
+ * Callback for after the content views finish inflating.
+ */
+ void onAsyncInflationFinished();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt
index 517fc3a..761d3fe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt
@@ -49,6 +49,7 @@
import com.android.systemui.statusbar.notification.ConversationNotificationProcessor
import com.android.systemui.statusbar.notification.InflationException
import com.android.systemui.statusbar.notification.NmSummarizationUiFlag
+import com.android.systemui.statusbar.notification.collection.EntryAdapter
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.promoted.PromotedNotificationContentExtractor
import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel
@@ -76,6 +77,7 @@
import com.android.systemui.statusbar.notification.row.shared.NotificationRowContentBinderRefactor
import com.android.systemui.statusbar.notification.row.ui.viewbinder.SingleLineViewBinder
import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper
+import com.android.systemui.statusbar.notification.shared.NotificationBundleUi
import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainer
import com.android.systemui.statusbar.policy.InflatedSmartReplyState
import com.android.systemui.statusbar.policy.InflatedSmartReplyViewHolder
@@ -536,7 +538,7 @@
val ident: String = (sbn.packageName + "/0x" + Integer.toHexString(sbn.id))
Log.e(TAG, "couldn't inflate view for notification $ident", e)
callback?.handleInflationException(
- row.entry,
+ if (NotificationBundleUi.isEnabled) entry else row.entry,
InflationException("Couldn't inflate contentViews$e"),
)
@@ -554,11 +556,11 @@
logger.logAsyncTaskProgress(entry, "aborted")
}
- override fun handleInflationException(entry: NotificationEntry, e: Exception) {
+ override fun handleInflationException(e: Exception) {
handleError(e)
}
- override fun onAsyncInflationFinished(entry: NotificationEntry) {
+ override fun onAsyncInflationFinished() {
this.entry.onInflationTaskFinished()
row.onNotificationUpdated()
callback?.onAsyncInflationFinished(this.entry)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowLogger.kt
index 9e1c974..dad57a0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowLogger.kt
@@ -22,8 +22,6 @@
import com.android.systemui.log.core.LogLevel
import com.android.systemui.log.dagger.NotificationLog
import com.android.systemui.log.dagger.NotificationRenderLog
-import com.android.systemui.statusbar.notification.collection.NotificationEntry
-import com.android.systemui.statusbar.notification.logKey
import com.android.systemui.statusbar.notification.stack.MagneticNotificationRowManagerImpl
import javax.inject.Inject
@@ -33,60 +31,60 @@
@NotificationLog private val buffer: LogBuffer,
@NotificationRenderLog private val notificationRenderBuffer: LogBuffer,
) {
- fun logKeepInParentChildDetached(child: NotificationEntry, oldParent: NotificationEntry?) {
+ fun logKeepInParentChildDetached(child: String, oldParent: String?) {
buffer.log(
TAG,
LogLevel.DEBUG,
{
- str1 = child.logKey
- str2 = oldParent.logKey
+ str1 = child
+ str2 = oldParent
},
{ "Detach child $str1 kept in parent $str2" },
)
}
- fun logSkipAttachingKeepInParentChild(child: NotificationEntry, newParent: NotificationEntry?) {
+ fun logSkipAttachingKeepInParentChild(child: String, newParent: String?) {
buffer.log(
TAG,
LogLevel.WARNING,
{
- str1 = child.logKey
- str2 = newParent.logKey
+ str1 = child
+ str2 = newParent
},
{ "Skipping to attach $str1 to $str2, because it still flagged to keep in parent" },
)
}
fun logRemoveTransientFromContainer(
- childEntry: NotificationEntry,
- containerEntry: NotificationEntry,
+ childEntry: String,
+ containerEntry: String,
) {
notificationRenderBuffer.log(
TAG,
LogLevel.INFO,
{
- str1 = childEntry.logKey
- str2 = containerEntry.logKey
+ str1 = childEntry
+ str2 = containerEntry
},
{ "RemoveTransientRow from ChildrenContainer: childKey: $str1 -- containerKey: $str2" },
)
}
- fun logRemoveTransientFromNssl(childEntry: NotificationEntry) {
+ fun logRemoveTransientFromNssl(childEntry: String) {
notificationRenderBuffer.log(
TAG,
LogLevel.INFO,
- { str1 = childEntry.logKey },
+ { str1 = childEntry },
{ "RemoveTransientRow from Nssl: childKey: $str1" },
)
}
- fun logRemoveTransientFromViewGroup(childEntry: NotificationEntry, containerView: ViewGroup) {
+ fun logRemoveTransientFromViewGroup(childEntry: String, containerView: ViewGroup) {
notificationRenderBuffer.log(
TAG,
LogLevel.WARNING,
{
- str1 = childEntry.logKey
+ str1 = childEntry
str2 = containerView.toString()
},
{ "RemoveTransientRow from other ViewGroup: childKey: $str1 -- ViewGroup: $str2" },
@@ -94,94 +92,94 @@
}
fun logAddTransientRow(
- childEntry: NotificationEntry,
- containerEntry: NotificationEntry,
+ childEntry: String,
+ containerEntry: String,
index: Int,
) {
notificationRenderBuffer.log(
TAG,
LogLevel.ERROR,
{
- str1 = childEntry.logKey
- str2 = containerEntry.logKey
+ str1 = childEntry
+ str2 = containerEntry
int1 = index
},
{ "addTransientRow to row: childKey: $str1 -- containerKey: $str2 -- index: $int1" },
)
}
- fun logRemoveTransientRow(childEntry: NotificationEntry, containerEntry: NotificationEntry) {
+ fun logRemoveTransientRow(childEntry: String, containerEntry: String) {
notificationRenderBuffer.log(
TAG,
LogLevel.ERROR,
{
- str1 = childEntry.logKey
- str2 = containerEntry.logKey
+ str1 = childEntry
+ str2 = containerEntry
},
{ "removeTransientRow from row: childKey: $str1 -- containerKey: $str2" },
)
}
- fun logResetAllContentAlphas(entry: NotificationEntry) {
+ fun logResetAllContentAlphas(entry: String) {
notificationRenderBuffer.log(
TAG,
LogLevel.INFO,
- { str1 = entry.logKey },
+ { str1 = entry },
{ "resetAllContentAlphas: $str1" },
)
}
- fun logSkipResetAllContentAlphas(entry: NotificationEntry) {
+ fun logSkipResetAllContentAlphas(entry: String) {
notificationRenderBuffer.log(
TAG,
LogLevel.INFO,
- { str1 = entry.logKey },
+ { str1 = entry },
{ "Skip resetAllContentAlphas: $str1" },
)
}
- fun logStartAppearAnimation(entry: NotificationEntry, isAppear: Boolean) {
+ fun logStartAppearAnimation(entry: String, isAppear: Boolean) {
notificationRenderBuffer.log(
TAG,
LogLevel.DEBUG,
{
- str1 = entry.logKey
+ str1 = entry
bool1 = isAppear
},
{ "startAppearAnimation childKey: $str1 isAppear:$bool1" },
)
}
- fun logCancelAppearDrawing(entry: NotificationEntry, wasDrawing: Boolean) {
+ fun logCancelAppearDrawing(entry: String, wasDrawing: Boolean) {
notificationRenderBuffer.log(
TAG,
LogLevel.WARNING,
{
- str1 = entry.logKey
+ str1 = entry
bool1 = wasDrawing
},
{ "cancelAppearDrawing childKey: $str1 wasDrawing:$bool1" },
)
}
- fun logAppearAnimationStarted(entry: NotificationEntry, isAppear: Boolean) {
+ fun logAppearAnimationStarted(entry: String, isAppear: Boolean) {
notificationRenderBuffer.log(
TAG,
LogLevel.DEBUG,
{
- str1 = entry.logKey
+ str1 = entry
bool1 = isAppear
},
{ "onAppearAnimationStarted childKey: $str1 isAppear:$bool1" },
)
}
- fun logAppearAnimationSkipped(entry: NotificationEntry, isAppear: Boolean) {
+ fun logAppearAnimationSkipped(entry: String, isAppear: Boolean) {
notificationRenderBuffer.log(
TAG,
LogLevel.WARNING,
{
- str1 = entry.logKey
+ str1 = entry
bool1 = isAppear
},
{ "Skipped an appear animation childKey: $str1 isAppear:$bool1" },
@@ -189,7 +187,7 @@
}
fun logAppearAnimationFinished(
- entry: NotificationEntry,
+ entry: String,
isAppear: Boolean,
cancelled: Boolean,
) {
@@ -197,7 +195,7 @@
TAG,
LogLevel.DEBUG,
{
- str1 = entry.logKey
+ str1 = entry
bool1 = isAppear
bool2 = cancelled
},
@@ -207,13 +205,13 @@
fun logMagneticAndRoundableTargetsNotSet(
state: MagneticNotificationRowManagerImpl.State,
- entry: NotificationEntry,
+ entry: String,
) {
buffer.log(
TAG,
LogLevel.ERROR,
{
- str1 = entry.logKey
+ str1 = entry
str2 = state.name
},
{ "Failed to set magnetic and roundable targets for $str1 on state $str2." },
@@ -222,13 +220,13 @@
fun logMagneticRowTranslationNotSet(
state: MagneticNotificationRowManagerImpl.State,
- entry: NotificationEntry,
+ entry: String,
) {
buffer.log(
TAG,
LogLevel.ERROR,
{
- str1 = entry.logKey
+ str1 = entry
str2 = state.name
},
{ "Failed to set magnetic row translation for $str1 on state $str2." },
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindStage.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindStage.java
index 6883ec5..da36140 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindStage.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindStage.java
@@ -21,10 +21,12 @@
import androidx.annotation.NonNull;
import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.statusbar.notification.collection.EntryAdapter;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.BindParams;
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationCallback;
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag;
+import com.android.systemui.statusbar.notification.shared.NotificationBundleUi;
import javax.inject.Inject;
@@ -52,7 +54,7 @@
@Override
protected void executeStage(
- @NonNull NotificationEntry entry,
+ final @NonNull NotificationEntry entry,
@NonNull ExpandableNotificationRow row,
@NonNull StageCallback callback) {
RowContentBindParams params = getStageParams(entry);
@@ -77,15 +79,35 @@
InflationCallback inflationCallback = new InflationCallback() {
@Override
- public void handleInflationException(NotificationEntry entry, Exception e) {
- mNotifInflationErrorManager.setInflationError(entry, e);
+ public void handleInflationException(NotificationEntry errorEntry, Exception e) {
+ if (NotificationBundleUi.isEnabled()) {
+ mNotifInflationErrorManager.setInflationError(entry, e);
+ } else {
+ mNotifInflationErrorManager.setInflationError(errorEntry, e);
+ }
}
@Override
- public void onAsyncInflationFinished(NotificationEntry entry) {
- mNotifInflationErrorManager.clearInflationError(entry);
- getStageParams(entry).clearDirtyContentViews();
- callback.onStageFinished(entry);
+ public void handleInflationException(Exception e) {
+
+ }
+
+ @Override
+ public void onAsyncInflationFinished(NotificationEntry finishedEntry) {
+ if (NotificationBundleUi.isEnabled()) {
+ mNotifInflationErrorManager.clearInflationError(entry);
+ getStageParams(entry).clearDirtyContentViews();
+ callback.onStageFinished(entry);
+ } else {
+ mNotifInflationErrorManager.clearInflationError(finishedEntry);
+ getStageParams(finishedEntry).clearDirtyContentViews();
+ callback.onStageFinished(finishedEntry);
+ }
+ }
+
+ @Override
+ public void onAsyncInflationFinished() {
+
}
};
mBinder.cancelBind(entry, row);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowInflaterTask.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowInflaterTask.java
index 9f634be..3971661 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowInflaterTask.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowInflaterTask.java
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.notification.row;
import android.content.Context;
+import android.os.UserHandle;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
@@ -29,9 +30,12 @@
import androidx.asynclayoutinflater.view.AsyncLayoutFactory;
import androidx.asynclayoutinflater.view.AsyncLayoutInflater;
+import com.android.systemui.Flags;
import com.android.systemui.res.R;
+import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.InflationTask;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.shared.NotificationBundleUi;
import com.android.systemui.util.time.SystemClock;
import java.util.concurrent.Executor;
@@ -41,7 +45,8 @@
/**
* An inflater task that asynchronously inflates a ExpandableNotificationRow
*/
-public class RowInflaterTask implements InflationTask, AsyncLayoutInflater.OnInflateFinishedListener {
+public class RowInflaterTask implements InflationTask,
+ AsyncLayoutInflater.OnInflateFinishedListener, AsyncRowInflater.OnInflateFinishedListener {
private static final String TAG = "RowInflaterTask";
private static final boolean TRACE_ORIGIN = true;
@@ -52,12 +57,17 @@
private Throwable mInflateOrigin;
private final SystemClock mSystemClock;
private final RowInflaterTaskLogger mLogger;
+ private final AsyncRowInflater mAsyncRowInflater;
private long mInflateStartTimeMs;
+ private UserTracker mUserTracker;
@Inject
- public RowInflaterTask(SystemClock systemClock, RowInflaterTaskLogger logger) {
+ public RowInflaterTask(SystemClock systemClock, RowInflaterTaskLogger logger,
+ UserTracker userTracker, AsyncRowInflater asyncRowInflater) {
mSystemClock = systemClock;
mLogger = logger;
+ mUserTracker = userTracker;
+ mAsyncRowInflater = asyncRowInflater;
}
/**
@@ -81,13 +91,19 @@
mInflateOrigin = new Throwable("inflate requested here");
}
mListener = listener;
- AsyncLayoutInflater inflater = new AsyncLayoutInflater(context, makeRowInflater(entry));
+ RowAsyncLayoutInflater asyncLayoutFactory = makeRowInflater(entry);
mEntry = entry;
entry.setInflationTask(this);
mLogger.logInflateStart(entry);
mInflateStartTimeMs = mSystemClock.elapsedRealtime();
- inflater.inflate(R.layout.status_bar_notification_row, parent, listenerExecutor, this);
+ if (Flags.useNotifInflationThreadForRow()) {
+ mAsyncRowInflater.inflate(context, asyncLayoutFactory,
+ R.layout.status_bar_notification_row, parent, this);
+ } else {
+ AsyncLayoutInflater inflater = new AsyncLayoutInflater(context, asyncLayoutFactory);
+ inflater.inflate(R.layout.status_bar_notification_row, parent, listenerExecutor, this);
+ }
}
/**
@@ -107,40 +123,8 @@
}
private RowAsyncLayoutInflater makeRowInflater(NotificationEntry entry) {
- return new RowAsyncLayoutInflater(entry, mSystemClock, mLogger);
- }
-
- /**
- * A {@link LayoutInflater} that is copy of BasicLayoutInflater.
- */
- private static class BasicRowInflater extends LayoutInflater {
- private static final String[] sClassPrefixList =
- {"android.widget.", "android.webkit.", "android.app."};
- BasicRowInflater(Context context) {
- super(context);
- }
-
- @Override
- public LayoutInflater cloneInContext(Context newContext) {
- return new BasicRowInflater(newContext);
- }
-
- @Override
- protected View onCreateView(String name, AttributeSet attrs) throws ClassNotFoundException {
- for (String prefix : sClassPrefixList) {
- try {
- View view = createView(name, prefix, attrs);
- if (view != null) {
- return view;
- }
- } catch (ClassNotFoundException e) {
- // In this case we want to let the base class take a crack
- // at it.
- }
- }
-
- return super.onCreateView(name, attrs);
- }
+ return new RowAsyncLayoutInflater(
+ entry, mSystemClock, mLogger, mUserTracker.getUserHandle());
}
@VisibleForTesting
@@ -148,12 +132,14 @@
private final NotificationEntry mEntry;
private final SystemClock mSystemClock;
private final RowInflaterTaskLogger mLogger;
+ private final UserHandle mTargetUser;
public RowAsyncLayoutInflater(NotificationEntry entry, SystemClock systemClock,
- RowInflaterTaskLogger logger) {
+ RowInflaterTaskLogger logger, UserHandle targetUser) {
mEntry = entry;
mSystemClock = systemClock;
mLogger = logger;
+ mTargetUser = targetUser;
}
@Nullable
@@ -165,8 +151,12 @@
}
final long startMs = mSystemClock.elapsedRealtime();
- final ExpandableNotificationRow row =
- new ExpandableNotificationRow(context, attrs, mEntry);
+ ExpandableNotificationRow row = null;
+ if (NotificationBundleUi.isEnabled()) {
+ row = new ExpandableNotificationRow(context, attrs, mTargetUser);
+ } else {
+ row = new ExpandableNotificationRow(context, attrs, mEntry);
+ }
final long elapsedMs = mSystemClock.elapsedRealtime() - startMs;
mLogger.logCreatedRow(mEntry, elapsedMs);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AnimationProperties.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AnimationProperties.java
index 00b9aa4..3d60092 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AnimationProperties.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AnimationProperties.java
@@ -23,6 +23,8 @@
import android.view.View;
import android.view.animation.Interpolator;
+import androidx.dynamicanimation.animation.DynamicAnimation;
+
import java.util.function.Consumer;
/**
@@ -77,6 +79,34 @@
}
/**
+ * @return a listener that will be added for a given property during its animation. Similar to
+ * the finish listener but used for Dynamic / SpringAnimations
+ */
+ public DynamicAnimation.OnAnimationEndListener getAnimationEndListener(Property property) {
+ if (mAnimationEndAction == null && mAnimationCancelAction == null) {
+ return null;
+ }
+ Consumer<Property> cancelAction = mAnimationCancelAction;
+ Consumer<Property> endAction = mAnimationEndAction;
+ return (animation, canceled, value, velocity) -> {
+ if (canceled && cancelAction != null) {
+ cancelAction.accept(property);
+ } else if (!canceled && endAction != null) {
+ endAction.accept(property);
+ }
+ };
+ }
+
+ /**
+ * @return a listener that is invoked when a property animation starts, used for dynamic
+ * animations. For classical, interpolator based animations used the listeneradapter instead,
+ * this is only for Dynamic Animations
+ */
+ public Consumer<DynamicAnimation> getAnimationStartListener(Property property) {
+ return null;
+ }
+
+ /**
* Add a callback for animation cancellation.
*/
public AnimationProperties setAnimationCancelAction(Consumer<Property> listener) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ExpandableViewState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ExpandableViewState.java
index 69c9a4b..8cf9dd3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ExpandableViewState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ExpandableViewState.java
@@ -16,23 +16,31 @@
package com.android.systemui.statusbar.notification.stack;
+import static com.android.systemui.Flags.physicalNotificationMovement;
+import static com.android.systemui.statusbar.notification.row.ExpandableView.HEIGHT_PROPERTY;
+import static com.android.systemui.statusbar.notification.row.ExpandableView.TAG_ANIMATOR_HEIGHT;
+
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
+import android.util.FloatProperty;
import android.view.View;
+import androidx.annotation.NonNull;
+
import com.android.app.animation.Interpolators;
import com.android.systemui.res.R;
+import com.android.systemui.statusbar.notification.PhysicsProperty;
+import com.android.systemui.statusbar.notification.PhysicsPropertyAnimator;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableView;
/**
-* A state of an expandable view
-*/
+ * A state of an expandable view
+ */
public class ExpandableViewState extends ViewState {
- private static final int TAG_ANIMATOR_HEIGHT = R.id.height_animator_tag;
private static final int TAG_ANIMATOR_TOP_INSET = R.id.top_inset_animator_tag;
private static final int TAG_ANIMATOR_BOTTOM_INSET = R.id.bottom_inset_animator_tag;
private static final int TAG_END_HEIGHT = R.id.height_animator_end_value_tag;
@@ -149,7 +157,7 @@
// apply height
if (height != newHeight) {
- expandableView.setActualHeight(newHeight, false /* notifyListeners */);
+ expandableView.setFinalActualHeight(newHeight);
}
// apply hiding sensitive
@@ -186,8 +194,24 @@
// start height animation
if (this.height != expandableView.getActualHeight()) {
- startHeightAnimation(expandableView, properties);
- } else {
+ if (mUsePhysicsForMovement) {
+ boolean animateHeight = properties.getAnimationFilter().animateHeight;
+ if (animateHeight) {
+ expandableView.setActualHeightAnimating(true);
+ }
+ PhysicsPropertyAnimator.setProperty(child, HEIGHT_PROPERTY, this.height, properties,
+ animateHeight,
+ (animation, canceled, value, velocity) -> {
+ expandableView.setActualHeightAnimating(false);
+ if (!canceled && child instanceof ExpandableNotificationRow) {
+ ((ExpandableNotificationRow) child).setGroupExpansionChanging(
+ false /* isExpansionChanging */);
+ }
+ });
+ } else {
+ startHeightAnimationInterpolator(expandableView, properties);
+ }
+ } else {
abortAnimation(child, TAG_ANIMATOR_HEIGHT);
}
@@ -224,7 +248,8 @@
}
}
- private void startHeightAnimation(final ExpandableView child, AnimationProperties properties) {
+ private void startHeightAnimationInterpolator(final ExpandableView child,
+ AnimationProperties properties) {
Integer previousStartValue = getChildTag(child, TAG_START_HEIGHT);
Integer previousEndValue = getChildTag(child, TAG_END_HEIGHT);
int newEndValue = this.height;
@@ -374,38 +399,16 @@
}
});
startAnimator(animator, listener);
- child.setTag(clipTop ? TAG_ANIMATOR_TOP_INSET:TAG_ANIMATOR_BOTTOM_INSET, animator);
- child.setTag(clipTop ? TAG_START_TOP_INSET: TAG_START_BOTTOM_INSET,
+ child.setTag(clipTop ? TAG_ANIMATOR_TOP_INSET : TAG_ANIMATOR_BOTTOM_INSET, animator);
+ child.setTag(clipTop ? TAG_START_TOP_INSET : TAG_START_BOTTOM_INSET,
clipTop ? child.getClipTopAmount() : child.getClipBottomAmount());
- child.setTag(clipTop ? TAG_END_TOP_INSET: TAG_END_BOTTOM_INSET, newEndValue);
- }
-
- /**
- * Get the end value of the height animation running on a view or the actualHeight
- * if no animation is running.
- */
- public static int getFinalActualHeight(ExpandableView view) {
- if (view == null) {
- return 0;
- }
- ValueAnimator heightAnimator = getChildTag(view, TAG_ANIMATOR_HEIGHT);
- if (heightAnimator == null) {
- return view.getActualHeight();
- } else {
- return getChildTag(view, TAG_END_HEIGHT);
- }
+ child.setTag(clipTop ? TAG_END_TOP_INSET : TAG_END_BOTTOM_INSET, newEndValue);
}
@Override
public void cancelAnimations(View view) {
super.cancelAnimations(view);
- Animator animator = getChildTag(view, TAG_ANIMATOR_HEIGHT);
- if (animator != null) {
- animator.cancel();
- }
- animator = getChildTag(view, TAG_ANIMATOR_TOP_INSET);
- if (animator != null) {
- animator.cancel();
- }
+ abortAnimation(view, TAG_ANIMATOR_HEIGHT);
+ abortAnimation(view, TAG_ANIMATOR_TOP_INSET);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManagerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManagerImpl.kt
index a507c4c..de4af37 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManagerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManagerImpl.kt
@@ -73,7 +73,7 @@
updateMagneticAndRoundableTargets(swipingRow, stackScrollLayout, sectionsManager)
currentState = State.TARGETS_SET
} else {
- logger.logMagneticAndRoundableTargetsNotSet(currentState, swipingRow.entry)
+ logger.logMagneticAndRoundableTargetsNotSet(currentState, swipingRow.loggingKey)
}
}
@@ -95,12 +95,15 @@
notificationTargetsHelper.findMagneticTargets(
expandableNotificationRow,
stackScrollLayout,
+ sectionsManager,
MAGNETIC_TRANSLATION_MULTIPLIERS.size,
)
- currentMagneticListeners.swipedListener()?.cancelTranslationAnimations()
newListeners.forEach {
if (currentMagneticListeners.contains(it)) {
it?.cancelMagneticAnimations()
+ if (it == currentMagneticListeners.swipedListener()) {
+ it?.cancelTranslationAnimations()
+ }
}
}
currentMagneticListeners = newListeners
@@ -116,7 +119,7 @@
currentMagneticListeners.swipedListener()?.canRowBeDismissed() ?: false
when (currentState) {
State.IDLE -> {
- logger.logMagneticRowTranslationNotSet(currentState, row.entry)
+ logger.logMagneticRowTranslationNotSet(currentState, row.getLoggingKey())
return false
}
State.TARGETS_SET -> {
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 ee57d45..1d18535 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
@@ -1352,10 +1352,11 @@
if (i < maxAllowedVisibleChildren) {
float singleLineHeight = child.getShowingLayout().getMinHeight(
false /* likeGroupExpanded */);
- child.setActualHeight((int) NotificationUtils.interpolate(singleLineHeight,
- childHeight, fraction), false);
+ childHeight = NotificationUtils.interpolate(singleLineHeight,
+ childHeight, fraction);
+ child.setFinalActualHeight((int) childHeight);
} else {
- child.setActualHeight((int) childHeight, false);
+ child.setFinalActualHeight((int) childHeight);
}
}
}
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 b9352bf..3d60e03 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
@@ -26,6 +26,7 @@
import static com.android.internal.jank.InteractionJankMonitor.CUJ_SHADE_CLEAR_ALL;
import static com.android.systemui.Flags.magneticNotificationSwipes;
import static com.android.systemui.Flags.notificationOverExpansionClippingFix;
+import static com.android.systemui.Flags.physicalNotificationMovement;
import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_SILENT;
import static com.android.systemui.statusbar.notification.stack.StackStateAnimator.ANIMATION_DURATION_SWIPE;
import static com.android.systemui.statusbar.notification.stack.shared.model.AccessibilityScrollEvent.SCROLL_DOWN;
@@ -109,6 +110,7 @@
import com.android.systemui.statusbar.notification.LaunchAnimationParameters;
import com.android.systemui.statusbar.notification.NotificationTransitionAnimatorController;
import com.android.systemui.statusbar.notification.NotificationUtils;
+import com.android.systemui.statusbar.notification.PhysicsPropertyAnimator;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
@@ -122,6 +124,7 @@
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableView;
import com.android.systemui.statusbar.notification.row.StackScrollerDecorView;
+import com.android.systemui.statusbar.notification.shared.NotificationBundleUi;
import com.android.systemui.statusbar.notification.shared.NotificationContentAlphaOptimization;
import com.android.systemui.statusbar.notification.shared.NotificationHeadsUpCycling;
import com.android.systemui.statusbar.notification.shared.NotificationThrottleHun;
@@ -2958,9 +2961,13 @@
}
private boolean isChildInGroup(View child) {
- return child instanceof ExpandableNotificationRow
- && mGroupMembershipManager.isChildInGroup(
- ((ExpandableNotificationRow) child).getEntry());
+ if (child instanceof ExpandableNotificationRow) {
+ ExpandableNotificationRow childRow = (ExpandableNotificationRow) child;
+ return NotificationBundleUi.isEnabled()
+ ? mGroupMembershipManager.isChildInGroup(childRow.getEntryAdapter())
+ : mGroupMembershipManager.isChildInGroup(childRow.getEntry());
+ }
+ return false;
}
/**
@@ -3639,6 +3646,9 @@
mScrollViewFields.sendCurrentGestureInGuts(false);
mScrollViewFields.sendCurrentGestureOverscroll(false);
setIsBeingDragged(false);
+ // dispatch to touchHandlers, so they can still finalize a previously started
+ // motion, while the shade is being dragged
+ return super.dispatchTouchEvent(ev);
}
return false;
}
@@ -5753,7 +5763,12 @@
+ view.getActualHeight() - mShelf.getIntrinsicHeight();
}
} else if (!firstVisibleView) {
- view.setTranslationY(wakeUplocation);
+ if (physicalNotificationMovement()) {
+ PhysicsPropertyAnimator.setProperty(view, PhysicsPropertyAnimator.Y_TRANSLATION,
+ wakeUplocation);
+ } else {
+ view.setTranslationY(wakeUplocation);
+ }
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationTargetsHelper.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationTargetsHelper.kt
index b69b936..8d7b2209 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationTargetsHelper.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationTargetsHelper.kt
@@ -5,7 +5,6 @@
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.statusbar.NotificationShelf
import com.android.systemui.statusbar.notification.Roundable
-import com.android.systemui.statusbar.notification.footer.ui.view.FooterView
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.row.ExpandableView
import javax.inject.Inject
@@ -88,6 +87,7 @@
*
* @param[viewSwiped] The [ExpandableNotificationRow] that is swiped.
* @param[stackScrollLayout] [NotificationStackScrollLayout] container.
+ * @param[sectionsManager] The [NotificationSectionsManager]
* @param[totalMagneticTargets] The total number of magnetic listeners in the resulting list.
* This includes the listener of the view swiped.
* @return The list of [MagneticRowListener]s above and below the swiped
@@ -96,6 +96,7 @@
fun findMagneticTargets(
viewSwiped: ExpandableNotificationRow,
stackScrollLayout: NotificationStackScrollLayout,
+ sectionsManager: NotificationSectionsManager,
totalMagneticTargets: Int,
): List<MagneticRowListener?> {
val notificationParent = viewSwiped.notificationParent
@@ -126,26 +127,34 @@
var canMoveRight = true
for (distance in 1..totalMagneticTargets / 2) {
if (canMoveLeft) {
- val leftElement = container.getOrNull(index = centerIndex - distance)
+ val leftElement =
+ container.getOrNull(index = centerIndex - distance)?.takeIf {
+ it.isValidMagneticBoundary() ||
+ !sectionsManager.beginsSection(view = viewSwiped, previous = it)
+ }
if (leftElement is ExpandableNotificationRow) {
magneticTargets[leftIndex] = leftElement.magneticRowListener
leftIndex--
} else {
if (leftElement.isValidMagneticBoundary()) {
- // Add the boundary and then stop the iterating
+ // Add the boundary and then stop iterating
magneticTargets[leftIndex] = leftElement?.magneticRowListener
}
canMoveLeft = false
}
}
if (canMoveRight) {
- val rightElement = container.getOrNull(index = centerIndex + distance)
+ val rightElement =
+ container.getOrNull(index = centerIndex + distance)?.takeIf {
+ it.isValidMagneticBoundary() ||
+ !sectionsManager.beginsSection(view = it, previous = viewSwiped)
+ }
if (rightElement is ExpandableNotificationRow) {
magneticTargets[rightIndex] = rightElement.magneticRowListener
rightIndex++
} else {
if (rightElement.isValidMagneticBoundary()) {
- // Add the boundary and then stop the iterating
+ // Add the boundary and then stop iterating
magneticTargets[rightIndex] = rightElement?.magneticRowListener
}
canMoveRight = false
@@ -157,7 +166,6 @@
private fun ExpandableView?.isValidMagneticBoundary(): Boolean =
when (this) {
- is FooterView,
is NotificationShelf,
is SectionHeaderView -> true
else -> false
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java
index c783250..5e0d57e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java
@@ -16,6 +16,8 @@
package com.android.systemui.statusbar.notification.stack;
+import static com.android.systemui.Flags.physicalNotificationMovement;
+import static com.android.systemui.statusbar.notification.row.ExpandableView.HEIGHT_PROPERTY;
import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_HEADS_UP_APPEAR;
import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_HEADS_UP_CYCLING_IN;
import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_HEADS_UP_CYCLING_OUT;
@@ -29,11 +31,14 @@
import android.util.Property;
import android.view.View;
+import androidx.dynamicanimation.animation.DynamicAnimation;
+
import com.android.app.animation.Interpolators;
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.res.R;
import com.android.systemui.shared.clocks.AnimatableClockView;
import com.android.systemui.statusbar.NotificationShelf;
+import com.android.systemui.statusbar.notification.PhysicsPropertyAnimator;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableView;
import com.android.systemui.statusbar.notification.row.StackScrollerDecorView;
@@ -41,6 +46,7 @@
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Stack;
+import java.util.function.Consumer;
/**
* An stack state animator which handles animations to new StackScrollStates
@@ -68,8 +74,10 @@
public static final int DELAY_EFFECT_MAX_INDEX_DIFFERENCE = 2;
private static final int MAX_STAGGER_COUNT = 5;
- @VisibleForTesting int mGoToFullShadeAppearingTranslation;
- @VisibleForTesting float mHeadsUpAppearStartAboveScreen;
+ @VisibleForTesting
+ int mGoToFullShadeAppearingTranslation;
+ @VisibleForTesting
+ float mHeadsUpAppearStartAboveScreen;
// Padding between the old and new heads up notifications for the hun cycling animation
private float mHeadsUpCyclingPadding;
private final ExpandableViewState mTmpState = new ExpandableViewState();
@@ -80,8 +88,9 @@
private ArrayList<View> mNewAddChildren = new ArrayList<>();
private HashSet<View> mHeadsUpAppearChildren = new HashSet<>();
private HashSet<View> mHeadsUpDisappearChildren = new HashSet<>();
- private HashSet<Animator> mAnimatorSet = new HashSet<>();
+ private HashSet<Object> mAnimatorSet = new HashSet<>();
private Stack<AnimatorListenerAdapter> mAnimationListenerPool = new Stack<>();
+ private Stack<DynamicAnimation.OnAnimationEndListener> mAnimationEndPool = new Stack<>();
private AnimationFilter mAnimationFilter = new AnimationFilter();
private long mCurrentLength;
private long mCurrentAdditionalDelay;
@@ -99,6 +108,9 @@
mHostLayout = hostLayout;
initView(context);
mAnimationProperties = new AnimationProperties() {
+
+ private final Consumer<DynamicAnimation> mDynamicAnimationConsumer = mAnimatorSet::add;
+
@Override
public AnimationFilter getAnimationFilter() {
return mAnimationFilter;
@@ -110,6 +122,17 @@
}
@Override
+ public DynamicAnimation.OnAnimationEndListener getAnimationEndListener(
+ Property property) {
+ return getGlobalAnimationEndListener();
+ }
+
+ @Override
+ public Consumer<DynamicAnimation> getAnimationStartListener(Property property) {
+ return mDynamicAnimationConsumer;
+ }
+
+ @Override
public boolean wasAdded(View view) {
return mNewAddChildren.contains(view);
}
@@ -187,11 +210,11 @@
adaptDurationWhenGoingToFullShade(child, viewState, wasAdded, animationStaggerCount);
mAnimationProperties.delay = 0;
if (wasAdded || mAnimationFilter.hasDelays
- && (viewState.getYTranslation() != child.getTranslationY()
- || viewState.getZTranslation() != child.getTranslationZ()
- || viewState.getAlpha() != child.getAlpha()
- || viewState.height != child.getActualHeight()
- || viewState.clipTopAmount != child.getClipTopAmount())) {
+ && (viewState.getYTranslation() != child.getTranslationY()
+ || viewState.getZTranslation() != child.getTranslationZ()
+ || viewState.getAlpha() != child.getAlpha()
+ || viewState.height != child.getActualHeight()
+ || viewState.clipTopAmount != child.getClipTopAmount())) {
mAnimationProperties.delay = mCurrentAdditionalDelay
+ calculateChildAnimationDelay(viewState, animationStaggerCount);
}
@@ -209,7 +232,13 @@
mAnimationProperties.duration = ANIMATION_DURATION_APPEAR_DISAPPEAR + 50
+ (long) (100 * longerDurationFactor);
}
- child.setTranslationY(viewState.getYTranslation() + startOffset);
+ float newTranslationY = viewState.getYTranslation() + startOffset;
+ if (physicalNotificationMovement()) {
+ PhysicsPropertyAnimator.setProperty(child, PhysicsPropertyAnimator.Y_TRANSLATION,
+ newTranslationY);
+ } else {
+ child.setTranslationY(newTranslationY);
+ }
}
}
@@ -312,7 +341,7 @@
/**
* @return an adapter which ensures that onAnimationFinished is called once no animation is
- * running anymore
+ * running anymore
*/
private AnimatorListenerAdapter getGlobalAnimationFinishedListener() {
if (!mAnimationListenerPool.empty()) {
@@ -345,6 +374,27 @@
};
}
+ /**
+ * @return an adapter which ensures that onAnimationFinished is called once no animation is
+ * running anymore
+ */
+ private DynamicAnimation.OnAnimationEndListener getGlobalAnimationEndListener() {
+ if (!mAnimationEndPool.empty()) {
+ return mAnimationEndPool.pop();
+ }
+ return new DynamicAnimation.OnAnimationEndListener() {
+ @Override
+ public void onAnimationEnd(DynamicAnimation animation, boolean canceled, float value,
+ float velocity) {
+ mAnimatorSet.remove(animation);
+ if (mAnimatorSet.isEmpty() && !canceled) {
+ onAnimationFinished();
+ }
+ mAnimationEndPool.push(this);
+ }
+ };
+ }
+
private void onAnimationFinished() {
mHostLayout.onChildAnimationFinished();
@@ -358,7 +408,7 @@
* Process the animationEvents for a new animation. Here is the place to do something custom,
* like to modify the ViewState or to create a custom animation for an event.
*
- * @param animationEvents the animation events for the animation to perform
+ * @param animationEvents the animation events for the animation to perform
* @return true if any custom animation was created
*/
private boolean processAnimationEvents(
@@ -428,7 +478,7 @@
translationDirection = ((viewState.getYTranslation()
- (ownPosition + actualHeight / 2.0f)) * 2 /
actualHeight);
- translationDirection = Math.max(Math.min(translationDirection, 1.0f),-1.0f);
+ translationDirection = Math.max(Math.min(translationDirection, 1.0f), -1.0f);
}
Runnable postAnimation;
@@ -446,7 +496,7 @@
changingView.removeFromTransientContainer();
};
} else {
- startAnimation = ()-> {
+ startAnimation = () -> {
changingView.setInRemovalAnimation(true);
};
postAnimation = () -> {
@@ -460,7 +510,7 @@
ExpandableView.ClipSide.BOTTOM);
needsCustomAnimation = true;
} else if (event.animationType ==
- NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_REMOVE_SWIPED_OUT) {
+ NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_REMOVE_SWIPED_OUT) {
boolean isFullySwipedOut = mHostLayout.isFullySwipedOut(changingView);
if (loggable) {
mLogger.processAnimationEventsRemoveSwipeOut(key, isFullySwipedOut, isHeadsUp);
@@ -699,8 +749,8 @@
/**
* @param headsUpFromBottom Whether we are showing the HUNs at the bottom of the screen
- * @param oldHunHeight Height of the old HUN
- * @param newHunHeight Height of the new HUN
+ * @param oldHunHeight Height of the old HUN
+ * @param newHunHeight Height of the new HUN
* @return The y translation target value of the HUN cycling out animation
*/
private float getHeadsUpCyclingOutYTranslation(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ViewState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ViewState.java
index b2ffa4a..2ef6f36 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ViewState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ViewState.java
@@ -16,6 +16,10 @@
package com.android.systemui.statusbar.notification.stack;
+import static com.android.systemui.Flags.physicalNotificationMovement;
+import static com.android.systemui.statusbar.notification.PhysicsPropertyAnimator.TAG_ANIMATOR_TRANSLATION_Y;
+import static com.android.systemui.statusbar.notification.PhysicsPropertyAnimator.Y_TRANSLATION;
+
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
@@ -26,14 +30,20 @@
import android.view.View;
import android.view.animation.Interpolator;
+import androidx.dynamicanimation.animation.DynamicAnimation;
+import androidx.dynamicanimation.animation.SpringAnimation;
+
import com.android.app.animation.Interpolators;
import com.android.systemui.Dumpable;
import com.android.systemui.res.R;
import com.android.systemui.statusbar.notification.AnimatableProperty;
import com.android.systemui.statusbar.notification.NotificationFadeAware.FadeOptimizedNotification;
+import com.android.systemui.statusbar.notification.PhysicsProperty;
+import com.android.systemui.statusbar.notification.PhysicsPropertyAnimator;
import com.android.systemui.statusbar.notification.PropertyAnimator;
-import com.android.systemui.statusbar.notification.row.ExpandableView;
+import com.android.systemui.statusbar.notification.PropertyData;
import com.android.systemui.statusbar.notification.headsup.HeadsUpUtil;
+import com.android.systemui.statusbar.notification.row.ExpandableView;
import java.io.PrintWriter;
import java.lang.reflect.Field;
@@ -46,6 +56,14 @@
*/
public class ViewState implements Dumpable {
+ public ViewState() {
+ this(physicalNotificationMovement());
+ }
+
+ public ViewState(boolean usePhysicsForMovement) {
+ setUsePhysicsForMovement(usePhysicsForMovement);
+ }
+
/**
* Some animation properties that can be used to update running animations but not creating
* any new ones.
@@ -59,7 +77,6 @@
}
};
private static final int TAG_ANIMATOR_TRANSLATION_X = R.id.translation_x_animator_tag;
- private static final int TAG_ANIMATOR_TRANSLATION_Y = R.id.translation_y_animator_tag;
private static final int TAG_ANIMATOR_TRANSLATION_Z = R.id.translation_z_animator_tag;
private static final int TAG_ANIMATOR_ALPHA = R.id.alpha_animator_tag;
private static final int TAG_END_TRANSLATION_X = R.id.translation_x_animator_end_value_tag;
@@ -72,8 +89,7 @@
private static final int TAG_START_ALPHA = R.id.alpha_animator_start_value_tag;
private static final String LOG_TAG = "StackViewState";
- private static final AnimatableProperty SCALE_X_PROPERTY
- = new AnimatableProperty() {
+ private static final AnimatableProperty SCALE_X_PROPERTY = new AnimatableProperty() {
@Override
public int getAnimationStartTag() {
@@ -96,8 +112,7 @@
}
};
- private static final AnimatableProperty SCALE_Y_PROPERTY
- = new AnimatableProperty() {
+ private static final AnimatableProperty SCALE_Y_PROPERTY = new AnimatableProperty() {
@Override
public int getAnimationStartTag() {
@@ -129,11 +144,16 @@
private float mZTranslation;
private float mScaleX = 1.0f;
private float mScaleY = 1.0f;
+ protected boolean mUsePhysicsForMovement = false;
public float getAlpha() {
return mAlpha;
}
+ public void setUsePhysicsForMovement(boolean usePhysicsForMovement) {
+ this.mUsePhysicsForMovement = usePhysicsForMovement;
+ }
+
/**
* @param alpha View transparency.
*/
@@ -230,6 +250,7 @@
hidden = viewState.hidden;
mScaleX = viewState.mScaleX;
mScaleY = viewState.mScaleY;
+ mUsePhysicsForMovement = viewState.mUsePhysicsForMovement;
}
public void initFrom(View view) {
@@ -261,11 +282,15 @@
}
// apply yTranslation
- boolean animatingY = isAnimating(view, TAG_ANIMATOR_TRANSLATION_Y);
- if (animatingY) {
- updateAnimationY(view);
- } else if (view.getTranslationY() != this.mYTranslation) {
- view.setTranslationY(this.mYTranslation);
+ if (mUsePhysicsForMovement) {
+ PhysicsPropertyAnimator.setProperty(view, Y_TRANSLATION, this.mYTranslation);
+ } else {
+ boolean animatingY = isAnimating(view, TAG_ANIMATOR_TRANSLATION_Y);
+ if (animatingY) {
+ updateAnimationY(view);
+ } else if (view.getTranslationY() != this.mYTranslation) {
+ view.setTranslationY(this.mYTranslation);
+ }
}
// apply zTranslation
@@ -293,8 +318,8 @@
}
int oldVisibility = view.getVisibility();
- boolean becomesInvisible = this.mAlpha == 0.0f
- || (this.hidden && (!isAnimating(view) || oldVisibility != View.VISIBLE));
+ boolean becomesInvisible = this.mAlpha == 0.0f || (this.hidden && (!isAnimating(view)
+ || oldVisibility != View.VISIBLE));
boolean animatingAlpha = isAnimating(view, TAG_ANIMATOR_ALPHA);
if (animatingAlpha) {
updateAlphaAnimation(view);
@@ -315,9 +340,8 @@
} else {
boolean newLayerTypeIsHardware = becomesFaded && view.hasOverlappingRendering();
int layerType = view.getLayerType();
- int newLayerType = newLayerTypeIsHardware
- ? View.LAYER_TYPE_HARDWARE
- : View.LAYER_TYPE_NONE;
+ int newLayerType =
+ newLayerTypeIsHardware ? View.LAYER_TYPE_HARDWARE : View.LAYER_TYPE_NONE;
if (layerType != newLayerType) {
view.setLayerType(newLayerType, null);
}
@@ -360,11 +384,19 @@
}
private static boolean isAnimating(View view, int tag) {
- return getChildTag(view, tag) != null;
+ Object childTag = getChildTag(view, tag);
+ if (childTag instanceof PropertyData propertyData) {
+ return propertyData.getAnimator() != null;
+ }
+ return childTag != null;
}
public static boolean isAnimating(View view, AnimatableProperty property) {
- return getChildTag(view, property.getAnimatorTag()) != null;
+ Object childTag = getChildTag(view, property.getAnimatorTag());
+ if (childTag instanceof PropertyData propertyData) {
+ return propertyData.getAnimator() != null;
+ }
+ return childTag != null;
}
/**
@@ -376,8 +408,7 @@
public void animateTo(View child, AnimationProperties animationProperties) {
boolean wasVisible = child.getVisibility() == View.VISIBLE;
final float alpha = this.mAlpha;
- if (!wasVisible && (alpha != 0 || child.getAlpha() != 0)
- && !this.gone && !this.hidden) {
+ if (!wasVisible && (alpha != 0 || child.getAlpha() != 0) && !this.gone && !this.hidden) {
child.setVisibility(View.VISIBLE);
}
float childAlpha = child.getAlpha();
@@ -465,8 +496,8 @@
}
}
- ObjectAnimator animator = ObjectAnimator.ofFloat(child, View.ALPHA,
- child.getAlpha(), newEndValue);
+ ObjectAnimator animator = ObjectAnimator.ofFloat(child, View.ALPHA, child.getAlpha(),
+ newEndValue);
animator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
// Handle layer type
child.setLayerType(View.LAYER_TYPE_HARDWARE, null);
@@ -516,8 +547,7 @@
startZTranslationAnimation(view, NO_NEW_ANIMATIONS);
}
- private void updateAnimation(View view, AnimatableProperty property,
- float endValue) {
+ private void updateAnimation(View view, AnimatableProperty property, float endValue) {
PropertyAnimator.startAnimation(view, property, endValue, NO_NEW_ANIMATIONS);
}
@@ -615,8 +645,8 @@
child.getTranslationX(), newEndValue);
Interpolator customInterpolator = properties.getCustomInterpolator(child,
View.TRANSLATION_X);
- Interpolator interpolator = customInterpolator != null ? customInterpolator
- : Interpolators.FAST_OUT_SLOW_IN;
+ Interpolator interpolator =
+ customInterpolator != null ? customInterpolator : Interpolators.FAST_OUT_SLOW_IN;
animator.setInterpolator(interpolator);
long newDuration = cancelAnimatorAndGetNewDuration(properties.duration, previousAnimator);
animator.setDuration(newDuration);
@@ -649,6 +679,24 @@
}
private void startYTranslationAnimation(final View child, AnimationProperties properties) {
+ if (mUsePhysicsForMovement) {
+ // Y Translation does some extra calls when it ends, so lets add a listener
+ DynamicAnimation.OnAnimationEndListener endListener =
+ (animation, canceled, value, velocity) -> {
+ if (!canceled) {
+ HeadsUpUtil.setNeedsHeadsUpDisappearAnimationAfterClick(child, false);
+ onYTranslationAnimationFinished(child);
+ }
+ };
+ PhysicsPropertyAnimator.setProperty(child, Y_TRANSLATION, this.mYTranslation,
+ properties, properties.getAnimationFilter().animateY, endListener);
+ } else {
+ startYTranslationInterpolatorAnimation(child, properties);
+ }
+ }
+
+ private void startYTranslationInterpolatorAnimation(View child,
+ AnimationProperties properties) {
Float previousStartValue = getChildTag(child, TAG_START_TRANSLATION_Y);
Float previousEndValue = getChildTag(child, TAG_END_TRANSLATION_Y);
float newEndValue = this.mYTranslation;
@@ -681,8 +729,8 @@
child.getTranslationY(), newEndValue);
Interpolator customInterpolator = properties.getCustomInterpolator(child,
View.TRANSLATION_Y);
- Interpolator interpolator = customInterpolator != null ? customInterpolator
- : Interpolators.FAST_OUT_SLOW_IN;
+ Interpolator interpolator =
+ customInterpolator != null ? customInterpolator : Interpolators.FAST_OUT_SLOW_IN;
animator.setInterpolator(interpolator);
long newDuration = cancelAnimatorAndGetNewDuration(properties.duration, previousAnimator);
animator.setDuration(newDuration);
@@ -731,9 +779,19 @@
}
protected void abortAnimation(View child, int animatorTag) {
- Animator previousAnimator = getChildTag(child, animatorTag);
- if (previousAnimator != null) {
- previousAnimator.cancel();
+ Object storedTag = getChildTag(child, animatorTag);
+ if (storedTag != null) {
+ if (storedTag instanceof Animator animator) {
+ animator.cancel();
+ } else if (storedTag instanceof PropertyData propertyData) {
+ // Physics based animation!
+ Runnable delayRunnable = propertyData.getDelayRunnable();
+ child.removeCallbacks(delayRunnable);
+ SpringAnimation animator = propertyData.getAnimator();
+ if (animator != null) {
+ animator.cancel();
+ }
+ }
}
}
@@ -750,46 +808,15 @@
if (previousAnimator != null) {
// We take either the desired length of the new animation or the remaining time of
// the previous animator, whichever is longer.
- newDuration = Math.max(previousAnimator.getDuration()
- - previousAnimator.getCurrentPlayTime(), newDuration);
+ newDuration = Math.max(
+ previousAnimator.getDuration() - previousAnimator.getCurrentPlayTime(),
+ newDuration);
previousAnimator.cancel();
}
return newDuration;
}
/**
- * Get the end value of the xTranslation animation running on a view or the xTranslation
- * if no animation is running.
- */
- public static float getFinalTranslationX(View view) {
- if (view == null) {
- return 0;
- }
- ValueAnimator xAnimator = getChildTag(view, TAG_ANIMATOR_TRANSLATION_X);
- if (xAnimator == null) {
- return view.getTranslationX();
- } else {
- return getChildTag(view, TAG_END_TRANSLATION_X);
- }
- }
-
- /**
- * Get the end value of the yTranslation animation running on a view or the yTranslation
- * if no animation is running.
- */
- public static float getFinalTranslationY(View view) {
- if (view == null) {
- return 0;
- }
- ValueAnimator yAnimator = getChildTag(view, TAG_ANIMATOR_TRANSLATION_Y);
- if (yAnimator == null) {
- return view.getTranslationY();
- } else {
- return getChildTag(view, TAG_END_TRANSLATION_Y);
- }
- }
-
- /**
* Get the end value of the zTranslation animation running on a view or the zTranslation
* if no animation is running.
*/
@@ -806,26 +833,14 @@
}
public static boolean isAnimatingY(View child) {
- return getChildTag(child, TAG_ANIMATOR_TRANSLATION_Y) != null;
+ return isAnimating(child, TAG_ANIMATOR_TRANSLATION_Y);
}
public void cancelAnimations(View view) {
- Animator animator = getChildTag(view, TAG_ANIMATOR_TRANSLATION_X);
- if (animator != null) {
- animator.cancel();
- }
- animator = getChildTag(view, TAG_ANIMATOR_TRANSLATION_Y);
- if (animator != null) {
- animator.cancel();
- }
- animator = getChildTag(view, TAG_ANIMATOR_TRANSLATION_Z);
- if (animator != null) {
- animator.cancel();
- }
- animator = getChildTag(view, TAG_ANIMATOR_ALPHA);
- if (animator != null) {
- animator.cancel();
- }
+ abortAnimation(view, TAG_ANIMATOR_TRANSLATION_X);
+ abortAnimation(view, TAG_ANIMATOR_TRANSLATION_Y);
+ abortAnimation(view, TAG_ANIMATOR_TRANSLATION_Z);
+ abortAnimation(view, TAG_ANIMATOR_ALPHA);
}
@Override
@@ -840,8 +855,8 @@
// Print field names paired with their values
for (Field field : fields) {
int modifiers = field.getModifiers();
- if (Modifier.isStatic(modifiers) || field.isSynthetic()
- || Modifier.isTransient(modifiers)) {
+ if (Modifier.isStatic(modifiers) || field.isSynthetic() || Modifier.isTransient(
+ modifiers)) {
continue;
}
if (!first) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/ShadeScrimBounds.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/ShadeScrimBounds.kt
index 832e690..78ece53 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/ShadeScrimBounds.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/ShadeScrimBounds.kt
@@ -16,6 +16,8 @@
package com.android.systemui.statusbar.notification.stack.shared.model
+import androidx.compose.ui.geometry.Rect
+
/** Models the bounds of the notification stack. */
data class ShadeScrimBounds(
/** The position of the left of the stack in its window coordinate system, in pixels. */
@@ -27,6 +29,10 @@
/** The position of the bottom of the stack in its window coordinate system, in pixels. */
val bottom: Float = 0f,
) {
+ constructor(
+ bounds: Rect
+ ) : this(left = bounds.left, top = bounds.top, right = bounds.right, bottom = bounds.bottom)
+
/** The current height of the notification container. */
val height: Float = bottom - top
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationListViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationListViewBinder.kt
index 6385d53..10b665d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationListViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationListViewBinder.kt
@@ -25,7 +25,7 @@
import com.android.internal.logging.nano.MetricsProto
import com.android.systemui.common.ui.ConfigurationState
import com.android.systemui.common.ui.view.setImportantForAccessibilityYesNo
-import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.dagger.qualifiers.NotifInflation
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.lifecycle.repeatWhenAttachedToWindow
import com.android.systemui.plugins.FalsingManager
@@ -76,7 +76,7 @@
class NotificationListViewBinder
@Inject
constructor(
- @Background private val backgroundDispatcher: CoroutineDispatcher,
+ @NotifInflation private val inflationDispatcher: CoroutineDispatcher,
private val hiderTracker: DisplaySwitchNotificationsHiderTracker,
@ShadeDisplayAware private val configuration: ConfigurationState,
private val falsingManager: FalsingManager,
@@ -155,7 +155,7 @@
parentView,
attachToRoot = false,
)
- .flowOn(backgroundDispatcher)
+ .flowOn(inflationDispatcher)
.collectLatest { footerView: FooterView ->
traceAsync("bind FooterView") {
parentView.setFooterView(footerView)
@@ -240,7 +240,7 @@
parentView,
attachToRoot = false,
)
- .flowOn(backgroundDispatcher)
+ .flowOn(inflationDispatcher)
.collectLatest { emptyShadeView: EmptyShadeView ->
traceAsync("bind EmptyShadeView") {
parentView.setEmptyShadeView(emptyShadeView)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
index 2c8c7a1..54efa4a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
@@ -48,7 +48,6 @@
import com.android.systemui.keyguard.ui.viewmodel.AodToLockscreenTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.AodToOccludedTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.AodToPrimaryBouncerTransitionViewModel
-import com.android.systemui.keyguard.ui.viewmodel.DozingToDreamingTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.DozingToGlanceableHubTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.DozingToLockscreenTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.DozingToOccludedTransitionViewModel
@@ -137,7 +136,6 @@
private val aodToLockscreenTransitionViewModel: AodToLockscreenTransitionViewModel,
private val aodToOccludedTransitionViewModel: AodToOccludedTransitionViewModel,
private val aodToPrimaryBouncerTransitionViewModel: AodToPrimaryBouncerTransitionViewModel,
- private val dozingToDreamingTransitionViewModel: DozingToDreamingTransitionViewModel,
dozingToGlanceableHubTransitionViewModel: DozingToGlanceableHubTransitionViewModel,
private val dozingToLockscreenTransitionViewModel: DozingToLockscreenTransitionViewModel,
private val dozingToOccludedTransitionViewModel: DozingToOccludedTransitionViewModel,
@@ -574,7 +572,6 @@
aodToLockscreenTransitionViewModel.notificationAlpha,
aodToOccludedTransitionViewModel.lockscreenAlpha(viewState),
aodToPrimaryBouncerTransitionViewModel.notificationAlpha,
- dozingToDreamingTransitionViewModel.notificationAlpha,
dozingToLockscreenTransitionViewModel.lockscreenAlpha,
dozingToOccludedTransitionViewModel.lockscreenAlpha(viewState),
dozingToPrimaryBouncerTransitionViewModel.notificationAlpha,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
index 4825a10..15d73d2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
@@ -735,6 +735,7 @@
private final Consumer<Property> mCannedAnimationEndListener;
public IconState(View child) {
+ super(false /* usePhysicsForMovement */);
mView = child;
mCannedAnimationEndListener = (property) -> {
// If we finished animating out of the shelf
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java
index 1dc9de4..05a46cd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java
@@ -54,6 +54,7 @@
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
+import com.android.systemui.statusbar.notification.shared.NotificationBundleUi;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.kotlin.JavaAdapter;
@@ -215,7 +216,11 @@
if (ExpandHeadsUpOnInlineReply.isEnabled()) {
if (row.isChildInGroup() && !row.areChildrenExpanded()) {
// The group isn't expanded, let's make sure it's visible!
- mGroupExpansionManager.toggleGroupExpansion(row.getEntry());
+ if (NotificationBundleUi.isEnabled()) {
+ mGroupExpansionManager.toggleGroupExpansion(row.getEntryAdapter());
+ } else {
+ mGroupExpansionManager.toggleGroupExpansion(row.getEntry());
+ }
} else if (!row.isChildInGroup()) {
final boolean expandNotification;
if (row.isPinned()) {
@@ -233,7 +238,11 @@
} else {
if (row.isChildInGroup() && !row.areChildrenExpanded()) {
// The group isn't expanded, let's make sure it's visible!
- mGroupExpansionManager.toggleGroupExpansion(row.getEntry());
+ if (NotificationBundleUi.isEnabled()) {
+ mGroupExpansionManager.toggleGroupExpansion(row.getEntryAdapter());
+ } else {
+ mGroupExpansionManager.toggleGroupExpansion(row.getEntry());
+ }
}
if (android.app.Flags.compactHeadsUpNotificationReply()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java
index 144939d..38c0d28 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java
@@ -443,6 +443,11 @@
}
public static class StatusIconState extends ViewState {
+
+ public StatusIconState() {
+ super(false /* usePhysicsForMovement */);
+ }
+
/// StatusBarIconView.STATE_*
public int visibleState = STATE_ICON;
public boolean justAdded = true;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/StatusBarChipsModernization.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/StatusBarChipsModernization.kt
index 9f8b455..b77e8f2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/StatusBarChipsModernization.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/StatusBarChipsModernization.kt
@@ -23,6 +23,10 @@
@Suppress("NOTHING_TO_INLINE")
object StatusBarChipsModernization {
/** The aconfig flag name */
+ @Deprecated(
+ "For tests, use @EnableChipsModernization or @DisableChipsModernization " +
+ "annotations instead"
+ )
const val FLAG_NAME = Flags.FLAG_STATUS_BAR_CHIPS_MODERNIZATION
/** A token used for dependency declaration */
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 2fd7d82..d6ca656 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
@@ -150,7 +150,14 @@
return when {
isVisible -> {
logger.d({ "Call app is visible: uid=$int1" }) { int1 = model.uid }
- OngoingCallModel.InCallWithVisibleApp
+ OngoingCallModel.InCallWithVisibleApp(
+ startTimeMs = model.whenTime,
+ notificationIconView = model.statusBarChipIconView,
+ intent = model.contentIntent,
+ notificationKey = model.key,
+ appName = model.appName,
+ promotedContent = model.promotedContent,
+ )
}
else -> {
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 6507b72..62f0ba0 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
@@ -28,8 +28,21 @@
/**
* There is an ongoing call but the call app is currently visible, so we don't need to show the
* chip.
+ *
+ * @property startTimeMs see [InCall.startTimeMs].
+ * @property notificationIconView see [InCall.notificationIconView].
+ * @property intent see [InCall.intent].
+ * @property appName see [InCall.appName].
+ * @property promotedContent see [InCall.promotedContent].
*/
- data object InCallWithVisibleApp : OngoingCallModel
+ data class InCallWithVisibleApp(
+ val startTimeMs: Long,
+ val notificationIconView: StatusBarIconView?,
+ val intent: PendingIntent?,
+ val notificationKey: String,
+ val appName: String,
+ val promotedContent: PromotedNotificationContentModel?,
+ ) : OngoingCallModel
/**
* There *is* an ongoing call.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt
index a1f7a81..0eabb4ec 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt
@@ -37,10 +37,8 @@
import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flatMapLatest
@@ -255,12 +253,7 @@
}
.stateIn(scope, SharingStarted.WhileSubscribed(), false)
- override val isNonTerrestrial: StateFlow<Boolean> =
- if (Flags.carrierEnabledSatelliteFlag()) {
- connectionRepository.isNonTerrestrial
- } else {
- MutableStateFlow(false).asStateFlow()
- }
+ override val isNonTerrestrial: StateFlow<Boolean> = connectionRepository.isNonTerrestrial
override val isRoaming: StateFlow<Boolean> =
combine(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileView.kt
index 4458b22..7eda87f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileView.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileView.kt
@@ -19,6 +19,7 @@
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
+import android.widget.FrameLayout
import android.widget.ImageView
import com.android.systemui.res.R
import com.android.systemui.statusbar.StatusBarIconView.getVisibleStateString
@@ -61,12 +62,33 @@
.also {
// Flag-specific configuration
if (NewStatusBarIcons.isEnabled) {
- val iconView = it.requireViewById<ImageView>(R.id.mobile_signal)
- val lp = iconView.layoutParams
- lp.height =
- context.resources.getDimensionPixelSize(
- R.dimen.status_bar_mobile_signal_size_updated
- )
+ // triangle
+ it.requireViewById<ImageView>(R.id.mobile_signal).apply {
+ layoutParams.height =
+ context.resources.getDimensionPixelSize(
+ R.dimen.status_bar_mobile_signal_size_updated
+ )
+ }
+
+ // RAT indicator container
+ it.requireViewById<FrameLayout>(R.id.mobile_type_container).apply {
+ (layoutParams as MarginLayoutParams).marginEnd =
+ context.resources.getDimensionPixelSize(
+ R.dimen.status_bar_mobile_container_margin_end
+ )
+ layoutParams.height =
+ context.resources.getDimensionPixelSize(
+ R.dimen.status_bar_mobile_container_height_updated
+ )
+ }
+
+ // RAT indicator
+ it.requireViewById<ImageView>(R.id.mobile_type).apply {
+ layoutParams.height =
+ context.resources.getDimensionPixelSize(
+ R.dimen.status_bar_mobile_type_size_updated
+ )
+ }
}
it.subId = viewModel.subscriptionId
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt
index 171e4f5..e37c3f1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt
@@ -23,6 +23,7 @@
import com.android.systemui.flags.Flags.NEW_NETWORK_SLICE_UI
import com.android.systemui.log.table.logDiffsForTable
import com.android.systemui.res.R
+import com.android.systemui.statusbar.core.NewStatusBarIcons
import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor
import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconInteractor
import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractor
@@ -278,10 +279,11 @@
flowOf(null)
} else {
iconInteractor.showSliceAttribution.map {
- if (it) {
- Icon.Resource(R.drawable.mobile_network_type_background, null)
- } else {
- null
+ when {
+ it && NewStatusBarIcons.isEnabled ->
+ Icon.Resource(R.drawable.mobile_network_type_background_updated, null)
+ it -> Icon.Resource(R.drawable.mobile_network_type_background, null)
+ else -> null
}
}
}
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 a961713..39a1b46 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
@@ -255,10 +255,9 @@
)
setContent {
- val chips =
- statusBarViewModel.statusBarPopupChips
- .collectAsStateWithLifecycle()
- StatusBarPopupChipsContainer(chips = chips.value)
+ StatusBarPopupChipsContainer(
+ chips = statusBarViewModel.popupChips
+ )
}
}
endSideContent.addView(composeView, 0)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt
index f396cbf..9ae2cb2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt
@@ -20,6 +20,7 @@
import android.graphics.Rect
import android.view.View
import androidx.compose.runtime.getValue
+import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
@@ -29,6 +30,7 @@
import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN
import com.android.systemui.keyguard.shared.model.KeyguardState.OCCLUDED
import com.android.systemui.keyguard.shared.model.TransitionState
+import com.android.systemui.lifecycle.Activatable
import com.android.systemui.lifecycle.ExclusiveActivatable
import com.android.systemui.lifecycle.Hydrator
import com.android.systemui.log.table.TableLogBufferFactory
@@ -49,6 +51,7 @@
import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipsViewModel
import com.android.systemui.statusbar.events.domain.interactor.SystemStatusEventAnimationInteractor
import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState.Idle
+import com.android.systemui.statusbar.featurepods.popups.StatusBarPopupChips
import com.android.systemui.statusbar.featurepods.popups.shared.model.PopupChipModel
import com.android.systemui.statusbar.featurepods.popups.ui.viewmodel.StatusBarPopupChipsViewModel
import com.android.systemui.statusbar.headsup.shared.StatusBarNoHunBehavior
@@ -71,6 +74,8 @@
import dagger.assisted.AssistedInject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.awaitCancellation
+import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
@@ -94,7 +99,7 @@
* [StatusBarHideIconsForBouncerManager]. We should move those pieces of logic to this class instead
* so that it's all in one place and easily testable outside of the fragment.
*/
-interface HomeStatusBarViewModel {
+interface HomeStatusBarViewModel : Activatable {
/** Factory to create the view model for the battery icon */
val batteryViewModelFactory: BatteryViewModel.Factory
@@ -133,7 +138,7 @@
val operatorNameViewModel: StatusBarOperatorNameViewModel
/** The popup chips that should be shown on the right-hand side of the status bar. */
- val statusBarPopupChips: StateFlow<List<PopupChipModel.Shown>>
+ val popupChips: List<PopupChipModel.Shown>
/**
* True if the current scene can show the home status bar (aka this status bar), and false if
@@ -208,7 +213,7 @@
shadeInteractor: ShadeInteractor,
shareToAppChipViewModel: ShareToAppChipViewModel,
ongoingActivityChipsViewModel: OngoingActivityChipsViewModel,
- statusBarPopupChipsViewModel: StatusBarPopupChipsViewModel,
+ statusBarPopupChipsViewModelFactory: StatusBarPopupChipsViewModel.Factory,
animations: SystemStatusEventAnimationInteractor,
statusBarContentInsetsViewModelStore: StatusBarContentInsetsViewModelStore,
@Background bgScope: CoroutineScope,
@@ -219,6 +224,8 @@
val tableLogger = tableLoggerFactory.getOrCreate(tableLogBufferName(thisDisplayId), 200)
+ private val statusBarPopupChips by lazy { statusBarPopupChipsViewModelFactory.create() }
+
override val isTransitioningFromLockscreenToOccluded: StateFlow<Boolean> =
keyguardTransitionInteractor
.isInTransition(Edge.create(from = LOCKSCREEN, to = OCCLUDED))
@@ -246,7 +253,8 @@
override val ongoingActivityChipsLegacy = ongoingActivityChipsViewModel.chipsLegacy
- override val statusBarPopupChips = statusBarPopupChipsViewModel.shownPopupChips
+ override val popupChips
+ get() = statusBarPopupChips.shownPopupChips
override val isHomeStatusBarAllowedByScene: StateFlow<Boolean> =
combine(
@@ -495,7 +503,13 @@
private fun Boolean.toVisibleOrInvisible(): Int = if (this) View.VISIBLE else View.INVISIBLE
override suspend fun onActivated(): Nothing {
- hydrator.activate()
+ coroutineScope {
+ launch { hydrator.activate() }
+ if (StatusBarPopupChips.isEnabled) {
+ launch { statusBarPopupChips.activate() }
+ }
+ awaitCancellation()
+ }
}
/** Inject this to create the display-dependent view model */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerImpl.java
index 9ab8175..36513f7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerImpl.java
@@ -24,6 +24,9 @@
import android.annotation.MainThread;
import android.app.IActivityManager;
+import android.app.role.OnRoleHoldersChangedListener;
+import android.app.role.RoleManager;
+import android.companion.AssociationRequest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.database.ExecutorContentObserver;
@@ -51,6 +54,8 @@
import com.android.systemui.util.ListenerSet;
import com.android.systemui.util.settings.GlobalSettings;
+import java.util.List;
+import java.util.Objects;
import java.util.Random;
import java.util.concurrent.Executor;
@@ -63,12 +68,14 @@
private static final String LOG_TAG = "SNPC";
private final SensitiveNotificationProtectionControllerLogger mLogger;
private final PackageManager mPackageManager;
+ private final RoleManager mRoleManager;
// Packages exempt from projection session protections (if they start a projection session)
private final ArraySet<String> mSessionProtectionExemptPackages = new ArraySet<>();
// Packages exempt from individual notification protections (if they post a notification)
private final ArraySet<String> mNotificationProtectionExemptPackages = new ArraySet<>();
private final ListenerSet<Runnable> mListeners = new ListenerSet<>();
private volatile MediaProjectionInfo mProjection;
+ private ArraySet<RoleHolder> mNotificationProtectionExemptByRolePackages = new ArraySet<>();
private SensitiveNotificatioMediaProjectionSession mActiveMediaProjectionSession;
boolean mDisableScreenShareProtections = false;
@@ -128,6 +135,27 @@
}
};
+ @VisibleForTesting
+ final OnRoleHoldersChangedListener mRoleHoldersChangedListener =
+ new OnRoleHoldersChangedListener() {
+ @Override
+ public void onRoleHoldersChanged(@NonNull String roleName,
+ @NonNull UserHandle user) {
+ if (!roleName.equals(AssociationRequest.DEVICE_PROFILE_APP_STREAMING)) {
+ return;
+ }
+
+ List<String> appStreamingRoleHolders = mRoleManager.getRoleHoldersAsUser(
+ roleName, user);
+ ArraySet<RoleHolder> roleHolders = new ArraySet<>();
+ for (String appStreamingRoleHolder : appStreamingRoleHolders) {
+ RoleHolder roleHolder = new RoleHolder(appStreamingRoleHolder, user);
+ roleHolders.add(roleHolder);
+ }
+ mNotificationProtectionExemptByRolePackages = roleHolders;
+ }
+ };
+
private void logSensitiveContentProtectionSessionStart(
long sessionId, int projectionAppUid, boolean exempt) {
mActiveMediaProjectionSession =
@@ -166,11 +194,13 @@
IActivityManager activityManager,
PackageManager packageManager,
TelephonyManager telephonyManager,
+ RoleManager roleManager,
@Main Handler mainHandler,
@Background Executor bgExecutor,
SensitiveNotificationProtectionControllerLogger logger) {
mLogger = logger;
mPackageManager = packageManager;
+ mRoleManager = roleManager;
if (!screenshareNotificationHiding()) {
return;
@@ -215,6 +245,8 @@
});
mediaProjectionManager.addCallback(mMediaProjectionCallback, mainHandler);
+ roleManager.addOnRoleHoldersChangedListenerAsUser(bgExecutor, mRoleHoldersChangedListener,
+ UserHandle.ALL);
}
@NonNull
@@ -314,6 +346,10 @@
Log.w(LOG_TAG, "Screen share protections exempt for package " + info.getPackageName()
+ " via permission");
return null;
+ } else if (info != null && isAppStreamingRoleHolder(info)) {
+ Log.w(LOG_TAG, "Screen share protections exempt for package " + info.getPackageName()
+ + " via role(s) held");
+ return null;
} else if (info != null && info.getLaunchCookie() != null) {
// Only enable sensitive content protection if sharing full screen
// Launch cookie only set (non-null) if sharing single app/task
@@ -323,11 +359,16 @@
return info;
}
+ private boolean isAppStreamingRoleHolder(@NonNull MediaProjectionInfo info) {
+ return mNotificationProtectionExemptByRolePackages.contains(
+ new RoleHolder(info.getPackageName(), info.getUserHandle()));
+ }
+
private boolean canRecordSensitiveContent(@NonNull String packageName) {
// RECORD_SENSITIVE_CONTENT is flagged api on sensitiveNotificationAppProtection
if (sensitiveNotificationAppProtection()) {
return mPackageManager.checkPermission(
- android.Manifest.permission.RECORD_SENSITIVE_CONTENT, packageName)
+ android.Manifest.permission.RECORD_SENSITIVE_CONTENT, packageName)
== PackageManager.PERMISSION_GRANTED;
}
return false;
@@ -382,4 +423,26 @@
boolean userForcesRedaction = entry.isChannelVisibilityPrivate();
return notificationRequestsRedaction || userForcesRedaction;
}
+
+ private static final class RoleHolder {
+ private final String mPackageName;
+ private final UserHandle mUserHandle;
+
+ RoleHolder(String packageName, UserHandle userHandle) {
+ mPackageName = packageName;
+ mUserHandle = userHandle;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof RoleHolder that)) return false;
+ return Objects.equals(mPackageName, that.mPackageName) && Objects.equals(
+ mUserHandle, that.mUserHandle);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mPackageName, mUserHandle);
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
index 28cf78f..9f60fe21 100644
--- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
+++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
@@ -18,8 +18,10 @@
import static android.util.TypedValue.TYPE_INT_COLOR_ARGB8;
+import static com.android.systemui.Flags.hardwareColorStyles;
import static com.android.systemui.Flags.themeOverlayControllerWakefulnessDeprecation;
import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_ASLEEP;
+import static com.android.systemui.monet.ColorScheme.GOOGLE_BLUE;
import static com.android.systemui.theme.ThemeOverlayApplier.COLOR_SOURCE_HOME;
import static com.android.systemui.theme.ThemeOverlayApplier.COLOR_SOURCE_LOCK;
import static com.android.systemui.theme.ThemeOverlayApplier.COLOR_SOURCE_PRESET;
@@ -73,6 +75,7 @@
import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags;
+import com.android.systemui.flags.SystemPropertiesHelper;
import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
import com.android.systemui.keyguard.shared.model.KeyguardState;
@@ -99,6 +102,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -136,9 +140,11 @@
private final DeviceProvisionedController mDeviceProvisionedController;
private final Resources mResources;
// Current wallpaper colors associated to a user.
- private final SparseArray<WallpaperColors> mCurrentColors = new SparseArray<>();
+ @VisibleForTesting
+ protected final SparseArray<WallpaperColors> mCurrentColors = new SparseArray<>();
private final WallpaperManager mWallpaperManager;
private final ActivityManager mActivityManager;
+ protected final SystemPropertiesHelper mSystemPropertiesHelper;
@VisibleForTesting
protected ColorScheme mColorScheme;
// If fabricated overlays were already created for the current theme.
@@ -423,7 +429,9 @@
JavaAdapter javaAdapter,
KeyguardTransitionInteractor keyguardTransitionInteractor,
UiModeManager uiModeManager,
- ActivityManager activityManager) {
+ ActivityManager activityManager,
+ SystemPropertiesHelper systemPropertiesHelper
+ ) {
mContext = context;
mIsMonetEnabled = featureFlags.isEnabled(Flags.MONET);
mIsFidelityEnabled = featureFlags.isEnabled(Flags.COLOR_FIDELITY);
@@ -443,6 +451,7 @@
mKeyguardTransitionInteractor = keyguardTransitionInteractor;
mUiModeManager = uiModeManager;
mActivityManager = activityManager;
+ mSystemPropertiesHelper = systemPropertiesHelper;
dumpManager.registerDumpable(TAG, this);
Flow<Boolean> isFinishedInAsleepStateFlow = mKeyguardTransitionInteractor
@@ -498,29 +507,38 @@
mUserTracker.addCallback(mUserTrackerCallback, mMainExecutor);
mDeviceProvisionedController.addCallback(mDeviceProvisionedListener);
+ WallpaperColors systemColor;
+ if (hardwareColorStyles() && !mDeviceProvisionedController.isCurrentUserSetup()) {
+ Pair<Integer, Color> defaultSettings = getThemeSettingsDefaults();
+ mThemeStyle = defaultSettings.first;
+ Color seedColor = defaultSettings.second;
+
+ // we only use the first color anyway, so we can pass only the single color we have
+ systemColor = new WallpaperColors(
+ /*primaryColor*/ seedColor,
+ /*secondaryColor*/ seedColor,
+ /*tertiaryColor*/ seedColor
+ );
+ } else {
+ systemColor = mWallpaperManager.getWallpaperColors(
+ getDefaultWallpaperColorsSource(mUserTracker.getUserId()));
+ }
+
// Upon boot, make sure we have the most up to date colors
Runnable updateColors = () -> {
- WallpaperColors systemColor = mWallpaperManager.getWallpaperColors(
- getDefaultWallpaperColorsSource(mUserTracker.getUserId()));
- Runnable applyColors = () -> {
- if (DEBUG) Log.d(TAG, "Boot colors: " + systemColor);
- mCurrentColors.put(mUserTracker.getUserId(), systemColor);
- reevaluateSystemTheme(false /* forceReload */);
- };
- if (mDeviceProvisionedController.isCurrentUserSetup()) {
- mMainExecutor.execute(applyColors);
- } else {
- applyColors.run();
- }
+ if (DEBUG) Log.d(TAG, "Boot colors: " + systemColor);
+ mCurrentColors.put(mUserTracker.getUserId(), systemColor);
+ reevaluateSystemTheme(false /* forceReload */);
};
// Whenever we're going directly to setup wizard, we need to process colors synchronously,
// otherwise we'll see some jank when the activity is recreated.
if (!mDeviceProvisionedController.isCurrentUserSetup()) {
- updateColors.run();
+ mMainExecutor.execute(updateColors);
} else {
mBgExecutor.execute(updateColors);
}
+
mWallpaperManager.addOnColorsChangedListener(mOnColorsChangedListener, null,
UserHandle.USER_ALL);
@@ -604,7 +622,7 @@
@VisibleForTesting
protected boolean isPrivateProfile(UserHandle userHandle) {
- Context usercontext = mContext.createContextAsUser(userHandle,0);
+ Context usercontext = mContext.createContextAsUser(userHandle, 0);
return usercontext.getSystemService(UserManager.class).isPrivateProfile();
}
@@ -720,6 +738,7 @@
return true;
}
+ @SuppressWarnings("StringCaseLocaleUsage") // Package name is not localized
private void updateThemeOverlays() {
final int currentUser = mUserTracker.getUserId();
final String overlayPackageJson = mSecureSettings.getStringForUser(
@@ -746,7 +765,7 @@
OverlayIdentifier systemPalette = categoryToPackage.get(OVERLAY_CATEGORY_SYSTEM_PALETTE);
if (mIsMonetEnabled && systemPalette != null && systemPalette.getPackageName() != null) {
try {
- String colorString = systemPalette.getPackageName().toLowerCase();
+ String colorString = systemPalette.getPackageName().toLowerCase();
if (!colorString.startsWith("#")) {
colorString = "#" + colorString;
}
@@ -856,6 +875,75 @@
return style;
}
+ protected Pair<Integer, String> getHardwareColorSetting() {
+ String deviceColorProperty = "ro.boot.hardware.color";
+
+ String[] themeData = mResources.getStringArray(
+ com.android.internal.R.array.theming_defaults);
+
+ // Color can be hex (`#FF0000`) or `home_wallpaper`
+ Map<String, Pair<Integer, String>> themeMap = new HashMap<>();
+
+ // extract all theme settings
+ for (String themeEntry : themeData) {
+ String[] themeComponents = themeEntry.split("\\|");
+ if (themeComponents.length != 3) continue;
+ themeMap.put(themeComponents[0],
+ new Pair<>(Style.valueOf(themeComponents[1]), themeComponents[2]));
+ }
+
+ Pair<Integer, String> fallbackTheme = themeMap.get("*");
+ if (fallbackTheme == null) {
+ Log.d(TAG, "Theming wildcard not found. Fallback to TONAL_SPOT|" + COLOR_SOURCE_HOME);
+ fallbackTheme = new Pair<>(Style.TONAL_SPOT, COLOR_SOURCE_HOME);
+ }
+
+ String deviceColorPropertyValue = mSystemPropertiesHelper.get(deviceColorProperty);
+ Pair<Integer, String> selectedTheme = themeMap.get(deviceColorPropertyValue);
+ if (selectedTheme == null) {
+ Log.d(TAG, "Sysprop `" + deviceColorProperty + "` of value '" + deviceColorPropertyValue
+ + "' not found in theming_defaults: " + Arrays.toString(themeData));
+ selectedTheme = fallbackTheme;
+ }
+
+ return selectedTheme;
+ }
+
+ @VisibleForTesting
+ protected Pair<Integer, Color> getThemeSettingsDefaults() {
+
+ Pair<Integer, String> selectedTheme = getHardwareColorSetting();
+
+ // Last fallback color
+ Color defaultSeedColor = Color.valueOf(GOOGLE_BLUE);
+
+ // defaultColor will come from wallpaper or be parsed from a string
+ boolean isWallpaper = selectedTheme.second.equals(COLOR_SOURCE_HOME);
+
+ if (isWallpaper) {
+ WallpaperColors wallpaperColors = mWallpaperManager.getWallpaperColors(
+ getDefaultWallpaperColorsSource(mUserTracker.getUserId()));
+
+ if (wallpaperColors != null) {
+ defaultSeedColor = wallpaperColors.getPrimaryColor();
+ }
+
+ Log.d(TAG, "Default seed color read from home wallpaper: " + Integer.toHexString(
+ defaultSeedColor.toArgb()));
+ } else {
+ try {
+ defaultSeedColor = Color.valueOf(Color.parseColor(selectedTheme.second));
+ Log.d(TAG, "Default seed color read from resource: " + Integer.toHexString(
+ defaultSeedColor.toArgb()));
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "Error parsing color: " + selectedTheme.second, e);
+ // defaultSeedColor remains unchanged in this case
+ }
+ }
+
+ return new Pair<>(selectedTheme.first, defaultSeedColor);
+ }
+
@Override
public void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
pw.println("mSystemColors=" + mCurrentColors);
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/TouchpadTutorialModule.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/TouchpadTutorialModule.kt
index a2125c8..d8a9527 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/TouchpadTutorialModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/TouchpadTutorialModule.kt
@@ -130,22 +130,32 @@
val easterEggGestureViewModel: EasterEggGestureViewModel,
) : TouchpadTutorialScreensProvider {
@Composable
- override fun BackGesture(onDoneButtonClicked: () -> Unit, onBack: () -> Unit) {
+ override fun BackGesture(
+ onDoneButtonClicked: () -> Unit,
+ onBack: () -> Unit,
+ isAutoProceed: Boolean,
+ ) {
BackGestureTutorialScreen(
backGestureScreenViewModel,
easterEggGestureViewModel,
onDoneButtonClicked,
onBack,
+ isAutoProceed,
)
}
@Composable
- override fun HomeGesture(onDoneButtonClicked: () -> Unit, onBack: () -> Unit) {
+ override fun HomeGesture(
+ onDoneButtonClicked: () -> Unit,
+ onBack: () -> Unit,
+ isAutoProceed: Boolean,
+ ) {
HomeGestureTutorialScreen(
homeGestureScreenViewModel,
easterEggGestureViewModel,
onDoneButtonClicked,
onBack,
+ isAutoProceed,
)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/BackGestureTutorialScreen.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/BackGestureTutorialScreen.kt
index bce55cb..c28483c 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/BackGestureTutorialScreen.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/BackGestureTutorialScreen.kt
@@ -33,6 +33,7 @@
easterEggGestureViewModel: EasterEggGestureViewModel,
onDoneButtonClicked: () -> Unit,
onBack: () -> Unit,
+ isAutoProceed: Boolean = false,
) {
val screenConfig =
TutorialScreenConfig(
@@ -47,6 +48,7 @@
bodyErrorResId = R.string.touchpad_back_gesture_error_body,
),
animations = TutorialScreenConfig.Animations(educationResId = R.raw.trackpad_back_edu),
+ hasNextButton = isAutoProceed,
)
GestureTutorialScreen(
screenConfig = screenConfig,
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/HomeGestureTutorialScreen.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/HomeGestureTutorialScreen.kt
index 4acdb60..b238a8d 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/HomeGestureTutorialScreen.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/HomeGestureTutorialScreen.kt
@@ -32,6 +32,7 @@
easterEggGestureViewModel: EasterEggGestureViewModel,
onDoneButtonClicked: () -> Unit,
onBack: () -> Unit,
+ isAutoProceed: Boolean = false,
) {
val screenConfig =
TutorialScreenConfig(
@@ -46,6 +47,7 @@
bodyErrorResId = R.string.touchpad_home_gesture_error_body,
),
animations = TutorialScreenConfig.Animations(educationResId = R.raw.trackpad_home_edu),
+ hasNextButton = isAutoProceed,
)
GestureTutorialScreen(
screenConfig = screenConfig,
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/DisplaySwitchLatencyLogger.kt b/packages/SystemUI/src/com/android/systemui/unfold/DisplaySwitchLatencyLogger.kt
index 76f7609..47e27bc 100644
--- a/packages/SystemUI/src/com/android/systemui/unfold/DisplaySwitchLatencyLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/unfold/DisplaySwitchLatencyLogger.kt
@@ -49,6 +49,7 @@
hallSensorToDeviceStateChangeMs,
onScreenTurningOnToOnDrawnMs,
onDrawnToOnScreenTurnedOnMs,
+ trackingResult,
)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/DisplaySwitchLatencyTracker.kt b/packages/SystemUI/src/com/android/systemui/unfold/DisplaySwitchLatencyTracker.kt
index e1640cd..66de522 100644
--- a/packages/SystemUI/src/com/android/systemui/unfold/DisplaySwitchLatencyTracker.kt
+++ b/packages/SystemUI/src/com/android/systemui/unfold/DisplaySwitchLatencyTracker.kt
@@ -37,12 +37,16 @@
import com.android.systemui.power.shared.model.WakefulnessState
import com.android.systemui.shared.system.SysUiStatsLog
import com.android.systemui.unfold.DisplaySwitchLatencyTracker.DisplaySwitchLatencyEvent
+import com.android.systemui.unfold.DisplaySwitchLatencyTracker.TrackingResult.CORRUPTED
+import com.android.systemui.unfold.DisplaySwitchLatencyTracker.TrackingResult.SUCCESS
+import com.android.systemui.unfold.DisplaySwitchLatencyTracker.TrackingResult.TIMED_OUT
import com.android.systemui.unfold.dagger.UnfoldSingleThreadBg
import com.android.systemui.unfold.data.repository.UnfoldTransitionStatus.TransitionStarted
import com.android.systemui.unfold.domain.interactor.UnfoldTransitionInteractor
import com.android.systemui.util.Compile
import com.android.systemui.util.Utils.isDeviceFoldable
import com.android.systemui.util.animation.data.repository.AnimationStatusRepository
+import com.android.systemui.util.kotlin.WithPrev
import com.android.systemui.util.kotlin.pairwise
import com.android.systemui.util.kotlin.race
import com.android.systemui.util.time.SystemClock
@@ -56,7 +60,6 @@
import kotlinx.coroutines.TimeoutCancellationException
import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.drop
import kotlinx.coroutines.flow.filter
@@ -116,10 +119,9 @@
latencyTracker.onActionStart(ACTION_SWITCH_DISPLAY_UNFOLD)
instantForTrack(TAG) { "unfold latency tracking started" }
}
+ val event = DisplaySwitchLatencyEvent().withBeforeFields(previousState.toStatsInt())
try {
withTimeout(SCREEN_EVENT_TIMEOUT) {
- val event =
- DisplaySwitchLatencyEvent().withBeforeFields(previousState.toStatsInt())
val displaySwitchTimeMs =
measureTimeMillis(systemClock) {
traceAsync(TAG, "displaySwitch") {
@@ -134,27 +136,43 @@
} catch (e: TimeoutCancellationException) {
instantForTrack(TAG) { "tracking timed out" }
latencyTracker.onActionCancel(ACTION_SWITCH_DISPLAY_UNFOLD)
+ logDisplaySwitchEvent(
+ event = event,
+ toFoldableDeviceState = newState,
+ displaySwitchTimeMs = SCREEN_EVENT_TIMEOUT.inWholeMilliseconds,
+ trackingResult = TIMED_OUT,
+ )
} catch (e: CancellationException) {
instantForTrack(TAG) { "new state interrupted, entering cool down" }
latencyTracker.onActionCancel(ACTION_SWITCH_DISPLAY_UNFOLD)
- startCoolDown()
+ startCoolDown(event)
}
}
}
}
@OptIn(FlowPreview::class)
- private fun startCoolDown() {
+ private fun startCoolDown(event: DisplaySwitchLatencyEvent) {
if (isCoolingDown) return
isCoolingDown = true
applicationScope.launch(context = backgroundDispatcher) {
val startTime = systemClock.elapsedRealtime()
+ var lastState: DeviceState? = null
try {
- startOrEndEvent.timeout(COOL_DOWN_DURATION).collect()
- } catch (e: TimeoutCancellationException) {
- instantForTrack(TAG) {
- "cool down finished, lasted ${systemClock.elapsedRealtime() - startTime} ms"
+ startOrEndEvent.timeout(COOL_DOWN_DURATION).collect {
+ if (it is WithPrev<*, *>) {
+ lastState = it.newValue as? DeviceState
+ }
}
+ } catch (e: TimeoutCancellationException) {
+ val totalCooldownTime = systemClock.elapsedRealtime() - startTime
+ logDisplaySwitchEvent(
+ event = event,
+ toFoldableDeviceState = lastState ?: DeviceState.UNKNOWN,
+ displaySwitchTimeMs = totalCooldownTime,
+ trackingResult = CORRUPTED,
+ )
+ instantForTrack(TAG) { "cool down finished, lasted $totalCooldownTime ms" }
isCoolingDown = false
}
}
@@ -164,12 +182,14 @@
event: DisplaySwitchLatencyEvent,
toFoldableDeviceState: DeviceState,
displaySwitchTimeMs: Long,
+ trackingResult: TrackingResult = SUCCESS,
) {
displaySwitchLatencyLogger.log(
event.withAfterFields(
- toFoldableDeviceState.toStatsInt(),
- displaySwitchTimeMs.toInt(),
+ toFoldableDeviceState,
+ displaySwitchTimeMs,
getCurrentState(),
+ trackingResult,
)
)
}
@@ -183,6 +203,13 @@
else -> FOLDABLE_DEVICE_STATE_UNKNOWN
}
+ private fun TrackingResult.toStatsInt(): Int =
+ when (this) {
+ SUCCESS -> SysUiStatsLog.DISPLAY_SWITCH_LATENCY_TRACKED__TRACKING_RESULT__SUCCESS
+ CORRUPTED -> SysUiStatsLog.DISPLAY_SWITCH_LATENCY_TRACKED__TRACKING_RESULT__CORRUPTED
+ TIMED_OUT -> SysUiStatsLog.DISPLAY_SWITCH_LATENCY_TRACKED__TRACKING_RESULT__TIMED_OUT
+ }
+
private suspend fun waitForDisplaySwitch(toFoldableDeviceState: Int) {
val isTransitionEnabled =
unfoldTransitionInteractor.isAvailable &&
@@ -264,21 +291,24 @@
}
private fun DisplaySwitchLatencyEvent.withAfterFields(
- toFoldableDeviceState: Int,
- displaySwitchTimeMs: Int,
+ toFoldableDeviceState: DeviceState,
+ displaySwitchTimeMs: Long,
toState: Int,
+ trackingResult: TrackingResult,
): DisplaySwitchLatencyEvent {
log {
- "toFoldableDeviceState=$toFoldableDeviceState, " +
+ "trackingResult=$trackingResult, " +
+ "toFoldableDeviceState=$toFoldableDeviceState, " +
"toState=$toState, " +
"latencyMs=$displaySwitchTimeMs"
}
instantForTrack(TAG) { "toFoldableDeviceState=$toFoldableDeviceState, toState=$toState" }
return copy(
- toFoldableDeviceState = toFoldableDeviceState,
- latencyMs = displaySwitchTimeMs,
+ toFoldableDeviceState = toFoldableDeviceState.toStatsInt(),
+ latencyMs = displaySwitchTimeMs.toInt(),
toState = toState,
+ trackingResult = trackingResult.toStatsInt(),
)
}
@@ -312,8 +342,16 @@
val hallSensorToDeviceStateChangeMs: Int = VALUE_UNKNOWN,
val onScreenTurningOnToOnDrawnMs: Int = VALUE_UNKNOWN,
val onDrawnToOnScreenTurnedOnMs: Int = VALUE_UNKNOWN,
+ val trackingResult: Int =
+ SysUiStatsLog.DISPLAY_SWITCH_LATENCY_TRACKED__TRACKING_RESULT__UNKNOWN_RESULT,
)
+ enum class TrackingResult {
+ SUCCESS,
+ CORRUPTED,
+ TIMED_OUT,
+ }
+
companion object {
private const val VALUE_UNKNOWN = -1
private const val TAG = "DisplaySwitchLatency"
diff --git a/packages/SystemUI/src/com/android/systemui/util/kotlin/SysUICoroutinesModule.kt b/packages/SystemUI/src/com/android/systemui/util/kotlin/SysUICoroutinesModule.kt
index e5c1e7d..79ff38e 100644
--- a/packages/SystemUI/src/com/android/systemui/util/kotlin/SysUICoroutinesModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/kotlin/SysUICoroutinesModule.kt
@@ -21,6 +21,7 @@
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.dagger.qualifiers.NotifInflation
import com.android.systemui.dagger.qualifiers.UiBackground
import com.android.systemui.util.settings.SettingsSingleThreadBackground
import dagger.Module
@@ -123,4 +124,19 @@
): CoroutineContext {
return uiBgCoroutineDispatcher
}
+
+ /** Coroutine dispatcher for background notification inflation. */
+ @Provides
+ @NotifInflation
+ @SysUISingleton
+ fun notifInflationCoroutineDispatcher(
+ @NotifInflation notifInflationExecutor: Executor,
+ @Background bgCoroutineDispatcher: CoroutineDispatcher,
+ ): CoroutineDispatcher {
+ if (com.android.systemui.Flags.useNotifInflationThreadForFooter()) {
+ return notifInflationExecutor.asCoroutineDispatcher()
+ } else {
+ return bgCoroutineDispatcher
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/util/settings/repository/SecureSettingsForUserRepository.kt b/packages/SystemUI/src/com/android/systemui/util/settings/repository/SecureSettingsForUserRepository.kt
new file mode 100644
index 0000000..4d6eb4d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/settings/repository/SecureSettingsForUserRepository.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.util.settings.repository
+
+import android.provider.Settings
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.util.settings.SecureSettings
+import javax.inject.Inject
+import kotlin.coroutines.CoroutineContext
+import kotlinx.coroutines.CoroutineDispatcher
+
+/** Repository observing values of a [Settings.Secure] for the specified user. */
+@SysUISingleton
+class SecureSettingsForUserRepository
+@Inject
+constructor(
+ secureSettings: SecureSettings,
+ @Background backgroundDispatcher: CoroutineDispatcher,
+ @Background backgroundContext: CoroutineContext,
+) : SettingsForUserRepository(secureSettings, backgroundDispatcher, backgroundContext)
diff --git a/packages/SystemUI/src/com/android/systemui/util/settings/repository/SettingsForUserRepository.kt b/packages/SystemUI/src/com/android/systemui/util/settings/repository/SettingsForUserRepository.kt
new file mode 100644
index 0000000..94b3fd2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/settings/repository/SettingsForUserRepository.kt
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2025 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.util.settings.repository
+
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.util.settings.SettingsProxyExt.observerFlow
+import com.android.systemui.util.settings.UserSettingsProxy
+import kotlin.coroutines.CoroutineContext
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.flowOn
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.onStart
+import kotlinx.coroutines.withContext
+
+/**
+ * Repository observing values of a [UserSettingsProxy] for the specified user. This repository
+ * should be used for any system that tracks the desired user internally (e.g. the Quick Settings
+ * tiles system). In other cases, use a [UserAwareSettingsRepository] instead.
+ */
+abstract class SettingsForUserRepository(
+ private val userSettings: UserSettingsProxy,
+ @Background private val backgroundDispatcher: CoroutineDispatcher,
+ @Background private val backgroundContext: CoroutineContext,
+) {
+ fun boolSettingForUser(
+ userId: Int,
+ name: String,
+ defaultValue: Boolean = false,
+ ): Flow<Boolean> =
+ settingObserver(name, userId) { userSettings.getBoolForUser(name, defaultValue, userId) }
+ .distinctUntilChanged()
+ .flowOn(backgroundDispatcher)
+
+ fun <T> settingObserver(name: String, userId: Int, settingsReader: () -> T): Flow<T> {
+ return userSettings
+ .observerFlow(userId, name)
+ .onStart { emit(Unit) }
+ .map { settingsReader.invoke() }
+ }
+
+ suspend fun setBoolForUser(userId: Int, name: String, value: Boolean) {
+ withContext(backgroundContext) { userSettings.putBoolForUser(name, value, userId) }
+ }
+
+ suspend fun getBoolForUser(userId: Int, name: String, defaultValue: Boolean = false): Boolean {
+ return withContext(backgroundContext) {
+ userSettings.getBoolForUser(name, defaultValue, userId)
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/settings/repository/UserAwareSettingsRepository.kt b/packages/SystemUI/src/com/android/systemui/util/settings/repository/UserAwareSettingsRepository.kt
index 73329b4..a8068cd 100644
--- a/packages/SystemUI/src/com/android/systemui/util/settings/repository/UserAwareSettingsRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/settings/repository/UserAwareSettingsRepository.kt
@@ -33,7 +33,8 @@
/**
* Repository for observing values of a [UserSettingsProxy], for the currently active user. That
* means that when the user is switched and the new user has a different value, the flow will emit
- * the new value.
+ * the new value. For any system that tracks the desired user internally (e.g. the Quick Settings
+ * tiles system), use a [SettingsForUserRepository] instead.
*/
// TODO: b/377244768 - Make internal when UserAwareSecureSettingsRepository can be made internal.
abstract class UserAwareSettingsRepository(
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index ae3756d..6fc9561 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -308,9 +308,9 @@
private int mWindowGravity;
@VisibleForTesting
- final int mVolumeRingerIconDrawableId = R.drawable.ic_speaker_on;
+ final int mVolumeRingerIconDrawableId = R.drawable.ic_legacy_speaker_on;
@VisibleForTesting
- final int mVolumeRingerMuteIconDrawableId = R.drawable.ic_speaker_mute;
+ final int mVolumeRingerMuteIconDrawableId = R.drawable.ic_legacy_speaker_mute;
private int mOriginalGravity;
private final DevicePostureController.Callback mDevicePostureControllerCallback;
@@ -1791,8 +1791,9 @@
enableRingerViewsH(!isZenMuted);
switch (mState.ringerModeInternal) {
case AudioManager.RINGER_MODE_VIBRATE:
- mRingerIcon.setImageResource(R.drawable.ic_volume_ringer_vibrate);
- mSelectedRingerIcon.setImageResource(R.drawable.ic_volume_ringer_vibrate);
+ mRingerIcon.setImageResource(R.drawable.ic_legacy_volume_ringer_vibrate);
+ mSelectedRingerIcon.setImageResource(
+ R.drawable.ic_legacy_volume_ringer_vibrate);
addAccessibilityDescription(mRingerIcon, RINGER_MODE_VIBRATE,
mContext.getString(R.string.volume_ringer_hint_mute));
mRingerIcon.setTag(Events.ICON_STATE_VIBRATE);
@@ -1990,7 +1991,7 @@
if (zenMuted) {
iconRes = com.android.internal.R.drawable.ic_qs_dnd;
} else if (isRingVibrate) {
- iconRes = R.drawable.ic_volume_ringer_vibrate;
+ iconRes = R.drawable.ic_legacy_volume_ringer_vibrate;
} else if (isRingSilent) {
iconRes = row.iconMuteRes;
} else if (ss.routedToBluetooth) {
@@ -2009,7 +2010,7 @@
row.setIcon(iconRes, mContext.getTheme());
row.iconState =
- iconRes == R.drawable.ic_volume_ringer_vibrate ? Events.ICON_STATE_VIBRATE
+ iconRes == R.drawable.ic_legacy_volume_ringer_vibrate ? Events.ICON_STATE_VIBRATE
: (iconRes == R.drawable.ic_volume_media_bt_mute || iconRes == row.iconMuteRes)
? Events.ICON_STATE_MUTE
: (iconRes == R.drawable.ic_volume_media_bt || iconRes == row.iconRes
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 ef75057..0bdf99e 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
@@ -27,6 +27,8 @@
import androidx.dynamicanimation.animation.FloatValueHolder
import androidx.dynamicanimation.animation.SpringAnimation
import androidx.dynamicanimation.animation.SpringForce
+import com.android.app.tracing.coroutines.launchInTraced
+import com.android.app.tracing.coroutines.launchTraced
import com.android.internal.R as internalR
import com.android.systemui.res.R
import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogScope
@@ -47,9 +49,7 @@
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
-import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.mapLatest
-import kotlinx.coroutines.launch
private const val CLOSE_DRAWER_DELAY = 300L
// Ensure roundness and color of button is updated when progress is changed by a minimum fraction.
@@ -107,13 +107,6 @@
fullRadius = volumeDialogBgFullRadius,
diff = volumeDialogBgFullRadius - volumeDialogBgSmallRadius,
progress,
- isBottom = false,
- )
- volumeDialogBackgroundView.applyCorners(
- fullRadius = volumeDialogBgFullRadius,
- diff = volumeDialogBgFullRadius - volumeDialogBgSmallRadius,
- progress,
- isBottom = true,
)
}
val ringerDrawerTransitionListener = VolumeDialogRingerDrawerTransitionListener {
@@ -122,7 +115,9 @@
drawerContainer.setTransitionListener(ringerDrawerTransitionListener)
volumeDialogBackgroundView.background = volumeDialogBackgroundView.background.mutate()
ringerBackgroundView.background = ringerBackgroundView.background.mutate()
- launch { dialogViewModel.addTouchableBounds(ringerBackgroundView) }
+ launchTraced("VDRVB#addTouchableBounds") {
+ dialogViewModel.addTouchableBounds(ringerBackgroundView)
+ }
viewModel.ringerViewModel
.mapLatest { ringerState ->
@@ -132,10 +127,10 @@
// Set up view background and visibility
drawerContainer.visibility = View.VISIBLE
+ (volumeDialogBackgroundView.background as GradientDrawable).cornerRadii =
+ bottomCornerRadii
when (uiModel.drawerState) {
is RingerDrawerState.Initial -> {
- (volumeDialogBackgroundView.background as GradientDrawable)
- .cornerRadii = bottomCornerRadii
drawerContainer.animateAndBindDrawerButtons(
viewModel,
uiModel,
@@ -216,8 +211,6 @@
drawerContainer.transitionToState(
R.id.volume_dialog_ringer_drawer_open
)
- volumeDialogBackgroundView.background =
- volumeDialogBackgroundView.background.mutate()
ringerBackgroundView.background =
ringerBackgroundView.background.mutate()
}
@@ -231,7 +224,7 @@
}
}
}
- .launchIn(this)
+ .launchInTraced("VDRVB#ringerViewModel", this)
}
private suspend fun MotionLayout.animateAndBindDrawerButtons(
@@ -261,7 +254,7 @@
val selectedCornerRadius =
(selectedButton.background as GradientDrawable).cornerRadius
if (selectedCornerRadius.toInt() != selectedButtonUiModel.cornerRadius) {
- launch {
+ launchTraced("VDRVB#selectedButtonAnimation") {
selectedButton.animateTo(
selectedButtonUiModel,
if (uiModel.currentButtonIndex == count - 1) {
@@ -275,7 +268,7 @@
val unselectedCornerRadius =
(unselectedButton.background as GradientDrawable).cornerRadius
if (unselectedCornerRadius.toInt() != unselectedButtonUiModel.cornerRadius) {
- launch {
+ launchTraced("VDRVB#unselectedButtonAnimation") {
unselectedButton.animateTo(
unselectedButtonUiModel,
if (previousIndex == count - 1) {
@@ -286,7 +279,7 @@
)
}
}
- launch {
+ launchTraced("VDRVB#bindButtons") {
delay(CLOSE_DRAWER_DELAY)
bindButtons(viewModel, uiModel, onAnimationEnd, isAnimated = true)
}
@@ -395,7 +388,7 @@
roundnessAnimation.minimumVisibleChange = BUTTON_MIN_VISIBLE_CHANGE
colorAnimation.minimumVisibleChange = BUTTON_MIN_VISIBLE_CHANGE
coroutineScope {
- launch {
+ launchTraced("VDRVB#colorAnimation") {
colorAnimation.suspendAnimate { value ->
val currentIconColor =
rgbEvaluator.evaluate(
@@ -423,14 +416,9 @@
}
}
- private fun View.applyCorners(fullRadius: Int, diff: Int, progress: Float, isBottom: Boolean) {
+ private fun View.applyCorners(fullRadius: Int, diff: Int, progress: Float) {
val radius = fullRadius - progress * diff
- (background as GradientDrawable).cornerRadii =
- if (isBottom) {
- floatArrayOf(0F, 0F, 0F, 0F, radius, radius, radius, radius)
- } else {
- FloatArray(8) { radius }
- }
+ (background as GradientDrawable).cornerRadius = radius
background.invalidateSelf()
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/settings/ui/binder/VolumeDialogSettingsButtonViewBinder.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/settings/ui/binder/VolumeDialogSettingsButtonViewBinder.kt
index 54f04e2..cf9136b 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/settings/ui/binder/VolumeDialogSettingsButtonViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/settings/ui/binder/VolumeDialogSettingsButtonViewBinder.kt
@@ -18,6 +18,8 @@
import android.view.View
import android.widget.ImageButton
+import com.android.app.tracing.coroutines.launchInTraced
+import com.android.app.tracing.coroutines.launchTraced
import com.android.systemui.res.R
import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogScope
import com.android.systemui.volume.dialog.settings.ui.viewmodel.VolumeDialogSettingsButtonViewModel
@@ -25,9 +27,7 @@
import com.android.systemui.volume.dialog.ui.viewmodel.VolumeDialogViewModel
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.launch
@VolumeDialogScope
class VolumeDialogSettingsButtonViewBinder
@@ -39,12 +39,12 @@
override fun CoroutineScope.bind(view: View) {
val button = view.requireViewById<ImageButton>(R.id.volume_dialog_settings)
- launch { dialogViewModel.addTouchableBounds(button) }
+ launchTraced("VDSBVB#addTouchableBounds") { dialogViewModel.addTouchableBounds(button) }
viewModel.isVisible
.onEach { isVisible -> button.visibility = if (isVisible) View.VISIBLE else View.GONE }
- .launchIn(this)
+ .launchInTraced("VDSBVB#isVisible", this)
- viewModel.icon.onEach { button.setImageDrawable(it) }.launchIn(this)
+ viewModel.icon.onEach { button.setImageDrawable(it) }.launchInTraced("VDSBVB#icon", this)
button.setOnClickListener { viewModel.onButtonClicked() }
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogOverscrollViewBinder.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogOverscrollViewBinder.kt
index 38feb69..c361b50 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogOverscrollViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogOverscrollViewBinder.kt
@@ -20,12 +20,12 @@
import androidx.dynamicanimation.animation.FloatValueHolder
import androidx.dynamicanimation.animation.SpringAnimation
import androidx.dynamicanimation.animation.SpringForce
+import com.android.app.tracing.coroutines.launchInTraced
import com.android.systemui.volume.dialog.sliders.dagger.VolumeDialogSliderScope
import com.android.systemui.volume.dialog.sliders.ui.viewmodel.VolumeDialogOverscrollViewModel
import com.android.systemui.volume.dialog.sliders.ui.viewmodel.VolumeDialogOverscrollViewModel.OverscrollEventModel
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
@VolumeDialogSliderScope
@@ -62,7 +62,7 @@
}
}
}
- .launchIn(this)
+ .launchInTraced("VDOVB#overscrollEvent", this)
}
}
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 2c9ee54..1c0fabe 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
@@ -39,7 +39,6 @@
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.remember
-import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@@ -99,7 +98,6 @@
hapticsViewModelFactory: SliderHapticsViewModel.Factory?,
modifier: Modifier = Modifier,
) {
- val coroutineScope = rememberCoroutineScope()
val colors =
SliderDefaults.colors(
thumbColor = MaterialTheme.colorScheme.primary,
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSlidersViewBinder.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSlidersViewBinder.kt
index 0d970e5..527f8bd 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSlidersViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSlidersViewBinder.kt
@@ -21,6 +21,8 @@
import android.view.ViewGroup
import androidx.annotation.LayoutRes
import androidx.compose.ui.util.fastForEachIndexed
+import com.android.app.tracing.coroutines.launchInTraced
+import com.android.app.tracing.coroutines.launchTraced
import com.android.systemui.res.R
import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogScope
import com.android.systemui.volume.dialog.sliders.dagger.VolumeDialogSliderComponent
@@ -29,9 +31,7 @@
import com.android.systemui.volume.dialog.ui.viewmodel.VolumeDialogViewModel
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.launch
@VolumeDialogScope
class VolumeDialogSlidersViewBinder
@@ -50,7 +50,9 @@
val bottomSection: View = view.requireViewById(R.id.volume_dialog_bottom_section_container)
val topSection: View = view.requireViewById(R.id.volume_dialog_top_section_container)
- launch { dialogViewModel.addTouchableBounds(mainSliderContainer, floatingSlidersContainer) }
+ launchTraced("VDSVB#addTouchableBounds") {
+ dialogViewModel.addTouchableBounds(mainSliderContainer, floatingSlidersContainer)
+ }
viewModel.sliders
.onEach { uiModel ->
bindSlider(
@@ -69,7 +71,7 @@
bindSlider(sliderComponent, sliderContainer, arrayOf(sliderContainer))
}
}
- .launchIn(this)
+ .launchInTraced("VDSVB#sliders", this)
}
private fun CoroutineScope.bindSlider(
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/binder/VolumeDialogViewBinder.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/binder/VolumeDialogViewBinder.kt
index 98042d5..0c10aaa 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/binder/VolumeDialogViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/binder/VolumeDialogViewBinder.kt
@@ -17,18 +17,22 @@
package com.android.systemui.volume.dialog.ui.binder
import android.app.Dialog
+import android.content.Context
import android.view.View
+import android.view.ViewGroup
import android.view.ViewTreeObserver
import android.view.WindowInsets
import androidx.compose.ui.util.lerp
-import androidx.constraintlayout.motion.widget.MotionLayout
import androidx.core.view.updatePadding
import androidx.dynamicanimation.animation.DynamicAnimation
import androidx.dynamicanimation.animation.FloatValueHolder
import androidx.dynamicanimation.animation.SpringAnimation
import androidx.dynamicanimation.animation.SpringForce
+import com.android.app.tracing.coroutines.launchInTraced
+import com.android.app.tracing.coroutines.launchTraced
import com.android.internal.view.RotationPolicy
import com.android.systemui.common.ui.view.onApplyWindowInsets
+import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.res.R
import com.android.systemui.util.kotlin.awaitCancellationThenDispose
import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogScope
@@ -43,11 +47,9 @@
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.mapLatest
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.scan
-import kotlinx.coroutines.launch
import kotlinx.coroutines.suspendCancellableCoroutine
private const val SPRING_STIFFNESS = 700f
@@ -63,32 +65,43 @@
class VolumeDialogViewBinder
@Inject
constructor(
+ @Application context: Context,
private val viewModel: VolumeDialogViewModel,
private val jankListenerFactory: JankListenerFactory,
private val tracer: VolumeTracer,
private val viewBinders: List<@JvmSuppressWildcards ViewBinder>,
) {
+ private val halfOpenedOffsetPx: Float =
+ context.resources.getDimensionPixelSize(R.dimen.volume_dialog_half_opened_offset).toFloat()
+
fun CoroutineScope.bind(dialog: Dialog) {
val insets: MutableStateFlow<WindowInsets> =
MutableStateFlow(WindowInsets.Builder().build())
// Root view of the Volume Dialog.
- val root: MotionLayout = dialog.requireViewById(R.id.volume_dialog)
+ val root: ViewGroup = dialog.requireViewById(R.id.volume_dialog)
animateVisibility(root, dialog, viewModel.dialogVisibilityModel)
- viewModel.dialogTitle.onEach { dialog.window?.setTitle(it) }.launchIn(this)
- viewModel.motionState
- .scan(0) { acc, motionState ->
+ viewModel.dialogTitle
+ .onEach { dialog.window?.setTitle(it) }
+ .launchInTraced("VDVB#dialogTitle", this)
+ viewModel.isHalfOpened
+ .scan<Boolean, Boolean?>(null) { acc, isHalfOpened ->
// don't animate the initial state
- root.transitionToState(motionState, animate = acc != 0)
- acc + 1
+ root.applyVerticalOffset(
+ offsetPx = if (isHalfOpened) halfOpenedOffsetPx else 0f,
+ shouldAnimate = acc != null,
+ )
+ isHalfOpened
}
- .launchIn(this)
+ .launchInTraced("VDVB#isHalfOpened", this)
- launch { root.viewTreeObserver.listenToComputeInternalInsets() }
+ launchTraced("VDVB#viewTreeObserver") {
+ root.viewTreeObserver.listenToComputeInternalInsets()
+ }
- launch {
+ launchTraced("VDVB#insets") {
root
.onApplyWindowInsets { v, newInsets ->
val insetsValues = newInsets.getInsets(WindowInsets.Type.displayCutout())
@@ -135,7 +148,7 @@
junkListener?.let(animation::removeUpdateListener)
junkListener =
jankListenerFactory.show(view).also(animation::addUpdateListener)
- animation.suspendAnimate(FRACTION_SHOW)
+ animation.animateToFinalPosition(FRACTION_SHOW)
}
is VolumeDialogVisibilityModel.Dismissed -> {
tracer.traceVisibilityEnd(it)
@@ -150,7 +163,7 @@
}
}
}
- .launchIn(this)
+ .launchInTraced("VDVB#visibilityModel", this)
}
/**
@@ -180,11 +193,11 @@
continuation.invokeOnCancellation { removeOnComputeInternalInsetsListener(listener) }
}
- private fun MotionLayout.transitionToState(newState: Int, animate: Boolean) {
- if (animate) {
- transitionToState(newState)
- } else {
- jumpToState(newState)
+ private suspend fun View.applyVerticalOffset(offsetPx: Float, shouldAnimate: Boolean) {
+ if (!shouldAnimate) {
+ translationY = offsetPx
+ return
}
+ animate().setDuration(150).translationY(offsetPx).suspendAnimate()
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/viewmodel/VolumeDialogViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/viewmodel/VolumeDialogViewModel.kt
index e47b531..8bfbc36 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/viewmodel/VolumeDialogViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/viewmodel/VolumeDialogViewModel.kt
@@ -56,18 +56,14 @@
configurationController: ConfigurationController,
) {
- val motionState: Flow<Int> =
+ val isHalfOpened: Flow<Boolean> =
combine(
devicePostureController.devicePosture(),
configurationController.onConfigChanged.onStart {
emit(context.resources.configuration)
},
) { devicePosture, configuration ->
- if (shouldOffsetVolumeDialog(devicePosture, configuration)) {
- R.id.volume_dialog_half_folded_constraint_set
- } else {
- R.id.volume_dialog_constraint_set
- }
+ shouldOffsetVolumeDialog(devicePosture, configuration)
}
val dialogVisibilityModel: Flow<VolumeDialogVisibilityModel> =
dialogVisibilityInteractor.dialogVisibility
diff --git a/packages/SystemUI/src/com/android/systemui/wallpapers/data/repository/NoopWallpaperRepository.kt b/packages/SystemUI/src/com/android/systemui/wallpapers/data/repository/NoopWallpaperRepository.kt
index ec74f4f..300a7e0 100644
--- a/packages/SystemUI/src/com/android/systemui/wallpapers/data/repository/NoopWallpaperRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/wallpapers/data/repository/NoopWallpaperRepository.kt
@@ -17,6 +17,8 @@
package com.android.systemui.wallpapers.data.repository
import android.app.WallpaperInfo
+import android.graphics.PointF
+import android.graphics.RectF
import android.view.View
import com.android.systemui.dagger.SysUISingleton
import javax.inject.Inject
@@ -37,4 +39,8 @@
override val wallpaperSupportsAmbientMode = flowOf(false)
override var rootView: View? = null
override val shouldSendFocalArea: StateFlow<Boolean> = MutableStateFlow(false).asStateFlow()
+
+ override fun sendLockScreenLayoutChangeCommand(wallpaperFocalAreaBounds: RectF) {}
+
+ override fun sendTapCommand(tapPosition: PointF) {}
}
diff --git a/packages/SystemUI/src/com/android/systemui/wallpapers/data/repository/WallpaperFocalAreaRepository.kt b/packages/SystemUI/src/com/android/systemui/wallpapers/data/repository/WallpaperFocalAreaRepository.kt
index 2c3491b..974468c 100644
--- a/packages/SystemUI/src/com/android/systemui/wallpapers/data/repository/WallpaperFocalAreaRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/wallpapers/data/repository/WallpaperFocalAreaRepository.kt
@@ -33,7 +33,8 @@
val wallpaperFocalAreaBounds: StateFlow<RectF>
- val wallpaperFocalAreaTapPosition: StateFlow<PointF>
+ /** It will be true when wallpaper requires focal area info. */
+ val hasFocalArea: StateFlow<Boolean>
/** top of notifications without bcsmartspace in small clock settings */
val notificationDefaultTop: StateFlow<Float>
@@ -51,7 +52,9 @@
}
@SysUISingleton
-class WallpaperFocalAreaRepositoryImpl @Inject constructor() : WallpaperFocalAreaRepository {
+class WallpaperFocalAreaRepositoryImpl
+@Inject
+constructor(val wallpaperRepository: WallpaperRepository) : WallpaperFocalAreaRepository {
private val _shortcutAbsoluteTop = MutableStateFlow(0F)
override val shortcutAbsoluteTop = _shortcutAbsoluteTop.asStateFlow()
@@ -63,13 +66,11 @@
override val wallpaperFocalAreaBounds: StateFlow<RectF> =
_wallpaperFocalAreaBounds.asStateFlow()
- private val _wallpaperFocalAreaTapPosition = MutableStateFlow(PointF(0F, 0F))
- override val wallpaperFocalAreaTapPosition: StateFlow<PointF> =
- _wallpaperFocalAreaTapPosition.asStateFlow()
-
private val _notificationDefaultTop = MutableStateFlow(0F)
override val notificationDefaultTop: StateFlow<Float> = _notificationDefaultTop.asStateFlow()
+ override val hasFocalArea = wallpaperRepository.shouldSendFocalArea
+
override fun setShortcutAbsoluteTop(top: Float) {
_shortcutAbsoluteTop.value = top
}
@@ -84,9 +85,10 @@
override fun setWallpaperFocalAreaBounds(bounds: RectF) {
_wallpaperFocalAreaBounds.value = bounds
+ wallpaperRepository.sendLockScreenLayoutChangeCommand(bounds)
}
- override fun setTapPosition(point: PointF) {
- _wallpaperFocalAreaTapPosition.value = point
+ override fun setTapPosition(tapPosition: PointF) {
+ wallpaperRepository.sendTapCommand(tapPosition)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/wallpapers/data/repository/WallpaperRepository.kt b/packages/SystemUI/src/com/android/systemui/wallpapers/data/repository/WallpaperRepository.kt
index a55f76b..b07342c 100644
--- a/packages/SystemUI/src/com/android/systemui/wallpapers/data/repository/WallpaperRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/wallpapers/data/repository/WallpaperRepository.kt
@@ -21,22 +21,18 @@
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
+import android.graphics.PointF
+import android.graphics.RectF
import android.os.Bundle
import android.os.UserHandle
import android.provider.Settings
+import android.util.Log
import android.view.View
-import androidx.annotation.VisibleForTesting
-import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.internal.R
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
-import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
-import com.android.systemui.keyguard.shared.model.Edge
-import com.android.systemui.keyguard.shared.model.KeyguardState
-import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.res.R as SysUIR
-import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shared.Flags.ambientAod
import com.android.systemui.shared.Flags.extendedWallpaperEffects
import com.android.systemui.user.data.model.SelectedUserModel
@@ -48,7 +44,6 @@
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
@@ -76,6 +71,10 @@
/** some wallpapers require bounds to be sent from keyguard */
val shouldSendFocalArea: StateFlow<Boolean>
+
+ fun sendLockScreenLayoutChangeCommand(wallpaperFocalAreaBounds: RectF)
+
+ fun sendTapCommand(tapPosition: PointF)
}
@SysUISingleton
@@ -86,10 +85,8 @@
@Background private val bgDispatcher: CoroutineDispatcher,
broadcastDispatcher: BroadcastDispatcher,
userRepository: UserRepository,
- wallpaperFocalAreaRepository: WallpaperFocalAreaRepository,
private val wallpaperManager: WallpaperManager,
private val context: Context,
- keyguardTransitionInteractor: KeyguardTransitionInteractor,
private val secureSettings: SecureSettings,
) : WallpaperRepository {
private val wallpaperChanged: Flow<Unit> =
@@ -109,9 +106,6 @@
// Only update the wallpaper status once the user selection has finished.
.filter { it.selectionStatus == SelectionStatus.SELECTION_COMPLETE }
- @VisibleForTesting var sendLockscreenLayoutJob: Job? = null
- @VisibleForTesting var sendTapInShapeEffectsJob: Job? = null
-
override val wallpaperInfo: StateFlow<WallpaperInfo?> =
if (!wallpaperManager.isWallpaperSupported) {
MutableStateFlow(null).asStateFlow()
@@ -143,77 +137,45 @@
override var rootView: View? = null
+ override fun sendLockScreenLayoutChangeCommand(wallpaperFocalAreaBounds: RectF) {
+ if (DEBUG) {
+ Log.d(TAG, "sendLockScreenLayoutChangeCommand $wallpaperFocalAreaBounds")
+ }
+ wallpaperManager.sendWallpaperCommand(
+ /* windowToken = */ rootView?.windowToken,
+ /* action = */ WallpaperManager.COMMAND_LOCKSCREEN_LAYOUT_CHANGED,
+ /* x = */ 0,
+ /* y = */ 0,
+ /* z = */ 0,
+ /* extras = */ Bundle().apply {
+ putFloat("wallpaperFocalAreaLeft", wallpaperFocalAreaBounds.left)
+ putFloat("wallpaperFocalAreaRight", wallpaperFocalAreaBounds.right)
+ putFloat("wallpaperFocalAreaTop", wallpaperFocalAreaBounds.top)
+ putFloat("wallpaperFocalAreaBottom", wallpaperFocalAreaBounds.bottom)
+ },
+ )
+ }
+
+ override fun sendTapCommand(tapPosition: PointF) {
+ if (DEBUG) {
+ Log.d(TAG, "sendTapCommand $tapPosition")
+ }
+
+ wallpaperManager.sendWallpaperCommand(
+ /* windowToken = */ rootView?.windowToken,
+ /* action = */ WallpaperManager.COMMAND_LOCKSCREEN_TAP,
+ /* x = */ tapPosition.x.toInt(),
+ /* y = */ tapPosition.y.toInt(),
+ /* z = */ 0,
+ /* extras = */ Bundle(),
+ )
+ }
+
override val shouldSendFocalArea =
wallpaperInfo
.map {
val focalAreaTarget = context.resources.getString(SysUIR.string.focal_area_target)
val shouldSendNotificationLayout = it?.component?.className == focalAreaTarget
- if (shouldSendNotificationLayout) {
- sendLockscreenLayoutJob =
- scope.launch {
- combine(
- wallpaperFocalAreaRepository.wallpaperFocalAreaBounds,
- keyguardTransitionInteractor
- .transition(
- edge = Edge.create(to = Scenes.Lockscreen),
- edgeWithoutSceneContainer =
- Edge.create(to = KeyguardState.LOCKSCREEN),
- )
- .filter { transitionStep ->
- transitionStep.transitionState ==
- TransitionState.STARTED
- },
- ::Pair,
- )
- .map { (bounds, _) -> bounds }
- .collect { wallpaperFocalAreaBounds ->
- wallpaperManager.sendWallpaperCommand(
- /* windowToken = */ rootView?.windowToken,
- /* action = */ WallpaperManager
- .COMMAND_LOCKSCREEN_LAYOUT_CHANGED,
- /* x = */ 0,
- /* y = */ 0,
- /* z = */ 0,
- /* extras = */ Bundle().apply {
- putFloat(
- "wallpaperFocalAreaLeft",
- wallpaperFocalAreaBounds.left,
- )
- putFloat(
- "wallpaperFocalAreaRight",
- wallpaperFocalAreaBounds.right,
- )
- putFloat(
- "wallpaperFocalAreaTop",
- wallpaperFocalAreaBounds.top,
- )
- putFloat(
- "wallpaperFocalAreaBottom",
- wallpaperFocalAreaBounds.bottom,
- )
- },
- )
- }
- }
-
- sendTapInShapeEffectsJob =
- scope.launch {
- wallpaperFocalAreaRepository.wallpaperFocalAreaTapPosition.collect {
- wallpaperFocalAreaTapPosition ->
- wallpaperManager.sendWallpaperCommand(
- /* windowToken = */ rootView?.windowToken,
- /* action = */ WallpaperManager.COMMAND_LOCKSCREEN_TAP,
- /* x = */ wallpaperFocalAreaTapPosition.x.toInt(),
- /* y = */ wallpaperFocalAreaTapPosition.y.toInt(),
- /* z = */ 0,
- /* extras = */ null,
- )
- }
- }
- } else {
- sendLockscreenLayoutJob?.cancel()
- sendTapInShapeEffectsJob?.cancel()
- }
shouldSendNotificationLayout
}
.stateIn(
@@ -227,4 +189,9 @@
wallpaperManager.getWallpaperInfoForUser(selectedUser.userInfo.id)
}
}
+
+ companion object {
+ private val TAG = WallpaperRepositoryImpl::class.simpleName
+ private val DEBUG = true
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/wallpapers/domain/interactor/WallpaperFocalAreaInteractor.kt b/packages/SystemUI/src/com/android/systemui/wallpapers/domain/interactor/WallpaperFocalAreaInteractor.kt
index 9b0f828..09c6cdf 100644
--- a/packages/SystemUI/src/com/android/systemui/wallpapers/domain/interactor/WallpaperFocalAreaInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/wallpapers/domain/interactor/WallpaperFocalAreaInteractor.kt
@@ -24,31 +24,25 @@
import android.util.TypedValue
import com.android.app.animation.MathUtils
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.res.R
import com.android.systemui.shade.data.repository.ShadeRepository
-import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor
import com.android.systemui.wallpapers.data.repository.WallpaperFocalAreaRepository
-import com.android.systemui.wallpapers.data.repository.WallpaperRepository
import javax.inject.Inject
import kotlin.math.min
-import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.filter
@SysUISingleton
class WallpaperFocalAreaInteractor
@Inject
constructor(
- @Application private val applicationScope: CoroutineScope,
private val context: Context,
private val wallpaperFocalAreaRepository: WallpaperFocalAreaRepository,
shadeRepository: ShadeRepository,
- activeNotificationsInteractor: ActiveNotificationsInteractor,
- val wallpaperRepository: WallpaperRepository,
) {
- val hasFocalArea = wallpaperRepository.shouldSendFocalArea
+ val hasFocalArea = wallpaperFocalAreaRepository.hasFocalArea
val wallpaperFocalAreaBounds: Flow<RectF> =
combine(
@@ -126,6 +120,8 @@
val bottom = scaledBounds.bottom - scaledBottomMargin
RectF(left, top, right, bottom).also { Log.d(TAG, "Focal area changes to $it") }
}
+ // Make sure a valid rec
+ .filter { it.width() >= 0 && it.height() >= 0 }
.distinctUntilChanged()
fun setFocalAreaBounds(bounds: RectF) {
diff --git a/packages/SystemUI/src/com/android/systemui/wallpapers/ui/viewmodel/WallpaperFocalAreaViewModel.kt b/packages/SystemUI/src/com/android/systemui/wallpapers/ui/viewmodel/WallpaperFocalAreaViewModel.kt
index 70a97d4..4cd49d0 100644
--- a/packages/SystemUI/src/com/android/systemui/wallpapers/ui/viewmodel/WallpaperFocalAreaViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/wallpapers/ui/viewmodel/WallpaperFocalAreaViewModel.kt
@@ -17,15 +17,41 @@
package com.android.systemui.wallpapers.ui.viewmodel
import android.graphics.RectF
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.shared.model.Edge
+import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.TransitionState
+import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.wallpapers.domain.interactor.WallpaperFocalAreaInteractor
import javax.inject.Inject
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.filter
+import kotlinx.coroutines.flow.map
class WallpaperFocalAreaViewModel
@Inject
-constructor(private val wallpaperFocalAreaInteractor: WallpaperFocalAreaInteractor) {
+constructor(
+ private val wallpaperFocalAreaInteractor: WallpaperFocalAreaInteractor,
+ val keyguardTransitionInteractor: KeyguardTransitionInteractor,
+) {
val hasFocalArea = wallpaperFocalAreaInteractor.hasFocalArea
- val wallpaperFocalAreaBounds = wallpaperFocalAreaInteractor.wallpaperFocalAreaBounds
+ val wallpaperFocalAreaBounds =
+ combine(
+ wallpaperFocalAreaInteractor.wallpaperFocalAreaBounds,
+ keyguardTransitionInteractor
+ .transition(
+ edge = Edge.create(to = Scenes.Lockscreen),
+ edgeWithoutSceneContainer = Edge.create(to = KeyguardState.LOCKSCREEN),
+ )
+ .filter { transitionStep ->
+ // Should not filter by TransitionState.STARTED, it may race with
+ // wakingup command, causing layout change command not be received.
+ transitionStep.transitionState == TransitionState.FINISHED
+ },
+ ::Pair,
+ )
+ .map { (bounds, _) -> bounds }
fun setFocalAreaBounds(bounds: RectF) {
wallpaperFocalAreaInteractor.setFocalAreaBounds(bounds)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/OnTeardownRuleTest.kt b/packages/SystemUI/tests/src/com/android/systemui/OnTeardownRuleTest.kt
similarity index 100%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/OnTeardownRuleTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/OnTeardownRuleTest.kt
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/IMagnificationConnectionTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/IMagnificationConnectionTest.java
similarity index 100%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/IMagnificationConnectionTest.java
rename to packages/SystemUI/tests/src/com/android/systemui/accessibility/IMagnificationConnectionTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/TextAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/TextAnimatorTest.kt
index dcf38800..14a81b3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/TextAnimatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/TextAnimatorTest.kt
@@ -30,7 +30,6 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
-import org.mockito.Mockito.eq
import org.mockito.Mockito.inOrder
import org.mockito.Mockito.mock
import org.mockito.Mockito.never
@@ -60,10 +59,11 @@
val textAnimator =
TextAnimator(layout, TypefaceVariantCacheImpl(typeface, 20)).apply {
this.textInterpolator = textInterpolator
+ this.createAnimator = { valueAnimator }
this.animator = valueAnimator
}
- textAnimator.setTextStyle(weight = 400, animate = true)
+ textAnimator.setTextStyle(TextAnimator.Style("'wght' 400"), TextAnimator.Animation())
// If animation is requested, the base state should be rebased and the target state should
// be updated.
@@ -90,10 +90,11 @@
val textAnimator =
TextAnimator(layout, TypefaceVariantCacheImpl(typeface, 20)).apply {
this.textInterpolator = textInterpolator
+ this.createAnimator = { valueAnimator }
this.animator = valueAnimator
}
- textAnimator.setTextStyle(weight = 400, animate = false)
+ textAnimator.setTextStyle(TextAnimator.Style("'wght' 400"))
// If animation is not requested, the progress should be 1 which is end of animation and the
// base state is rebased to target state by calling rebase.
@@ -118,23 +119,24 @@
val textAnimator =
TextAnimator(layout, TypefaceVariantCacheImpl(typeface, 20)).apply {
this.textInterpolator = textInterpolator
+ this.createAnimator = { valueAnimator }
this.animator = valueAnimator
}
textAnimator.setTextStyle(
- weight = 400,
- animate = true,
- onAnimationEnd = animationEndCallback,
+ TextAnimator.Style("'wght' 400"),
+ TextAnimator.Animation(animate = true, onAnimationEnd = animationEndCallback),
)
// Verify animationEnd callback has been added.
val captor = ArgumentCaptor.forClass(AnimatorListenerAdapter::class.java)
- verify(valueAnimator).addListener(captor.capture())
- captor.value.onAnimationEnd(valueAnimator)
+ verify(valueAnimator, times(2)).addListener(captor.capture())
+ for (callback in captor.allValues) {
+ callback.onAnimationEnd(valueAnimator)
+ }
// Verify animationEnd callback has been invoked and removed.
verify(animationEndCallback).run()
- verify(valueAnimator).removeListener(eq(captor.value))
}
@Test
@@ -148,18 +150,20 @@
val textAnimator =
TextAnimator(layout, TypefaceVariantCacheImpl(typeface, 20)).apply {
this.textInterpolator = textInterpolator
+ this.createAnimator = { valueAnimator }
this.animator = valueAnimator
}
- textAnimator.setTextStyle(weight = 400, animate = true)
+ val animation = TextAnimator.Animation(animate = true)
+ textAnimator.setTextStyle(TextAnimator.Style("'wght' 400"), animation)
val prevTypeface = paint.typeface
- textAnimator.setTextStyle(weight = 700, animate = true)
+ textAnimator.setTextStyle(TextAnimator.Style("'wght' 700"), animation)
assertThat(paint.typeface).isNotSameInstanceAs(prevTypeface)
- textAnimator.setTextStyle(weight = 400, animate = true)
+ textAnimator.setTextStyle(TextAnimator.Style("'wght' 400"), animation)
assertThat(paint.typeface).isSameInstanceAs(prevTypeface)
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
similarity index 100%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDialogDelegateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDialogDelegateTest.kt
similarity index 100%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDialogDelegateTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDialogDelegateTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothDetailsContentViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothDetailsContentViewModelTest.kt
index bfc5361..f04fc86 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothDetailsContentViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothDetailsContentViewModelTest.kt
@@ -43,6 +43,7 @@
import com.android.systemui.util.mockito.nullable
import com.android.systemui.util.mockito.whenever
import com.android.systemui.util.time.FakeSystemClock
+import com.android.systemui.volume.domain.interactor.audioModeInteractor
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.MutableSharedFlow
@@ -146,6 +147,7 @@
)
),
kosmos.audioSharingInteractor,
+ kosmos.audioModeInteractor,
kosmos.audioSharingButtonViewModelFactory,
bluetoothDeviceMetadataInteractor,
mDialogTransitionAnimator,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemFactoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemFactoryTest.kt
index 0aa5199..7c8822b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemFactoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemFactoryTest.kt
@@ -18,7 +18,6 @@
import android.bluetooth.BluetoothDevice
import android.graphics.drawable.Drawable
-import android.media.AudioManager
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import android.testing.TestableLooper
@@ -61,8 +60,6 @@
private val connectedDeviceItemFactory = ConnectedDeviceItemFactory()
private val savedDeviceItemFactory = SavedDeviceItemFactory()
- private val audioManager = context.getSystemService(AudioManager::class.java)!!
-
@Before
fun setup() {
mockitoSession =
@@ -132,7 +129,12 @@
fun testAvailableAudioSharingMediaDeviceItemFactory_isFilterMatched_flagOff_returnsFalse() {
assertThat(
AvailableAudioSharingMediaDeviceItemFactory(localBluetoothManager)
- .isFilterMatched(context, cachedDevice, audioManager, false)
+ .isFilterMatched(
+ context,
+ cachedDevice,
+ isOngoingCall = false,
+ audioSharingAvailable = false,
+ )
)
.isFalse()
}
@@ -143,7 +145,12 @@
assertThat(
AvailableAudioSharingMediaDeviceItemFactory(localBluetoothManager)
- .isFilterMatched(context, cachedDevice, audioManager, true)
+ .isFilterMatched(
+ context,
+ cachedDevice,
+ isOngoingCall = false,
+ audioSharingAvailable = true,
+ )
)
.isFalse()
}
@@ -157,7 +164,26 @@
assertThat(
AvailableAudioSharingMediaDeviceItemFactory(localBluetoothManager)
- .isFilterMatched(context, cachedDevice, audioManager, true)
+ .isFilterMatched(
+ context,
+ cachedDevice,
+ isOngoingCall = false,
+ audioSharingAvailable = true,
+ )
+ )
+ .isFalse()
+ }
+
+ @Test
+ fun testAvailableAudioSharingMediaDeviceItemFactory_isFilterMatched_inCall_false() {
+ assertThat(
+ AvailableAudioSharingMediaDeviceItemFactory(localBluetoothManager)
+ .isFilterMatched(
+ context,
+ cachedDevice,
+ isOngoingCall = true,
+ audioSharingAvailable = true,
+ )
)
.isFalse()
}
@@ -171,7 +197,12 @@
assertThat(
AvailableAudioSharingMediaDeviceItemFactory(localBluetoothManager)
- .isFilterMatched(context, cachedDevice, audioManager, true)
+ .isFilterMatched(
+ context,
+ cachedDevice,
+ isOngoingCall = false,
+ audioSharingAvailable = true,
+ )
)
.isTrue()
}
@@ -182,7 +213,9 @@
`when`(cachedDevice.bondState).thenReturn(BluetoothDevice.BOND_BONDED)
`when`(cachedDevice.isConnected).thenReturn(false)
- assertThat(savedDeviceItemFactory.isFilterMatched(context, cachedDevice, audioManager))
+ assertThat(
+ savedDeviceItemFactory.isFilterMatched(context, cachedDevice, isOngoingCall = false)
+ )
.isTrue()
}
@@ -192,7 +225,9 @@
`when`(cachedDevice.bondState).thenReturn(BluetoothDevice.BOND_BONDED)
`when`(cachedDevice.isConnected).thenReturn(true)
- assertThat(savedDeviceItemFactory.isFilterMatched(context, cachedDevice, audioManager))
+ assertThat(
+ savedDeviceItemFactory.isFilterMatched(context, cachedDevice, isOngoingCall = false)
+ )
.isFalse()
}
@@ -201,7 +236,9 @@
fun testSavedFactory_isFilterMatched_notBonded_returnsFalse() {
`when`(cachedDevice.bondState).thenReturn(BluetoothDevice.BOND_NONE)
- assertThat(savedDeviceItemFactory.isFilterMatched(context, cachedDevice, audioManager))
+ assertThat(
+ savedDeviceItemFactory.isFilterMatched(context, cachedDevice, isOngoingCall = false)
+ )
.isFalse()
}
@@ -211,7 +248,9 @@
`when`(cachedDevice.device).thenReturn(bluetoothDevice)
`when`(BluetoothUtils.isExclusivelyManagedBluetoothDevice(any(), any())).thenReturn(true)
- assertThat(savedDeviceItemFactory.isFilterMatched(context, cachedDevice, audioManager))
+ assertThat(
+ savedDeviceItemFactory.isFilterMatched(context, cachedDevice, isOngoingCall = false)
+ )
.isFalse()
}
@@ -223,7 +262,9 @@
`when`(cachedDevice.bondState).thenReturn(BluetoothDevice.BOND_BONDED)
`when`(cachedDevice.isConnected).thenReturn(false)
- assertThat(savedDeviceItemFactory.isFilterMatched(context, cachedDevice, audioManager))
+ assertThat(
+ savedDeviceItemFactory.isFilterMatched(context, cachedDevice, isOngoingCall = false)
+ )
.isTrue()
}
@@ -235,7 +276,9 @@
`when`(cachedDevice.bondState).thenReturn(BluetoothDevice.BOND_BONDED)
`when`(cachedDevice.isConnected).thenReturn(true)
- assertThat(savedDeviceItemFactory.isFilterMatched(context, cachedDevice, audioManager))
+ assertThat(
+ savedDeviceItemFactory.isFilterMatched(context, cachedDevice, isOngoingCall = false)
+ )
.isFalse()
}
@@ -244,14 +287,26 @@
fun testConnectedFactory_isFilterMatched_bondedAndConnected_returnsTrue() {
`when`(BluetoothUtils.isConnectedBluetoothDevice(any(), any())).thenReturn(true)
- assertThat(connectedDeviceItemFactory.isFilterMatched(context, cachedDevice, audioManager))
+ assertThat(
+ connectedDeviceItemFactory.isFilterMatched(
+ context,
+ cachedDevice,
+ isOngoingCall = false,
+ )
+ )
.isTrue()
}
@Test
@DisableFlags(Flags.FLAG_ENABLE_HIDE_EXCLUSIVELY_MANAGED_BLUETOOTH_DEVICE)
fun testConnectedFactory_isFilterMatched_notConnected_returnsFalse() {
- assertThat(connectedDeviceItemFactory.isFilterMatched(context, cachedDevice, audioManager))
+ assertThat(
+ connectedDeviceItemFactory.isFilterMatched(
+ context,
+ cachedDevice,
+ isOngoingCall = false,
+ )
+ )
.isFalse()
}
@@ -261,7 +316,13 @@
`when`(cachedDevice.device).thenReturn(bluetoothDevice)
`when`(BluetoothUtils.isExclusivelyManagedBluetoothDevice(any(), any())).thenReturn(true)
- assertThat(connectedDeviceItemFactory.isFilterMatched(context, cachedDevice, audioManager))
+ assertThat(
+ connectedDeviceItemFactory.isFilterMatched(
+ context,
+ cachedDevice,
+ isOngoingCall = false,
+ )
+ )
.isFalse()
}
@@ -272,7 +333,13 @@
`when`(BluetoothUtils.isExclusivelyManagedBluetoothDevice(any(), any())).thenReturn(false)
`when`(BluetoothUtils.isConnectedBluetoothDevice(any(), any())).thenReturn(true)
- assertThat(connectedDeviceItemFactory.isFilterMatched(context, cachedDevice, audioManager))
+ assertThat(
+ connectedDeviceItemFactory.isFilterMatched(
+ context,
+ cachedDevice,
+ isOngoingCall = false,
+ )
+ )
.isTrue()
}
@@ -283,7 +350,13 @@
`when`(BluetoothUtils.isExclusivelyManagedBluetoothDevice(any(), any())).thenReturn(false)
`when`(BluetoothUtils.isConnectedBluetoothDevice(any(), any())).thenReturn(false)
- assertThat(connectedDeviceItemFactory.isFilterMatched(context, cachedDevice, audioManager))
+ assertThat(
+ connectedDeviceItemFactory.isFilterMatched(
+ context,
+ cachedDevice,
+ isOngoingCall = false,
+ )
+ )
.isFalse()
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemInteractorTest.kt
index 42dc50d..943b89a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemInteractorTest.kt
@@ -29,6 +29,7 @@
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.testKosmos
import com.android.systemui.util.time.FakeSystemClock
+import com.android.systemui.volume.domain.interactor.audioModeInteractor
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.test.TestScope
@@ -102,7 +103,6 @@
DeviceItemInteractor(
bluetoothTileDialogRepository,
kosmos.audioSharingInteractor,
- audioManager,
adapter,
localBluetoothManager,
fakeSystemClock,
@@ -111,6 +111,7 @@
emptyList(),
testScope.backgroundScope,
dispatcher,
+ kosmos.audioModeInteractor,
)
val latest by collectLastValue(interactor.deviceItemUpdate)
@@ -130,7 +131,6 @@
DeviceItemInteractor(
bluetoothTileDialogRepository,
kosmos.audioSharingInteractor,
- audioManager,
adapter,
localBluetoothManager,
fakeSystemClock,
@@ -139,6 +139,7 @@
emptyList(),
testScope.backgroundScope,
dispatcher,
+ kosmos.audioModeInteractor,
)
val latest by collectLastValue(interactor.deviceItemUpdate)
@@ -158,7 +159,6 @@
DeviceItemInteractor(
bluetoothTileDialogRepository,
kosmos.audioSharingInteractor,
- audioManager,
adapter,
localBluetoothManager,
fakeSystemClock,
@@ -167,6 +167,7 @@
emptyList(),
testScope.backgroundScope,
dispatcher,
+ kosmos.audioModeInteractor,
)
val latest by collectLastValue(interactor.deviceItemUpdate)
@@ -186,7 +187,6 @@
DeviceItemInteractor(
bluetoothTileDialogRepository,
kosmos.audioSharingInteractor,
- audioManager,
adapter,
localBluetoothManager,
fakeSystemClock,
@@ -198,6 +198,7 @@
emptyList(),
testScope.backgroundScope,
dispatcher,
+ kosmos.audioModeInteractor,
)
val latest by collectLastValue(interactor.deviceItemUpdate)
@@ -217,7 +218,6 @@
DeviceItemInteractor(
bluetoothTileDialogRepository,
kosmos.audioSharingInteractor,
- audioManager,
adapter,
localBluetoothManager,
fakeSystemClock,
@@ -238,6 +238,7 @@
),
testScope.backgroundScope,
dispatcher,
+ kosmos.audioModeInteractor,
)
`when`(deviceItem1.type).thenReturn(DeviceItemType.CONNECTED_BLUETOOTH_DEVICE)
`when`(deviceItem2.type).thenReturn(DeviceItemType.SAVED_BLUETOOTH_DEVICE)
@@ -259,7 +260,6 @@
DeviceItemInteractor(
bluetoothTileDialogRepository,
kosmos.audioSharingInteractor,
- audioManager,
adapter,
localBluetoothManager,
fakeSystemClock,
@@ -277,6 +277,7 @@
listOf(DeviceItemType.CONNECTED_BLUETOOTH_DEVICE),
testScope.backgroundScope,
dispatcher,
+ kosmos.audioModeInteractor,
)
`when`(deviceItem1.type).thenReturn(DeviceItemType.CONNECTED_BLUETOOTH_DEVICE)
`when`(deviceItem2.type).thenReturn(DeviceItemType.CONNECTED_BLUETOOTH_DEVICE)
@@ -300,7 +301,6 @@
DeviceItemInteractor(
bluetoothTileDialogRepository,
kosmos.audioSharingInteractor,
- audioManager,
adapter,
localBluetoothManager,
fakeSystemClock,
@@ -309,6 +309,7 @@
emptyList(),
testScope.backgroundScope,
dispatcher,
+ kosmos.audioModeInteractor,
)
val latest by collectLastValue(interactor.deviceItemUpdate)
val latestShowSeeAll by collectLastValue(interactor.showSeeAllUpdate)
@@ -327,7 +328,7 @@
override fun isFilterMatched(
context: Context,
cachedDevice: CachedBluetoothDevice,
- audioManager: AudioManager,
+ isOngoingCall: Boolean,
audioSharingAvailable: Boolean,
) = isFilterMatchFunc(cachedDevice)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt
similarity index 100%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dump/LogEulogizerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/dump/LogEulogizerTest.kt
similarity index 100%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/dump/LogEulogizerTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/dump/LogEulogizerTest.kt
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/ui/view/ContextualEduUiCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/education/domain/ui/view/ContextualEduUiCoordinatorTest.kt
similarity index 100%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/ui/view/ContextualEduUiCoordinatorTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/education/domain/ui/view/ContextualEduUiCoordinatorTest.kt
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModelTest.kt
similarity index 100%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModelTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModelTest.kt
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/lifecycle/HydratorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/lifecycle/HydratorTest.kt
similarity index 100%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/lifecycle/HydratorTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/lifecycle/HydratorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerTest.kt
index a2bd5ec..aaf5559 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerTest.kt
@@ -66,6 +66,7 @@
import com.android.systemui.scene.data.repository.setSceneTransition
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.statusbar.featurepods.media.domain.interactor.mediaControlChipInteractor
import com.android.systemui.statusbar.notification.collection.provider.OnReorderingAllowedListener
import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider
import com.android.systemui.statusbar.policy.ConfigurationController
@@ -203,6 +204,7 @@
mediaCarouselViewModel = kosmos.mediaCarouselViewModel,
mediaViewControllerFactory = mediaViewControllerFactory,
deviceEntryInteractor = kosmos.deviceEntryInteractor,
+ mediaControlChipInteractor = kosmos.mediaControlChipInteractor,
)
verify(configurationController).addCallback(capture(configListener))
verify(visualStabilityProvider)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
index 23282b1..205ccea 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
@@ -84,7 +84,7 @@
private final Kosmos mKosmos = SysuiTestCaseExtKt.testKosmos(this);
// Mock
- private MediaOutputBaseAdapter mMediaOutputBaseAdapter = mock(MediaOutputBaseAdapter.class);
+ private MediaOutputAdapterBase mMediaOutputBaseAdapter = mock(MediaOutputAdapterBase.class);
private MediaController mMediaController = mock(MediaController.class);
private PlaybackState mPlaybackState = mock(PlaybackState.class);
private MediaSessionManager mMediaSessionManager = mock(MediaSessionManager.class);
@@ -219,7 +219,6 @@
public void refresh_withIconCompat_iconIsVisible() {
mIconCompat = IconCompat.createWithBitmap(
Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888));
- when(mMediaOutputBaseAdapter.getController()).thenReturn(mMediaSwitchingController);
mMediaOutputBaseDialogImpl.refresh();
final ImageView view = mMediaOutputBaseDialogImpl.mDialogView.requireViewById(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/QSFragmentComposeTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/QSFragmentComposeTest.kt
similarity index 100%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/QSFragmentComposeTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/QSFragmentComposeTest.kt
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/sensorprivacy/SensorUseStartedActivityTest.kt b/packages/SystemUI/tests/src/com/android/systemui/sensorprivacy/SensorUseStartedActivityTest.kt
similarity index 100%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/sensorprivacy/SensorUseStartedActivityTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/sensorprivacy/SensorUseStartedActivityTest.kt
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 944604f..ae8b52a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt
@@ -18,7 +18,7 @@
import android.graphics.Insets
import android.graphics.Rect
-import android.os.PowerManager
+import android.os.powerManager
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import android.testing.AndroidTestingRunner
@@ -32,7 +32,7 @@
import androidx.lifecycle.LifecycleOwner
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
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
@@ -40,7 +40,6 @@
import com.android.systemui.ambient.touch.TouchMonitor
import com.android.systemui.ambient.touch.dagger.AmbientTouchComponent
import com.android.systemui.bouncer.data.repository.fakeKeyguardBouncerRepository
-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
@@ -58,8 +57,10 @@
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.kosmos.collectLastValue
+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.media.controls.controller.keyguardMediaController
import com.android.systemui.res.R
@@ -69,8 +70,8 @@
import com.android.systemui.statusbar.notification.stack.notificationStackScrollLayoutController
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.runTest
import org.junit.After
import org.junit.Assert.assertThrows
@@ -89,33 +90,23 @@
@RunWith(AndroidTestingRunner::class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@SmallTest
+@EnableFlags(FLAG_COMMUNAL_HUB)
class GlanceableHubContainerControllerTest : SysuiTestCase() {
- private val kosmos: Kosmos =
- testKosmos().apply {
- // UnconfinedTestDispatcher makes testing simpler due to CommunalInteractor flows using
- // SharedFlow
- testDispatcher = UnconfinedTestDispatcher()
- }
+ private val kosmos: Kosmos = testKosmos().useUnconfinedTestDispatcher()
- private var communalViewModel = mock<CommunalViewModel>()
- private var powerManager = mock<PowerManager>()
- private var touchMonitor = mock<TouchMonitor>()
- private var communalColors = mock<CommunalColors>()
- private var communalContent = mock<CommunalContent>()
- private lateinit var ambientTouchComponentFactory: AmbientTouchComponent.Factory
+ private val swipeToHubEnabled = MutableStateFlow(false)
+ private val mockCommunalViewModel =
+ mock<CommunalViewModel> { on { swipeToHubEnabled } doReturn swipeToHubEnabled }
+ private val touchMonitor = mock<TouchMonitor>()
private lateinit var parentView: FrameLayout
private lateinit var containerView: View
- private lateinit var testableLooper: TestableLooper
- private lateinit var communalRepository: FakeCommunalSceneRepository
- private lateinit var underTest: GlanceableHubContainerController
+ private val Kosmos.testableLooper by
+ Kosmos.Fixture { TestableLooper.get(this@GlanceableHubContainerControllerTest) }
- @Before
- fun setUp() {
- communalRepository = kosmos.fakeCommunalSceneRepository
-
- ambientTouchComponentFactory =
+ private val Kosmos.ambientTouchComponentFactory by
+ Kosmos.Fixture {
object : AmbientTouchComponent.Factory {
override fun create(
lifecycleOwner: LifecycleOwner,
@@ -126,50 +117,39 @@
override fun getTouchMonitor(): TouchMonitor = touchMonitor
}
}
-
- with(kosmos) {
- underTest =
- GlanceableHubContainerController(
- communalInteractor,
- communalSettingsInteractor,
- communalViewModel,
- keyguardInteractor,
- keyguardTransitionInteractor,
- shadeInteractor,
- powerManager,
- communalColors,
- ambientTouchComponentFactory,
- communalContent,
- 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)
+ private val Kosmos.underTest by
+ Kosmos.Fixture {
+ GlanceableHubContainerController(
+ communalInteractor,
+ communalSettingsInteractor,
+ mockCommunalViewModel,
+ keyguardInteractor,
+ keyguardTransitionInteractor,
+ shadeInteractor,
+ powerManager,
+ mock<CommunalColors>(),
+ ambientTouchComponentFactory,
+ mock<CommunalContent>(),
+ sceneDataSourceDelegator,
+ notificationStackScrollLayoutController,
+ keyguardMediaController,
+ lockscreenSmartspaceController,
+ logcatLogBuffer("GlanceableHubContainerControllerTest"),
+ )
+ }
+
+ @Before
+ fun setUp() {
overrideResource(R.dimen.communal_right_edge_swipe_region_width, RIGHT_SWIPE_REGION_WIDTH)
overrideResource(R.dimen.communal_top_edge_swipe_region_height, TOP_SWIPE_REGION_WIDTH)
overrideResource(
R.dimen.communal_bottom_edge_swipe_region_height,
BOTTOM_SWIPE_REGION_WIDTH,
)
-
- // Make communal available so that communalInteractor.desiredScene accurately reflects
- // scene changes instead of just returning Blank.
- mSetFlagsRule.enableFlags(Flags.FLAG_COMMUNAL_HUB)
- with(kosmos.testScope) {
- launch { kosmos.setCommunalAvailable(true) }
- testScheduler.runCurrent()
- }
-
- initAndAttachContainerView()
+ runBlocking { kosmos.setCommunalAvailable(true) }
+ kosmos.initAndAttachContainerView()
}
@After
@@ -179,606 +159,531 @@
@Test
fun initView_calledTwice_throwsException() =
- with(kosmos) {
- testScope.runTest {
- underTest =
- GlanceableHubContainerController(
- communalInteractor,
- kosmos.communalSettingsInteractor,
- communalViewModel,
- keyguardInteractor,
- kosmos.keyguardTransitionInteractor,
- shadeInteractor,
- powerManager,
- communalColors,
- ambientTouchComponentFactory,
- communalContent,
- kosmos.sceneDataSourceDelegator,
- kosmos.notificationStackScrollLayoutController,
- kosmos.keyguardMediaController,
- kosmos.lockscreenSmartspaceController,
- logcatLogBuffer("GlanceableHubContainerControllerTest"),
- )
+ kosmos.runTest {
+ val controller =
+ GlanceableHubContainerController(
+ communalInteractor,
+ communalSettingsInteractor,
+ mockCommunalViewModel,
+ keyguardInteractor,
+ keyguardTransitionInteractor,
+ shadeInteractor,
+ powerManager,
+ mock<CommunalColors>(),
+ ambientTouchComponentFactory,
+ mock<CommunalContent>(),
+ sceneDataSourceDelegator,
+ notificationStackScrollLayoutController,
+ keyguardMediaController,
+ lockscreenSmartspaceController,
+ logcatLogBuffer("GlanceableHubContainerControllerTest"),
+ )
- // First call succeeds.
- underTest.initView(context)
+ // First call succeeds.
+ controller.initView(context)
- // Second call throws.
- assertThrows(RuntimeException::class.java) { underTest.initView(context) }
- }
+ // Second call throws.
+ assertThrows(RuntimeException::class.java) { controller.initView(context) }
}
@Test
fun lifecycle_initializedAfterConstruction() =
- with(kosmos) {
- val underTest =
+ kosmos.runTest {
+ val controller =
GlanceableHubContainerController(
communalInteractor,
- kosmos.communalSettingsInteractor,
- communalViewModel,
+ communalSettingsInteractor,
+ mockCommunalViewModel,
keyguardInteractor,
- kosmos.keyguardTransitionInteractor,
+ keyguardTransitionInteractor,
shadeInteractor,
powerManager,
- communalColors,
+ mock<CommunalColors>(),
ambientTouchComponentFactory,
- communalContent,
- kosmos.sceneDataSourceDelegator,
- kosmos.notificationStackScrollLayoutController,
- kosmos.keyguardMediaController,
- kosmos.lockscreenSmartspaceController,
+ mock<CommunalContent>(),
+ sceneDataSourceDelegator,
+ notificationStackScrollLayoutController,
+ keyguardMediaController,
+ lockscreenSmartspaceController,
logcatLogBuffer("GlanceableHubContainerControllerTest"),
)
- assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.INITIALIZED)
+ assertThat(controller.lifecycle.currentState).isEqualTo(Lifecycle.State.INITIALIZED)
}
@Test
fun lifecycle_createdAfterViewCreated() =
- with(kosmos) {
- val underTest =
+ kosmos.runTest {
+ val controller =
GlanceableHubContainerController(
communalInteractor,
- kosmos.communalSettingsInteractor,
- communalViewModel,
+ communalSettingsInteractor,
+ mockCommunalViewModel,
keyguardInteractor,
- kosmos.keyguardTransitionInteractor,
+ keyguardTransitionInteractor,
shadeInteractor,
powerManager,
- communalColors,
+ mock<CommunalColors>(),
ambientTouchComponentFactory,
- communalContent,
- kosmos.sceneDataSourceDelegator,
- kosmos.notificationStackScrollLayoutController,
- kosmos.keyguardMediaController,
- kosmos.lockscreenSmartspaceController,
+ mock<CommunalContent>(),
+ sceneDataSourceDelegator,
+ notificationStackScrollLayoutController,
+ keyguardMediaController,
+ lockscreenSmartspaceController,
logcatLogBuffer("GlanceableHubContainerControllerTest"),
)
// Only initView without attaching a view as we don't want the flows to start collecting
// yet.
- underTest.initView(View(context))
+ controller.initView(View(context))
+
+ assertThat(controller.lifecycle.currentState).isEqualTo(Lifecycle.State.CREATED)
+ }
+
+ @Test
+ fun lifecycle_startedAfterFlowsUpdate() =
+ kosmos.runTest {
+ // Flows start collecting due to test setup, causing the state to advance to STARTED.
+ assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.STARTED)
+ }
+
+ @Test
+ fun lifecycle_resumedAfterCommunalShows() =
+ kosmos.runTest {
+ // Communal is open.
+ goToScene(CommunalScenes.Communal)
+
+ assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.RESUMED)
+ }
+
+ @Test
+ fun lifecycle_startedAfterCommunalCloses() =
+ kosmos.runTest {
+ // Communal is open.
+ goToScene(CommunalScenes.Communal)
+
+ assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.RESUMED)
+
+ // Communal closes.
+ goToScene(CommunalScenes.Blank)
+
+ assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.STARTED)
+ }
+
+ @Test
+ fun lifecycle_startedAfterPrimaryBouncerShows() =
+ kosmos.runTest {
+ // Communal is open.
+ goToScene(CommunalScenes.Communal)
+
+ // Bouncer is visible.
+ fakeKeyguardBouncerRepository.setPrimaryShow(true)
+ testableLooper.processAllMessages()
+
+ assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.STARTED)
+ }
+
+ @Test
+ fun lifecycle_startedAfterAlternateBouncerShows() =
+ kosmos.runTest {
+ // Communal is open.
+ goToScene(CommunalScenes.Communal)
+
+ // Bouncer is visible.
+ fakeKeyguardBouncerRepository.setAlternateVisible(true)
+ testableLooper.processAllMessages()
+
+ assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.STARTED)
+ }
+
+ @Test
+ fun lifecycle_startedWhenEditActivityShowing() =
+ kosmos.runTest {
+ // Communal is open.
+ goToScene(CommunalScenes.Communal)
+
+ // Edit activity is showing.
+ communalInteractor.setEditActivityShowing(true)
+ testableLooper.processAllMessages()
+
+ assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.STARTED)
+ }
+
+ @Test
+ fun lifecycle_startedWhenEditModeTransitionStarted() =
+ kosmos.runTest {
+ // Communal is open.
+ goToScene(CommunalScenes.Communal)
+
+ // Leaving edit mode to return to the hub.
+ fakeKeyguardTransitionRepository.sendTransitionStep(
+ TransitionStep(
+ from = KeyguardState.GONE,
+ to = KeyguardState.GLANCEABLE_HUB,
+ value = 1.0f,
+ transitionState = TransitionState.RUNNING,
+ )
+ )
+ testableLooper.processAllMessages()
+
+ assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.STARTED)
+ }
+
+ @Test
+ fun lifecycle_createdAfterDisposeView() =
+ kosmos.runTest {
+ // Container view disposed.
+ underTest.disposeView()
assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.CREATED)
}
@Test
- fun lifecycle_startedAfterFlowsUpdate() {
- // Flows start collecting due to test setup, causing the state to advance to STARTED.
- assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.STARTED)
- }
-
- @Test
- fun lifecycle_resumedAfterCommunalShows() =
- with(kosmos) {
- testScope.runTest {
- // Communal is open.
- goToScene(CommunalScenes.Communal)
-
- assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.RESUMED)
- }
- }
-
- @Test
- fun lifecycle_startedAfterCommunalCloses() =
- with(kosmos) {
- testScope.runTest {
- // Communal is open.
- goToScene(CommunalScenes.Communal)
-
- assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.RESUMED)
-
- // Communal closes.
- goToScene(CommunalScenes.Blank)
-
- assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.STARTED)
- }
- }
-
- @Test
- fun lifecycle_startedAfterPrimaryBouncerShows() =
- with(kosmos) {
- testScope.runTest {
- // Communal is open.
- goToScene(CommunalScenes.Communal)
-
- // Bouncer is visible.
- fakeKeyguardBouncerRepository.setPrimaryShow(true)
- testableLooper.processAllMessages()
-
- assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.STARTED)
- }
- }
-
- @Test
- fun lifecycle_startedAfterAlternateBouncerShows() =
- with(kosmos) {
- testScope.runTest {
- // Communal is open.
- goToScene(CommunalScenes.Communal)
-
- // Bouncer is visible.
- fakeKeyguardBouncerRepository.setAlternateVisible(true)
- testableLooper.processAllMessages()
-
- assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.STARTED)
- }
- }
-
- @Test
- fun lifecycle_startedWhenEditActivityShowing() =
- with(kosmos) {
- testScope.runTest {
- // Communal is open.
- goToScene(CommunalScenes.Communal)
-
- // Edit activity is showing.
- communalInteractor.setEditActivityShowing(true)
- testableLooper.processAllMessages()
-
- assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.STARTED)
- }
- }
-
- @Test
- fun lifecycle_startedWhenEditModeTransitionStarted() =
- with(kosmos) {
- testScope.runTest {
- // Communal is open.
- goToScene(CommunalScenes.Communal)
-
- // Leaving edit mode to return to the hub.
- fakeKeyguardTransitionRepository.sendTransitionStep(
- TransitionStep(
- from = KeyguardState.GONE,
- to = KeyguardState.GLANCEABLE_HUB,
- value = 1.0f,
- transitionState = TransitionState.RUNNING,
- )
- )
- testableLooper.processAllMessages()
-
- assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.STARTED)
- }
- }
-
- @Test
- fun lifecycle_createdAfterDisposeView() {
- // Container view disposed.
- underTest.disposeView()
-
- assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.CREATED)
- }
-
- @Test
fun lifecycle_startedAfterShadeShows() =
- with(kosmos) {
- testScope.runTest {
- // Communal is open.
- goToScene(CommunalScenes.Communal)
+ kosmos.runTest {
+ // Communal is open.
+ goToScene(CommunalScenes.Communal)
- // Shade shows up.
- shadeTestUtil.setQsExpansion(1.0f)
- testableLooper.processAllMessages()
+ // Shade shows up.
+ shadeTestUtil.setQsExpansion(1.0f)
+ testableLooper.processAllMessages()
- assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.STARTED)
- }
+ assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.STARTED)
}
@Test
fun lifecycle_doesNotResumeOnUserInteractivityOnceExpanded() =
- with(kosmos) {
- testScope.runTest {
- // Communal is open.
- goToScene(CommunalScenes.Communal)
+ kosmos.runTest {
+ // Communal is open.
+ goToScene(CommunalScenes.Communal)
- // Shade shows up.
- shadeTestUtil.setShadeExpansion(1.0f)
- testableLooper.processAllMessages()
- underTest.onTouchEvent(DOWN_EVENT)
- testableLooper.processAllMessages()
+ // Shade shows up.
+ shadeTestUtil.setShadeExpansion(1.0f)
+ testableLooper.processAllMessages()
+ underTest.onTouchEvent(DOWN_EVENT)
+ testableLooper.processAllMessages()
- assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.STARTED)
+ assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.STARTED)
- // Shade starts collapsing.
- shadeTestUtil.setShadeExpansion(.5f)
- testableLooper.processAllMessages()
- underTest.onTouchEvent(DOWN_EVENT)
- testableLooper.processAllMessages()
+ // Shade starts collapsing.
+ shadeTestUtil.setShadeExpansion(.5f)
+ testableLooper.processAllMessages()
+ underTest.onTouchEvent(DOWN_EVENT)
+ testableLooper.processAllMessages()
- assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.STARTED)
+ assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.STARTED)
- // Shade fully collpase, and then expand should with touch interaction should now
- // be resumed.
- shadeTestUtil.setShadeExpansion(0f)
- testableLooper.processAllMessages()
- shadeTestUtil.setShadeExpansion(.5f)
- testableLooper.processAllMessages()
- underTest.onTouchEvent(DOWN_EVENT)
- testableLooper.processAllMessages()
+ // Shade fully collpase, and then expand should with touch interaction should now
+ // be resumed.
+ shadeTestUtil.setShadeExpansion(0f)
+ testableLooper.processAllMessages()
+ shadeTestUtil.setShadeExpansion(.5f)
+ testableLooper.processAllMessages()
+ underTest.onTouchEvent(DOWN_EVENT)
+ testableLooper.processAllMessages()
- assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.RESUMED)
- }
+ assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.RESUMED)
}
@Test
fun touchHandling_moveEventProcessedAfterCancel() =
- with(kosmos) {
- testScope.runTest {
- // Communal is open.
- goToScene(CommunalScenes.Communal)
+ kosmos.runTest {
+ // Communal is open.
+ goToScene(CommunalScenes.Communal)
- // Touch starts and ends.
- assertThat(underTest.onTouchEvent(DOWN_EVENT)).isTrue()
- assertThat(underTest.onTouchEvent(CANCEL_EVENT)).isTrue()
+ // Touch starts and ends.
+ assertThat(underTest.onTouchEvent(DOWN_EVENT)).isTrue()
+ assertThat(underTest.onTouchEvent(CANCEL_EVENT)).isTrue()
- // Up event is no longer processed
- assertThat(underTest.onTouchEvent(UP_EVENT)).isFalse()
+ // Up event is no longer processed
+ assertThat(underTest.onTouchEvent(UP_EVENT)).isFalse()
- // Move event can still be processed
- assertThat(underTest.onTouchEvent(MOVE_EVENT)).isTrue()
- assertThat(underTest.onTouchEvent(MOVE_EVENT)).isTrue()
- assertThat(underTest.onTouchEvent(UP_EVENT)).isTrue()
- }
+ // Move event can still be processed
+ assertThat(underTest.onTouchEvent(MOVE_EVENT)).isTrue()
+ assertThat(underTest.onTouchEvent(MOVE_EVENT)).isTrue()
+ assertThat(underTest.onTouchEvent(UP_EVENT)).isTrue()
}
@Test
fun editMode_communalAvailable() =
- with(kosmos) {
- testScope.runTest {
- val available by collectLastValue(underTest.communalAvailable())
- setCommunalAvailable(false)
+ kosmos.runTest {
+ val available by collectLastValue(underTest.communalAvailable())
+ setCommunalAvailable(false)
- assertThat(available).isFalse()
- communalInteractor.setEditModeOpen(true)
- assertThat(available).isTrue()
- }
+ assertThat(available).isFalse()
+ communalInteractor.setEditModeOpen(true)
+ assertThat(available).isTrue()
}
@Test
@DisableFlags(FLAG_HUBMODE_FULLSCREEN_VERTICAL_SWIPE_FIX)
fun gestureExclusionZone_setAfterInit() =
- with(kosmos) {
- testScope.runTest {
- goToScene(CommunalScenes.Communal)
+ kosmos.runTest {
+ goToScene(CommunalScenes.Communal)
- assertThat(containerView.systemGestureExclusionRects)
- .containsExactly(
- Rect(
- /* left= */ 0,
- /* top= */ TOP_SWIPE_REGION_WIDTH,
- /* right= */ CONTAINER_WIDTH,
- /* bottom= */ CONTAINER_HEIGHT - BOTTOM_SWIPE_REGION_WIDTH,
- )
+ assertThat(containerView.systemGestureExclusionRects)
+ .containsExactly(
+ Rect(
+ /* left= */ 0,
+ /* top= */ TOP_SWIPE_REGION_WIDTH,
+ /* right= */ CONTAINER_WIDTH,
+ /* bottom= */ CONTAINER_HEIGHT - BOTTOM_SWIPE_REGION_WIDTH,
)
- }
+ )
}
@Test
@EnableFlags(FLAG_HUBMODE_FULLSCREEN_VERTICAL_SWIPE_FIX)
fun gestureExclusionZone_setAfterInit_fullSwipe() =
- with(kosmos) {
- testScope.runTest {
- goToScene(CommunalScenes.Communal)
+ kosmos.runTest {
+ goToScene(CommunalScenes.Communal)
- assertThat(containerView.systemGestureExclusionRects).isEmpty()
- }
+ assertThat(containerView.systemGestureExclusionRects).isEmpty()
}
@Test
@DisableFlags(FLAG_HUBMODE_FULLSCREEN_VERTICAL_SWIPE_FIX)
fun gestureExclusionZone_unsetWhenShadeOpen() =
- with(kosmos) {
- testScope.runTest {
- goToScene(CommunalScenes.Communal)
+ kosmos.runTest {
+ goToScene(CommunalScenes.Communal)
- // Exclusion rect is set.
- assertThat(containerView.systemGestureExclusionRects).isNotEmpty()
+ // Exclusion rect is set.
+ assertThat(containerView.systemGestureExclusionRects).isNotEmpty()
- // Shade shows up.
- shadeTestUtil.setQsExpansion(1.0f)
- testableLooper.processAllMessages()
+ // Shade shows up.
+ shadeTestUtil.setQsExpansion(1.0f)
+ testableLooper.processAllMessages()
- // Exclusion rects are unset.
- assertThat(containerView.systemGestureExclusionRects).isEmpty()
- }
+ // Exclusion rects are unset.
+ assertThat(containerView.systemGestureExclusionRects).isEmpty()
}
@Test
@DisableFlags(FLAG_HUBMODE_FULLSCREEN_VERTICAL_SWIPE_FIX)
fun gestureExclusionZone_unsetWhenBouncerOpen() =
- with(kosmos) {
- testScope.runTest {
- goToScene(CommunalScenes.Communal)
+ kosmos.runTest {
+ goToScene(CommunalScenes.Communal)
- // Exclusion rect is set.
- assertThat(containerView.systemGestureExclusionRects).isNotEmpty()
+ // Exclusion rect is set.
+ assertThat(containerView.systemGestureExclusionRects).isNotEmpty()
- // Bouncer is visible.
- fakeKeyguardBouncerRepository.setPrimaryShow(true)
- testableLooper.processAllMessages()
+ // Bouncer is visible.
+ fakeKeyguardBouncerRepository.setPrimaryShow(true)
+ testableLooper.processAllMessages()
- // Exclusion rects are unset.
- assertThat(containerView.systemGestureExclusionRects).isEmpty()
- }
+ // Exclusion rects are unset.
+ assertThat(containerView.systemGestureExclusionRects).isEmpty()
}
@Test
@DisableFlags(FLAG_HUBMODE_FULLSCREEN_VERTICAL_SWIPE_FIX)
fun gestureExclusionZone_unsetWhenHubClosed() =
- with(kosmos) {
- testScope.runTest {
- goToScene(CommunalScenes.Communal)
+ kosmos.runTest {
+ goToScene(CommunalScenes.Communal)
- // Exclusion rect is set.
- assertThat(containerView.systemGestureExclusionRects).isNotEmpty()
+ // Exclusion rect is set.
+ assertThat(containerView.systemGestureExclusionRects).isNotEmpty()
- // Leave the hub.
- goToScene(CommunalScenes.Blank)
+ // Leave the hub.
+ goToScene(CommunalScenes.Blank)
- // Exclusion rect is unset.
- assertThat(containerView.systemGestureExclusionRects).isEmpty()
- }
+ // Exclusion rect is unset.
+ assertThat(containerView.systemGestureExclusionRects).isEmpty()
}
@Test
fun fullScreenSwipeGesture_doNotProcessTouchesInNotificationStack() =
- with(kosmos) {
- testScope.runTest {
- // Communal is closed.
- goToScene(CommunalScenes.Blank)
- whenever(
- notificationStackScrollLayoutController.isBelowLastNotification(
- any(),
- any(),
- )
- )
- .thenReturn(false)
- assertThat(underTest.onTouchEvent(DOWN_EVENT)).isFalse()
- }
+ kosmos.runTest {
+ // Communal is closed.
+ goToScene(CommunalScenes.Blank)
+ whenever(notificationStackScrollLayoutController.isBelowLastNotification(any(), any()))
+ .thenReturn(false)
+ assertThat(underTest.onTouchEvent(DOWN_EVENT)).isFalse()
}
@Test
fun fullScreenSwipeGesture_doNotProcessTouchesInUmo() =
- with(kosmos) {
- testScope.runTest {
- // Communal is closed.
- goToScene(CommunalScenes.Blank)
- whenever(keyguardMediaController.isWithinMediaViewBounds(any(), any()))
- .thenReturn(true)
- assertThat(underTest.onTouchEvent(DOWN_EVENT)).isFalse()
- }
+ kosmos.runTest {
+ // Communal is closed.
+ goToScene(CommunalScenes.Blank)
+ whenever(keyguardMediaController.isWithinMediaViewBounds(any(), any())).thenReturn(true)
+ assertThat(underTest.onTouchEvent(DOWN_EVENT)).isFalse()
}
@Test
fun fullScreenSwipeGesture_doNotProcessTouchesInSmartspace() =
- with(kosmos) {
- testScope.runTest {
- // Communal is closed.
- goToScene(CommunalScenes.Blank)
- whenever(lockscreenSmartspaceController.isWithinSmartspaceBounds(any(), any()))
- .thenReturn(true)
- assertThat(underTest.onTouchEvent(DOWN_EVENT)).isFalse()
- }
+ kosmos.runTest {
+ // Communal is closed.
+ goToScene(CommunalScenes.Blank)
+ whenever(lockscreenSmartspaceController.isWithinSmartspaceBounds(any(), any()))
+ .thenReturn(true)
+ assertThat(underTest.onTouchEvent(DOWN_EVENT)).isFalse()
}
@Test
fun onTouchEvent_hubOpen_touchesDispatched() =
- with(kosmos) {
- testScope.runTest {
- // Communal is open.
- goToScene(CommunalScenes.Communal)
+ kosmos.runTest {
+ // Communal is open.
+ goToScene(CommunalScenes.Communal)
- // Touch event is sent to the container view.
- assertThat(underTest.onTouchEvent(DOWN_EVENT)).isTrue()
- verify(containerView).onTouchEvent(DOWN_EVENT)
- assertThat(underTest.onTouchEvent(UP_EVENT)).isTrue()
- verify(containerView).onTouchEvent(UP_EVENT)
- }
+ // Touch event is sent to the container view.
+ assertThat(underTest.onTouchEvent(DOWN_EVENT)).isTrue()
+ verify(containerView).onTouchEvent(DOWN_EVENT)
+ assertThat(underTest.onTouchEvent(UP_EVENT)).isTrue()
+ verify(containerView).onTouchEvent(UP_EVENT)
}
@Test
fun onTouchEvent_editActivityShowing_touchesConsumedButNotDispatched() =
- with(kosmos) {
- testScope.runTest {
- // Communal is open.
- goToScene(CommunalScenes.Communal)
+ kosmos.runTest {
+ // Communal is open.
+ goToScene(CommunalScenes.Communal)
- // Transitioning to or from edit mode.
- communalInteractor.setEditActivityShowing(true)
- testableLooper.processAllMessages()
+ // Transitioning to or from edit mode.
+ communalInteractor.setEditActivityShowing(true)
+ testableLooper.processAllMessages()
- // onTouchEvent returns true to consume the touch, but it is not sent to the
- // container view.
- assertThat(underTest.onTouchEvent(DOWN_EVENT)).isTrue()
- verify(containerView, never()).onTouchEvent(any())
- }
+ // onTouchEvent returns true to consume the touch, but it is not sent to the
+ // container view.
+ assertThat(underTest.onTouchEvent(DOWN_EVENT)).isTrue()
+ verify(containerView, never()).onTouchEvent(any())
}
@Test
fun onTouchEvent_editModeTransitionStarted_touchesConsumedButNotDispatched() =
- with(kosmos) {
- testScope.runTest {
- // Communal is open.
- goToScene(CommunalScenes.Communal)
+ kosmos.runTest {
+ // Communal is open.
+ goToScene(CommunalScenes.Communal)
- // Leaving edit mode to return to the hub.
- fakeKeyguardTransitionRepository.sendTransitionStep(
- TransitionStep(
- from = KeyguardState.GONE,
- to = KeyguardState.GLANCEABLE_HUB,
- value = 1.0f,
- transitionState = TransitionState.RUNNING,
- )
+ // Leaving edit mode to return to the hub.
+ fakeKeyguardTransitionRepository.sendTransitionStep(
+ TransitionStep(
+ from = KeyguardState.GONE,
+ to = KeyguardState.GLANCEABLE_HUB,
+ value = 1.0f,
+ transitionState = TransitionState.RUNNING,
)
- testableLooper.processAllMessages()
+ )
+ testableLooper.processAllMessages()
- // onTouchEvent returns true to consume the touch, but it is not sent to the
- // container view.
- assertThat(underTest.onTouchEvent(DOWN_EVENT)).isTrue()
- verify(containerView, never()).onTouchEvent(any())
- }
+ // onTouchEvent returns true to consume the touch, but it is not sent to the
+ // container view.
+ assertThat(underTest.onTouchEvent(DOWN_EVENT)).isTrue()
+ verify(containerView, never()).onTouchEvent(any())
}
@Test
fun onTouchEvent_shadeInteracting_movesNotDispatched() =
- with(kosmos) {
- testScope.runTest {
- `whenever`(communalViewModel.swipeToHubEnabled()).thenReturn(true)
- // On lockscreen.
- goToScene(CommunalScenes.Blank)
- whenever(
- notificationStackScrollLayoutController.isBelowLastNotification(
- any(),
- any(),
- )
- )
- .thenReturn(true)
+ kosmos.runTest {
+ swipeToHubEnabled.value = true
- // Touches not consumed by default but are received by containerView.
- assertThat(underTest.onTouchEvent(DOWN_EVENT)).isFalse()
- verify(containerView).onTouchEvent(DOWN_EVENT)
+ // On lockscreen.
+ goToScene(CommunalScenes.Blank)
+ whenever(notificationStackScrollLayoutController.isBelowLastNotification(any(), any()))
+ .thenReturn(true)
- // User is interacting with shade on lockscreen.
- shadeTestUtil.setLockscreenShadeTracking(true)
- testableLooper.processAllMessages()
+ // Touches not consumed by default but are received by containerView.
+ assertThat(underTest.onTouchEvent(DOWN_EVENT)).isFalse()
+ verify(containerView).onTouchEvent(DOWN_EVENT)
- // A move event is ignored while the user is already interacting.
- assertThat(underTest.onTouchEvent(MOVE_EVENT)).isFalse()
- verify(containerView, never()).onTouchEvent(MOVE_EVENT)
+ // User is interacting with shade on lockscreen.
+ shadeTestUtil.setLockscreenShadeTracking(true)
+ testableLooper.processAllMessages()
- // An up event is still delivered.
- assertThat(underTest.onTouchEvent(UP_EVENT)).isFalse()
- verify(containerView).onTouchEvent(UP_EVENT)
- }
+ // A move event is ignored while the user is already interacting.
+ assertThat(underTest.onTouchEvent(MOVE_EVENT)).isFalse()
+ verify(containerView, never()).onTouchEvent(MOVE_EVENT)
+
+ // An up event is still delivered.
+ assertThat(underTest.onTouchEvent(UP_EVENT)).isFalse()
+ verify(containerView).onTouchEvent(UP_EVENT)
}
@Test
fun onTouchEvent_shadeExpanding_touchesNotDispatched() =
- with(kosmos) {
- testScope.runTest {
- // On lockscreen.
- goToScene(CommunalScenes.Blank)
- whenever(
- notificationStackScrollLayoutController.isBelowLastNotification(
- any(),
- any(),
- )
- )
- .thenReturn(true)
+ kosmos.runTest {
+ // On lockscreen.
+ goToScene(CommunalScenes.Blank)
+ whenever(notificationStackScrollLayoutController.isBelowLastNotification(any(), any()))
+ .thenReturn(true)
- // Shade is open slightly.
- shadeTestUtil.setShadeExpansion(0.01f)
- testableLooper.processAllMessages()
+ // Shade is open slightly.
+ shadeTestUtil.setShadeExpansion(0.01f)
+ testableLooper.processAllMessages()
- // Touches are not consumed.
- assertThat(underTest.onTouchEvent(DOWN_EVENT)).isFalse()
- verify(containerView, never()).onTouchEvent(DOWN_EVENT)
- }
+ // Touches are not consumed.
+ assertThat(underTest.onTouchEvent(DOWN_EVENT)).isFalse()
+ verify(containerView, never()).onTouchEvent(DOWN_EVENT)
}
@Test
fun onTouchEvent_qsExpanding_touchesNotDispatched() =
- with(kosmos) {
- testScope.runTest {
- // On lockscreen.
- goToScene(CommunalScenes.Blank)
- whenever(
- notificationStackScrollLayoutController.isBelowLastNotification(
- any(),
- any(),
- )
- )
- .thenReturn(true)
+ kosmos.runTest {
+ // On lockscreen.
+ goToScene(CommunalScenes.Blank)
+ whenever(notificationStackScrollLayoutController.isBelowLastNotification(any(), any()))
+ .thenReturn(true)
- // Shade is open slightly.
- shadeTestUtil.setQsExpansion(0.01f)
- testableLooper.processAllMessages()
+ // Shade is open slightly.
+ shadeTestUtil.setQsExpansion(0.01f)
+ testableLooper.processAllMessages()
- // Touches are not consumed.
- assertThat(underTest.onTouchEvent(DOWN_EVENT)).isFalse()
- verify(containerView, never()).onTouchEvent(DOWN_EVENT)
- }
+ // Touches are not consumed.
+ assertThat(underTest.onTouchEvent(DOWN_EVENT)).isFalse()
+ verify(containerView, never()).onTouchEvent(DOWN_EVENT)
}
@Test
fun onTouchEvent_bouncerInteracting_movesNotDispatched() =
- with(kosmos) {
- testScope.runTest {
- `whenever`(communalViewModel.swipeToHubEnabled()).thenReturn(true)
- // On lockscreen.
- goToScene(CommunalScenes.Blank)
- whenever(
- notificationStackScrollLayoutController.isBelowLastNotification(
- any(),
- any(),
- )
- )
- .thenReturn(true)
+ kosmos.runTest {
+ swipeToHubEnabled.value = true
+ // On lockscreen.
+ goToScene(CommunalScenes.Blank)
+ whenever(notificationStackScrollLayoutController.isBelowLastNotification(any(), any()))
+ .thenReturn(true)
- // Touches not consumed by default but are received by containerView.
- assertThat(underTest.onTouchEvent(DOWN_EVENT)).isFalse()
- verify(containerView).onTouchEvent(DOWN_EVENT)
+ // Touches not consumed by default but are received by containerView.
+ assertThat(underTest.onTouchEvent(DOWN_EVENT)).isFalse()
+ verify(containerView).onTouchEvent(DOWN_EVENT)
- // User is interacting with bouncer on lockscreen.
- fakeKeyguardBouncerRepository.setPrimaryShow(true)
- testableLooper.processAllMessages()
+ // User is interacting with bouncer on lockscreen.
+ fakeKeyguardBouncerRepository.setPrimaryShow(true)
+ testableLooper.processAllMessages()
- // A move event is ignored while the user is already interacting.
- assertThat(underTest.onTouchEvent(MOVE_EVENT)).isFalse()
- verify(containerView, never()).onTouchEvent(MOVE_EVENT)
+ // A move event is ignored while the user is already interacting.
+ assertThat(underTest.onTouchEvent(MOVE_EVENT)).isFalse()
+ verify(containerView, never()).onTouchEvent(MOVE_EVENT)
- // An up event is still delivered.
- assertThat(underTest.onTouchEvent(UP_EVENT)).isFalse()
- verify(containerView).onTouchEvent(UP_EVENT)
- }
+ // An up event is still delivered.
+ assertThat(underTest.onTouchEvent(UP_EVENT)).isFalse()
+ verify(containerView).onTouchEvent(UP_EVENT)
}
@EnableFlags(FLAG_GLANCEABLE_HUB_V2)
@Test
fun onTouchEvent_onLockscreenAndGlanceableHubV2_touchIgnored() =
- with(kosmos) {
- testScope.runTest {
- kosmos.setCommunalV2ConfigEnabled(true)
+ kosmos.runTest {
+ swipeToHubEnabled.value = false
+ setCommunalV2ConfigEnabled(true)
- // On lockscreen.
- goToScene(CommunalScenes.Blank)
+ // On lockscreen.
+ goToScene(CommunalScenes.Blank)
- assertThat(underTest.onTouchEvent(DOWN_EVENT)).isFalse()
- verify(containerView, never()).onTouchEvent(DOWN_EVENT)
- }
+ assertThat(underTest.onTouchEvent(DOWN_EVENT)).isFalse()
+ verify(containerView, never()).onTouchEvent(DOWN_EVENT)
}
@Test
- fun disposeView_destroysTouchMonitor() {
- clearInvocations(touchMonitor)
+ fun disposeView_destroysTouchMonitor() =
+ kosmos.runTest {
+ clearInvocations(touchMonitor)
- underTest.disposeView()
+ underTest.disposeView()
- verify(touchMonitor).destroy()
- }
+ verify(touchMonitor).destroy()
+ }
- private fun initAndAttachContainerView() {
+ private fun Kosmos.initAndAttachContainerView() {
val mockInsets =
mock<WindowInsets> {
on { getInsets(WindowInsets.Type.systemGestures()) } doReturn FAKE_INSETS
@@ -802,8 +707,8 @@
testableLooper.processAllMessages()
}
- private suspend fun goToScene(scene: SceneKey) {
- communalRepository.changeScene(scene)
+ private suspend fun Kosmos.goToScene(scene: SceneKey) {
+ fakeCommunalSceneRepository.changeScene(scene)
if (scene == CommunalScenes.Communal) {
kosmos.fakeKeyguardTransitionRepository.sendTransitionSteps(
from = KeyguardState.LOCKSCREEN,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/QuickSettingsControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerImplTest.java
similarity index 100%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/shade/QuickSettingsControllerImplTest.java
rename to packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerImplTest.java
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shadow/DoubleShadowTextClockTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shadow/DoubleShadowTextClockTest.kt
similarity index 100%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/shadow/DoubleShadowTextClockTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/shadow/DoubleShadowTextClockTest.kt
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/clocks/AnimatableClockViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/AnimatableClockViewTest.kt
similarity index 68%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/shared/clocks/AnimatableClockViewTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/shared/clocks/AnimatableClockViewTest.kt
index e076418..79e78c9 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/clocks/AnimatableClockViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/AnimatableClockViewTest.kt
@@ -20,9 +20,10 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.app.animation.Interpolators
-import com.android.systemui.customization.R
import com.android.systemui.SysuiTestCase
+import com.android.systemui.animation.FontVariationUtils
import com.android.systemui.animation.TextAnimator
+import com.android.systemui.customization.R
import com.android.systemui.util.mockito.any
import org.junit.Before
import org.junit.Rule
@@ -32,7 +33,9 @@
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyNoMoreInteractions
+import org.mockito.Mockito.`when` as whenever
import org.mockito.junit.MockitoJUnit
+import org.mockito.kotlin.eq
@RunWith(AndroidJUnit4::class)
@SmallTest
@@ -46,6 +49,7 @@
@Before
fun setUp() {
val layoutInflater = LayoutInflater.from(context)
+ whenever(mockTextAnimator.fontVariationUtils).thenReturn(FontVariationUtils())
clockView =
layoutInflater.inflate(R.layout.clock_default_small, null) as AnimatableClockView
clockView.textAnimatorFactory = { _, _ -> mockTextAnimator }
@@ -57,18 +61,19 @@
clockView.animateAppearOnLockscreen()
clockView.measure(50, 50)
+ verify(mockTextAnimator).fontVariationUtils
verify(mockTextAnimator).glyphFilter = any()
verify(mockTextAnimator)
.setTextStyle(
- weight = 300,
- textSize = -1.0f,
- color = 200,
- strokeWidth = -1F,
- animate = false,
- duration = 833L,
- interpolator = Interpolators.EMPHASIZED_DECELERATE,
- delay = 0L,
- onAnimationEnd = null
+ eq(TextAnimator.Style(fVar = "'wght' 300", color = 200)),
+ eq(
+ TextAnimator.Animation(
+ animate = false,
+ duration = 833L,
+ interpolator = Interpolators.EMPHASIZED_DECELERATE,
+ onAnimationEnd = null,
+ )
+ ),
)
verifyNoMoreInteractions(mockTextAnimator)
}
@@ -79,30 +84,24 @@
clockView.measure(50, 50)
clockView.animateAppearOnLockscreen()
+ verify(mockTextAnimator, times(2)).fontVariationUtils
verify(mockTextAnimator, times(2)).glyphFilter = any()
verify(mockTextAnimator)
.setTextStyle(
- weight = 100,
- textSize = -1.0f,
- color = 200,
- strokeWidth = -1F,
- animate = false,
- duration = 0L,
- interpolator = null,
- delay = 0L,
- onAnimationEnd = null
+ eq(TextAnimator.Style(fVar = "'wght' 100", color = 200)),
+ eq(TextAnimator.Animation(animate = false, duration = 0)),
)
+
verify(mockTextAnimator)
.setTextStyle(
- weight = 300,
- textSize = -1.0f,
- color = 200,
- strokeWidth = -1F,
- animate = true,
- duration = 833L,
- interpolator = Interpolators.EMPHASIZED_DECELERATE,
- delay = 0L,
- onAnimationEnd = null
+ eq(TextAnimator.Style(fVar = "'wght' 300", color = 200)),
+ eq(
+ TextAnimator.Animation(
+ animate = true,
+ duration = 833L,
+ interpolator = Interpolators.EMPHASIZED_DECELERATE,
+ )
+ ),
)
verifyNoMoreInteractions(mockTextAnimator)
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/CombinedConditionTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/condition/CombinedConditionTest.kt
similarity index 100%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/CombinedConditionTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/shared/condition/CombinedConditionTest.kt
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/system/UncaughtExceptionPreHandlerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/system/UncaughtExceptionPreHandlerTest.kt
similarity index 100%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/shared/system/UncaughtExceptionPreHandlerTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/shared/system/UncaughtExceptionPreHandlerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/featurepods/popups/ui/viewmodel/StatusBarPopupChipsViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/featurepods/popups/ui/viewmodel/StatusBarPopupChipsViewModelTest.kt
new file mode 100644
index 0000000..510d6fe
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/featurepods/popups/ui/viewmodel/StatusBarPopupChipsViewModelTest.kt
@@ -0,0 +1,95 @@
+/*
+ * 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.featurepods.popups.ui.viewmodel
+
+import android.platform.test.annotations.EnableFlags
+import androidx.compose.runtime.snapshots.Snapshot
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.kosmos.runTest
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
+import com.android.systemui.lifecycle.activateIn
+import com.android.systemui.media.controls.data.repository.mediaFilterRepository
+import com.android.systemui.media.controls.shared.model.MediaData
+import com.android.systemui.media.controls.shared.model.MediaDataLoadingModel
+import com.android.systemui.statusbar.featurepods.popups.StatusBarPopupChips
+import com.android.systemui.statusbar.featurepods.popups.shared.model.PopupChipId
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@EnableFlags(StatusBarPopupChips.FLAG_NAME)
+@RunWith(AndroidJUnit4::class)
+class StatusBarPopupChipsViewModelTest : SysuiTestCase() {
+ private val kosmos = testKosmos().useUnconfinedTestDispatcher()
+ private val underTest = kosmos.statusBarPopupChipsViewModelFactory.create()
+
+ @Before
+ fun setUp() {
+ underTest.activateIn(kosmos.testScope)
+ }
+
+ @Test
+ fun shownPopupChips_allHidden_empty() =
+ kosmos.runTest {
+ val shownPopupChips = underTest.shownPopupChips
+ assertThat(shownPopupChips).isEmpty()
+ }
+
+ @Test
+ fun shownPopupChips_activeMedia_restHidden_mediaControlChipShown() =
+ kosmos.runTest {
+ val shownPopupChips = underTest.shownPopupChips
+ val userMedia = MediaData(active = true, song = "test")
+ val instanceId = userMedia.instanceId
+
+ mediaFilterRepository.addSelectedUserMediaEntry(userMedia)
+ mediaFilterRepository.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId))
+
+ Snapshot.takeSnapshot {
+ assertThat(shownPopupChips).hasSize(1)
+ assertThat(shownPopupChips.first().chipId).isEqualTo(PopupChipId.MediaControl)
+ }
+ }
+
+ @Test
+ fun shownPopupChips_mediaChipToggled_popupShown() =
+ kosmos.runTest {
+ val shownPopupChips = underTest.shownPopupChips
+
+ val userMedia = MediaData(active = true, song = "test")
+ val instanceId = userMedia.instanceId
+
+ mediaFilterRepository.addSelectedUserMediaEntry(userMedia)
+ mediaFilterRepository.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId))
+
+ Snapshot.takeSnapshot {
+ assertThat(shownPopupChips).hasSize(1)
+ val mediaChip = shownPopupChips.first()
+ assertThat(mediaChip.isPopupShown).isFalse()
+
+ mediaChip.showPopup.invoke()
+ assertThat(shownPopupChips.first().isPopupShown).isTrue()
+ }
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/layout/StatusBarBoundsProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/layout/StatusBarBoundsProviderTest.kt
similarity index 100%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/layout/StatusBarBoundsProviderTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/statusbar/layout/StatusBarBoundsProviderTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java
index 281ce16..19d1224 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java
@@ -28,6 +28,8 @@
import static com.android.systemui.statusbar.NotificationEntryHelper.modifyRanking;
import static com.android.systemui.statusbar.NotificationEntryHelper.modifySbn;
+import static com.google.common.truth.Truth.assertThat;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -46,6 +48,7 @@
import android.os.UserHandle;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.service.notification.NotificationListenerService.Ranking;
import android.service.notification.SnoozeCriterion;
import android.service.notification.StatusBarNotification;
@@ -59,9 +62,12 @@
import com.android.systemui.statusbar.SbnBuilder;
import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips;
import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUi;
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
+import com.android.systemui.statusbar.notification.shared.NotificationBundleUi;
import com.android.systemui.util.time.FakeSystemClock;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
@@ -83,6 +89,9 @@
private NotificationChannel mChannel = Mockito.mock(NotificationChannel.class);
private final FakeSystemClock mClock = new FakeSystemClock();
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
@Before
public void setup() {
Notification.Builder n = new Notification.Builder(mContext, "")
@@ -444,6 +453,145 @@
// no crash, good
}
+ @Test
+ @EnableFlags(NotificationBundleUi.FLAG_NAME)
+ public void getParent_adapter() {
+ GroupEntry ge = new GroupEntryBuilder()
+ .build();
+ Notification notification = new Notification.Builder(mContext, "")
+ .setSmallIcon(R.drawable.ic_person)
+ .build();
+
+ NotificationEntry entry = new NotificationEntryBuilder()
+ .setPkg(TEST_PACKAGE_NAME)
+ .setOpPkg(TEST_PACKAGE_NAME)
+ .setUid(TEST_UID)
+ .setChannel(mChannel)
+ .setId(mId++)
+ .setNotification(notification)
+ .setUser(new UserHandle(ActivityManager.getCurrentUser()))
+ .setParent(ge)
+ .build();
+
+ assertThat(entry.getEntryAdapter().getParent()).isEqualTo(entry.getParent());
+ }
+
+ @Test
+ @EnableFlags(NotificationBundleUi.FLAG_NAME)
+ public void isTopLevelEntry_adapter() {
+ Notification notification = new Notification.Builder(mContext, "")
+ .setSmallIcon(R.drawable.ic_person)
+ .build();
+
+ NotificationEntry entry = new NotificationEntryBuilder()
+ .setPkg(TEST_PACKAGE_NAME)
+ .setOpPkg(TEST_PACKAGE_NAME)
+ .setUid(TEST_UID)
+ .setChannel(mChannel)
+ .setId(mId++)
+ .setNotification(notification)
+ .setUser(new UserHandle(ActivityManager.getCurrentUser()))
+ .setParent(GroupEntry.ROOT_ENTRY)
+ .build();
+
+ assertThat(entry.getEntryAdapter().isTopLevelEntry()).isTrue();
+ }
+
+ @Test
+ @EnableFlags(NotificationBundleUi.FLAG_NAME)
+ public void getKey_adapter() {
+ Notification notification = new Notification.Builder(mContext, "")
+ .setSmallIcon(R.drawable.ic_person)
+ .build();
+
+ NotificationEntry entry = new NotificationEntryBuilder()
+ .setPkg(TEST_PACKAGE_NAME)
+ .setOpPkg(TEST_PACKAGE_NAME)
+ .setUid(TEST_UID)
+ .setChannel(mChannel)
+ .setId(mId++)
+ .setNotification(notification)
+ .setUser(new UserHandle(ActivityManager.getCurrentUser()))
+ .build();
+
+ assertThat(entry.getEntryAdapter().getKey()).isEqualTo(entry.getKey());
+ }
+
+ @Test
+ @EnableFlags(NotificationBundleUi.FLAG_NAME)
+ public void getRow_adapter() {
+ ExpandableNotificationRow row = mock(ExpandableNotificationRow.class);
+ Notification notification = new Notification.Builder(mContext, "")
+ .setSmallIcon(R.drawable.ic_person)
+ .build();
+
+ NotificationEntry entry = new NotificationEntryBuilder()
+ .setPkg(TEST_PACKAGE_NAME)
+ .setOpPkg(TEST_PACKAGE_NAME)
+ .setUid(TEST_UID)
+ .setChannel(mChannel)
+ .setId(mId++)
+ .setNotification(notification)
+ .setUser(new UserHandle(ActivityManager.getCurrentUser()))
+ .build();
+ entry.setRow(row);
+
+ assertThat(entry.getEntryAdapter().getRow()).isEqualTo(entry.getRow());
+ }
+
+ @Test
+ @EnableFlags(NotificationBundleUi.FLAG_NAME)
+ public void getGroupRoot_adapter_groupSummary() {
+ ExpandableNotificationRow row = mock(ExpandableNotificationRow.class);
+ Notification notification = new Notification.Builder(mContext, "")
+ .setSmallIcon(R.drawable.ic_person)
+ .setGroupSummary(true)
+ .setGroup("key")
+ .build();
+
+ NotificationEntry entry = new NotificationEntryBuilder()
+ .setPkg(TEST_PACKAGE_NAME)
+ .setOpPkg(TEST_PACKAGE_NAME)
+ .setUid(TEST_UID)
+ .setChannel(mChannel)
+ .setId(mId++)
+ .setNotification(notification)
+ .setUser(new UserHandle(ActivityManager.getCurrentUser()))
+ .setParent(GroupEntry.ROOT_ENTRY)
+ .build();
+ entry.setRow(row);
+
+ assertThat(entry.getEntryAdapter().getGroupRoot()).isNull();
+ }
+
+ @Test
+ @EnableFlags(NotificationBundleUi.FLAG_NAME)
+ public void getGroupRoot_adapter_groupChild() {
+ Notification notification = new Notification.Builder(mContext, "")
+ .setSmallIcon(R.drawable.ic_person)
+ .setGroupSummary(true)
+ .setGroup("key")
+ .build();
+
+ NotificationEntry parent = new NotificationEntryBuilder()
+ .setParent(GroupEntry.ROOT_ENTRY)
+ .build();
+ GroupEntryBuilder groupEntry = new GroupEntryBuilder()
+ .setSummary(parent);
+
+ NotificationEntry entry = new NotificationEntryBuilder()
+ .setPkg(TEST_PACKAGE_NAME)
+ .setOpPkg(TEST_PACKAGE_NAME)
+ .setUid(TEST_UID)
+ .setChannel(mChannel)
+ .setId(mId++)
+ .setNotification(notification)
+ .setUser(new UserHandle(ActivityManager.getCurrentUser()))
+ .setParent(groupEntry.build())
+ .build();
+
+ assertThat(entry.getEntryAdapter().getGroupRoot()).isEqualTo(parent.getEntryAdapter());
+ }
private Notification.Action createContextualAction(String title) {
return new Notification.Action.Builder(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java
similarity index 100%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java
rename to packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/BigPictureIconManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/BigPictureIconManagerTest.kt
similarity index 100%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/BigPictureIconManagerTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/BigPictureIconManagerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
index 77b116e..1b53531 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
@@ -16,6 +16,8 @@
package com.android.systemui.statusbar.notification.row;
+import static android.app.Flags.FLAG_NOTIFICATIONS_REDESIGN_TEMPLATES;
+
import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_ALL;
import static com.android.systemui.statusbar.notification.row.NotificationTestHelper.PKG;
import static com.android.systemui.statusbar.notification.row.NotificationTestHelper.USER_HANDLE;
@@ -29,6 +31,7 @@
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
@@ -189,6 +192,54 @@
}
@Test
+ @EnableFlags(FLAG_NOTIFICATIONS_REDESIGN_TEMPLATES)
+ public void setSensitive_doesNothingIfCalledAgain() throws Exception {
+ ExpandableNotificationRow row = mNotificationTestHelper.createRow();
+ measureAndLayout(row);
+
+ // GIVEN a mocked public layout
+ NotificationContentView mockPublicLayout = mock(NotificationContentView.class);
+ row.setPublicLayout(mockPublicLayout);
+
+ // GIVEN a sensitive notification row that's currently redacted
+ row.setHideSensitiveForIntrinsicHeight(true);
+ row.setSensitive(true, true);
+ assertThat(row.getShowingLayout()).isSameInstanceAs(row.getPublicLayout());
+ verify(mockPublicLayout).requestSelectLayout(eq(true));
+ clearInvocations(mockPublicLayout);
+
+ // WHEN the row is set to the same sensitive settings
+ row.setSensitive(true, true);
+
+ // VERIFY that the layout is not updated again
+ assertThat(row.getShowingLayout()).isSameInstanceAs(row.getPublicLayout());
+ verify(mockPublicLayout, never()).requestSelectLayout(anyBoolean());
+ }
+
+ @Test
+ @EnableFlags(FLAG_NOTIFICATIONS_REDESIGN_TEMPLATES)
+ public void testSetSensitiveOnNotifRowUpdatesLayout() throws Exception {
+ // GIVEN a sensitive notification row that's currently redacted
+ ExpandableNotificationRow row = mNotificationTestHelper.createRow();
+ measureAndLayout(row);
+ row.setHideSensitiveForIntrinsicHeight(true);
+ row.setSensitive(true, true);
+ assertThat(row.getShowingLayout()).isSameInstanceAs(row.getPublicLayout());
+
+ // GIVEN a mocked private layout
+ NotificationContentView mockPrivateLayout = mock(NotificationContentView.class);
+ row.setPrivateLayout(mockPrivateLayout);
+
+ // WHEN the row is set to no longer be sensitive
+ row.setSensitive(false, true);
+
+ // VERIFY that the layout is updated
+ assertThat(row.getShowingLayout()).isSameInstanceAs(row.getPrivateLayout());
+ verify(mockPrivateLayout).requestSelectLayout(eq(true));
+ }
+
+ @Test
+ @DisableFlags(FLAG_NOTIFICATIONS_REDESIGN_TEMPLATES)
public void testSetSensitiveOnNotifRowNotifiesOfHeightChange() throws Exception {
// GIVEN a sensitive notification row that's currently redacted
ExpandableNotificationRow row = mNotificationTestHelper.createRow();
@@ -612,8 +663,8 @@
Assert.assertTrue(group.getAttachedChildren().isEmpty());
Assert.assertNotEquals(group, child.getNotificationParent());
verify(mNotificationTestHelper.getMockLogger()).logSkipAttachingKeepInParentChild(
- /*child=*/ child.getEntry(),
- /*newParent=*/ group.getEntry()
+ /*child=*/ child.getLoggingKey(),
+ /*newParent=*/ group.getLoggingKey()
);
}
@@ -629,7 +680,7 @@
Assert.assertNull(child.getNotificationParent());
Assert.assertFalse(child.keepInParentForDismissAnimation());
verify(mNotificationTestHelper.getMockLogger())
- .logCancelAppearDrawing(child.getEntry(), false);
+ .logCancelAppearDrawing(child.getLoggingKey(), false);
verifyNoMoreInteractions(mNotificationTestHelper.getMockLogger());
}
@@ -645,8 +696,8 @@
Assert.assertNull(child.getNotificationParent());
Assert.assertFalse(child.keepInParentForDismissAnimation());
verify(mNotificationTestHelper.getMockLogger()).logKeepInParentChildDetached(
- /*child=*/ child.getEntry(),
- /*oldParent=*/ group.getEntry()
+ /*child=*/ child.getLoggingKey(),
+ /*oldParent=*/ group.getLoggingKey()
);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.kt
index 699e8c3..47238fe 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.kt
@@ -23,6 +23,7 @@
import android.testing.TestableLooper
import android.testing.ViewUtils
import android.view.NotificationHeaderView
+import android.view.NotificationTopLineView
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
@@ -37,6 +38,7 @@
import com.android.systemui.statusbar.notification.FeedbackIcon
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier
+import com.android.systemui.statusbar.notification.shared.NotificationBundleUi
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
@@ -82,8 +84,21 @@
val mockEntry = createMockNotificationEntry()
row =
spy(
- ExpandableNotificationRow(mContext, /* attrs= */ null, mockEntry).apply {
- entry = mockEntry
+ when (NotificationBundleUi.isEnabled) {
+ true -> {
+ ExpandableNotificationRow(
+ mContext,
+ /* attrs= */ null,
+ UserHandle.CURRENT
+ ).apply {
+ entry = mockEntry
+ }
+ }
+ false -> {
+ ExpandableNotificationRow(mContext, /* attrs= */ null, mockEntry).apply {
+ entry = mockEntry
+ }
+ }
}
)
ViewUtils.attachView(fakeParent)
@@ -270,7 +285,7 @@
val icon =
FeedbackIcon(
R.drawable.ic_feedback_alerted,
- R.string.notification_feedback_indicator_alerted
+ R.string.notification_feedback_indicator_alerted,
)
view.setFeedbackIcon(icon)
@@ -291,10 +306,7 @@
val mockHeadsUpEB = mock<NotificationExpandButton>()
val mockHeadsUp = createMockNotificationHeaderView(contractedHeight, mockHeadsUpEB)
- val view =
- createContentView(
- isSystemExpanded = false,
- )
+ val view = createContentView(isSystemExpanded = false)
// Update all 3 child forms
view.apply {
@@ -319,12 +331,14 @@
private fun createMockNotificationHeaderView(
height: Int,
- mockExpandedEB: NotificationExpandButton
+ mockExpandedEB: NotificationExpandButton,
) =
spy(NotificationHeaderView(mContext, /* attrs= */ null).apply { minimumHeight = height })
.apply {
whenever(this.animate()).thenReturn(mock())
whenever(this.findViewById<View>(R.id.expand_button)).thenReturn(mockExpandedEB)
+ whenever(this.findViewById<View>(R.id.notification_top_line))
+ .thenReturn(mock<NotificationTopLineView>())
}
@Test
@@ -344,7 +358,7 @@
isSystemExpanded = false,
contractedView = mockContracted,
expandedView = mockExpanded,
- headsUpView = mockHeadsUp
+ headsUpView = mockHeadsUp,
)
view.setRemoteInputVisible(true)
@@ -373,7 +387,7 @@
isSystemExpanded = false,
contractedView = mockContracted,
expandedView = mockExpanded,
- headsUpView = mockHeadsUp
+ headsUpView = mockHeadsUp,
)
view.setRemoteInputVisible(false)
@@ -635,7 +649,7 @@
contractedView: View = createViewWithHeight(contractedHeight),
expandedView: View = createViewWithHeight(expandedHeight),
headsUpView: View = createViewWithHeight(contractedHeight),
- row: ExpandableNotificationRow = this.row
+ row: ExpandableNotificationRow = this.row,
): NotificationContentView {
val height = if (isSystemExpanded) expandedHeight else contractedHeight
doReturn(height).whenever(row).intrinsicHeight
@@ -647,7 +661,7 @@
setHeights(
/* smallHeight= */ contractedHeight,
/* headsUpMaxHeight= */ contractedHeight,
- /* maxHeight= */ expandedHeight
+ /* maxHeight= */ expandedHeight,
)
contractedChild = contractedView
expandedChild = expandedView
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/RowImageInflaterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/RowImageInflaterTest.kt
similarity index 100%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/RowImageInflaterTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/RowImageInflaterTest.kt
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.kt
similarity index 100%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.kt
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 14a1233..1088676 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
@@ -63,6 +63,7 @@
import com.android.systemui.animation.ShadeInterpolation;
import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants;
import com.android.systemui.dock.DockManager;
+import com.android.systemui.flags.DisableSceneContainer;
import com.android.systemui.flags.EnableSceneContainer;
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository;
@@ -118,10 +119,8 @@
@Rule public Expect mExpect = Expect.create();
private final KosmosJavaAdapter mKosmos = new KosmosJavaAdapter(this);
- private final FakeConfigurationController mConfigurationController =
- new FakeConfigurationController();
- private final LargeScreenShadeInterpolator
- mLinearLargeScreenShadeInterpolator = new LinearLargeScreenShadeInterpolator();
+ private FakeConfigurationController mConfigurationController;
+ private LargeScreenShadeInterpolator mLinearLargeScreenShadeInterpolator;
private final TestScope mTestScope = mKosmos.getTestScope();
private final JavaAdapter mJavaAdapter = new JavaAdapter(mTestScope.getBackgroundScope());
@@ -137,6 +136,7 @@
private boolean mAlwaysOnEnabled;
private TestableLooper mLooper;
private Context mContext;
+
@Mock private DozeParameters mDozeParameters;
@Mock private LightBarController mLightBarController;
@Mock private DelayedWakeLock.Factory mDelayedWakeLockFactory;
@@ -149,12 +149,11 @@
@Mock private PrimaryBouncerToGoneTransitionViewModel mPrimaryBouncerToGoneTransitionViewModel;
@Mock private AlternateBouncerToGoneTransitionViewModel
mAlternateBouncerToGoneTransitionViewModel;
- private final KeyguardTransitionInteractor mKeyguardTransitionInteractor =
- mKosmos.getKeyguardTransitionInteractor();
- private final FakeKeyguardTransitionRepository mKeyguardTransitionRepository =
- mKosmos.getKeyguardTransitionRepository();
@Mock private KeyguardInteractor mKeyguardInteractor;
+ private KeyguardTransitionInteractor mKeyguardTransitionInteractor;
+ private FakeKeyguardTransitionRepository mKeyguardTransitionRepository;
+
// 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.)
@Mock private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
@@ -238,6 +237,9 @@
when(mContext.getColor(com.android.internal.R.color.materialColorSurface))
.thenAnswer(invocation -> mSurfaceColor);
+ mConfigurationController = new FakeConfigurationController();
+ mLinearLargeScreenShadeInterpolator = new LinearLargeScreenShadeInterpolator();
+
mScrimBehind = spy(new ScrimView(mContext));
mScrimInFront = new ScrimView(mContext);
mNotificationsScrim = new ScrimView(mContext);
@@ -270,6 +272,9 @@
when(mAlternateBouncerToGoneTransitionViewModel.getScrimAlpha())
.thenReturn(emptyFlow());
+ mKeyguardTransitionRepository = mKosmos.getKeyguardTransitionRepository();
+ mKeyguardTransitionInteractor = mKosmos.getKeyguardTransitionInteractor();
+
mScrimController = new ScrimController(
mLightBarController,
mDozeParameters,
@@ -322,6 +327,7 @@
}
@Test
+ @DisableSceneContainer
public void transitionToKeyguard() {
mScrimController.legacyTransitionTo(ScrimState.KEYGUARD);
finishAnimationsImmediately();
@@ -337,6 +343,7 @@
}
@Test
+ @DisableSceneContainer
public void transitionToShadeLocked() {
mScrimController.legacyTransitionTo(SHADE_LOCKED);
mScrimController.setQsPosition(1f, 0);
@@ -373,6 +380,7 @@
}
@Test
+ @DisableSceneContainer
public void transitionToShadeLocked_clippingQs() {
mScrimController.setClipsQsScrim(true);
mScrimController.legacyTransitionTo(SHADE_LOCKED);
@@ -391,6 +399,7 @@
}
@Test
+ @DisableSceneContainer
public void transitionToOff() {
mScrimController.legacyTransitionTo(ScrimState.OFF);
finishAnimationsImmediately();
@@ -406,6 +415,7 @@
}
@Test
+ @DisableSceneContainer
public void transitionToAod_withRegularWallpaper() {
mScrimController.legacyTransitionTo(ScrimState.AOD);
finishAnimationsImmediately();
@@ -421,6 +431,7 @@
}
@Test
+ @DisableSceneContainer
public void transitionToAod_withFrontAlphaUpdates() {
// Assert that setting the AOD front scrim alpha doesn't take effect in a non-AOD state.
mScrimController.legacyTransitionTo(ScrimState.KEYGUARD);
@@ -465,6 +476,7 @@
}
@Test
+ @DisableSceneContainer
public void transitionToAod_afterDocked_ignoresAlwaysOnAndUpdatesFrontAlpha() {
// Assert that setting the AOD front scrim alpha doesn't take effect in a non-AOD state.
mScrimController.legacyTransitionTo(ScrimState.KEYGUARD);
@@ -506,6 +518,7 @@
}
@Test
+ @DisableSceneContainer
public void transitionToPulsing_withFrontAlphaUpdates() {
// Pre-condition
// Need to go to AoD first because PULSING doesn't change
@@ -551,6 +564,7 @@
}
@Test
+ @DisableSceneContainer
public void transitionToKeyguardBouncer() {
mScrimController.legacyTransitionTo(BOUNCER);
finishAnimationsImmediately();
@@ -571,6 +585,7 @@
}
@Test
+ @DisableSceneContainer
public void lockscreenToHubTransition_setsBehindScrimAlpha() {
// Start on lockscreen.
mScrimController.legacyTransitionTo(ScrimState.KEYGUARD);
@@ -617,6 +632,7 @@
}
@Test
+ @DisableSceneContainer
public void hubToLockscreenTransition_setsViewAlpha() {
// Start on glanceable hub.
mScrimController.legacyTransitionTo(ScrimState.GLANCEABLE_HUB);
@@ -663,6 +679,7 @@
}
@Test
+ @DisableSceneContainer
public void transitionToHub() {
mScrimController.setRawPanelExpansionFraction(0f);
mScrimController.setBouncerHiddenFraction(KeyguardBouncerConstants.EXPANSION_HIDDEN);
@@ -677,6 +694,7 @@
}
@Test
+ @DisableSceneContainer
public void openBouncerOnHub() {
mScrimController.legacyTransitionTo(ScrimState.GLANCEABLE_HUB);
@@ -706,6 +724,7 @@
}
@Test
+ @DisableSceneContainer
public void openShadeOnHub() {
mScrimController.legacyTransitionTo(ScrimState.GLANCEABLE_HUB);
@@ -734,6 +753,7 @@
}
@Test
+ @DisableSceneContainer
public void transitionToHubOverDream() {
mScrimController.setRawPanelExpansionFraction(0f);
mScrimController.setBouncerHiddenFraction(KeyguardBouncerConstants.EXPANSION_HIDDEN);
@@ -748,6 +768,7 @@
}
@Test
+ @DisableSceneContainer
public void openBouncerOnHubOverDream() {
mScrimController.legacyTransitionTo(ScrimState.GLANCEABLE_HUB_OVER_DREAM);
@@ -777,6 +798,7 @@
}
@Test
+ @DisableSceneContainer
public void openShadeOnHubOverDream() {
mScrimController.legacyTransitionTo(ScrimState.GLANCEABLE_HUB_OVER_DREAM);
@@ -805,6 +827,7 @@
}
@Test
+ @DisableSceneContainer
public void onThemeChange_bouncerBehindTint_isUpdatedToSurfaceColor() {
assertEquals(BOUNCER.getBehindTint(), 0x112233);
mSurfaceColor = 0x223344;
@@ -813,6 +836,7 @@
}
@Test
+ @DisableSceneContainer
public void onThemeChangeWhileClipQsScrim_bouncerBehindTint_remainsBlack() {
mScrimController.setClipsQsScrim(true);
mScrimController.legacyTransitionTo(BOUNCER);
@@ -825,6 +849,7 @@
}
@Test
+ @DisableSceneContainer
public void transitionToKeyguardBouncer_clippingQs() {
mScrimController.setClipsQsScrim(true);
mScrimController.legacyTransitionTo(BOUNCER);
@@ -845,6 +870,7 @@
}
@Test
+ @DisableSceneContainer
public void disableClipQsScrimWithoutStateTransition_updatesTintAndAlpha() {
mScrimController.setClipsQsScrim(true);
mScrimController.legacyTransitionTo(BOUNCER);
@@ -867,6 +893,7 @@
}
@Test
+ @DisableSceneContainer
public void enableClipQsScrimWithoutStateTransition_updatesTintAndAlpha() {
mScrimController.setClipsQsScrim(false);
mScrimController.legacyTransitionTo(BOUNCER);
@@ -889,6 +916,7 @@
}
@Test
+ @DisableSceneContainer
public void transitionToBouncer() {
mScrimController.legacyTransitionTo(ScrimState.BOUNCER_SCRIMMED);
finishAnimationsImmediately();
@@ -902,6 +930,7 @@
}
@Test
+ @DisableSceneContainer
public void transitionToUnlocked_clippedQs() {
mScrimController.setClipsQsScrim(true);
mScrimController.setRawPanelExpansionFraction(0f);
@@ -960,6 +989,7 @@
}
@Test
+ @DisableSceneContainer
public void transitionToUnlocked_nonClippedQs_followsLargeScreensInterpolator() {
mScrimController.setClipsQsScrim(false);
mScrimController.setRawPanelExpansionFraction(0f);
@@ -999,6 +1029,7 @@
}
@Test
+ @DisableSceneContainer
public void scrimStateCallback() {
mScrimController.legacyTransitionTo(ScrimState.UNLOCKED);
finishAnimationsImmediately();
@@ -1014,6 +1045,7 @@
}
@Test
+ @DisableSceneContainer
public void panelExpansion() {
mScrimController.setRawPanelExpansionFraction(0f);
mScrimController.setRawPanelExpansionFraction(0.5f);
@@ -1036,6 +1068,7 @@
}
@Test
+ @DisableSceneContainer
public void qsExpansion() {
reset(mScrimBehind);
mScrimController.setQsPosition(1f, 999 /* value doesn't matter */);
@@ -1048,6 +1081,7 @@
}
@Test
+ @DisableSceneContainer
public void qsExpansion_clippingQs() {
reset(mScrimBehind);
mScrimController.setClipsQsScrim(true);
@@ -1061,6 +1095,7 @@
}
@Test
+ @DisableSceneContainer
public void qsExpansion_half_clippingQs() {
reset(mScrimBehind);
mScrimController.setClipsQsScrim(true);
@@ -1074,6 +1109,7 @@
}
@Test
+ @DisableSceneContainer
public void panelExpansionAffectsAlpha() {
mScrimController.setRawPanelExpansionFraction(0f);
mScrimController.setRawPanelExpansionFraction(0.5f);
@@ -1096,6 +1132,7 @@
}
@Test
+ @DisableSceneContainer
public void transitionToUnlockedFromOff() {
// Simulate unlock with fingerprint without AOD
mScrimController.legacyTransitionTo(ScrimState.OFF);
@@ -1118,6 +1155,7 @@
}
@Test
+ @DisableSceneContainer
public void transitionToUnlockedFromAod() {
// Simulate unlock with fingerprint
mScrimController.legacyTransitionTo(ScrimState.AOD);
@@ -1140,6 +1178,7 @@
}
@Test
+ @DisableSceneContainer
public void scrimBlanksBeforeLeavingAod() {
// Simulate unlock with fingerprint
mScrimController.legacyTransitionTo(ScrimState.AOD);
@@ -1163,6 +1202,7 @@
}
@Test
+ @DisableSceneContainer
public void scrimBlankCallbackWhenUnlockingFromPulse() {
boolean[] blanked = {false};
// Simulate unlock with fingerprint
@@ -1181,6 +1221,7 @@
}
@Test
+ @DisableSceneContainer
public void blankingNotRequired_leavingAoD() {
// GIVEN display does NOT need blanking
when(mDozeParameters.getDisplayNeedsBlanking()).thenReturn(false);
@@ -1236,6 +1277,7 @@
}
@Test
+ @DisableSceneContainer
public void testScrimCallback() {
int[] callOrder = {0, 0, 0};
int[] currentCall = {0};
@@ -1262,12 +1304,14 @@
}
@Test
+ @DisableSceneContainer
public void testScrimCallbacksWithoutAmbientDisplay() {
mAlwaysOnEnabled = false;
testScrimCallback();
}
@Test
+ @DisableSceneContainer
public void testScrimCallbackCancelled() {
boolean[] cancelledCalled = {false};
mScrimController.legacyTransitionTo(ScrimState.AOD, new ScrimController.Callback() {
@@ -1281,6 +1325,7 @@
}
@Test
+ @DisableSceneContainer
public void testHoldsWakeLock_whenAOD() {
mScrimController.legacyTransitionTo(ScrimState.AOD);
verify(mWakeLock).acquire(anyString());
@@ -1290,6 +1335,7 @@
}
@Test
+ @DisableSceneContainer
public void testDoesNotHoldWakeLock_whenUnlocking() {
mScrimController.legacyTransitionTo(ScrimState.UNLOCKED);
finishAnimationsImmediately();
@@ -1297,6 +1343,7 @@
}
@Test
+ @DisableSceneContainer
public void testCallbackInvokedOnSameStateTransition() {
mScrimController.legacyTransitionTo(ScrimState.UNLOCKED);
finishAnimationsImmediately();
@@ -1306,6 +1353,7 @@
}
@Test
+ @DisableSceneContainer
public void testConservesExpansionOpacityAfterTransition() {
mScrimController.legacyTransitionTo(ScrimState.UNLOCKED);
mScrimController.setRawPanelExpansionFraction(0.5f);
@@ -1323,6 +1371,7 @@
}
@Test
+ @DisableSceneContainer
public void testCancelsOldAnimationBeforeBlanking() {
mScrimController.legacyTransitionTo(ScrimState.AOD);
finishAnimationsImmediately();
@@ -1335,6 +1384,7 @@
}
@Test
+ @DisableSceneContainer
public void testScrimsAreNotFocusable() {
assertFalse("Behind scrim should not be focusable", mScrimBehind.isFocusable());
assertFalse("Front scrim should not be focusable", mScrimInFront.isFocusable());
@@ -1343,6 +1393,7 @@
}
@Test
+ @DisableSceneContainer
public void testEatsTouchEvent() {
HashSet<ScrimState> eatsTouches =
new HashSet<>(Collections.singletonList(ScrimState.AOD));
@@ -1359,6 +1410,7 @@
}
@Test
+ @DisableSceneContainer
public void testAnimatesTransitionToAod() {
when(mDozeParameters.shouldControlScreenOff()).thenReturn(false);
ScrimState.AOD.prepare(ScrimState.KEYGUARD);
@@ -1373,6 +1425,7 @@
}
@Test
+ @DisableSceneContainer
public void testIsLowPowerMode() {
HashSet<ScrimState> lowPowerModeStates = new HashSet<>(Arrays.asList(
ScrimState.OFF, ScrimState.AOD, ScrimState.PULSING));
@@ -1390,6 +1443,7 @@
}
@Test
+ @DisableSceneContainer
public void testScrimsOpaque_whenShadeFullyExpanded() {
mScrimController.legacyTransitionTo(ScrimState.UNLOCKED);
mScrimController.setRawPanelExpansionFraction(1);
@@ -1404,6 +1458,7 @@
}
@Test
+ @DisableSceneContainer
public void testScrimsVisible_whenShadeVisible() {
mScrimController.setClipsQsScrim(true);
mScrimController.legacyTransitionTo(ScrimState.UNLOCKED);
@@ -1419,6 +1474,7 @@
}
@Test
+ @DisableSceneContainer
public void testDoesntAnimate_whenUnlocking() {
// LightRevealScrim will animate the transition, we should only hide the keyguard scrims.
ScrimState.UNLOCKED.prepare(ScrimState.KEYGUARD);
@@ -1439,6 +1495,7 @@
}
@Test
+ @DisableSceneContainer
public void testScrimsVisible_whenShadeVisible_clippingQs() {
mScrimController.setClipsQsScrim(true);
mScrimController.legacyTransitionTo(ScrimState.UNLOCKED);
@@ -1454,6 +1511,7 @@
}
@Test
+ @DisableSceneContainer
public void testScrimsVisible_whenShadeVisibleOnLockscreen() {
mScrimController.legacyTransitionTo(ScrimState.KEYGUARD);
mScrimController.setQsPosition(0.25f, 300);
@@ -1465,6 +1523,7 @@
}
@Test
+ @DisableSceneContainer
public void testNotificationScrimTransparent_whenOnLockscreen() {
mScrimController.legacyTransitionTo(ScrimState.KEYGUARD);
// even if shade is not pulled down, panel has expansion of 1 on the lockscreen
@@ -1477,6 +1536,7 @@
}
@Test
+ @DisableSceneContainer
public void testNotificationScrimVisible_afterOpeningShadeFromLockscreen() {
mScrimController.setRawPanelExpansionFraction(1);
mScrimController.legacyTransitionTo(SHADE_LOCKED);
@@ -1488,6 +1548,7 @@
}
@Test
+ @DisableSceneContainer
public void qsExpansion_BehindTint_shadeLocked_bouncerActive_usesBouncerProgress() {
when(mStatusBarKeyguardViewManager.isPrimaryBouncerInTransit()).thenReturn(true);
// clipping doesn't change tested logic but allows to assert scrims more in line with
@@ -1504,6 +1565,7 @@
}
@Test
+ @DisableSceneContainer
public void expansionNotificationAlpha_shadeLocked_bouncerActive_usesBouncerInterpolator() {
when(mStatusBarKeyguardViewManager.isPrimaryBouncerInTransit()).thenReturn(true);
@@ -1520,6 +1582,7 @@
}
@Test
+ @DisableSceneContainer
public void expansionNotificationAlpha_shadeLocked_bouncerNotActive_usesShadeInterpolator() {
when(mStatusBarKeyguardViewManager.isPrimaryBouncerInTransit()).thenReturn(false);
@@ -1535,6 +1598,7 @@
}
@Test
+ @DisableSceneContainer
public void notificationAlpha_unnocclusionAnimating_bouncerNotActive_usesKeyguardNotifAlpha() {
when(mStatusBarKeyguardViewManager.isPrimaryBouncerInTransit()).thenReturn(false);
@@ -1554,6 +1618,7 @@
}
@Test
+ @DisableSceneContainer
public void notificationAlpha_inKeyguardState_bouncerActive_usesInvertedBouncerInterpolator() {
when(mStatusBarKeyguardViewManager.isPrimaryBouncerInTransit()).thenReturn(true);
mScrimController.setClipsQsScrim(true);
@@ -1574,6 +1639,7 @@
}
@Test
+ @DisableSceneContainer
public void notificationAlpha_inKeyguardState_bouncerNotActive_usesInvertedShadeInterpolator() {
when(mStatusBarKeyguardViewManager.isPrimaryBouncerInTransit()).thenReturn(false);
mScrimController.setClipsQsScrim(true);
@@ -1594,6 +1660,7 @@
}
@Test
+ @DisableSceneContainer
public void behindTint_inKeyguardState_bouncerNotActive_usesKeyguardBehindTint() {
when(mStatusBarKeyguardViewManager.isPrimaryBouncerInTransit()).thenReturn(false);
mScrimController.setClipsQsScrim(false);
@@ -1605,6 +1672,7 @@
}
@Test
+ @DisableSceneContainer
public void testNotificationTransparency_followsTransitionToFullShade() {
mScrimController.setClipsQsScrim(true);
@@ -1646,6 +1714,7 @@
}
@Test
+ @DisableSceneContainer
public void notificationTransparency_followsNotificationScrimProgress() {
mScrimController.legacyTransitionTo(SHADE_LOCKED);
mScrimController.setRawPanelExpansionFraction(1.0f);
@@ -1662,6 +1731,7 @@
}
@Test
+ @DisableSceneContainer
public void notificationAlpha_qsNotClipped_alphaMatchesNotificationExpansionProgress() {
mScrimController.setClipsQsScrim(false);
mScrimController.legacyTransitionTo(ScrimState.KEYGUARD);
@@ -1697,6 +1767,7 @@
}
@Test
+ @DisableSceneContainer
public void setNotificationsOverScrollAmount_setsTranslationYOnNotificationsScrim() {
int overScrollAmount = 10;
@@ -1706,6 +1777,7 @@
}
@Test
+ @DisableSceneContainer
public void setNotificationsOverScrollAmount_doesNotSetTranslationYOnBehindScrim() {
int overScrollAmount = 10;
@@ -1715,6 +1787,7 @@
}
@Test
+ @DisableSceneContainer
public void setNotificationsOverScrollAmount_doesNotSetTranslationYOnFrontScrim() {
int overScrollAmount = 10;
@@ -1724,6 +1797,7 @@
}
@Test
+ @DisableSceneContainer
public void notificationBoundsTopGetsPassedToKeyguard() {
mScrimController.legacyTransitionTo(SHADE_LOCKED);
mScrimController.setQsPosition(1f, 0);
@@ -1734,6 +1808,7 @@
}
@Test
+ @DisableSceneContainer
public void notificationBoundsTopDoesNotGetPassedToKeyguardWhenNotifScrimIsNotVisible() {
mScrimController.setKeyguardOccluded(true);
mScrimController.legacyTransitionTo(ScrimState.KEYGUARD);
@@ -1744,6 +1819,7 @@
}
@Test
+ @DisableSceneContainer
public void transitionToDreaming() {
mScrimController.setRawPanelExpansionFraction(0f);
mScrimController.setBouncerHiddenFraction(KeyguardBouncerConstants.EXPANSION_HIDDEN);
@@ -1763,6 +1839,7 @@
}
@Test
+ @DisableSceneContainer
public void keyguardGoingAwayUpdateScrims() {
when(mKeyguardStateController.isKeyguardGoingAway()).thenReturn(true);
mScrimController.updateScrims();
@@ -1772,6 +1849,7 @@
@Test
+ @DisableSceneContainer
public void setUnOccludingAnimationKeyguard() {
mScrimController.legacyTransitionTo(ScrimState.KEYGUARD);
finishAnimationsImmediately();
@@ -1786,6 +1864,7 @@
}
@Test
+ @DisableSceneContainer
public void testHidesScrimFlickerInActivity() {
mScrimController.setKeyguardOccluded(true);
mScrimController.legacyTransitionTo(ScrimState.KEYGUARD);
@@ -1804,6 +1883,7 @@
}
@Test
+ @DisableSceneContainer
public void notificationAlpha_inKeyguardState_bouncerNotActive_clipsQsScrimFalse() {
mScrimController.setClipsQsScrim(false);
mScrimController.legacyTransitionTo(ScrimState.KEYGUARD);
@@ -1813,6 +1893,7 @@
}
@Test
+ @DisableSceneContainer
public void aodStateSetsFrontScrimToNotBlend() {
mScrimController.legacyTransitionTo(ScrimState.AOD);
assertFalse("Front scrim should not blend with main color",
@@ -1820,6 +1901,7 @@
}
@Test
+ @DisableSceneContainer
public void applyState_unlocked_bouncerShowing() {
mScrimController.legacyTransitionTo(ScrimState.UNLOCKED);
mScrimController.setBouncerHiddenFraction(0.99f);
@@ -1829,6 +1911,7 @@
}
@Test
+ @DisableSceneContainer
public void ignoreTransitionRequestWhileKeyguardTransitionRunning() {
mScrimController.legacyTransitionTo(ScrimState.UNLOCKED);
mScrimController.mBouncerToGoneTransition.accept(
@@ -1841,6 +1924,7 @@
}
@Test
+ @DisableSceneContainer
public void primaryBouncerToGoneOnFinishCallsKeyguardFadedAway() {
when(mKeyguardStateController.isKeyguardFadingAway()).thenReturn(true);
mScrimController.mBouncerToGoneTransition.accept(
@@ -1851,6 +1935,7 @@
}
@Test
+ @DisableSceneContainer
public void primaryBouncerToGoneOnFinishCallsLightBarController() {
reset(mLightBarController);
mScrimController.mBouncerToGoneTransition.accept(
@@ -1862,6 +1947,7 @@
}
@Test
+ @DisableSceneContainer
public void testDoNotAnimateChangeIfOccludeAnimationPlaying() {
mScrimController.setOccludeAnimationPlaying(true);
mScrimController.legacyTransitionTo(ScrimState.UNLOCKED);
@@ -1870,6 +1956,7 @@
}
@Test
+ @DisableSceneContainer
public void testNotifScrimAlpha_1f_afterUnlockFinishedAndExpanded() {
mScrimController.legacyTransitionTo(ScrimState.KEYGUARD);
when(mKeyguardUnlockAnimationController.isPlayingCannedUnlockAnimation()).thenReturn(true);
@@ -1942,9 +2029,9 @@
// Check combined scrim visibility.
final int visibility;
- if (scrimToAlpha.values().contains(OPAQUE)) {
+ if (scrimToAlpha.containsValue(OPAQUE)) {
visibility = OPAQUE;
- } else if (scrimToAlpha.values().contains(SEMI_TRANSPARENT)) {
+ } else if (scrimToAlpha.containsValue(SEMI_TRANSPARENT)) {
visibility = SEMI_TRANSPARENT;
} else {
visibility = TRANSPARENT;
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
similarity index 100%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
rename to packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt
index df5c6e9..a51e919 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt
@@ -129,11 +129,7 @@
@Mock private lateinit var context: Context
private val mobileMappings = FakeMobileMappingsProxy()
- private val systemUiCarrierConfig =
- SystemUiCarrierConfig(
- SUB_1_ID,
- createTestConfig(),
- )
+ private val systemUiCarrierConfig = SystemUiCarrierConfig(SUB_1_ID, createTestConfig())
private val testDispatcher = UnconfinedTestDispatcher()
private val testScope = TestScope(testDispatcher)
@@ -902,11 +898,7 @@
assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN"))
- val intentWithoutInfo =
- spnIntent(
- showSpn = false,
- showPlmn = false,
- )
+ val intentWithoutInfo = spnIntent(showSpn = false, showPlmn = false)
captor.lastValue.onReceive(context, intentWithoutInfo)
@@ -929,11 +921,7 @@
assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN"))
- val intentWithoutInfo =
- spnIntent(
- showSpn = false,
- showPlmn = false,
- )
+ val intentWithoutInfo = spnIntent(showSpn = false, showPlmn = false)
captor.lastValue.onReceive(context, intentWithoutInfo)
@@ -1301,7 +1289,6 @@
}
@Test
- @EnableFlags(com.android.internal.telephony.flags.Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
fun isNonTerrestrial_updatesFromCallback0() =
testScope.runTest {
val latest by collectLastValue(underTest.isNonTerrestrial)
@@ -1430,10 +1417,7 @@
return MobileTelephonyHelpers.getTelephonyCallbackForType(telephonyManager)
}
- private fun carrierIdIntent(
- subId: Int = SUB_1_ID,
- carrierId: Int,
- ): Intent =
+ private fun carrierIdIntent(subId: Int = SUB_1_ID, carrierId: Int): Intent =
Intent(TelephonyManager.ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED).apply {
putExtra(EXTRA_SUBSCRIPTION_ID, subId)
putExtra(EXTRA_CARRIER_ID, carrierId)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerTest.kt
index 5739275..7e27783 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerTest.kt
@@ -25,6 +25,9 @@
import android.app.NotificationChannel
import android.app.NotificationManager.IMPORTANCE_HIGH
import android.app.NotificationManager.VISIBILITY_NO_OVERRIDE
+import android.app.role.OnRoleHoldersChangedListener
+import android.app.role.RoleManager
+import android.companion.AssociationRequest
import android.content.pm.PackageManager
import android.media.projection.MediaProjectionInfo
import android.media.projection.MediaProjectionManager
@@ -89,6 +92,7 @@
@Mock private lateinit var activityManager: IActivityManager
@Mock private lateinit var mediaProjectionManager: MediaProjectionManager
@Mock private lateinit var packageManager: PackageManager
+ @Mock private lateinit var roleManager: RoleManager
@Mock private lateinit var telephonyManager: TelephonyManager
@Mock private lateinit var listener1: Runnable
@Mock private lateinit var listener2: Runnable
@@ -98,6 +102,7 @@
private lateinit var executor: FakeExecutor
private lateinit var globalSettings: FakeGlobalSettings
private lateinit var mediaProjectionCallback: MediaProjectionManager.Callback
+ private lateinit var roleHolderCallback: OnRoleHoldersChangedListener
private lateinit var controller: SensitiveNotificationProtectionControllerImpl
private lateinit var mediaProjectionInfo: MediaProjectionInfo
@@ -117,14 +122,14 @@
whenever(
packageManager.getPackageUidAsUser(
TEST_PROJECTION_PACKAGE_NAME,
- UserHandle.CURRENT.identifier
+ UserHandle.CURRENT.identifier,
)
)
.thenReturn(TEST_PROJECTION_PACKAGE_UID)
whenever(
packageManager.getPackageUidAsUser(
BUGREPORT_PACKAGE_NAME,
- UserHandle.CURRENT.identifier
+ UserHandle.CURRENT.identifier,
)
)
.thenReturn(BUGREPORT_PACKAGE_UID)
@@ -134,7 +139,7 @@
whenever(
packageManager.getPackageUidAsUser(
mContext.packageName,
- UserHandle.CURRENT.identifier
+ UserHandle.CURRENT.identifier,
)
)
.thenReturn(mContext.applicationInfo.uid)
@@ -155,9 +160,10 @@
activityManager,
packageManager,
telephonyManager,
+ roleManager,
mockExecutorHandler(executor),
executor,
- logger
+ logger,
)
// Process pending work (getting global setting and list of exemptions)
@@ -167,6 +173,9 @@
mediaProjectionCallback = withArgCaptor {
verify(mediaProjectionManager).addCallback(capture(), any())
}
+ roleHolderCallback = withArgCaptor {
+ verify(roleManager).addOnRoleHoldersChangedListenerAsUser(any(), capture(), any())
+ }
}
@After
@@ -307,7 +316,7 @@
whenever(
packageManager.checkPermission(
android.Manifest.permission.RECORD_SENSITIVE_CONTENT,
- mediaProjectionInfo.packageName
+ mediaProjectionInfo.packageName,
)
)
.thenReturn(PackageManager.PERMISSION_GRANTED)
@@ -322,7 +331,7 @@
whenever(
packageManager.checkPermission(
android.Manifest.permission.RECORD_SENSITIVE_CONTENT,
- mediaProjectionInfo.packageName
+ mediaProjectionInfo.packageName,
)
)
.thenReturn(PackageManager.PERMISSION_GRANTED)
@@ -340,6 +349,25 @@
}
@Test
+ fun isSensitiveStateActive_projectionActive_appStreamingRoleHolderExempt_false() {
+ setShareFullScreen()
+ whenever(
+ roleManager.getRoleHoldersAsUser(
+ AssociationRequest.DEVICE_PROFILE_APP_STREAMING,
+ mediaProjectionInfo.userHandle,
+ )
+ )
+ .thenReturn(listOf(TEST_PROJECTION_PACKAGE_NAME))
+ roleHolderCallback.onRoleHoldersChanged(
+ AssociationRequest.DEVICE_PROFILE_APP_STREAMING,
+ mediaProjectionInfo.userHandle,
+ )
+ mediaProjectionCallback.onStart(mediaProjectionInfo)
+
+ assertFalse(controller.isSensitiveStateActive)
+ }
+
+ @Test
fun isSensitiveStateActive_projectionActive_disabledViaDevOption_false() {
setDisabledViaDeveloperOption()
mediaProjectionCallback.onStart(mediaProjectionInfo)
@@ -449,7 +477,7 @@
whenever(
packageManager.checkPermission(
android.Manifest.permission.RECORD_SENSITIVE_CONTENT,
- mediaProjectionInfo.packageName
+ mediaProjectionInfo.packageName,
)
)
.thenReturn(PackageManager.PERMISSION_GRANTED)
@@ -466,7 +494,7 @@
whenever(
packageManager.checkPermission(
android.Manifest.permission.RECORD_SENSITIVE_CONTENT,
- mediaProjectionInfo.packageName
+ mediaProjectionInfo.packageName,
)
)
.thenReturn(PackageManager.PERMISSION_GRANTED)
@@ -528,7 +556,7 @@
eq(TEST_PROJECTION_PACKAGE_UID),
eq(false),
eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__STATE__START),
- eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__SOURCE__SYS_UI)
+ eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__SOURCE__SYS_UI),
)
}
@@ -541,7 +569,7 @@
eq(TEST_PROJECTION_PACKAGE_UID),
eq(false),
eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__STATE__STOP),
- eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__SOURCE__SYS_UI)
+ eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__SOURCE__SYS_UI),
)
}
}
@@ -559,7 +587,7 @@
eq(TEST_PROJECTION_PACKAGE_UID),
eq(true),
eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__STATE__START),
- eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__SOURCE__SYS_UI)
+ eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__SOURCE__SYS_UI),
)
}
@@ -572,7 +600,7 @@
eq(TEST_PROJECTION_PACKAGE_UID),
eq(true),
eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__STATE__STOP),
- eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__SOURCE__SYS_UI)
+ eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__SOURCE__SYS_UI),
)
}
}
@@ -590,7 +618,7 @@
eq(TEST_PROJECTION_PACKAGE_UID),
eq(true),
eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__STATE__START),
- eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__SOURCE__SYS_UI)
+ eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__SOURCE__SYS_UI),
)
}
@@ -603,7 +631,7 @@
eq(TEST_PROJECTION_PACKAGE_UID),
eq(true),
eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__STATE__STOP),
- eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__SOURCE__SYS_UI)
+ eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__SOURCE__SYS_UI),
)
}
}
@@ -623,7 +651,7 @@
eq(mContext.applicationInfo.uid),
eq(true),
eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__STATE__START),
- eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__SOURCE__SYS_UI)
+ eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__SOURCE__SYS_UI),
)
}
@@ -636,7 +664,7 @@
eq(mContext.applicationInfo.uid),
eq(true),
eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__STATE__STOP),
- eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__SOURCE__SYS_UI)
+ eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__SOURCE__SYS_UI),
)
}
}
@@ -654,7 +682,7 @@
eq(BUGREPORT_PACKAGE_UID),
eq(true),
eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__STATE__START),
- eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__SOURCE__SYS_UI)
+ eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__SOURCE__SYS_UI),
)
}
@@ -667,7 +695,7 @@
eq(BUGREPORT_PACKAGE_UID),
eq(true),
eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__STATE__STOP),
- eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__SOURCE__SYS_UI)
+ eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__SOURCE__SYS_UI),
)
}
}
@@ -757,7 +785,7 @@
return setupNotificationEntry(
packageName,
overrideVisibility = true,
- overrideChannelVisibility = true
+ overrideChannelVisibility = true,
)
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/temporarydisplay/TouchableRegionViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TouchableRegionViewControllerTest.kt
similarity index 100%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/temporarydisplay/TouchableRegionViewControllerTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TouchableRegionViewControllerTest.kt
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/FoldAodAnimationControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldAodAnimationControllerTest.kt
similarity index 100%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/FoldAodAnimationControllerTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/unfold/FoldAodAnimationControllerTest.kt
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/UnfoldLatencyTrackerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldLatencyTrackerTest.kt
similarity index 100%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/UnfoldLatencyTrackerTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldLatencyTrackerTest.kt
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProviderTest.kt
similarity index 100%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProviderTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProviderTest.kt
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/progress/UnfoldRemoteFilterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/UnfoldRemoteFilterTest.kt
similarity index 100%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/progress/UnfoldRemoteFilterTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/unfold/progress/UnfoldRemoteFilterTest.kt
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/usb/UsbPermissionActivityTest.kt b/packages/SystemUI/tests/src/com/android/systemui/usb/UsbPermissionActivityTest.kt
similarity index 100%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/usb/UsbPermissionActivityTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/usb/UsbPermissionActivityTest.kt
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/user/CreateUserActivityTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/CreateUserActivityTest.kt
similarity index 100%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/user/CreateUserActivityTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/user/CreateUserActivityTest.kt
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/util/kotlin/FlowUtilTests.kt b/packages/SystemUI/tests/src/com/android/systemui/util/kotlin/FlowUtilTests.kt
similarity index 100%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/util/kotlin/FlowUtilTests.kt
rename to packages/SystemUI/tests/src/com/android/systemui/util/kotlin/FlowUtilTests.kt
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/util/kotlin/PackageManagerExtComponentEnabledTest.kt b/packages/SystemUI/tests/src/com/android/systemui/util/kotlin/PackageManagerExtComponentEnabledTest.kt
similarity index 100%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/util/kotlin/PackageManagerExtComponentEnabledTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/util/kotlin/PackageManagerExtComponentEnabledTest.kt
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/util/sensors/AsyncSensorManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/AsyncSensorManagerTest.java
similarity index 100%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/util/sensors/AsyncSensorManagerTest.java
rename to packages/SystemUI/tests/src/com/android/systemui/util/sensors/AsyncSensorManagerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
index 8d05ea1..4439242 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
@@ -465,9 +465,9 @@
public void notificationVolumeSeparated_theRingerIconChangesToSpeakerIcon() {
// already separated. assert icon is new based on res id
assertEquals(mDialog.mVolumeRingerIconDrawableId,
- R.drawable.ic_speaker_on);
+ R.drawable.ic_legacy_speaker_on);
assertEquals(mDialog.mVolumeRingerMuteIconDrawableId,
- R.drawable.ic_speaker_mute);
+ R.drawable.ic_legacy_speaker_mute);
}
@Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/wallpapers/GradientColorWallpaperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/wallpapers/GradientColorWallpaperTest.kt
similarity index 100%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/wallpapers/GradientColorWallpaperTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/wallpapers/GradientColorWallpaperTest.kt
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/BatteryMeterViewControllerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/BatteryMeterViewControllerKosmos.kt
new file mode 100644
index 0000000..f3bccb1
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/BatteryMeterViewControllerKosmos.kt
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2025 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.battery
+
+import android.os.Handler
+import android.test.mock.MockContentResolver
+import com.android.systemui.flags.fake
+import com.android.systemui.flags.featureFlagsClassic
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.settings.userTracker
+import com.android.systemui.statusbar.policy.batteryController
+import com.android.systemui.statusbar.policy.configurationController
+import com.android.systemui.tuner.tunerService
+import org.mockito.kotlin.mock
+
+val Kosmos.batteryMeterViewControllerFactory: BatteryMeterViewController.Factory by
+Kosmos.Fixture {
+ BatteryMeterViewController.Factory(
+ userTracker,
+ configurationController,
+ tunerService,
+ mock<Handler>(),
+ MockContentResolver(),
+ featureFlagsClassic.fake,
+ batteryController
+ )
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/dialog/QSResetDialogDelegateKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/dialog/QSResetDialogDelegateKosmos.kt
index c58d55e..73d8dc6 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/dialog/QSResetDialogDelegateKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/dialog/QSResetDialogDelegateKosmos.kt
@@ -18,7 +18,14 @@
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.qs.panels.domain.interactor.sizedTilesResetInteractor
+import com.android.systemui.shade.data.repository.shadeDialogContextInteractor
import com.android.systemui.statusbar.phone.systemUIDialogFactory
val Kosmos.qsResetDialogDelegateKosmos by
- Kosmos.Fixture { QSResetDialogDelegate(systemUIDialogFactory, sizedTilesResetInteractor) }
+ Kosmos.Fixture {
+ QSResetDialogDelegate(
+ systemUIDialogFactory,
+ shadeDialogContextInteractor,
+ sizedTilesResetInteractor,
+ )
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/shared/model/FakeSceneDataSource.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/shared/model/FakeSceneDataSource.kt
index 60c0f34..f9917ac 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/shared/model/FakeSceneDataSource.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/shared/model/FakeSceneDataSource.kt
@@ -44,6 +44,8 @@
var pendingOverlays: Set<OverlayKey>? = null
private set
+ var freezeAndAnimateToCurrentStateCallCount = 0
+
override fun changeScene(toScene: SceneKey, transitionKey: TransitionKey?) {
if (_isPaused) {
_pendingScene = toScene
@@ -85,6 +87,10 @@
hideOverlay(overlay)
}
+ override fun freezeAndAnimateToCurrentState() {
+ freezeAndAnimateToCurrentStateCallCount++
+ }
+
/**
* Pauses scene and overlay changes.
*
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/data/repository/ShadeAnimationRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/data/repository/ShadeAnimationRepositoryKosmos.kt
index 3ed7302..e1ca86a 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/data/repository/ShadeAnimationRepositoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/data/repository/ShadeAnimationRepositoryKosmos.kt
@@ -18,12 +18,8 @@
import android.content.applicationContext
import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.shade.domain.interactor.ShadeDialogContextInteractor
-import org.mockito.kotlin.doReturn
-import org.mockito.kotlin.mock
+import com.android.systemui.shade.domain.interactor.FakeShadeDialogContextInteractor
val Kosmos.shadeAnimationRepository by Kosmos.Fixture { ShadeAnimationRepository() }
val Kosmos.shadeDialogContextInteractor by
- Kosmos.Fixture {
- mock<ShadeDialogContextInteractor> { on { context } doReturn applicationContext }
- }
+ Kosmos.Fixture { FakeShadeDialogContextInteractor(applicationContext) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/data/repository/ShadeDisplaysRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/data/repository/ShadeDisplaysRepositoryKosmos.kt
index ba7557e..26a441b 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/data/repository/ShadeDisplaysRepositoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/data/repository/ShadeDisplaysRepositoryKosmos.kt
@@ -30,7 +30,6 @@
import com.android.systemui.shade.display.StatusBarTouchShadeDisplayPolicy
import com.android.systemui.shade.domain.interactor.notificationElement
import com.android.systemui.shade.domain.interactor.qsElement
-import com.android.systemui.shade.domain.interactor.shadeInteractor
import com.android.systemui.util.settings.fakeGlobalSettings
val Kosmos.defaultShadeDisplayPolicy: DefaultDisplayShadePolicy by
@@ -49,9 +48,8 @@
StatusBarTouchShadeDisplayPolicy(
displayRepository = displayRepository,
backgroundScope = testScope.backgroundScope,
- shadeInteractor = { shadeInteractor },
- notificationElement = { notificationElement },
qsShadeElement = { qsElement },
+ notificationElement = { notificationElement },
)
}
val Kosmos.shadeExpansionIntent: ShadeExpansionIntent by
@@ -65,6 +63,7 @@
defaultPolicy = defaultShadeDisplayPolicy,
shadeOnDefaultDisplayWhenLocked = true,
keyguardRepository = keyguardRepository,
+ displayRepository = displayRepository,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/NotificationsShadeOverlayContentViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/NotificationsShadeOverlayContentViewModelKosmos.kt
index 20e4523..55e35f2 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/NotificationsShadeOverlayContentViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/NotificationsShadeOverlayContentViewModelKosmos.kt
@@ -18,9 +18,11 @@
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.media.controls.domain.pipeline.interactor.mediaCarouselInteractor
import com.android.systemui.notifications.ui.viewmodel.NotificationsShadeOverlayContentViewModel
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.shade.domain.interactor.shadeInteractor
+import com.android.systemui.statusbar.disableflags.domain.interactor.disableFlagsInteractor
import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor
import com.android.systemui.statusbar.notification.stack.ui.viewmodel.notificationsPlaceholderViewModelFactory
@@ -31,6 +33,8 @@
notificationsPlaceholderViewModelFactory = notificationsPlaceholderViewModelFactory,
sceneInteractor = sceneInteractor,
shadeInteractor = shadeInteractor,
+ disableFlagsInteractor = disableFlagsInteractor,
+ mediaCarouselInteractor = mediaCarouselInteractor,
activeNotificationsInteractor = activeNotificationsInteractor,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModelKosmos.kt
index cfc2075..08de73b 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModelKosmos.kt
@@ -17,7 +17,7 @@
package com.android.systemui.shade.ui.viewmodel
import android.content.applicationContext
-import com.android.systemui.battery.BatteryMeterViewController
+import com.android.systemui.battery.batteryMeterViewControllerFactory
import com.android.systemui.broadcast.broadcastDispatcher
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.plugins.activityStarter
@@ -28,7 +28,7 @@
import com.android.systemui.shade.domain.interactor.shadeModeInteractor
import com.android.systemui.statusbar.notification.icon.ui.viewbinder.NotificationIconContainerStatusBarViewBinder
import com.android.systemui.statusbar.phone.ui.StatusBarIconController
-import com.android.systemui.statusbar.phone.ui.TintedIconManager
+import com.android.systemui.statusbar.phone.ui.tintedIconManagerFactory
import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.mobileIconsInteractor
import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.mobileIconsViewModel
import org.mockito.kotlin.mock
@@ -45,8 +45,8 @@
mobileIconsViewModel = mobileIconsViewModel,
privacyChipInteractor = privacyChipInteractor,
clockInteractor = shadeHeaderClockInteractor,
- tintedIconManagerFactory = mock<TintedIconManager.Factory>(),
- batteryMeterViewControllerFactory = mock<BatteryMeterViewController.Factory>(),
+ tintedIconManagerFactory = tintedIconManagerFactory,
+ batteryMeterViewControllerFactory = batteryMeterViewControllerFactory,
statusBarIconController = mock<StatusBarIconController>(),
notificationIconContainerStatusBarViewBinder =
mock<NotificationIconContainerStatusBarViewBinder>(),
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelKosmos.kt
index 878c2de..d8e0cfe 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelKosmos.kt
@@ -21,6 +21,7 @@
import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.statusbar.chips.notification.domain.interactor.statusBarNotificationChipsInteractor
import com.android.systemui.statusbar.notification.stack.domain.interactor.headsUpNotificationInteractor
+import com.android.systemui.util.time.fakeSystemClock
val Kosmos.notifChipsViewModel: NotifChipsViewModel by
Kosmos.Fixture {
@@ -29,5 +30,6 @@
applicationCoroutineScope,
statusBarNotificationChipsInteractor,
headsUpNotificationInteractor,
+ fakeSystemClock,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/connectivity/ui/MobileContextProviderKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/connectivity/ui/MobileContextProviderKosmos.kt
new file mode 100644
index 0000000..18d6520
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/connectivity/ui/MobileContextProviderKosmos.kt
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2025 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.connectivity.ui
+
+import com.android.systemui.kosmos.Kosmos
+import org.mockito.kotlin.mock
+
+// NOTE: `mobileContextProvider` is a mock instance.
+val Kosmos.mobileContextProvider by
+Kosmos.Fixture {
+ mock<MobileContextProvider>()
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/featurepods/popups/ui/viewmodel/StatusBarPopupChipsViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/featurepods/popups/ui/viewmodel/StatusBarPopupChipsViewModelKosmos.kt
index 93502f3..b876095 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/featurepods/popups/ui/viewmodel/StatusBarPopupChipsViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/featurepods/popups/ui/viewmodel/StatusBarPopupChipsViewModelKosmos.kt
@@ -17,13 +17,14 @@
package com.android.systemui.statusbar.featurepods.popups.ui.viewmodel
import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.kosmos.testScope
import com.android.systemui.statusbar.featurepods.media.ui.viewmodel.mediaControlChipViewModel
-val Kosmos.statusBarPopupChipsViewModel: StatusBarPopupChipsViewModel by
+private val Kosmos.statusBarPopupChipsViewModel: StatusBarPopupChipsViewModel by
+ Kosmos.Fixture { StatusBarPopupChipsViewModel(mediaControlChip = mediaControlChipViewModel) }
+
+val Kosmos.statusBarPopupChipsViewModelFactory by
Kosmos.Fixture {
- StatusBarPopupChipsViewModel(
- testScope.backgroundScope,
- mediaControlChipViewModel = mediaControlChipViewModel,
- )
+ object : StatusBarPopupChipsViewModel.Factory {
+ override fun create(): StatusBarPopupChipsViewModel = statusBarPopupChipsViewModel
+ }
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/NotificationEntryBuilderKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/NotificationEntryBuilderKosmos.kt
new file mode 100644
index 0000000..59f5ecd
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/NotificationEntryBuilderKosmos.kt
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification
+
+import android.app.Notification
+import android.app.PendingIntent
+import android.app.Person
+import android.content.Intent
+import android.content.applicationContext
+import android.graphics.drawable.Icon
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
+import com.android.systemui.statusbar.notification.icon.IconPack
+import com.android.systemui.statusbar.notification.promoted.setPromotedContent
+import org.mockito.kotlin.mock
+
+fun Kosmos.setIconPackWithMockIconViews(entry: NotificationEntry) {
+ entry.icons =
+ IconPack.buildPack(
+ /* statusBarIcon = */ mock(),
+ /* statusBarChipIcon = */ mock(),
+ /* shelfIcon = */ mock(),
+ /* aodIcon = */ mock(),
+ /* source = */ null,
+ )
+}
+
+fun Kosmos.buildOngoingCallEntry(
+ promoted: Boolean = false,
+ block: NotificationEntryBuilder.() -> Unit = {},
+): NotificationEntry =
+ buildNotificationEntry(
+ tag = "call",
+ promoted = promoted,
+ style = makeOngoingCallStyle(),
+ block = block,
+ )
+
+fun Kosmos.buildPromotedOngoingEntry(
+ block: NotificationEntryBuilder.() -> Unit = {}
+): NotificationEntry =
+ buildNotificationEntry(tag = "ron", promoted = true, style = null, block = block)
+
+fun Kosmos.buildNotificationEntry(
+ tag: String? = null,
+ promoted: Boolean = false,
+ style: Notification.Style? = null,
+ block: NotificationEntryBuilder.() -> Unit = {},
+): NotificationEntry =
+ NotificationEntryBuilder()
+ .apply {
+ setTag(tag)
+ setFlag(applicationContext, Notification.FLAG_PROMOTED_ONGOING, promoted)
+ modifyNotification(applicationContext)
+ .setSmallIcon(Icon.createWithContentUri("content://null"))
+ .setStyle(style)
+ }
+ .apply(block)
+ .build()
+ .also {
+ setIconPackWithMockIconViews(it)
+ if (promoted) setPromotedContent(it)
+ }
+
+private fun Kosmos.makeOngoingCallStyle(): Notification.CallStyle {
+ val pendingIntent =
+ PendingIntent.getBroadcast(
+ applicationContext,
+ 0,
+ Intent("action"),
+ PendingIntent.FLAG_IMMUTABLE,
+ )
+ val person = Person.Builder().setName("person").build()
+ return Notification.CallStyle.forOngoingCall(person, pendingIntent)
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/NotifPipelineKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/NotifPipelineKosmos.kt
index a48b270..fa3702ce 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/NotifPipelineKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/NotifPipelineKosmos.kt
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.notification.collection
import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.util.mockito.mock
+import org.mockito.kotlin.mock
-var Kosmos.notifPipeline by Kosmos.Fixture { mock<NotifPipeline>() }
+var Kosmos.notifPipeline by Kosmos.Fixture { mockNotifPipeline }
+var Kosmos.mockNotifPipeline by Kosmos.Fixture { mock<NotifPipeline>() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorKosmos.kt
index 63521de..da879d9 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorKosmos.kt
@@ -16,15 +16,31 @@
package com.android.systemui.statusbar.notification.promoted
+import android.app.Notification
import android.content.applicationContext
import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.row.RowImageInflater
import com.android.systemui.statusbar.notification.row.shared.skeletonImageTransform
+import com.android.systemui.util.time.systemClock
var Kosmos.promotedNotificationContentExtractor by
Kosmos.Fixture {
PromotedNotificationContentExtractorImpl(
applicationContext,
skeletonImageTransform,
+ systemClock,
promotedNotificationLogger,
)
}
+
+fun Kosmos.setPromotedContent(entry: NotificationEntry) {
+ val extractedContent =
+ promotedNotificationContentExtractor.extractContent(
+ entry,
+ Notification.Builder.recoverBuilder(applicationContext, entry.sbn.notification),
+ RowImageInflater.newInstance(null).useForContentModel(),
+ )
+ entry.promotedNotificationContentModel =
+ requireNotNull(extractedContent) { "extractContent returned null" }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/AODPromotedNotificationInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/AODPromotedNotificationInteractorKosmos.kt
index df1c822..fcd4843 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/AODPromotedNotificationInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/AODPromotedNotificationInteractorKosmos.kt
@@ -18,12 +18,11 @@
import com.android.systemui.dump.dumpManager
import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor
val Kosmos.aodPromotedNotificationInteractor by
Kosmos.Fixture {
AODPromotedNotificationInteractor(
- activeNotificationsInteractor = activeNotificationsInteractor,
+ promotedNotificationsInteractor = promotedNotificationsInteractor,
dumpManager = dumpManager,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PromotedNotificationsInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PromotedNotificationsInteractorKosmos.kt
new file mode 100644
index 0000000..093ec10
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PromotedNotificationsInteractorKosmos.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.promoted.domain.interactor
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.statusbar.chips.call.domain.interactor.callChipInteractor
+import com.android.systemui.statusbar.chips.notification.domain.interactor.statusBarNotificationChipsInteractor
+import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor
+
+val Kosmos.promotedNotificationsInteractor by
+ Kosmos.Fixture {
+ PromotedNotificationsInteractor(
+ activeNotificationsInteractor = activeNotificationsInteractor,
+ callChipInteractor = callChipInteractor,
+ notifChipsInteractor = statusBarNotificationChipsInteractor,
+ backgroundDispatcher = testDispatcher,
+ )
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowBuilder.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowBuilder.kt
index e445a73..09c632c 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowBuilder.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowBuilder.kt
@@ -41,6 +41,7 @@
import com.android.systemui.media.dialog.MediaOutputDialogManager
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.settings.UserTracker
import com.android.systemui.shared.system.ActivityManagerWrapper
import com.android.systemui.shared.system.DevicePolicyManagerWrapper
import com.android.systemui.shared.system.PackageManagerWrapper
@@ -227,6 +228,7 @@
PromotedNotificationContentExtractorImpl(
context,
SkeletonImageTransform(context),
+ mFakeSystemClock,
PromotedNotificationLogger(logcatLogBuffer("PromotedNotifLog")),
)
@@ -346,10 +348,15 @@
// NOTE: This flag is read when the ExpandableNotificationRow is inflated, so it needs to be
// set, but we do not want to override an existing value that is needed by a specific test.
+ val userTracker = Mockito.mock(UserTracker::class.java, STUB_ONLY)
+ whenever(userTracker.userHandle).thenReturn(context.user)
+
val rowInflaterTask =
RowInflaterTask(
mFakeSystemClock,
Mockito.mock(RowInflaterTaskLogger::class.java, STUB_ONLY),
+ userTracker,
+ Mockito.mock(AsyncRowInflater::class.java, STUB_ONLY),
)
val row = rowInflaterTask.inflateSynchronously(context, null, entry)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationListViewBinderKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationListViewBinderKosmos.kt
index bc1363a..970b87c 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationListViewBinderKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationListViewBinderKosmos.kt
@@ -33,7 +33,7 @@
val Kosmos.notificationListViewBinder by Fixture {
NotificationListViewBinder(
- backgroundDispatcher = testDispatcher,
+ inflationDispatcher = testDispatcher,
hiderTracker = displaySwitchNotificationsHiderTracker,
configuration = configurationState,
falsingManager = falsingManager,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelKosmos.kt
index 047bd13..7a2b7c2 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelKosmos.kt
@@ -29,7 +29,6 @@
import com.android.systemui.keyguard.ui.viewmodel.aodToLockscreenTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.aodToOccludedTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.aodToPrimaryBouncerTransitionViewModel
-import com.android.systemui.keyguard.ui.viewmodel.dozingToDreamingTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.dozingToGlanceableHubTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.dozingToLockscreenTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.dozingToOccludedTransitionViewModel
@@ -82,7 +81,6 @@
aodToLockscreenTransitionViewModel = aodToLockscreenTransitionViewModel,
aodToOccludedTransitionViewModel = aodToOccludedTransitionViewModel,
aodToPrimaryBouncerTransitionViewModel = aodToPrimaryBouncerTransitionViewModel,
- dozingToDreamingTransitionViewModel = dozingToDreamingTransitionViewModel,
dozingToGlanceableHubTransitionViewModel = dozingToGlanceableHubTransitionViewModel,
dozingToLockscreenTransitionViewModel = dozingToLockscreenTransitionViewModel,
dozingToOccludedTransitionViewModel = dozingToOccludedTransitionViewModel,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ongoingcall/DisableChipsModernization.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ongoingcall/DisableChipsModernization.kt
new file mode 100644
index 0000000..69eecc0
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ongoingcall/DisableChipsModernization.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2025 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.phone.ongoingcall
+
+import android.platform.test.annotations.DisableFlags
+
+/** Disables all the flags necessary for [StatusBarChipsModernization.isEnabled] to return false. */
+@DisableFlags(StatusBarChipsModernization.FLAG_NAME)
+@Retention(AnnotationRetention.RUNTIME)
+@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS)
+annotation class DisableChipsModernization
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ongoingcall/EnableChipsModernization.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ongoingcall/EnableChipsModernization.kt
new file mode 100644
index 0000000..caa4373
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ongoingcall/EnableChipsModernization.kt
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2025 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.phone.ongoingcall
+
+import android.platform.test.annotations.EnableFlags
+import com.android.systemui.statusbar.core.StatusBarRootModernization
+
+/** Enables all the flags necessary for [StatusBarChipsModernization.isEnabled] to return true. */
+@EnableFlags(StatusBarChipsModernization.FLAG_NAME, StatusBarRootModernization.FLAG_NAME)
+@Retention(AnnotationRetention.RUNTIME)
+@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS)
+annotation class EnableChipsModernization
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ui/StatusBarIconControllerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ui/StatusBarIconControllerKosmos.kt
new file mode 100644
index 0000000..0a387f8
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ui/StatusBarIconControllerKosmos.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2025 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.phone.ui
+
+import com.android.systemui.kosmos.Kosmos
+import org.mockito.kotlin.mock
+
+// NOTE: `statusBarIconController` is a mock instance.
+val Kosmos.statusBarIconController by Kosmos.Fixture {
+ mock<StatusBarIconControllerImpl>()
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ui/TintedIconManagerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ui/TintedIconManagerKosmos.kt
new file mode 100644
index 0000000..8e13b62
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ui/TintedIconManagerKosmos.kt
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2025 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.phone.ui
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.statusbar.connectivity.ui.mobileContextProvider
+import com.android.systemui.statusbar.pipeline.mobile.ui.mobileUiAdapter
+import com.android.systemui.statusbar.pipeline.wifi.ui.wifiUiAdapter
+
+val Kosmos.tintedIconManagerFactory by
+Kosmos.Fixture {
+ TintedIconManager.Factory(
+ wifiUiAdapter,
+ mobileUiAdapter,
+ mobileContextProvider,
+ )
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/airplane/ui/viewmodel/AirplaneModeViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/airplane/ui/viewmodel/AirplaneModeViewModelKosmos.kt
new file mode 100644
index 0000000..5089545
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/airplane/ui/viewmodel/AirplaneModeViewModelKosmos.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2025 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.pipeline.airplane.ui.viewmodel
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.backgroundScope
+import com.android.systemui.log.table.logcatTableLogBuffer
+import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.airplaneModeInteractor
+
+val Kosmos.airplaneModeViewModel by Kosmos.Fixture {
+ AirplaneModeViewModelImpl(
+ airplaneModeInteractor,
+ logcatTableLogBuffer(this, "AirplaneModeTableLogBuffer"),
+ backgroundScope,
+ )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileUiAdapterKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileUiAdapterKosmos.kt
new file mode 100644
index 0000000..a87d3b0
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileUiAdapterKosmos.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2025 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.pipeline.mobile.ui
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.statusbar.phone.ui.statusBarIconController
+import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.mobileIconsViewModel
+
+val Kosmos.mobileUiAdapter by
+ Kosmos.Fixture {
+ MobileUiAdapter(
+ statusBarIconController,
+ mobileIconsViewModel,
+ mobileViewLogger,
+ applicationCoroutineScope,
+ )
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileViewLoggerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileViewLoggerKosmos.kt
new file mode 100644
index 0000000..206ecd3
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileViewLoggerKosmos.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2025 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.pipeline.mobile.ui
+
+import com.android.systemui.kosmos.Kosmos
+import org.mockito.kotlin.mock
+
+// NOTE: `mobileViewLogger` is a mock instance.
+val Kosmos.mobileViewLogger by Kosmos.Fixture { mock<MobileViewLogger>() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelKosmos.kt
index fbada93..a97c651 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelKosmos.kt
@@ -29,7 +29,7 @@
import com.android.systemui.statusbar.chips.sharetoapp.ui.viewmodel.shareToAppChipViewModel
import com.android.systemui.statusbar.chips.ui.viewmodel.ongoingActivityChipsViewModel
import com.android.systemui.statusbar.events.domain.interactor.systemStatusEventAnimationInteractor
-import com.android.systemui.statusbar.featurepods.popups.ui.viewmodel.statusBarPopupChipsViewModel
+import com.android.systemui.statusbar.featurepods.popups.ui.viewmodel.statusBarPopupChipsViewModelFactory
import com.android.systemui.statusbar.layout.ui.viewmodel.multiDisplayStatusBarContentInsetsViewModelStore
import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor
import com.android.systemui.statusbar.notification.stack.domain.interactor.headsUpNotificationInteractor
@@ -59,7 +59,7 @@
shadeInteractor,
shareToAppChipViewModel,
ongoingActivityChipsViewModel,
- statusBarPopupChipsViewModel,
+ statusBarPopupChipsViewModelFactory,
systemStatusEventAnimationInteractor,
multiDisplayStatusBarContentInsetsViewModelStore,
backgroundScope,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/wifi/ui/WifiUiAdapterKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/wifi/ui/WifiUiAdapterKosmos.kt
new file mode 100644
index 0000000..4e3c3ca
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/wifi/ui/WifiUiAdapterKosmos.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2025 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.pipeline.wifi.ui
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.statusbar.phone.ui.statusBarIconController
+import com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel.wifiViewModel
+
+val Kosmos.wifiUiAdapter by
+Kosmos.Fixture {
+ WifiUiAdapter(
+ statusBarIconController,
+ wifiViewModel,
+ )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelKosmos.kt
new file mode 100644
index 0000000..15057cd
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelKosmos.kt
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2025 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.pipeline.wifi.ui.viewmodel
+
+import android.content.applicationContext
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.log.table.logcatTableLogBuffer
+import com.android.systemui.statusbar.pipeline.airplane.ui.viewmodel.airplaneModeViewModel
+import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants
+import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.wifiInteractor
+import com.android.systemui.statusbar.pipeline.wifi.shared.WifiConstants
+import kotlinx.coroutines.flow.MutableStateFlow
+import org.mockito.kotlin.mock
+
+val Kosmos.wifiViewModel by
+ Kosmos.Fixture {
+ WifiViewModel(
+ airplaneModeViewModel,
+ { MutableStateFlow(false) },
+ mock<ConnectivityConstants>(),
+ applicationContext,
+ logcatTableLogBuffer(this, "WifiViewModelTest"),
+ wifiInteractor,
+ applicationCoroutineScope,
+ mock<WifiConstants>(),
+ )
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/data/repository/SecureSettingsForUserRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/data/repository/SecureSettingsForUserRepositoryKosmos.kt
new file mode 100644
index 0000000..81f71e9
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/data/repository/SecureSettingsForUserRepositoryKosmos.kt
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2025 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.util.settings.data.repository
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.backgroundCoroutineContext
+import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.util.settings.fakeSettings
+import com.android.systemui.util.settings.repository.SecureSettingsForUserRepository
+
+val Kosmos.secureSettingsForUserRepository by
+ Kosmos.Fixture {
+ SecureSettingsForUserRepository(fakeSettings, testDispatcher, backgroundCoroutineContext)
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/util/time/FakeSystemClockKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/util/time/FakeSystemClockKosmos.kt
index a209ec9..06af32e 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/util/time/FakeSystemClockKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/util/time/FakeSystemClockKosmos.kt
@@ -22,7 +22,7 @@
import com.android.systemui.util.mockito.whenever
import kotlinx.coroutines.test.currentTime
-val Kosmos.systemClock by
+var Kosmos.systemClock by
Kosmos.Fixture<SystemClock> {
mock {
whenever(elapsedRealtime()).thenAnswer { testScope.currentTime }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/dialog/ui/binder/VolumeDialogViewBinderKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/dialog/ui/binder/VolumeDialogViewBinderKosmos.kt
index 386e0fe..5411884 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/dialog/ui/binder/VolumeDialogViewBinderKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/dialog/ui/binder/VolumeDialogViewBinderKosmos.kt
@@ -16,6 +16,7 @@
package com.android.systemui.volume.dialog.ui.binder
+import android.content.applicationContext
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.volume.dialog.ringer.volumeDialogRingerViewBinder
import com.android.systemui.volume.dialog.settings.ui.binder.volumeDialogSettingsButtonViewBinder
@@ -27,6 +28,7 @@
val Kosmos.volumeDialogViewBinder by
Kosmos.Fixture {
VolumeDialogViewBinder(
+ applicationContext,
volumeDialogViewModel,
jankListenerFactory,
volumeTracer,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/wallpapers/data/repository/FakeWallpaperFocalAreaRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/wallpapers/data/repository/FakeWallpaperFocalAreaRepository.kt
index aeff86e..24d2f1f 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/wallpapers/data/repository/FakeWallpaperFocalAreaRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/wallpapers/data/repository/FakeWallpaperFocalAreaRepository.kt
@@ -34,12 +34,15 @@
_wallpaperFocalAreaBounds.asStateFlow()
private val _wallpaperFocalAreaTapPosition = MutableStateFlow(PointF(0F, 0F))
- override val wallpaperFocalAreaTapPosition: StateFlow<PointF> =
+ val wallpaperFocalAreaTapPosition: StateFlow<PointF> =
_wallpaperFocalAreaTapPosition.asStateFlow()
private val _notificationDefaultTop = MutableStateFlow(0F)
override val notificationDefaultTop: StateFlow<Float> = _notificationDefaultTop.asStateFlow()
+ private val _hasFocalArea = MutableStateFlow(false)
+ override val hasFocalArea: StateFlow<Boolean> = _hasFocalArea.asStateFlow()
+
override fun setShortcutAbsoluteTop(top: Float) {
_shortcutAbsoluteTop.value = top
}
@@ -56,7 +59,7 @@
_wallpaperFocalAreaBounds.value = bounds
}
- override fun setTapPosition(point: PointF) {
- _wallpaperFocalAreaTapPosition.value = point
+ override fun setTapPosition(tapPosition: PointF) {
+ _wallpaperFocalAreaTapPosition.value = tapPosition
}
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/wallpapers/data/repository/FakeWallpaperRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/wallpapers/data/repository/FakeWallpaperRepository.kt
index 8689e04..66bb803 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/wallpapers/data/repository/FakeWallpaperRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/wallpapers/data/repository/FakeWallpaperRepository.kt
@@ -17,6 +17,8 @@
package com.android.systemui.wallpapers.data.repository
import android.app.WallpaperInfo
+import android.graphics.PointF
+import android.graphics.RectF
import android.view.View
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
@@ -34,9 +36,9 @@
private val _shouldSendFocalArea = MutableStateFlow(false)
override val shouldSendFocalArea: StateFlow<Boolean> = _shouldSendFocalArea.asStateFlow()
- fun setShouldSendFocalArea(shouldSendFocalArea: Boolean) {
- _shouldSendFocalArea.value = shouldSendFocalArea
- }
+ override fun sendLockScreenLayoutChangeCommand(wallpaperFocalAreaBounds: RectF) {}
+
+ override fun sendTapCommand(tapPosition: PointF) {}
fun setWallpaperInfo(wallpaperInfo: WallpaperInfo?) {
_wallpaperInfo.value = wallpaperInfo
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/wallpapers/data/repository/WallpaperRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/wallpapers/data/repository/WallpaperRepositoryKosmos.kt
index 7ebec6c..1761503 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/wallpapers/data/repository/WallpaperRepositoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/wallpapers/data/repository/WallpaperRepositoryKosmos.kt
@@ -19,7 +19,6 @@
import android.content.applicationContext
import com.android.app.wallpaperManager
import com.android.systemui.broadcast.broadcastDispatcher
-import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
import com.android.systemui.kosmos.testDispatcher
@@ -34,8 +33,6 @@
bgDispatcher = testDispatcher,
broadcastDispatcher = broadcastDispatcher,
userRepository = userRepository,
- keyguardTransitionInteractor = keyguardTransitionInteractor,
- wallpaperFocalAreaRepository = wallpaperFocalAreaRepository,
wallpaperManager = wallpaperManager,
secureSettings = fakeSettings,
)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/wallpapers/domain/interactor/WallpaperFocalAreaInteractor.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/wallpapers/domain/interactor/WallpaperFocalAreaInteractor.kt
index 88eb551..eaf55a7 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/wallpapers/domain/interactor/WallpaperFocalAreaInteractor.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/wallpapers/domain/interactor/WallpaperFocalAreaInteractor.kt
@@ -18,20 +18,14 @@
import android.content.applicationContext
import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.shade.data.repository.shadeRepository
-import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor
import com.android.systemui.wallpapers.data.repository.wallpaperFocalAreaRepository
-import com.android.systemui.wallpapers.data.repository.wallpaperRepository
-val Kosmos.wallpaperFocalAreaInteractor by
+var Kosmos.wallpaperFocalAreaInteractor by
Kosmos.Fixture {
WallpaperFocalAreaInteractor(
- applicationScope = applicationCoroutineScope,
context = applicationContext,
wallpaperFocalAreaRepository = wallpaperFocalAreaRepository,
shadeRepository = shadeRepository,
- activeNotificationsInteractor = activeNotificationsInteractor,
- wallpaperRepository = wallpaperRepository,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/wallpapers/ui/viewmodel/WallpaperFocalAreaViewModel.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/wallpapers/ui/viewmodel/WallpaperFocalAreaViewModel.kt
index 7e232c5..4032503 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/wallpapers/ui/viewmodel/WallpaperFocalAreaViewModel.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/wallpapers/ui/viewmodel/WallpaperFocalAreaViewModel.kt
@@ -16,10 +16,14 @@
package com.android.systemui.wallpapers.ui.viewmodel
+import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.wallpapers.domain.interactor.wallpaperFocalAreaInteractor
var Kosmos.wallpaperFocalAreaViewModel by
Kosmos.Fixture {
- WallpaperFocalAreaViewModel(wallpaperFocalAreaInteractor = wallpaperFocalAreaInteractor)
+ WallpaperFocalAreaViewModel(
+ wallpaperFocalAreaInteractor = wallpaperFocalAreaInteractor,
+ keyguardTransitionInteractor = keyguardTransitionInteractor,
+ )
}
diff --git a/ravenwood/TEST_MAPPING b/ravenwood/TEST_MAPPING
index cb54e9f..df63cb9 100644
--- a/ravenwood/TEST_MAPPING
+++ b/ravenwood/TEST_MAPPING
@@ -2,6 +2,7 @@
"presubmit": [
{ "name": "tiny-framework-dump-test" },
{ "name": "hoststubgentest" },
+ { "name": "ravenhelpertest" },
{ "name": "hoststubgen-test-tiny-test" },
{ "name": "hoststubgen-invoke-test" },
{ "name": "RavenwoodMockitoTest_device" },
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodMethodCallLogger.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodMethodCallLogger.java
new file mode 100644
index 0000000..7ee9d7a
--- /dev/null
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodMethodCallLogger.java
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2025 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.platform.test.ravenwood;
+
+import com.android.ravenwood.RavenwoodRuntimeNative;
+
+import java.io.PrintStream;
+import java.util.HashSet;
+import java.util.Objects;
+
+/**
+ * Provides a method call hook that prints almost all (see below) the framework methods being
+ * called with indentation.
+ *
+ * We don't log methods that are trivial, uninteresting, or would be too noisy.
+ * e.g. we don't want to log any logging related methods, or collection APIs.
+ *
+ */
+public class RavenwoodMethodCallLogger {
+ private RavenwoodMethodCallLogger() {
+ }
+
+ /** We don't want to log anything before ravenwood is initialized. This flag controls it.*/
+ private static volatile boolean sEnabled = false;
+
+ private static volatile PrintStream sOut = System.out;
+
+ /** Return the current thread's call nest level. */
+ private static int getNestLevel() {
+ return Thread.currentThread().getStackTrace().length;
+ }
+
+ private static class ThreadInfo {
+ /**
+ * We save the current thread's nest call level here and use that as the initial level.
+ * We do it because otherwise the nest level would be too deep by the time test
+ * starts.
+ */
+ public final int mInitialNestLevel = getNestLevel();
+
+ /**
+ * A nest level where shouldLog() returned false.
+ * Once it's set, we ignore all calls deeper than this.
+ */
+ public int mDisabledNestLevel = Integer.MAX_VALUE;
+ }
+
+ private static final ThreadLocal<ThreadInfo> sThreadInfo = new ThreadLocal<>() {
+ @Override
+ protected ThreadInfo initialValue() {
+ return new ThreadInfo();
+ }
+ };
+
+ /** Classes that should be logged. Uses a map for fast lookup. */
+ private static final HashSet<Class> sIgnoreClasses = new HashSet<>();
+ static {
+ // The following classes are not interesting...
+ sIgnoreClasses.add(android.util.Log.class);
+ sIgnoreClasses.add(android.util.Slog.class);
+ sIgnoreClasses.add(android.util.EventLog.class);
+ sIgnoreClasses.add(android.util.TimingsTraceLog.class);
+
+ sIgnoreClasses.add(android.util.SparseArray.class);
+ sIgnoreClasses.add(android.util.SparseIntArray.class);
+ sIgnoreClasses.add(android.util.SparseLongArray.class);
+ sIgnoreClasses.add(android.util.SparseBooleanArray.class);
+ sIgnoreClasses.add(android.util.SparseDoubleArray.class);
+ sIgnoreClasses.add(android.util.SparseSetArray.class);
+ sIgnoreClasses.add(android.util.SparseArrayMap.class);
+ sIgnoreClasses.add(android.util.LongSparseArray.class);
+ sIgnoreClasses.add(android.util.LongSparseLongArray.class);
+ sIgnoreClasses.add(android.util.LongArray.class);
+
+ sIgnoreClasses.add(android.text.FontConfig.class);
+
+ sIgnoreClasses.add(android.os.SystemClock.class);
+ sIgnoreClasses.add(android.os.Trace.class);
+ sIgnoreClasses.add(android.os.LocaleList.class);
+ sIgnoreClasses.add(android.os.Build.class);
+ sIgnoreClasses.add(android.os.SystemProperties.class);
+
+ sIgnoreClasses.add(com.android.internal.util.Preconditions.class);
+
+ sIgnoreClasses.add(android.graphics.FontListParser.class);
+ sIgnoreClasses.add(android.graphics.ColorSpace.class);
+
+ sIgnoreClasses.add(android.graphics.fonts.FontStyle.class);
+ sIgnoreClasses.add(android.graphics.fonts.FontVariationAxis.class);
+
+ sIgnoreClasses.add(com.android.internal.compat.CompatibilityChangeInfo.class);
+ sIgnoreClasses.add(com.android.internal.os.LoggingPrintStream.class);
+
+ sIgnoreClasses.add(android.os.ThreadLocalWorkSource.class);
+
+ // Following classes *may* be interesting for some purposes, but the initialization is
+ // too noisy...
+ sIgnoreClasses.add(android.graphics.fonts.SystemFonts.class);
+
+ }
+
+ /**
+ * Return if a class should be ignored. Uses {link #sIgnoreCladsses}, but
+ * we ignore more classes.
+ */
+ private static boolean shouldIgnoreClass(Class<?> clazz) {
+ if (sIgnoreClasses.contains(clazz)) {
+ return true;
+ }
+ // Let's also ignore collection-ish classes in android.util.
+ if (java.util.Collection.class.isAssignableFrom(clazz)
+ || java.util.Map.class.isAssignableFrom(clazz)
+ ) {
+ if ("android.util".equals(clazz.getPackageName())) {
+ return true;
+ }
+ return false;
+ }
+
+ switch (clazz.getSimpleName()) {
+ case "EventLogTags":
+ return false;
+ }
+
+ // Following are classes that can't be referred to here directly.
+ // e.g. AndroidPrintStream is package-private, so we can't use its "class" here.
+ switch (clazz.getName()) {
+ case "com.android.internal.os.AndroidPrintStream":
+ return false;
+ }
+ return false;
+ }
+
+ private static boolean shouldLog(
+ Class<?> methodClass,
+ String methodName,
+ @SuppressWarnings("UnusedVariable") String methodDescriptor
+ ) {
+ // Should we ignore this class?
+ if (shouldIgnoreClass(methodClass)) {
+ return false;
+ }
+ // Is it a nested class in a class that should be ignored?
+ var host = methodClass.getNestHost();
+ if (host != methodClass && shouldIgnoreClass(host)) {
+ return false;
+ }
+
+ var className = methodClass.getName();
+
+ // Ad-hoc ignore list. They'd be too noisy.
+ if ("create".equals(methodName)
+ // We may apply jarjar, so use endsWith().
+ && className.endsWith("com.android.server.compat.CompatConfig")) {
+ return false;
+ }
+
+ var pkg = methodClass.getPackageName();
+ if (pkg.startsWith("android.icu")) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Call this to enable logging.
+ */
+ public static void enable(PrintStream out) {
+ sEnabled = true;
+ sOut = Objects.requireNonNull(out);
+
+ // It's called from the test thread (Java's main thread). Because we're already
+ // in deep nest calls, we initialize the initial nest level here.
+ sThreadInfo.get();
+ }
+
+ /** Actual method hook entry point.*/
+ public static void logMethodCall(
+ Class<?> methodClass,
+ String methodName,
+ String methodDescriptor
+ ) {
+ if (!sEnabled) {
+ return;
+ }
+ final var ti = sThreadInfo.get();
+ final int nestLevel = getNestLevel() - ti.mInitialNestLevel;
+
+ // Once shouldLog() returns false, we just ignore all deeper calls.
+ if (ti.mDisabledNestLevel < nestLevel) {
+ return; // Still ignore.
+ }
+ final boolean shouldLog = shouldLog(methodClass, methodName, methodDescriptor);
+
+ if (!shouldLog) {
+ ti.mDisabledNestLevel = nestLevel;
+ return;
+ }
+ ti.mDisabledNestLevel = Integer.MAX_VALUE;
+
+ var out = sOut;
+ out.print("# [");
+ out.print(RavenwoodRuntimeNative.gettid());
+ out.print(": ");
+ out.print(Thread.currentThread().getName());
+ out.print("]: ");
+ out.print("[@");
+ out.printf("%2d", nestLevel);
+ out.print("] ");
+ for (int i = 0; i < nestLevel; i++) {
+ out.print(" ");
+ }
+ out.println(methodClass.getName() + "." + methodName + methodDescriptor);
+ }
+}
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java
index 7af03ed..ae88bb2 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java
@@ -23,7 +23,6 @@
import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_EMPTY_RESOURCES_APK;
import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_INST_RESOURCE_APK;
import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_RESOURCE_APK;
-import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_VERBOSE_LOGGING;
import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_VERSION_JAVA_SYSPROP;
import static com.android.ravenwood.common.RavenwoodCommonUtils.parseNullableInt;
import static com.android.ravenwood.common.RavenwoodCommonUtils.withDefault;
@@ -103,6 +102,10 @@
private RavenwoodRuntimeEnvironmentController() {
}
+ private static final PrintStream sStdOut = System.out;
+ @SuppressWarnings("UnusedVariable")
+ private static final PrintStream sStdErr = System.err;
+
private static final String MAIN_THREAD_NAME = "RavenwoodMain";
private static final String LIBRAVENWOOD_INITIALIZER_NAME = "ravenwood_initializer";
private static final String RAVENWOOD_NATIVE_RUNTIME_NAME = "ravenwood_runtime";
@@ -212,9 +215,9 @@
}
private static void globalInitInner() throws IOException {
- if (RAVENWOOD_VERBOSE_LOGGING) {
- Log.v(TAG, "globalInit() called here...", new RuntimeException("NOT A CRASH"));
- }
+ // We haven't initialized liblog yet, so directly write to System.out here.
+ RavenwoodCommonUtils.log(TAG, "globalInitInner()");
+
if (ENABLE_UNCAUGHT_EXCEPTION_DETECTION) {
Thread.setDefaultUncaughtExceptionHandler(sUncaughtExceptionHandler);
}
@@ -234,9 +237,6 @@
dumpJavaProperties();
dumpOtherInfo();
- // We haven't initialized liblog yet, so directly write to System.out here.
- RavenwoodCommonUtils.log(TAG, "globalInitInner()");
-
// Make sure libravenwood_runtime is loaded.
System.load(RavenwoodCommonUtils.getJniLibraryPath(RAVENWOOD_NATIVE_RUNTIME_NAME));
@@ -261,6 +261,9 @@
// Make sure libandroid_runtime is loaded.
RavenwoodNativeLoader.loadFrameworkNativeCode();
+ // Start method logging.
+ RavenwoodMethodCallLogger.enable(sStdOut);
+
// Touch some references early to ensure they're <clinit>'ed
Objects.requireNonNull(Build.TYPE);
Objects.requireNonNull(Build.VERSION.SDK);
diff --git a/ravenwood/runtime-jni/ravenwood_initializer.cpp b/ravenwood/runtime-jni/ravenwood_initializer.cpp
index 391c5d5..8a35ade 100644
--- a/ravenwood/runtime-jni/ravenwood_initializer.cpp
+++ b/ravenwood/runtime-jni/ravenwood_initializer.cpp
@@ -26,6 +26,10 @@
#include <fcntl.h>
#include <set>
+#include <fstream>
+#include <iostream>
+#include <string>
+#include <cstdlib>
#include "jni_helper.h"
@@ -182,17 +186,82 @@
}
}
+// Find the PPID of child_pid using /proc/N/stat. The 4th field is the PPID.
+// Also returns child_pid's process name (2nd field).
+static pid_t getppid_of(pid_t child_pid, std::string& out_process_name) {
+ if (child_pid < 0) {
+ return -1;
+ }
+ std::string stat_file = "/proc/" + std::to_string(child_pid) + "/stat";
+ std::ifstream stat_stream(stat_file);
+ if (!stat_stream.is_open()) {
+ ALOGW("Unable to open '%s': %s", stat_file.c_str(), strerror(errno));
+ return -1;
+ }
+
+ std::string field;
+ int field_count = 0;
+ while (std::getline(stat_stream, field, ' ')) {
+ if (++field_count == 4) {
+ return atoi(field.c_str());
+ }
+ if (field_count == 2) {
+ out_process_name = field;
+ }
+ }
+ ALOGW("Unexpected format in '%s'", stat_file.c_str());
+ return -1;
+}
+
+// Find atest's PID. Climb up the process tree, and find "atest-py3".
+static pid_t find_atest_pid() {
+ auto ret = getpid(); // self (isolation runner process)
+
+ while (ret != -1) {
+ std::string proc;
+ ret = getppid_of(ret, proc);
+ if (proc == "(atest-py3)") {
+ return ret;
+ }
+ }
+
+ return ret;
+}
+
+// If $RAVENWOOD_LOG_OUT is set, redirect stdout/err to this file.
+// Originally it was added to allow to monitor log in realtime, with
+// RAVENWOOD_LOG_OUT=$(tty) atest...
+//
+// As a special case, if $RAVENWOOD_LOG_OUT is set to "-", we try to find
+// atest's process and send the output to its stdout. It's sort of hacky, but
+// this allows shell redirection to work on Ravenwood output too,
+// so e.g. `atest ... |tee atest.log` would work on Ravenwood's output.
+// (which wouldn't work with `RAVENWOOD_LOG_OUT=$(tty)`).
+//
+// Otherwise -- if $RAVENWOOD_LOG_OUT isn't set -- atest/tradefed just writes
+// the test's output to its own log file.
static void maybeRedirectLog() {
auto ravenwoodLogOut = getenv("RAVENWOOD_LOG_OUT");
- if (ravenwoodLogOut == NULL) {
+ if (ravenwoodLogOut == NULL || *ravenwoodLogOut == '\0') {
return;
}
- ALOGI("RAVENWOOD_LOG_OUT set. Redirecting output to %s", ravenwoodLogOut);
+ std::string path;
+ if (strcmp("-", ravenwoodLogOut) == 0) {
+ pid_t ppid = find_atest_pid();
+ if (ppid < 0) {
+ ALOGI("RAVENWOOD_LOG_OUT set to '-', but unable to find atest's PID");
+ return;
+ }
+ path = std::format("/proc/{}/fd/1", ppid);
+ } else {
+ path = ravenwoodLogOut;
+ }
+ ALOGI("RAVENWOOD_LOG_OUT set. Redirecting output to '%s'", path.c_str());
// Redirect stdin / stdout to /dev/tty.
- int ttyFd = open(ravenwoodLogOut, O_WRONLY | O_APPEND);
+ int ttyFd = open(path.c_str(), O_WRONLY | O_APPEND);
if (ttyFd == -1) {
- ALOGW("$RAVENWOOD_LOG_OUT is set to %s, but failed to open: %s ", ravenwoodLogOut,
+ ALOGW("$RAVENWOOD_LOG_OUT is set, but failed to open '%s': %s ", path.c_str(),
strerror(errno));
return;
}
diff --git a/ravenwood/scripts/run-ravenwood-tests.sh b/ravenwood/scripts/run-ravenwood-tests.sh
index 27c5ea1..67ebb1f 100755
--- a/ravenwood/scripts/run-ravenwood-tests.sh
+++ b/ravenwood/scripts/run-ravenwood-tests.sh
@@ -66,7 +66,7 @@
done
shift $(($OPTIND - 1))
-all_tests=(hoststubgentest tiny-framework-dump-test hoststubgen-invoke-test ravenwood-stats-checker)
+all_tests=(hoststubgentest tiny-framework-dump-test hoststubgen-invoke-test ravenwood-stats-checker ravenhelpertest)
all_tests+=( $(${0%/*}/list-ravenwood-tests.sh) )
filter() {
diff --git a/ravenwood/texts/ravenwood-standard-options.txt b/ravenwood/texts/ravenwood-standard-options.txt
index 91fd928..0edc348 100644
--- a/ravenwood/texts/ravenwood-standard-options.txt
+++ b/ravenwood/texts/ravenwood-standard-options.txt
@@ -9,8 +9,10 @@
# Uncomment below lines to enable each feature.
+# Enable method call hook.
#--default-method-call-hook
-# com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+# android.platform.test.ravenwood.RavenwoodMethodCallLogger.logMethodCall
+
#--default-class-load-hook
# com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
diff --git a/ravenwood/tools/hoststubgen/helper-runtime-src/com/android/hoststubgen/hosthelper/HostTestUtils.java b/ravenwood/tools/hoststubgen/helper-runtime-src/com/android/hoststubgen/hosthelper/HostTestUtils.java
index 78fd8f7..145325c 100644
--- a/ravenwood/tools/hoststubgen/helper-runtime-src/com/android/hoststubgen/hosthelper/HostTestUtils.java
+++ b/ravenwood/tools/hoststubgen/helper-runtime-src/com/android/hoststubgen/hosthelper/HostTestUtils.java
@@ -18,6 +18,7 @@
import java.io.PrintStream;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
+import java.util.Arrays;
/**
* Utilities used in the host side test environment.
@@ -36,9 +37,14 @@
public static final String CLASS_INTERNAL_NAME = getInternalName(HostTestUtils.class);
+ /** If true, we skip all method call hooks */
+ private static final boolean SKIP_METHOD_CALL_HOOK = "1".equals(System.getenv(
+ "HOSTTEST_SKIP_METHOD_CALL_HOOK"));
+
/** If true, we won't print method call log. */
- private static final boolean SKIP_METHOD_LOG = "1".equals(System.getenv(
- "HOSTTEST_SKIP_METHOD_LOG"));
+ private static final boolean SKIP_METHOD_LOG =
+ "1".equals(System.getenv("HOSTTEST_SKIP_METHOD_LOG"))
+ || "1".equals(System.getenv("RAVENWOOD_NO_METHOD_LOG"));
/** If true, we won't print class load log. */
private static final boolean SKIP_CLASS_LOG = "1".equals(System.getenv(
@@ -65,6 +71,9 @@
+ "consider using Mockito; more details at go/ravenwood-docs");
}
+ private static final Class<?>[] sMethodHookArgTypes =
+ { Class.class, String.class, String.class};
+
/**
* Trampoline method for method-call-hook.
*/
@@ -74,16 +83,22 @@
String methodDescriptor,
String callbackMethod
) {
- callStaticMethodByName(callbackMethod, "method call hook", methodClass,
- methodName, methodDescriptor);
+ if (SKIP_METHOD_CALL_HOOK) {
+ return;
+ }
+ callStaticMethodByName(callbackMethod, "method call hook", sMethodHookArgTypes,
+ methodClass, methodName, methodDescriptor);
}
/**
+ * Simple implementation of method call hook, which just prints the information of the
+ * method. This is just for basic testing. We don't use it in Ravenwood, because this would
+ * be way too noisy as it prints every single method, even trivial ones. (iterator methods,
+ * etc..)
+ *
* I can be used as
* {@code --default-method-call-hook
* com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall}.
- *
- * It logs every single methods called.
*/
public static void logMethodCall(
Class<?> methodClass,
@@ -97,6 +112,8 @@
+ methodName + methodDescriptor);
}
+ private static final Class<?>[] sClassLoadHookArgTypes = { Class.class };
+
/**
* Called when any top level class (not nested classes) in the impl jar is loaded.
*
@@ -111,11 +128,12 @@
logPrintStream.println("! Class loaded: " + loadedClass.getCanonicalName()
+ " calling hook " + callbackMethod);
- callStaticMethodByName(callbackMethod, "class load hook", loadedClass);
+ callStaticMethodByName(
+ callbackMethod, "class load hook", sClassLoadHookArgTypes, loadedClass);
}
private static void callStaticMethodByName(String classAndMethodName,
- String description, Object... args) {
+ String description, Class<?>[] argTypes, Object... args) {
// Forward the call to callbackMethod.
final int lastPeriod = classAndMethodName.lastIndexOf(".");
@@ -145,19 +163,14 @@
className));
}
- Class<?>[] argTypes = new Class[args.length];
- for (int i = 0; i < args.length; i++) {
- argTypes[i] = args[i].getClass();
- }
-
Method method = null;
try {
method = clazz.getMethod(methodName, argTypes);
} catch (Exception e) {
throw new HostTestException(String.format(
"Unable to find %s: class %s doesn't have method %s"
- + " (method must take exactly one parameter of type Class,"
- + " and public static)",
+ + " Method must be public static, and arg types must be: "
+ + Arrays.toString(argTypes),
description, className, methodName), e);
}
if (!(Modifier.isPublic(method.getModifiers())
diff --git a/ravenwood/tools/hoststubgen/framework-policy-override.txt b/ravenwood/tools/hoststubgen/hoststubgen-test-policy-override.txt
similarity index 72%
rename from ravenwood/tools/hoststubgen/framework-policy-override.txt
rename to ravenwood/tools/hoststubgen/hoststubgen-test-policy-override.txt
index af3789e..000771a 100644
--- a/ravenwood/tools/hoststubgen/framework-policy-override.txt
+++ b/ravenwood/tools/hoststubgen/hoststubgen-test-policy-override.txt
@@ -1,30 +1,7 @@
-# --------------------------------------------------------------------------------------------------
-# This file contains rules to process `framework-all.jar` to generate the host side test "stub" and
-# "impl" jars, without using Java annotations.
-#
-# Useful when:
-# - The class is auto-generated and annotations can't be added.
-# (We need to figure out what to do on auto-generated classes.)
-# - Want to quickly change filter rules without having to rebuild framework.jar.
-#
-# Using this file, one can control the visibility of APIs on a per-class, per-field and per-method
-# basis, but in most cases, per-class directives would be sufficient. That is:
-#
-# - To put the entire class, including its members and nested classes, in the "stub" jar,
-# so that the test / target code can use the API, use `stubclass`.
-#
-# class package.class stubclass
-#
-# - To put the entire class, including its members and nested classes, in the "impl" jar,
-# but not in the "stub" jar, use `keepclass`. Use this when you don't want to expose an API to
-# tests/target directly, but it's still needed at runtime, because it's used by other "stub" APIs
-# directly or indirectly.
-#
-# class package.class keepclass
-#
-# All other classes will be removed from both the stub jar and impl jar.
-#
-# --------------------------------------------------------------------------------------------------
+# *************************************************************************************************
+# This file contains "policies" for HostStubGen used by its automated tests.
+# For the "real" Ravenwood policies, see the frameworks/base/ravenwood/texts/ directory.
+# *************************************************************************************************
# --------------------------------------------------------------------------------------------------
# Directions on auto-generated classes, where we can't use Java annotations (yet).
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGen.kt b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGen.kt
index 9859475..83a7069 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGen.kt
+++ b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGen.kt
@@ -29,7 +29,7 @@
import com.android.hoststubgen.filters.SanitizationFilter
import com.android.hoststubgen.filters.TextFileFilterPolicyBuilder
import com.android.hoststubgen.filters.printAsTextPolicy
-import com.android.hoststubgen.utils.ClassFilter
+import com.android.hoststubgen.utils.ClassPredicate
import com.android.hoststubgen.visitors.BaseAdapter
import com.android.hoststubgen.visitors.PackageRedirectRemapper
import java.io.BufferedInputStream
@@ -145,6 +145,7 @@
// Inject default hooks from options.
filter = DefaultHookInjectingFilter(
+ allClasses,
options.defaultClassLoadHook.get,
options.defaultMethodCallHook.get,
filter
@@ -152,9 +153,9 @@
val annotationAllowedClassesFilter = options.annotationAllowedClassesFile.get.let { file ->
if (file == null) {
- ClassFilter.newNullFilter(true) // Allow all classes
+ ClassPredicate.newConstantPredicate(true) // Allow all classes
} else {
- ClassFilter.loadFromFile(file, false)
+ ClassPredicate.loadFromFile(file, false)
}
}
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/AnnotationBasedFilter.kt b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/AnnotationBasedFilter.kt
index 36adf06..9b5d602 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/AnnotationBasedFilter.kt
+++ b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/AnnotationBasedFilter.kt
@@ -31,7 +31,7 @@
import com.android.hoststubgen.asm.toHumanReadableMethodName
import com.android.hoststubgen.asm.toJvmClassName
import com.android.hoststubgen.log
-import com.android.hoststubgen.utils.ClassFilter
+import com.android.hoststubgen.utils.ClassPredicate
import org.objectweb.asm.tree.AnnotationNode
import org.objectweb.asm.tree.ClassNode
@@ -54,7 +54,7 @@
redirectionClassAnnotations_: Set<String>,
classLoadHookAnnotations_: Set<String>,
keepStaticInitializerAnnotations_: Set<String>,
- private val annotationAllowedClassesFilter: ClassFilter,
+ private val annotationAllowedClassesFilter: ClassPredicate,
fallback: OutputFilter,
) : DelegatingFilter(fallback) {
private val keepAnnotations = convertToInternalNames(keepAnnotations_)
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/DefaultHookInjectingFilter.kt b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/DefaultHookInjectingFilter.kt
index d771003..aaf49c1 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/DefaultHookInjectingFilter.kt
+++ b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/DefaultHookInjectingFilter.kt
@@ -16,8 +16,11 @@
package com.android.hoststubgen.filters
import com.android.hoststubgen.addLists
+import com.android.hoststubgen.asm.ClassNodes
+import com.android.hoststubgen.asm.isAnnotation
class DefaultHookInjectingFilter(
+ val classes: ClassNodes,
defaultClassLoadHook: String?,
defaultMethodCallHook: String?,
fallback: OutputFilter
@@ -36,8 +39,30 @@
private val defaultClassLoadHookAsList: List<String> = toSingleList(defaultClassLoadHook)
private val defaultMethodCallHookAsList: List<String> = toSingleList(defaultMethodCallHook)
+ private fun shouldInject(className: String): Boolean {
+ // Let's not inject default hooks to annotation classes or inner classes of an annotation
+ // class, because these methods could be called at the class load time, which
+ // is very confusing, and usually not useful.
+
+ val cn = classes.findClass(className) ?: return false
+ if (cn.isAnnotation()) {
+ return false
+ }
+ cn.nestHostClass?.let { nestHostClass ->
+ val nestHost = classes.findClass(nestHostClass) ?: return false
+ if (nestHost.isAnnotation()) {
+ return false
+ }
+ }
+ return true
+ }
+
override fun getClassLoadHooks(className: String): List<String> {
- return addLists(super.getClassLoadHooks(className), defaultClassLoadHookAsList)
+ val s = super.getClassLoadHooks(className)
+ if (!shouldInject(className)) {
+ return s
+ }
+ return addLists(s, defaultClassLoadHookAsList)
}
override fun getMethodCallHooks(
@@ -45,9 +70,23 @@
methodName: String,
descriptor: String
): List<String> {
- return addLists(
- super.getMethodCallHooks(className, methodName, descriptor),
- defaultMethodCallHookAsList,
- )
+ val s = super.getMethodCallHooks(className, methodName, descriptor)
+ if (!shouldInject(className)) {
+ return s
+ }
+ // Don't hook Object methods.
+ if (methodName == "finalize" && descriptor == "()V") {
+ return s
+ }
+ if (methodName == "toString" && descriptor == "()Ljava/lang/String;") {
+ return s
+ }
+ if (methodName == "equals" && descriptor == "(Ljava/lang/Object;)Z") {
+ return s
+ }
+ if (methodName == "hashCode" && descriptor == "()I") {
+ return s
+ }
+ return addLists(s, defaultMethodCallHookAsList)
}
-}
\ No newline at end of file
+}
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/utils/ClassFilter.kt b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/utils/ClassPredicate.kt
similarity index 93%
rename from ravenwood/tools/hoststubgen/src/com/android/hoststubgen/utils/ClassFilter.kt
rename to ravenwood/tools/hoststubgen/src/com/android/hoststubgen/utils/ClassPredicate.kt
index d6aa761..810dd71 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/utils/ClassFilter.kt
+++ b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/utils/ClassPredicate.kt
@@ -24,7 +24,7 @@
/**
* General purpose filter for class names.
*/
-class ClassFilter private constructor(
+class ClassPredicate private constructor(
private val defaultResult: Boolean,
) {
private enum class MatchType {
@@ -81,14 +81,14 @@
companion object {
/**
- * Return a filter that alawys returns true or false.
+ * Return a filter that always returns true or false.
*/
- fun newNullFilter(defaultResult: Boolean): ClassFilter {
- return ClassFilter(defaultResult)
+ fun newConstantPredicate(defaultResult: Boolean): ClassPredicate {
+ return ClassPredicate(defaultResult)
}
/** Build a filter from a file. */
- fun loadFromFile(filename: String, defaultResult: Boolean): ClassFilter {
+ fun loadFromFile(filename: String, defaultResult: Boolean): ClassPredicate {
return buildFromString(File(filename).readText(), defaultResult, filename)
}
@@ -97,8 +97,8 @@
filterString: String,
defaultResult: Boolean,
filenameForErrorMessage: String
- ): ClassFilter {
- val ret = ClassFilter(defaultResult)
+ ): ClassPredicate {
+ val ret = ClassPredicate(defaultResult)
var lineNo = 0
filterString.split('\n').forEach { s ->
diff --git a/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/13-hoststubgen-test-tiny-framework-host-ext-dump.txt b/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/13-hoststubgen-test-tiny-framework-host-ext-dump.txt
index 49769e6..fb225ff 100644
--- a/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/13-hoststubgen-test-tiny-framework-host-ext-dump.txt
+++ b/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/13-hoststubgen-test-tiny-framework-host-ext-dump.txt
@@ -6,17 +6,9 @@
flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
this_class: #x // android/hosttest/annotation/HostSideTestClassLoadHook
super_class: #x // java/lang/Object
- interfaces: 1, fields: 0, methods: 2, attributes: 2
- private static {};
- descriptor: ()V
- flags: (0x000a) ACC_PRIVATE, ACC_STATIC
- Code:
- stack=2, locals=0, args_size=0
- x: ldc #x // class android/hosttest/annotation/HostSideTestClassLoadHook
- x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
- x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
- x: return
-
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
public abstract java.lang.String value();
descriptor: ()Ljava/lang/String;
flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
@@ -44,16 +36,9 @@
flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
this_class: #x // android/hosttest/annotation/HostSideTestKeep
super_class: #x // java/lang/Object
- interfaces: 1, fields: 0, methods: 1, attributes: 2
- private static {};
- descriptor: ()V
- flags: (0x000a) ACC_PRIVATE, ACC_STATIC
- Code:
- stack=2, locals=0, args_size=0
- x: ldc #x // class android/hosttest/annotation/HostSideTestKeep
- x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
- x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
- x: return
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestKeep.java"
RuntimeVisibleAnnotations:
@@ -75,16 +60,9 @@
flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
this_class: #x // android/hosttest/annotation/HostSideTestRedirect
super_class: #x // java/lang/Object
- interfaces: 1, fields: 0, methods: 1, attributes: 2
- private static {};
- descriptor: ()V
- flags: (0x000a) ACC_PRIVATE, ACC_STATIC
- Code:
- stack=2, locals=0, args_size=0
- x: ldc #x // class android/hosttest/annotation/HostSideTestRedirect
- x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
- x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
- x: return
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestRedirect.java"
RuntimeVisibleAnnotations:
@@ -106,17 +84,9 @@
flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
this_class: #x // android/hosttest/annotation/HostSideTestRedirectionClass
super_class: #x // java/lang/Object
- interfaces: 1, fields: 0, methods: 2, attributes: 2
- private static {};
- descriptor: ()V
- flags: (0x000a) ACC_PRIVATE, ACC_STATIC
- Code:
- stack=2, locals=0, args_size=0
- x: ldc #x // class android/hosttest/annotation/HostSideTestRedirectionClass
- x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
- x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
- x: return
-
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
public abstract java.lang.String value();
descriptor: ()Ljava/lang/String;
flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
@@ -144,16 +114,9 @@
flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
this_class: #x // android/hosttest/annotation/HostSideTestRemove
super_class: #x // java/lang/Object
- interfaces: 1, fields: 0, methods: 1, attributes: 2
- private static {};
- descriptor: ()V
- flags: (0x000a) ACC_PRIVATE, ACC_STATIC
- Code:
- stack=2, locals=0, args_size=0
- x: ldc #x // class android/hosttest/annotation/HostSideTestRemove
- x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
- x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
- x: return
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestRemove.java"
RuntimeVisibleAnnotations:
@@ -175,16 +138,9 @@
flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
this_class: #x // android/hosttest/annotation/HostSideTestStaticInitializerKeep
super_class: #x // java/lang/Object
- interfaces: 1, fields: 0, methods: 1, attributes: 2
- private static {};
- descriptor: ()V
- flags: (0x000a) ACC_PRIVATE, ACC_STATIC
- Code:
- stack=2, locals=0, args_size=0
- x: ldc #x // class android/hosttest/annotation/HostSideTestStaticInitializerKeep
- x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
- x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
- x: return
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestStaticInitializerKeep.java"
RuntimeVisibleAnnotations:
@@ -206,17 +162,9 @@
flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
this_class: #x // android/hosttest/annotation/HostSideTestSubstitute
super_class: #x // java/lang/Object
- interfaces: 1, fields: 0, methods: 2, attributes: 2
- private static {};
- descriptor: ()V
- flags: (0x000a) ACC_PRIVATE, ACC_STATIC
- Code:
- stack=2, locals=0, args_size=0
- x: ldc #x // class android/hosttest/annotation/HostSideTestSubstitute
- x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
- x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
- x: return
-
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
public abstract java.lang.String suffix();
descriptor: ()Ljava/lang/String;
flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
@@ -244,16 +192,9 @@
flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
this_class: #x // android/hosttest/annotation/HostSideTestThrow
super_class: #x // java/lang/Object
- interfaces: 1, fields: 0, methods: 1, attributes: 2
- private static {};
- descriptor: ()V
- flags: (0x000a) ACC_PRIVATE, ACC_STATIC
- Code:
- stack=2, locals=0, args_size=0
- x: ldc #x // class android/hosttest/annotation/HostSideTestThrow
- x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
- x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
- x: return
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestThrow.java"
RuntimeVisibleAnnotations:
@@ -275,16 +216,9 @@
flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
this_class: #x // android/hosttest/annotation/HostSideTestWholeClassKeep
super_class: #x // java/lang/Object
- interfaces: 1, fields: 0, methods: 1, attributes: 2
- private static {};
- descriptor: ()V
- flags: (0x000a) ACC_PRIVATE, ACC_STATIC
- Code:
- stack=2, locals=0, args_size=0
- x: ldc #x // class android/hosttest/annotation/HostSideTestWholeClassKeep
- x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
- x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
- x: return
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestWholeClassKeep.java"
RuntimeVisibleAnnotations:
diff --git a/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output/13-hoststubgen-test-tiny-framework-host-ext-dump.txt b/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output/13-hoststubgen-test-tiny-framework-host-ext-dump.txt
index 0f8af92..e4b9db2 100644
--- a/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output/13-hoststubgen-test-tiny-framework-host-ext-dump.txt
+++ b/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output/13-hoststubgen-test-tiny-framework-host-ext-dump.txt
@@ -6,17 +6,9 @@
flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
this_class: #x // android/hosttest/annotation/HostSideTestClassLoadHook
super_class: #x // java/lang/Object
- interfaces: 1, fields: 0, methods: 2, attributes: 2
- private static {};
- descriptor: ()V
- flags: (0x000a) ACC_PRIVATE, ACC_STATIC
- Code:
- stack=2, locals=0, args_size=0
- x: ldc #x // class android/hosttest/annotation/HostSideTestClassLoadHook
- x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
- x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
- x: return
-
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
public abstract java.lang.String value();
descriptor: ()Ljava/lang/String;
flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
@@ -44,16 +36,9 @@
flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
this_class: #x // android/hosttest/annotation/HostSideTestKeep
super_class: #x // java/lang/Object
- interfaces: 1, fields: 0, methods: 1, attributes: 2
- private static {};
- descriptor: ()V
- flags: (0x000a) ACC_PRIVATE, ACC_STATIC
- Code:
- stack=2, locals=0, args_size=0
- x: ldc #x // class android/hosttest/annotation/HostSideTestKeep
- x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
- x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
- x: return
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestKeep.java"
RuntimeVisibleAnnotations:
@@ -75,16 +60,9 @@
flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
this_class: #x // android/hosttest/annotation/HostSideTestRedirect
super_class: #x // java/lang/Object
- interfaces: 1, fields: 0, methods: 1, attributes: 2
- private static {};
- descriptor: ()V
- flags: (0x000a) ACC_PRIVATE, ACC_STATIC
- Code:
- stack=2, locals=0, args_size=0
- x: ldc #x // class android/hosttest/annotation/HostSideTestRedirect
- x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
- x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
- x: return
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestRedirect.java"
RuntimeVisibleAnnotations:
@@ -106,17 +84,9 @@
flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
this_class: #x // android/hosttest/annotation/HostSideTestRedirectionClass
super_class: #x // java/lang/Object
- interfaces: 1, fields: 0, methods: 2, attributes: 2
- private static {};
- descriptor: ()V
- flags: (0x000a) ACC_PRIVATE, ACC_STATIC
- Code:
- stack=2, locals=0, args_size=0
- x: ldc #x // class android/hosttest/annotation/HostSideTestRedirectionClass
- x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
- x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
- x: return
-
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
public abstract java.lang.String value();
descriptor: ()Ljava/lang/String;
flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
@@ -144,16 +114,9 @@
flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
this_class: #x // android/hosttest/annotation/HostSideTestRemove
super_class: #x // java/lang/Object
- interfaces: 1, fields: 0, methods: 1, attributes: 2
- private static {};
- descriptor: ()V
- flags: (0x000a) ACC_PRIVATE, ACC_STATIC
- Code:
- stack=2, locals=0, args_size=0
- x: ldc #x // class android/hosttest/annotation/HostSideTestRemove
- x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
- x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
- x: return
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestRemove.java"
RuntimeVisibleAnnotations:
@@ -175,16 +138,9 @@
flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
this_class: #x // android/hosttest/annotation/HostSideTestStaticInitializerKeep
super_class: #x // java/lang/Object
- interfaces: 1, fields: 0, methods: 1, attributes: 2
- private static {};
- descriptor: ()V
- flags: (0x000a) ACC_PRIVATE, ACC_STATIC
- Code:
- stack=2, locals=0, args_size=0
- x: ldc #x // class android/hosttest/annotation/HostSideTestStaticInitializerKeep
- x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
- x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
- x: return
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestStaticInitializerKeep.java"
RuntimeVisibleAnnotations:
@@ -206,17 +162,9 @@
flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
this_class: #x // android/hosttest/annotation/HostSideTestSubstitute
super_class: #x // java/lang/Object
- interfaces: 1, fields: 0, methods: 2, attributes: 2
- private static {};
- descriptor: ()V
- flags: (0x000a) ACC_PRIVATE, ACC_STATIC
- Code:
- stack=2, locals=0, args_size=0
- x: ldc #x // class android/hosttest/annotation/HostSideTestSubstitute
- x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
- x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
- x: return
-
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
public abstract java.lang.String suffix();
descriptor: ()Ljava/lang/String;
flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
@@ -244,16 +192,9 @@
flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
this_class: #x // android/hosttest/annotation/HostSideTestThrow
super_class: #x // java/lang/Object
- interfaces: 1, fields: 0, methods: 1, attributes: 2
- private static {};
- descriptor: ()V
- flags: (0x000a) ACC_PRIVATE, ACC_STATIC
- Code:
- stack=2, locals=0, args_size=0
- x: ldc #x // class android/hosttest/annotation/HostSideTestThrow
- x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
- x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
- x: return
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestThrow.java"
RuntimeVisibleAnnotations:
@@ -275,16 +216,9 @@
flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
this_class: #x // android/hosttest/annotation/HostSideTestWholeClassKeep
super_class: #x // java/lang/Object
- interfaces: 1, fields: 0, methods: 1, attributes: 2
- private static {};
- descriptor: ()V
- flags: (0x000a) ACC_PRIVATE, ACC_STATIC
- Code:
- stack=2, locals=0, args_size=0
- x: ldc #x // class android/hosttest/annotation/HostSideTestWholeClassKeep
- x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
- x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
- x: return
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestWholeClassKeep.java"
RuntimeVisibleAnnotations:
@@ -307,6 +241,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 3, attributes: 4
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -377,6 +313,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 3, attributes: 4
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -447,6 +385,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/IPretendingAidl
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 4
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -476,6 +416,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/R$Nested
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 2, attributes: 4
+Constant pool:
+{
public static int[] ARRAY;
descriptor: [I
flags: (0x0009) ACC_PUBLIC, ACC_STATIC
@@ -546,6 +488,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/R
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 2, attributes: 4
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -594,6 +538,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 7, attributes: 3
+Constant pool:
+{
public int keep;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -785,6 +731,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 3, attributes: 3
+Constant pool:
+{
public static final java.util.Set<java.lang.Class<?>> sLoadedClasses;
descriptor: Ljava/util/Set;
flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
@@ -880,6 +828,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 5, attributes: 3
+Constant pool:
+{
public int keep;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -1010,6 +960,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerDefault
super_class: #x // java/lang/Object
interfaces: 0, fields: 2, methods: 0, attributes: 3
+Constant pool:
+{
public static boolean sInitialized;
descriptor: Z
flags: (0x0009) ACC_PUBLIC, ACC_STATIC
@@ -1047,6 +999,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub
super_class: #x // java/lang/Object
interfaces: 0, fields: 2, methods: 1, attributes: 3
+Constant pool:
+{
public static boolean sInitialized;
descriptor: Z
flags: (0x0009) ACC_PUBLIC, ACC_STATIC
@@ -1117,6 +1071,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
super_class: #x // java/lang/Enum
interfaces: 0, fields: 6, methods: 7, attributes: 4
+Constant pool:
+{
public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex RED;
descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
@@ -1400,6 +1356,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
super_class: #x // java/lang/Enum
interfaces: 0, fields: 3, methods: 5, attributes: 4
+Constant pool:
+{
public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple CAT;
descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
@@ -1576,6 +1534,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 3, attributes: 3
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -1659,6 +1619,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 15, attributes: 2
+Constant pool:
+{
public int stub;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -1971,6 +1933,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
super_class: #x // java/lang/Object
interfaces: 0, fields: 2, methods: 8, attributes: 6
+Constant pool:
+{
public final java.util.function.Supplier<java.lang.Integer> mSupplier;
descriptor: Ljava/util/function/Supplier;
flags: (0x0011) ACC_PUBLIC, ACC_FINAL
@@ -2201,6 +2165,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
super_class: #x // java/lang/Object
interfaces: 0, fields: 2, methods: 8, attributes: 6
+Constant pool:
+{
public final java.util.function.Supplier<java.lang.Integer> mSupplier;
descriptor: Ljava/util/function/Supplier;
flags: (0x0011) ACC_PUBLIC, ACC_FINAL
@@ -2432,6 +2398,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 4, attributes: 4
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -2526,6 +2494,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 5, attributes: 6
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -2665,6 +2635,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 15, attributes: 3
+Constant pool:
+{
int value;
descriptor: I
flags: (0x0000)
@@ -2998,6 +2970,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 8, attributes: 3
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -3173,6 +3147,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
super_class: #x // java/lang/Object
interfaces: 1, fields: 1, methods: 4, attributes: 6
+Constant pool:
+{
final com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses this$0;
descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
flags: (0x1010) ACC_FINAL, ACC_SYNTHETIC
@@ -3278,6 +3254,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 4, attributes: 6
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -3369,6 +3347,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
super_class: #x // java/lang/Object
interfaces: 1, fields: 1, methods: 4, attributes: 6
+Constant pool:
+{
final com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses this$0;
descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
flags: (0x1010) ACC_FINAL, ACC_SYNTHETIC
@@ -3474,6 +3454,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 4, attributes: 6
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -3565,6 +3547,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 2, attributes: 4
+Constant pool:
+{
public int value;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -3623,6 +3607,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass
super_class: #x // java/lang/Object
interfaces: 0, fields: 2, methods: 2, attributes: 4
+Constant pool:
+{
public int value;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -3694,6 +3680,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 4, attributes: 6
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -3786,6 +3774,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 2, attributes: 4
+Constant pool:
+{
public int value;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -3844,6 +3834,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 3, attributes: 4
+Constant pool:
+{
public int value;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -3923,6 +3915,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass
super_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
interfaces: 0, fields: 0, methods: 2, attributes: 4
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -3973,6 +3967,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
super_class: #x // java/lang/Object
interfaces: 0, fields: 2, methods: 4, attributes: 5
+Constant pool:
+{
public final java.util.function.Supplier<java.lang.Integer> mSupplier;
descriptor: Ljava/util/function/Supplier;
flags: (0x0011) ACC_PUBLIC, ACC_FINAL
@@ -4121,6 +4117,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 3, attributes: 3
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4192,6 +4190,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 3, attributes: 3
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4263,6 +4263,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/packagetest/A
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4286,6 +4288,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/packagetest/sub/A
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4309,6 +4313,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C1
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4332,6 +4338,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C2
super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C1
interfaces: 0, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4355,6 +4363,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C3
super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C2
interfaces: 0, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4378,6 +4388,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/CA
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4401,6 +4413,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/CB
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4424,6 +4438,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C1
super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C1
interfaces: 0, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4447,6 +4463,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C2
super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C2
interfaces: 0, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4470,6 +4488,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C3
super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C3
interfaces: 0, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4493,6 +4513,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4516,6 +4538,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1_IA
super_class: #x // java/lang/Object
interfaces: 2, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4539,6 +4563,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I2
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4562,6 +4588,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I3
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4585,6 +4613,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/I1
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4608,6 +4638,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/I2
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4631,6 +4663,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/I3
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4654,6 +4688,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/IA
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4677,6 +4713,8 @@
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/IB
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4700,6 +4738,8 @@
this_class: #x // com/supported/UnsupportedClass
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 3, attributes: 3
+Constant pool:
+{
private final int mValue;
descriptor: I
flags: (0x0012) ACC_PRIVATE, ACC_FINAL
@@ -4779,6 +4819,8 @@
this_class: #x // com/unsupported/UnsupportedClass
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 3, attributes: 3
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4854,6 +4896,8 @@
this_class: #x // rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 3, attributes: 3
+Constant pool:
+{
private final int mValue;
descriptor: I
flags: (0x0012) ACC_PRIVATE, ACC_FINAL
diff --git a/ravenwood/tools/hoststubgen/test/com/android/hoststubgen/utils/ClassFilterTest.kt b/ravenwood/tools/hoststubgen/test/com/android/hoststubgen/utils/ClassPredicateTest.kt
similarity index 89%
rename from ravenwood/tools/hoststubgen/test/com/android/hoststubgen/utils/ClassFilterTest.kt
rename to ravenwood/tools/hoststubgen/test/com/android/hoststubgen/utils/ClassPredicateTest.kt
index d4e75d4..5a877e6 100644
--- a/ravenwood/tools/hoststubgen/test/com/android/hoststubgen/utils/ClassFilterTest.kt
+++ b/ravenwood/tools/hoststubgen/test/com/android/hoststubgen/utils/ClassPredicateTest.kt
@@ -20,22 +20,22 @@
import org.junit.Assert.fail
import org.junit.Test
-class ClassFilterTest {
+class ClassPredicateTest {
@Test
fun testDefaultTrue() {
- val f = ClassFilter.newNullFilter(true)
+ val f = ClassPredicate.newConstantPredicate(true)
assertThat(f.matches("a/b/c")).isEqualTo(true)
}
@Test
fun testDefaultFalse() {
- val f = ClassFilter.newNullFilter(false)
+ val f = ClassPredicate.newConstantPredicate(false)
assertThat(f.matches("a/b/c")).isEqualTo(false)
}
@Test
fun testComplex1() {
- val f = ClassFilter.buildFromString("""
+ val f = ClassPredicate.buildFromString("""
# ** this is a comment **
a.b.c # allow
!a.b.d # disallow
@@ -57,7 +57,7 @@
@Test
fun testComplex2() {
- val f = ClassFilter.buildFromString("""
+ val f = ClassPredicate.buildFromString("""
a.b.c # allow
!a.* # disallow everything else in package "a".
!d.e.f # disallow d.e.f.
@@ -75,7 +75,7 @@
@Test
fun testNestedClass() {
- val f = ClassFilter.buildFromString("a.b.c\nm.n.o\$p\n", false, "X")
+ val f = ClassPredicate.buildFromString("a.b.c\nm.n.o\$p\n", false, "X")
assertThat(f.matches("a/b/c")).isEqualTo(true)
assertThat(f.matches("a/b/c\$d")).isEqualTo(true)
assertThat(f.matches("a/b/c\$d\$e")).isEqualTo(true)
@@ -88,7 +88,7 @@
@Test
fun testBadFilter1() {
try {
- ClassFilter.buildFromString("""
+ ClassPredicate.buildFromString("""
a*
""".trimIndent(), true, "FILENAME")
fail("ParseException didn't happen")
@@ -101,7 +101,7 @@
@Test
fun testSuffix() {
- val f = ClassFilter.buildFromString("""
+ val f = ClassPredicate.buildFromString("""
*.Abc # allow
!* # Disallow by default
""".trimIndent(), true, "X")
diff --git a/ravenwood/tools/ravenhelper/Android.bp b/ravenwood/tools/ravenhelper/Android.bp
index a7ee468..3da6dd8 100644
--- a/ravenwood/tools/ravenhelper/Android.bp
+++ b/ravenwood/tools/ravenhelper/Android.bp
@@ -24,3 +24,14 @@
],
visibility: ["//visibility:public"],
}
+
+java_test_host {
+ name: "ravenhelpertest",
+ srcs: ["test/**/*.kt"],
+ static_libs: [
+ "ravenhelper",
+ "truth",
+ ],
+ test_suites: ["general-tests"],
+ visibility: ["//visibility:private"],
+}
diff --git a/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/policytoannot/PtaProcessor.kt b/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/policytoannot/PtaProcessor.kt
index 3657a90..b6089ea 100644
--- a/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/policytoannot/PtaProcessor.kt
+++ b/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/policytoannot/PtaProcessor.kt
@@ -24,7 +24,7 @@
import com.android.hoststubgen.filters.TextFileFilterPolicyParser
import com.android.hoststubgen.filters.TextFilePolicyMethodReplaceFilter
import com.android.hoststubgen.log
-import com.android.hoststubgen.utils.ClassFilter
+import com.android.hoststubgen.utils.ClassPredicate
import com.android.platform.test.ravenwood.ravenhelper.SubcommandHandler
import com.android.platform.test.ravenwood.ravenhelper.psi.createUastEnvironment
import com.android.platform.test.ravenwood.ravenhelper.sourcemap.AllClassInfo
@@ -66,11 +66,11 @@
val annotations: Annotations,
val dumpOperations: Boolean,
) {
- private val annotationAllowedClasses: ClassFilter = annotationAllowedClassesFile.let { file ->
+ private val annotationAllowedClasses: ClassPredicate = annotationAllowedClassesFile.let { file ->
if (file == null) {
- ClassFilter.newNullFilter(true) // Allow all classes
+ ClassPredicate.newConstantPredicate(true) // Allow all classes
} else {
- ClassFilter.loadFromFile(file, false)
+ ClassPredicate.loadFromFile(file, false)
}
}
diff --git a/ravenwood/tools/ravenhelper/test/com/android/platform/test/ravenwood/ravenhelper/RavenhelperTest.kt b/ravenwood/tools/ravenhelper/test/com/android/platform/test/ravenwood/ravenhelper/RavenhelperTest.kt
new file mode 100644
index 0000000..203fab1
--- /dev/null
+++ b/ravenwood/tools/ravenhelper/test/com/android/platform/test/ravenwood/ravenhelper/RavenhelperTest.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2025 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.platform.test.ravenwood.ravenhelper
+
+import com.android.platform.test.ravenwood.ravenhelper.psi.createUastEnvironment
+import org.junit.Test
+
+class RavenhelperTest {
+ @Test
+ fun testPsiInitialization() {
+ val env = createUastEnvironment()
+ env.dispose()
+ }
+}
\ No newline at end of file
diff --git a/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickTypePanel.java b/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickTypePanel.java
index 614b228..c74e4f5 100644
--- a/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickTypePanel.java
+++ b/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickTypePanel.java
@@ -77,14 +77,21 @@
// Whether the panel is expanded or not.
private boolean mExpanded = false;
+ // Whether autoclick is paused.
+ private boolean mPaused = false;
+
private final LinearLayout mLeftClickButton;
private final LinearLayout mRightClickButton;
private final LinearLayout mDoubleClickButton;
private final LinearLayout mDragButton;
private final LinearLayout mScrollButton;
+ private final LinearLayout mPauseButton;
private LinearLayout mSelectedButton;
+ private final Drawable mPauseButtonDrawable;
+ private final Drawable mResumeButtonDrawable;
+
public AutoclickTypePanel(
Context context,
WindowManager windowManager,
@@ -93,6 +100,11 @@
mWindowManager = windowManager;
mClickPanelController = clickPanelController;
+ mPauseButtonDrawable = mContext.getDrawable(
+ R.drawable.accessibility_autoclick_pause);
+ mResumeButtonDrawable = mContext.getDrawable(
+ R.drawable.accessibility_autoclick_resume);
+
mContentView =
LayoutInflater.from(context)
.inflate(R.layout.accessibility_autoclick_type_panel, null);
@@ -104,6 +116,7 @@
mContentView.findViewById(R.id.accessibility_autoclick_double_click_layout);
mScrollButton = mContentView.findViewById(R.id.accessibility_autoclick_scroll_layout);
mDragButton = mContentView.findViewById(R.id.accessibility_autoclick_drag_layout);
+ mPauseButton = mContentView.findViewById(R.id.accessibility_autoclick_pause_layout);
initializeButtonState();
}
@@ -116,8 +129,7 @@
mScrollButton.setOnClickListener(v -> togglePanelExpansion(AUTOCLICK_TYPE_SCROLL));
mDragButton.setOnClickListener(v -> togglePanelExpansion(AUTOCLICK_TYPE_DRAG));
- // TODO(b/388872274): registers listener for pause button and allows users to pause/resume
- // the autoclick.
+ mPauseButton.setOnClickListener(v -> togglePause());
// TODO(b/388847771): registers listener for position button and allows users to move the
// panel to a different position.
@@ -196,6 +208,17 @@
mExpanded = !mExpanded;
}
+ private void togglePause() {
+ mPaused = !mPaused;
+
+ ImageButton imageButton = (ImageButton) mPauseButton.getChildAt(/* index= */ 0);
+ if (mPaused) {
+ imageButton.setImageDrawable(mResumeButtonDrawable);
+ } else {
+ imageButton.setImageDrawable(mPauseButtonDrawable);
+ }
+ }
+
/** Hide all buttons on the panel except pause and position buttons. */
private void hideAllClickTypeButtons() {
mLeftClickButton.setVisibility(View.GONE);
diff --git a/services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerServiceImpl.java b/services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerServiceImpl.java
index d0ee7af..5191fb5 100644
--- a/services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerServiceImpl.java
+++ b/services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerServiceImpl.java
@@ -20,6 +20,8 @@
import static android.app.appfunctions.AppFunctionRuntimeMetadata.APP_FUNCTION_RUNTIME_NAMESPACE;
import static com.android.server.appfunctions.AppFunctionExecutors.THREAD_POOL_EXECUTOR;
+import static com.android.server.appfunctions.CallerValidator.CAN_EXECUTE_APP_FUNCTIONS_ALLOWED_HAS_PERMISSION;
+import static com.android.server.appfunctions.CallerValidator.CAN_EXECUTE_APP_FUNCTIONS_DENIED;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -236,30 +238,42 @@
requestInternal.getCallingPackage(),
targetPackageName,
requestInternal.getClientRequest().getFunctionIdentifier())
- .thenAccept(
- canExecute -> {
- if (!canExecute) {
- throw new SecurityException(
- "Caller does not have permission to execute the"
- + " appfunction");
- }
- })
.thenCompose(
- isEnabled ->
- isAppFunctionEnabled(
- requestInternal.getClientRequest().getFunctionIdentifier(),
- requestInternal.getClientRequest().getTargetPackageName(),
- getAppSearchManagerAsUser(requestInternal.getUserHandle()),
- THREAD_POOL_EXECUTOR))
- .thenAccept(
- isEnabled -> {
- if (!isEnabled) {
- throw new DisabledAppFunctionException(
- "The app function is disabled");
+ canExecuteResult -> {
+ if (canExecuteResult == CAN_EXECUTE_APP_FUNCTIONS_DENIED) {
+ return AndroidFuture.failedFuture(new SecurityException(
+ "Caller does not have permission to execute the"
+ + " appfunction"));
}
+ return isAppFunctionEnabled(
+ requestInternal
+ .getClientRequest()
+ .getFunctionIdentifier(),
+ requestInternal
+ .getClientRequest()
+ .getTargetPackageName(),
+ getAppSearchManagerAsUser(
+ requestInternal.getUserHandle()),
+ THREAD_POOL_EXECUTOR)
+ .thenApply(
+ isEnabled -> {
+ if (!isEnabled) {
+ throw new DisabledAppFunctionException(
+ "The app function is disabled");
+ }
+ return canExecuteResult;
+ });
})
.thenAccept(
- unused -> {
+ canExecuteResult -> {
+ int bindFlags = Context.BIND_AUTO_CREATE;
+ if (canExecuteResult
+ == CAN_EXECUTE_APP_FUNCTIONS_ALLOWED_HAS_PERMISSION) {
+ // If the caller doesn't have the permission, do not use
+ // BIND_FOREGROUND_SERVICE to avoid it raising its process state by
+ // calling its own AppFunctions.
+ bindFlags |= Context.BIND_FOREGROUND_SERVICE;
+ }
Intent serviceIntent =
mInternalServiceHelper.resolveAppFunctionService(
targetPackageName, targetUser);
@@ -294,8 +308,7 @@
targetUser,
localCancelTransport,
safeExecuteAppFunctionCallback,
- /* bindFlags= */ Context.BIND_AUTO_CREATE
- | Context.BIND_FOREGROUND_SERVICE,
+ bindFlags,
callerBinder,
callingUid);
})
diff --git a/services/appfunctions/java/com/android/server/appfunctions/CallerValidator.java b/services/appfunctions/java/com/android/server/appfunctions/CallerValidator.java
index 98ef974..c8038a4 100644
--- a/services/appfunctions/java/com/android/server/appfunctions/CallerValidator.java
+++ b/services/appfunctions/java/com/android/server/appfunctions/CallerValidator.java
@@ -17,12 +17,16 @@
package com.android.server.appfunctions;
import android.Manifest;
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.os.UserHandle;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.infra.AndroidFuture;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
/**
* Interface for validating that the caller has the correct privilege to call an AppFunctionManager
* API.
@@ -70,7 +74,8 @@
* @param functionId The id of the app function to execute.
* @return Whether the caller can execute the specified app function.
*/
- AndroidFuture<Boolean> verifyCallerCanExecuteAppFunction(
+ @CanExecuteAppFunctionResult
+ AndroidFuture<Integer> verifyCallerCanExecuteAppFunction(
int callingUid,
int callingPid,
@NonNull UserHandle targetUser,
@@ -78,6 +83,31 @@
@NonNull String targetPackageName,
@NonNull String functionId);
+ @IntDef(
+ prefix = {"CAN_EXECUTE_APP_FUNCTIONS_"},
+ value = {
+ CAN_EXECUTE_APP_FUNCTIONS_DENIED,
+ CAN_EXECUTE_APP_FUNCTIONS_ALLOWED_SAME_PACKAGE,
+ CAN_EXECUTE_APP_FUNCTIONS_ALLOWED_HAS_PERMISSION,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ @interface CanExecuteAppFunctionResult {}
+
+ /** Callers are not allowed to execute app functions. */
+ int CAN_EXECUTE_APP_FUNCTIONS_DENIED = 0;
+
+ /**
+ * Callers can execute app functions because they are calling app functions from the same
+ * package.
+ */
+ int CAN_EXECUTE_APP_FUNCTIONS_ALLOWED_SAME_PACKAGE = 1;
+
+ /**
+ * Callers can execute app functions because they have the necessary permission.
+ * This case also applies when a caller with the permission invokes their own app functions.
+ */
+ int CAN_EXECUTE_APP_FUNCTIONS_ALLOWED_HAS_PERMISSION = 2;
+
/**
* Checks if the app function policy is allowed.
*
diff --git a/services/appfunctions/java/com/android/server/appfunctions/CallerValidatorImpl.java b/services/appfunctions/java/com/android/server/appfunctions/CallerValidatorImpl.java
index fe163d7..3f8b2e3 100644
--- a/services/appfunctions/java/com/android/server/appfunctions/CallerValidatorImpl.java
+++ b/services/appfunctions/java/com/android/server/appfunctions/CallerValidatorImpl.java
@@ -16,24 +16,12 @@
package com.android.server.appfunctions;
-import static android.app.appfunctions.AppFunctionStaticMetadataHelper.APP_FUNCTION_STATIC_METADATA_DB;
-import static android.app.appfunctions.AppFunctionStaticMetadataHelper.APP_FUNCTION_STATIC_NAMESPACE;
-import static android.app.appfunctions.AppFunctionStaticMetadataHelper.getDocumentIdForAppFunction;
-
-import static com.android.server.appfunctions.AppFunctionExecutors.THREAD_POOL_EXECUTOR;
-
import android.Manifest;
import android.annotation.BinderThread;
import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.app.admin.DevicePolicyManager;
import android.app.admin.DevicePolicyManager.AppFunctionsPolicy;
-import android.app.appsearch.AppSearchBatchResult;
-import android.app.appsearch.AppSearchManager;
-import android.app.appsearch.AppSearchManager.SearchContext;
-import android.app.appsearch.AppSearchResult;
-import android.app.appsearch.GenericDocument;
-import android.app.appsearch.GetByDocumentIdRequest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Binder;
@@ -84,64 +72,25 @@
@Override
@RequiresPermission(Manifest.permission.EXECUTE_APP_FUNCTIONS)
- public AndroidFuture<Boolean> verifyCallerCanExecuteAppFunction(
+ @CanExecuteAppFunctionResult
+ public AndroidFuture<Integer> verifyCallerCanExecuteAppFunction(
int callingUid,
int callingPid,
@NonNull UserHandle targetUser,
@NonNull String callerPackageName,
@NonNull String targetPackageName,
@NonNull String functionId) {
- if (callerPackageName.equals(targetPackageName)) {
- return AndroidFuture.completedFuture(true);
- }
-
boolean hasExecutionPermission =
mContext.checkPermission(
- Manifest.permission.EXECUTE_APP_FUNCTIONS, callingPid, callingUid)
+ Manifest.permission.EXECUTE_APP_FUNCTIONS, callingPid, callingUid)
== PackageManager.PERMISSION_GRANTED;
-
- if (!hasExecutionPermission) {
- return AndroidFuture.completedFuture(false);
+ if (hasExecutionPermission) {
+ return AndroidFuture.completedFuture(CAN_EXECUTE_APP_FUNCTIONS_ALLOWED_HAS_PERMISSION);
}
-
- FutureAppSearchSession futureAppSearchSession =
- new FutureAppSearchSessionImpl(
- Objects.requireNonNull(
- mContext.createContextAsUser(targetUser, 0)
- .getSystemService(AppSearchManager.class)),
- THREAD_POOL_EXECUTOR,
- new SearchContext.Builder(APP_FUNCTION_STATIC_METADATA_DB).build());
-
- String documentId = getDocumentIdForAppFunction(targetPackageName, functionId);
-
- return futureAppSearchSession
- .getByDocumentId(
- new GetByDocumentIdRequest.Builder(APP_FUNCTION_STATIC_NAMESPACE)
- .addIds(documentId)
- .build())
- .thenApply(
- batchResult -> getGenericDocumentFromBatchResult(batchResult, documentId))
- // At this point, already checked the app has the permission.
- .thenApply(document -> true)
- .whenComplete(
- (result, throwable) -> {
- futureAppSearchSession.close();
- });
- }
-
- private static GenericDocument getGenericDocumentFromBatchResult(
- AppSearchBatchResult<String, GenericDocument> result, String documentId) {
- if (result.isSuccess()) {
- return result.getSuccesses().get(documentId);
+ if (callerPackageName.equals(targetPackageName)) {
+ return AndroidFuture.completedFuture(CAN_EXECUTE_APP_FUNCTIONS_ALLOWED_SAME_PACKAGE);
}
-
- AppSearchResult<GenericDocument> failedResult = result.getFailures().get(documentId);
- throw new AppSearchException(
- failedResult.getResultCode(),
- "Unable to retrieve document with id: "
- + documentId
- + " due to "
- + failedResult.getErrorMessage());
+ return AndroidFuture.completedFuture(CAN_EXECUTE_APP_FUNCTIONS_DENIED);
}
@Override
diff --git a/services/appwidget/Android.bp b/services/appwidget/Android.bp
index 8119073..9548afe 100644
--- a/services/appwidget/Android.bp
+++ b/services/appwidget/Android.bp
@@ -17,6 +17,12 @@
java_library_static {
name: "services.appwidget",
defaults: ["platform_service_defaults"],
- srcs: [":services.appwidget-sources"],
- libs: ["services.core"],
+ srcs: [
+ ":services.appwidget-sources",
+ ":statslog-framework-java-gen",
+ ],
+ libs: [
+ "androidx.annotation_annotation",
+ "services.core",
+ ],
}
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index e0f2939..74a87ed 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -50,6 +50,7 @@
import android.app.IServiceConnection;
import android.app.KeyguardManager;
import android.app.PendingIntent;
+import android.app.StatsManager;
import android.app.admin.DevicePolicyManagerInternal;
import android.app.admin.DevicePolicyManagerInternal.OnCrossProfileWidgetProvidersChangeListener;
import android.app.usage.Flags;
@@ -124,6 +125,7 @@
import android.util.SparseBooleanArray;
import android.util.SparseIntArray;
import android.util.SparseLongArray;
+import android.util.StatsEvent;
import android.util.TypedValue;
import android.util.Xml;
import android.util.proto.ProtoInputStream;
@@ -145,6 +147,7 @@
import com.android.internal.os.SomeArgs;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.DumpUtils;
+import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.widget.IRemoteViewsFactory;
import com.android.modules.utils.TypedXmlPullParser;
import com.android.modules.utils.TypedXmlSerializer;
@@ -433,6 +436,44 @@
mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
mAppOpsManagerInternal = LocalServices.getService(AppOpsManagerInternal.class);
mUsageStatsManagerInternal = LocalServices.getService(UsageStatsManagerInternal.class);
+ registerPullCallbacks();
+ }
+
+ /**
+ * Register callbacks for pull atoms.
+ */
+ private void registerPullCallbacks() {
+ final StatsManager manager = mContext.getSystemService(StatsManager.class);
+ manager.setPullAtomCallback(FrameworkStatsLog.WIDGET_MEMORY_STATS,
+ new StatsManager.PullAtomMetadata.Builder().build(),
+ new HandlerExecutor(mCallbackHandler), this::onPullAtom);
+ }
+
+ /**
+ * Callback from StatsManager to log events indicated by the atomTag. This function will add
+ * the relevant events to the data list.
+ *
+ * @return PULL_SUCCESS if the pull was successful and events should be used, else PULL_SKIP.
+ */
+ private int onPullAtom(int atomTag, @NonNull List<StatsEvent> data) {
+ if (atomTag == FrameworkStatsLog.WIDGET_MEMORY_STATS) {
+ synchronized (mLock) {
+ for (Widget widget : mWidgets) {
+ if (widget.views != null) {
+ final int uid = widget.provider.id.uid;
+ final int appWidgetId = widget.appWidgetId;
+ final long bitmapMemoryUsage =
+ widget.views.estimateTotalBitmapMemoryUsage();
+ StatsEvent event = FrameworkStatsLog.buildStatsEvent(
+ FrameworkStatsLog.WIDGET_MEMORY_STATS, uid, appWidgetId,
+ bitmapMemoryUsage);
+ data.add(event);
+ }
+ }
+ }
+ return StatsManager.PULL_SUCCESS;
+ }
+ return StatsManager.PULL_SKIP;
}
/**
diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
index f03e8c7..28efdfc 100644
--- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
+++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
@@ -163,6 +163,16 @@
*/
private static final long PENDING_TRAMPOLINE_TIMEOUT_MS = 5000;
+ /**
+ * Global lock for this Virtual Device.
+ *
+ * Never call outside this class while holding this lock. A number of other system services like
+ * WindowManager, DisplayManager, etc. call into this device to get device-specific information,
+ * while holding their own global locks.
+ *
+ * Making a call to another service while holding this lock creates lock order inversion and
+ * will potentially cause a deadlock.
+ */
private final Object mVirtualDeviceLock = new Object();
private final int mBaseVirtualDisplayFlags;
@@ -179,14 +189,6 @@
private final int mDeviceId;
@Nullable
private final String mPersistentDeviceId;
- // Thou shall not hold the mVirtualDeviceLock over the mInputController calls.
- // Holding the lock can lead to lock inversion with GlobalWindowManagerLock.
- // 1. After display is created the window manager calls into VDM during construction
- // of display specific context to fetch device id corresponding to the display.
- // mVirtualDeviceLock will be held while this is done.
- // 2. InputController interactions result in calls to DisplayManager (to set IME,
- // possibly more indirect calls), and those attempt to lock GlobalWindowManagerLock which
- // creates lock inversion.
private final InputController mInputController;
private final SensorController mSensorController;
private final CameraAccessController mCameraAccessController;
@@ -205,19 +207,23 @@
private final DisplayManagerGlobal mDisplayManager;
private final DisplayManagerInternal mDisplayManagerInternal;
private final PowerManager mPowerManager;
- @GuardedBy("mVirtualDeviceLock")
+ @GuardedBy("mIntentInterceptors")
private final Map<IBinder, IntentFilter> mIntentInterceptors = new ArrayMap<>();
@NonNull
private final Consumer<ArraySet<Integer>> mRunningAppsChangedCallback;
+
// The default setting for showing the pointer on new displays.
@GuardedBy("mVirtualDeviceLock")
private boolean mDefaultShowPointerIcon = true;
@GuardedBy("mVirtualDeviceLock")
@Nullable
private LocaleList mLocaleList = null;
- @GuardedBy("mVirtualDeviceLock")
+
+ // Lock for power operations for this virtual device that allow calling PowerManager.
+ private final Object mPowerLock = new Object();
+ @GuardedBy("mPowerLock")
private boolean mLockdownActive = false;
- @GuardedBy("mVirtualDeviceLock")
+ @GuardedBy("mPowerLock")
private boolean mRequestedToBeAwake = true;
@NonNull
@@ -334,7 +340,7 @@
*/
@Override
public boolean shouldInterceptIntent(@NonNull Intent intent) {
- synchronized (mVirtualDeviceLock) {
+ synchronized (mIntentInterceptors) {
boolean hasInterceptedIntent = false;
for (Map.Entry<IBinder, IntentFilter> interceptor
: mIntentInterceptors.entrySet()) {
@@ -500,7 +506,7 @@
}
void onLockdownChanged(boolean lockdownActive) {
- synchronized (mVirtualDeviceLock) {
+ synchronized (mPowerLock) {
if (lockdownActive != mLockdownActive) {
mLockdownActive = lockdownActive;
if (mLockdownActive) {
@@ -610,7 +616,7 @@
@Override // Binder call
public void goToSleep() {
checkCallerIsDeviceOwner();
- synchronized (mVirtualDeviceLock) {
+ synchronized (mPowerLock) {
mRequestedToBeAwake = false;
}
final long ident = Binder.clearCallingIdentity();
@@ -624,7 +630,7 @@
@Override // Binder call
public void wakeUp() {
checkCallerIsDeviceOwner();
- synchronized (mVirtualDeviceLock) {
+ synchronized (mPowerLock) {
mRequestedToBeAwake = true;
if (mLockdownActive) {
Slog.w(TAG, "Cannot wake up device during lockdown.");
@@ -850,8 +856,8 @@
checkDisplayOwnedByVirtualDeviceLocked(displayId);
if (mVirtualAudioController == null) {
mVirtualAudioController = new VirtualAudioController(mContext, mAttributionSource);
- GenericWindowPolicyController gwpc = mVirtualDisplays.get(
- displayId).getWindowPolicyController();
+ GenericWindowPolicyController gwpc =
+ mVirtualDisplays.get(displayId).getWindowPolicyController();
mVirtualAudioController.startListening(gwpc, routingCallback,
configChangedCallback);
}
@@ -1293,7 +1299,7 @@
checkCallerIsDeviceOwner();
Objects.requireNonNull(intentInterceptor);
Objects.requireNonNull(filter);
- synchronized (mVirtualDeviceLock) {
+ synchronized (mIntentInterceptors) {
mIntentInterceptors.put(intentInterceptor.asBinder(), filter);
}
}
@@ -1303,7 +1309,7 @@
@NonNull IVirtualDeviceIntentInterceptor intentInterceptor) {
checkCallerIsDeviceOwner();
Objects.requireNonNull(intentInterceptor);
- synchronized (mVirtualDeviceLock) {
+ synchronized (mIntentInterceptors) {
mIntentInterceptors.remove(intentInterceptor.asBinder());
}
}
@@ -1653,6 +1659,7 @@
void goToSleepInternal(@PowerManager.GoToSleepReason int reason) {
final long now = SystemClock.uptimeMillis();
+ IntArray displayIds = new IntArray();
synchronized (mVirtualDeviceLock) {
for (int i = 0; i < mVirtualDisplays.size(); i++) {
VirtualDisplayWrapper wrapper = mVirtualDisplays.valueAt(i);
@@ -1660,13 +1667,17 @@
continue;
}
int displayId = mVirtualDisplays.keyAt(i);
- mPowerManager.goToSleep(displayId, now, reason, /* flags= */ 0);
+ displayIds.add(displayId);
}
}
+ for (int i = 0; i < displayIds.size(); ++i) {
+ mPowerManager.goToSleep(displayIds.get(i), now, reason, /* flags= */ 0);
+ }
}
void wakeUpInternal(@PowerManager.WakeReason int reason, String details) {
final long now = SystemClock.uptimeMillis();
+ IntArray displayIds = new IntArray();
synchronized (mVirtualDeviceLock) {
for (int i = 0; i < mVirtualDisplays.size(); i++) {
VirtualDisplayWrapper wrapper = mVirtualDisplays.valueAt(i);
@@ -1674,9 +1685,12 @@
continue;
}
int displayId = mVirtualDisplays.keyAt(i);
- mPowerManager.wakeUp(now, reason, details, displayId);
+ displayIds.add(displayId);
}
}
+ for (int i = 0; i < displayIds.size(); ++i) {
+ mPowerManager.wakeUp(now, reason, details, displayIds.get(i));
+ }
}
/**
diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
index ff82ca0..139bbae 100644
--- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
@@ -117,7 +117,18 @@
*/
static final int CDM_ASSOCIATION_ID_NONE = 0;
+ /**
+ * Global VDM lock.
+ *
+ * Never call outside this class while holding this lock. A number of other system services like
+ * WindowManager, DisplayManager, etc. call into VDM to get device-specific information, while
+ * holding their own global locks.
+ *
+ * Making a call to another service while holding this lock creates lock order inversion and
+ * will potentially cause a deadlock.
+ */
private final Object mVirtualDeviceManagerLock = new Object();
+
private final VirtualDeviceManagerImpl mImpl;
private final VirtualDeviceManagerNativeImpl mNativeImpl;
private final VirtualDeviceManagerInternal mLocalService;
@@ -235,10 +246,9 @@
// Called when the global lockdown state changes, i.e. lockdown is considered active if any user
// is in lockdown mode, and inactive if no users are in lockdown mode.
void onLockdownChanged(boolean lockdownActive) {
- synchronized (mVirtualDeviceManagerLock) {
- for (int i = 0; i < mVirtualDevices.size(); i++) {
- mVirtualDevices.valueAt(i).onLockdownChanged(lockdownActive);
- }
+ ArrayList<VirtualDeviceImpl> virtualDevicesSnapshot = getVirtualDevicesSnapshot();
+ for (int i = 0; i < virtualDevicesSnapshot.size(); i++) {
+ virtualDevicesSnapshot.get(i).onLockdownChanged(lockdownActive);
}
}
@@ -264,16 +274,14 @@
return null;
}
int userId = userHandle.getIdentifier();
- synchronized (mVirtualDeviceManagerLock) {
- for (int i = 0; i < mVirtualDevices.size(); i++) {
- final CameraAccessController cameraAccessController =
- mVirtualDevices.valueAt(i).getCameraAccessController();
- if (cameraAccessController.getUserId() == userId) {
- return cameraAccessController;
- }
+ ArrayList<VirtualDeviceImpl> virtualDevicesSnapshot = getVirtualDevicesSnapshot();
+ for (int i = 0; i < virtualDevicesSnapshot.size(); i++) {
+ final CameraAccessController cameraAccessController =
+ virtualDevicesSnapshot.get(i).getCameraAccessController();
+ if (cameraAccessController.getUserId() == userId) {
+ return cameraAccessController;
}
- }
- Context userContext = getContext().createContextAsUser(userHandle, 0);
+ } Context userContext = getContext().createContextAsUser(userHandle, 0);
return new CameraAccessController(userContext, mLocalService, this::onCameraAccessBlocked);
}
@@ -520,11 +528,10 @@
@Override // Binder call
public List<VirtualDevice> getVirtualDevices() {
List<VirtualDevice> virtualDevices = new ArrayList<>();
- synchronized (mVirtualDeviceManagerLock) {
- for (int i = 0; i < mVirtualDevices.size(); i++) {
- final VirtualDeviceImpl device = mVirtualDevices.valueAt(i);
- virtualDevices.add(device.getPublicVirtualDeviceObject());
- }
+ ArrayList<VirtualDeviceImpl> virtualDevicesSnapshot = getVirtualDevicesSnapshot();
+ for (int i = 0; i < virtualDevicesSnapshot.size(); i++) {
+ VirtualDeviceImpl device = virtualDevicesSnapshot.get(i);
+ virtualDevices.add(device.getPublicVirtualDeviceObject());
}
return virtualDevices;
}
@@ -834,15 +841,17 @@
@Nullable
public LocaleList getPreferredLocaleListForUid(int uid) {
// TODO: b/263188984 support the case where an app is running on multiple VDs
+ VirtualDeviceImpl virtualDevice = null;
synchronized (mVirtualDeviceManagerLock) {
for (int i = 0; i < mAppsOnVirtualDevices.size(); i++) {
if (mAppsOnVirtualDevices.valueAt(i).contains(uid)) {
int deviceId = mAppsOnVirtualDevices.keyAt(i);
- return mVirtualDevices.get(deviceId).getDeviceLocaleList();
+ virtualDevice = mVirtualDevices.get(deviceId);
+ break;
}
}
}
- return null;
+ return virtualDevice == null ? null : virtualDevice.getDeviceLocaleList();
}
@Override
diff --git a/services/contextualsearch/java/com/android/server/contextualsearch/ContextualSearchManagerService.java b/services/contextualsearch/java/com/android/server/contextualsearch/ContextualSearchManagerService.java
index 700a162..d8e10f8 100644
--- a/services/contextualsearch/java/com/android/server/contextualsearch/ContextualSearchManagerService.java
+++ b/services/contextualsearch/java/com/android/server/contextualsearch/ContextualSearchManagerService.java
@@ -38,7 +38,6 @@
import android.app.ActivityManagerInternal;
import android.app.ActivityOptions;
import android.app.AppOpsManager;
-import android.app.admin.DevicePolicyManagerInternal;
import android.app.assist.AssistContent;
import android.app.assist.AssistStructure;
import android.app.contextualsearch.CallbackToken;
@@ -67,6 +66,7 @@
import android.os.ServiceManager;
import android.os.ShellCallback;
import android.os.SystemClock;
+import android.os.UserManager;
import android.provider.Settings;
import android.util.Log;
import android.util.Slog;
@@ -112,8 +112,8 @@
private final ActivityTaskManagerInternal mAtmInternal;
private final PackageManagerInternal mPackageManager;
private final WindowManagerInternal mWmInternal;
- private final DevicePolicyManagerInternal mDpmInternal;
private final AudioManager mAudioManager;
+ private final UserManager mUserManager;
private final Object mLock = new Object();
private final AssistDataRequester mAssistDataRequester;
@@ -179,9 +179,9 @@
LocalServices.getService(ActivityTaskManagerInternal.class));
mPackageManager = LocalServices.getService(PackageManagerInternal.class);
mAudioManager = context.getSystemService(AudioManager.class);
+ mUserManager = context.getSystemService(UserManager.class);
mWmInternal = Objects.requireNonNull(LocalServices.getService(WindowManagerInternal.class));
- mDpmInternal = LocalServices.getService(DevicePolicyManagerInternal.class);
mAssistDataRequester = new AssistDataRequester(
mContext,
IWindowManager.Stub.asInterface(ServiceManager.getService(Context.WINDOW_SERVICE)),
@@ -308,6 +308,11 @@
}
}
+ @RequiresPermission(anyOf = {
+ android.Manifest.permission.MANAGE_USERS,
+ android.Manifest.permission.CREATE_USERS,
+ android.Manifest.permission.QUERY_USERS
+ })
private Intent getContextualSearchIntent(int entrypoint, int userId, CallbackToken mToken) {
final Intent launchIntent = getResolvedLaunchIntent(userId);
if (launchIntent == null) {
@@ -338,8 +343,7 @@
visiblePackageNames.add(record.getComponentName().getPackageName());
activityTokens.add(record.getActivityToken());
}
- if (mDpmInternal != null
- && mDpmInternal.isUserOrganizationManaged(record.getUserId())) {
+ if (mUserManager.isManagedProfile(record.getUserId())) {
isManagedProfileVisible = true;
}
}
@@ -507,7 +511,10 @@
Intent launchIntent = getContextualSearchIntent(entrypoint, callingUserId, mToken);
if (launchIntent != null) {
int result = invokeContextualSearchIntent(launchIntent, callingUserId);
- if (DEBUG) Log.d(TAG, "Launch result: " + result);
+ if (DEBUG) {
+ Log.d(TAG, "Launch intent: " + launchIntent);
+ Log.d(TAG, "Launch result: " + result);
+ }
}
});
}
diff --git a/services/core/java/com/android/server/SensitiveContentProtectionManagerService.java b/services/core/java/com/android/server/SensitiveContentProtectionManagerService.java
index 04edb57..cd632e6 100644
--- a/services/core/java/com/android/server/SensitiveContentProtectionManagerService.java
+++ b/services/core/java/com/android/server/SensitiveContentProtectionManagerService.java
@@ -31,6 +31,8 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.role.RoleManager;
+import android.companion.AssociationRequest;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageManager;
@@ -81,6 +83,8 @@
private PackageManagerInternal mPackageManagerInternal;
+ private RoleManager mRoleManager;
+
@Nullable
private WindowManagerInternal mWindowManager;
@@ -225,7 +229,8 @@
}
@Override
- public void onStart() {}
+ public void onStart() {
+ }
@Override
public void onBootPhase(int phase) {
@@ -237,6 +242,7 @@
init(getContext().getSystemService(MediaProjectionManager.class),
LocalServices.getService(WindowManagerInternal.class),
LocalServices.getService(PackageManagerInternal.class),
+ getContext().getSystemService(RoleManager.class),
getExemptedPackages()
);
if (sensitiveContentAppProtection()) {
@@ -247,7 +253,8 @@
@VisibleForTesting
void init(MediaProjectionManager projectionManager, WindowManagerInternal windowManager,
- PackageManagerInternal packageManagerInternal, ArraySet<String> exemptedPackages) {
+ PackageManagerInternal packageManagerInternal, RoleManager roleManager,
+ ArraySet<String> exemptedPackages) {
if (DEBUG) Log.d(TAG, "init");
Objects.requireNonNull(projectionManager);
@@ -256,6 +263,7 @@
mProjectionManager = projectionManager;
mWindowManager = windowManager;
mPackageManagerInternal = packageManagerInternal;
+ mRoleManager = roleManager;
mExemptedPackages = exemptedPackages;
// TODO(b/317250444): use MediaProjectionManagerService directly, reduces unnecessary
@@ -312,8 +320,10 @@
boolean isPackageExempted = (mExemptedPackages != null && mExemptedPackages.contains(
projectionInfo.getPackageName()))
|| canRecordSensitiveContent(projectionInfo.getPackageName())
+ || holdsAppStreamingRole(projectionInfo.getPackageName(),
+ projectionInfo.getUserHandle())
|| isAutofillServiceRecorderPackage(projectionInfo.getUserHandle().getIdentifier(),
- projectionInfo.getPackageName());
+ projectionInfo.getPackageName());
// TODO(b/324447419): move GlobalSettings lookup to background thread
boolean isFeatureDisabled = Settings.Global.getInt(getContext().getContentResolver(),
DISABLE_SCREEN_SHARE_PROTECTIONS_FOR_APPS_AND_NOTIFICATIONS, 0) != 0;
@@ -348,6 +358,11 @@
}
}
+ private boolean holdsAppStreamingRole(String packageName, UserHandle userHandle) {
+ return mRoleManager.getRoleHoldersAsUser(
+ AssociationRequest.DEVICE_PROFILE_APP_STREAMING, userHandle).contains(packageName);
+ }
+
private void onProjectionEnd() {
synchronized (mSensitiveContentProtectionLock) {
mProjectionActive = false;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 6e3d7bd..07a4d52 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -301,6 +301,7 @@
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.SharedLibraryInfo;
+import android.content.pm.SystemFeaturesCache;
import android.content.pm.TestUtilityService;
import android.content.pm.UserInfo;
import android.content.pm.UserProperties;
@@ -2559,9 +2560,20 @@
mTraceErrorLogger = new TraceErrorLogger();
mComponentAliasResolver = new ComponentAliasResolver(this);
sCreatorTokenCacheCleaner = new Handler(mHandlerThread.getLooper());
+
+ ApplicationSharedMemory applicationSharedMemory = ApplicationSharedMemory.getInstance();
+ if (android.content.pm.Flags.cacheSdkSystemFeatures()) {
+ // Install the cache into the process-wide singleton for in-proc queries, as well as
+ // shared memory. Apps will inflate the cache from shared memory in bindApplication.
+ SystemFeaturesCache systemFeaturesCache =
+ new SystemFeaturesCache(SystemConfig.getInstance().getAvailableFeatures());
+ SystemFeaturesCache.setInstance(systemFeaturesCache);
+ applicationSharedMemory.writeSystemFeaturesCache(
+ systemFeaturesCache.getSdkFeatureVersions());
+ }
try {
mApplicationSharedMemoryReadOnlyFd =
- ApplicationSharedMemory.getInstance().getReadOnlyFileDescriptor();
+ applicationSharedMemory.getReadOnlyFileDescriptor();
} catch (IOException e) {
Slog.e(TAG, "Failed to get read only fd for shared memory", e);
throw new RuntimeException(e);
diff --git a/services/core/java/com/android/server/am/AppStartInfoTracker.java b/services/core/java/com/android/server/am/AppStartInfoTracker.java
index 961022b..517279b 100644
--- a/services/core/java/com/android/server/am/AppStartInfoTracker.java
+++ b/services/core/java/com/android/server/am/AppStartInfoTracker.java
@@ -54,15 +54,21 @@
import com.android.internal.app.ProcessMap;
import com.android.internal.os.Clock;
import com.android.internal.os.MonotonicClock;
+import com.android.modules.utils.TypedXmlPullParser;
+import com.android.modules.utils.TypedXmlSerializer;
import com.android.server.IoThread;
import com.android.server.ServiceThread;
import com.android.server.SystemServiceManager;
import com.android.server.wm.WindowProcessController;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
@@ -1006,6 +1012,12 @@
throws IOException, WireTypeMismatchException, ClassNotFoundException {
long token = proto.start(fieldId);
String pkgName = "";
+
+ // Create objects for reuse.
+ ByteArrayInputStream byteArrayInputStream = null;
+ ObjectInputStream objectInputStream = null;
+ TypedXmlPullParser typedXmlPullParser = null;
+
for (int next = proto.nextField();
next != ProtoInputStream.NO_MORE_FIELDS;
next = proto.nextField()) {
@@ -1017,7 +1029,7 @@
AppStartInfoContainer container =
new AppStartInfoContainer(mAppStartInfoHistoryListSize);
int uid = container.readFromProto(proto, AppsStartInfoProto.Package.USERS,
- pkgName);
+ pkgName, byteArrayInputStream, objectInputStream, typedXmlPullParser);
// If the isolated process flag is enabled and the uid is that of an isolated
// process, then break early so that the container will not be added to mData.
@@ -1052,6 +1064,12 @@
out = af.startWrite();
ProtoOutputStream proto = new ProtoOutputStream(out);
proto.write(AppsStartInfoProto.LAST_UPDATE_TIMESTAMP, now);
+
+ // Create objects for reuse.
+ ByteArrayOutputStream byteArrayOutputStream = null;
+ ObjectOutputStream objectOutputStream = null;
+ TypedXmlSerializer typedXmlSerializer = null;
+
synchronized (mLock) {
succeeded = forEachPackageLocked(
(packageName, records) -> {
@@ -1060,8 +1078,9 @@
int uidArraySize = records.size();
for (int j = 0; j < uidArraySize; j++) {
try {
- records.valueAt(j)
- .writeToProto(proto, AppsStartInfoProto.Package.USERS);
+ records.valueAt(j).writeToProto(proto,
+ AppsStartInfoProto.Package.USERS, byteArrayOutputStream,
+ objectOutputStream, typedXmlSerializer);
} catch (IOException e) {
Slog.w(TAG, "Unable to write app start info into persistent"
+ "storage: " + e);
@@ -1414,19 +1433,23 @@
}
@GuardedBy("mLock")
- void writeToProto(ProtoOutputStream proto, long fieldId) throws IOException {
+ void writeToProto(ProtoOutputStream proto, long fieldId,
+ ByteArrayOutputStream byteArrayOutputStream, ObjectOutputStream objectOutputStream,
+ TypedXmlSerializer typedXmlSerializer) throws IOException {
long token = proto.start(fieldId);
proto.write(AppsStartInfoProto.Package.User.UID, mUid);
int size = mInfos.size();
for (int i = 0; i < size; i++) {
- mInfos.get(i)
- .writeToProto(proto, AppsStartInfoProto.Package.User.APP_START_INFO);
+ mInfos.get(i).writeToProto(proto, AppsStartInfoProto.Package.User.APP_START_INFO,
+ byteArrayOutputStream, objectOutputStream, typedXmlSerializer);
}
proto.write(AppsStartInfoProto.Package.User.MONITORING_ENABLED, mMonitoringModeEnabled);
proto.end(token);
}
- int readFromProto(ProtoInputStream proto, long fieldId, String packageName)
+ int readFromProto(ProtoInputStream proto, long fieldId, String packageName,
+ ByteArrayInputStream byteArrayInputStream, ObjectInputStream objectInputStream,
+ TypedXmlPullParser typedXmlPullParser)
throws IOException, WireTypeMismatchException, ClassNotFoundException {
long token = proto.start(fieldId);
for (int next = proto.nextField();
@@ -1440,7 +1463,8 @@
// Create record with monotonic time 0 in case the persisted record does not
// have a create time.
ApplicationStartInfo info = new ApplicationStartInfo(0);
- info.readFromProto(proto, AppsStartInfoProto.Package.User.APP_START_INFO);
+ info.readFromProto(proto, AppsStartInfoProto.Package.User.APP_START_INFO,
+ byteArrayInputStream, objectInputStream, typedXmlPullParser);
info.setPackageName(packageName);
mInfos.add(info);
break;
diff --git a/services/core/java/com/android/server/appop/DiscreteOpsSqlRegistry.java b/services/core/java/com/android/server/appop/DiscreteOpsSqlRegistry.java
index 30c2a82..604cb30 100644
--- a/services/core/java/com/android/server/appop/DiscreteOpsSqlRegistry.java
+++ b/services/core/java/com/android/server/appop/DiscreteOpsSqlRegistry.java
@@ -418,7 +418,9 @@
evictedEvents.addAll(mCache);
mCache.clear();
}
- mSqliteWriteHandler.obtainMessage(WRITE_CACHE_EVICTED_OP_EVENTS, evictedEvents);
+ Message msg = mSqliteWriteHandler.obtainMessage(
+ WRITE_CACHE_EVICTED_OP_EVENTS, evictedEvents);
+ mSqliteWriteHandler.sendMessage(msg);
}
}
}
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index 6d6e1fb..ef80d59 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -18,6 +18,7 @@
import static android.media.audio.Flags.scoManagedByAudio;
import static com.android.media.audio.Flags.equalScoLeaVcIndexRange;
+import static com.android.media.audio.Flags.optimizeBtDeviceSwitch;
import static com.android.server.audio.AudioService.BT_COMM_DEVICE_ACTIVE_BLE_HEADSET;
import static com.android.server.audio.AudioService.BT_COMM_DEVICE_ACTIVE_BLE_SPEAKER;
import static com.android.server.audio.AudioService.BT_COMM_DEVICE_ACTIVE_SCO;
@@ -290,8 +291,8 @@
}
@GuardedBy("mDeviceStateLock")
- /*package*/ void onSetBtScoActiveDevice(BluetoothDevice btDevice) {
- mBtHelper.onSetBtScoActiveDevice(btDevice);
+ /*package*/ void onSetBtScoActiveDevice(BluetoothDevice btDevice, boolean deviceSwitch) {
+ mBtHelper.onSetBtScoActiveDevice(btDevice, deviceSwitch);
}
/*package*/ void setBluetoothA2dpOn_Async(boolean on, String source) {
@@ -941,6 +942,7 @@
final @NonNull String mEventSource;
final int mAudioSystemDevice;
final int mMusicDevice;
+ final boolean mIsDeviceSwitch;
BtDeviceInfo(@NonNull BtDeviceChangedData d, @NonNull BluetoothDevice device, int state,
int audioDevice, @AudioSystem.AudioFormatNativeEnumForBtCodec int codec) {
@@ -953,6 +955,8 @@
mEventSource = d.mEventSource;
mAudioSystemDevice = audioDevice;
mMusicDevice = AudioSystem.DEVICE_NONE;
+ mIsDeviceSwitch = optimizeBtDeviceSwitch()
+ && d.mNewDevice != null && d.mPreviousDevice != null;
}
// constructor used by AudioDeviceBroker to search similar message
@@ -966,6 +970,7 @@
mSupprNoisy = false;
mVolume = -1;
mIsLeOutput = false;
+ mIsDeviceSwitch = false;
}
// constructor used by AudioDeviceInventory when config change failed
@@ -980,6 +985,7 @@
mSupprNoisy = false;
mVolume = -1;
mIsLeOutput = false;
+ mIsDeviceSwitch = false;
}
BtDeviceInfo(@NonNull BtDeviceInfo src, int state) {
@@ -992,6 +998,7 @@
mEventSource = src.mEventSource;
mAudioSystemDevice = src.mAudioSystemDevice;
mMusicDevice = src.mMusicDevice;
+ mIsDeviceSwitch = false;
}
// redefine equality op so we can match messages intended for this device
@@ -1026,7 +1033,8 @@
+ " isLeOutput=" + mIsLeOutput
+ " eventSource=" + mEventSource
+ " audioSystemDevice=" + mAudioSystemDevice
- + " musicDevice=" + mMusicDevice;
+ + " musicDevice=" + mMusicDevice
+ + " isDeviceSwitch=" + mIsDeviceSwitch;
}
}
@@ -1196,6 +1204,8 @@
AudioSystem.setParameters("A2dpSuspended=true");
AudioSystem.setParameters("LeAudioSuspended=true");
AudioSystem.setParameters("BT_SCO=on");
+ mBluetoothA2dpSuspendedApplied = true;
+ mBluetoothLeSuspendedApplied = true;
} else {
AudioSystem.setParameters("BT_SCO=off");
if (mBluetoothA2dpSuspendedApplied) {
@@ -1680,10 +1690,11 @@
}
/*package*/ boolean handleDeviceConnection(@NonNull AudioDeviceAttributes attributes,
- boolean connect, @Nullable BluetoothDevice btDevice) {
+ boolean connect, @Nullable BluetoothDevice btDevice,
+ boolean deviceSwitch) {
synchronized (mDeviceStateLock) {
return mDeviceInventory.handleDeviceConnection(
- attributes, connect, false /*for test*/, btDevice);
+ attributes, connect, false /*for test*/, btDevice, deviceSwitch);
}
}
@@ -1776,6 +1787,18 @@
pw.println("\n" + prefix + "mScoManagedByAudio: " + mScoManagedByAudio);
+ pw.println("\n" + prefix + "Bluetooth SCO on"
+ + ", requested: " + mBluetoothScoOn
+ + ", applied: " + mBluetoothScoOnApplied);
+ pw.println("\n" + prefix + "Bluetooth A2DP suspended"
+ + ", requested ext: " + mBluetoothA2dpSuspendedExt
+ + ", requested int: " + mBluetoothA2dpSuspendedInt
+ + ", applied " + mBluetoothA2dpSuspendedApplied);
+ pw.println("\n" + prefix + "Bluetooth LE Audio suspended"
+ + ", requested ext: " + mBluetoothLeSuspendedExt
+ + ", requested int: " + mBluetoothLeSuspendedInt
+ + ", applied " + mBluetoothLeSuspendedApplied);
+
mBtHelper.dump(pw, prefix);
}
@@ -1930,10 +1953,12 @@
|| btInfo.mIsLeOutput)
? mAudioService.getBluetoothContextualVolumeStream()
: AudioSystem.STREAM_DEFAULT);
- if (btInfo.mProfile == BluetoothProfile.LE_AUDIO
+ if ((btInfo.mProfile == BluetoothProfile.LE_AUDIO
|| btInfo.mProfile == BluetoothProfile.HEARING_AID
|| (mScoManagedByAudio
- && btInfo.mProfile == BluetoothProfile.HEADSET)) {
+ && btInfo.mProfile == BluetoothProfile.HEADSET))
+ && (btInfo.mState == BluetoothProfile.STATE_CONNECTED
+ || !btInfo.mIsDeviceSwitch)) {
onUpdateCommunicationRouteClient(
bluetoothScoRequestOwnerAttributionSource(),
"setBluetoothActiveDevice");
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index ef10793..ae91934 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -799,7 +799,7 @@
di.mDeviceAddress,
di.mDeviceName),
AudioSystem.DEVICE_STATE_AVAILABLE,
- di.mDeviceCodecFormat);
+ di.mDeviceCodecFormat, false /*deviceSwitch*/);
if (asDeviceConnectionFailure() && res != AudioSystem.AUDIO_STATUS_OK) {
failedReconnectionDeviceList.add(di);
}
@@ -811,7 +811,7 @@
EventLogger.Event.ALOGE, TAG);
mConnectedDevices.remove(di.getKey(), di);
if (AudioSystem.isBluetoothScoDevice(di.mDeviceType)) {
- mDeviceBroker.onSetBtScoActiveDevice(null);
+ mDeviceBroker.onSetBtScoActiveDevice(null, false /*deviceSwitch*/);
}
}
}
@@ -851,7 +851,8 @@
Log.d(TAG, "onSetBtActiveDevice"
+ " btDevice=" + btInfo.mDevice
+ " profile=" + BluetoothProfile.getProfileName(btInfo.mProfile)
- + " state=" + BluetoothProfile.getConnectionStateName(btInfo.mState));
+ + " state=" + BluetoothProfile.getConnectionStateName(btInfo.mState)
+ + " isDeviceSwitch=" + btInfo.mIsDeviceSwitch);
}
String address = btInfo.mDevice.getAddress();
if (!BluetoothAdapter.checkBluetoothAddress(address)) {
@@ -897,7 +898,8 @@
break;
case BluetoothProfile.A2DP:
if (switchToUnavailable) {
- makeA2dpDeviceUnavailableNow(address, di.mDeviceCodecFormat);
+ makeA2dpDeviceUnavailableNow(address, di.mDeviceCodecFormat,
+ btInfo.mIsDeviceSwitch);
} else if (switchToAvailable) {
// device is not already connected
if (btInfo.mVolume != -1) {
@@ -911,7 +913,7 @@
break;
case BluetoothProfile.HEARING_AID:
if (switchToUnavailable) {
- makeHearingAidDeviceUnavailable(address);
+ makeHearingAidDeviceUnavailable(address, btInfo.mIsDeviceSwitch);
} else if (switchToAvailable) {
makeHearingAidDeviceAvailable(address, BtHelper.getName(btInfo.mDevice),
streamType, "onSetBtActiveDevice");
@@ -921,7 +923,8 @@
case BluetoothProfile.LE_AUDIO_BROADCAST:
if (switchToUnavailable) {
makeLeAudioDeviceUnavailableNow(address,
- btInfo.mAudioSystemDevice, di.mDeviceCodecFormat);
+ btInfo.mAudioSystemDevice, di.mDeviceCodecFormat,
+ btInfo.mIsDeviceSwitch);
} else if (switchToAvailable) {
makeLeAudioDeviceAvailable(
btInfo, streamType, codec, "onSetBtActiveDevice");
@@ -930,9 +933,10 @@
case BluetoothProfile.HEADSET:
if (mDeviceBroker.isScoManagedByAudio()) {
if (switchToUnavailable) {
- mDeviceBroker.onSetBtScoActiveDevice(null);
+ mDeviceBroker.onSetBtScoActiveDevice(null, btInfo.mIsDeviceSwitch);
} else if (switchToAvailable) {
- mDeviceBroker.onSetBtScoActiveDevice(btInfo.mDevice);
+ mDeviceBroker.onSetBtScoActiveDevice(
+ btInfo.mDevice, false /*deviceSwitch*/);
}
}
break;
@@ -1053,19 +1057,19 @@
/*package*/ void onMakeA2dpDeviceUnavailableNow(String address, int a2dpCodec) {
synchronized (mDevicesLock) {
- makeA2dpDeviceUnavailableNow(address, a2dpCodec);
+ makeA2dpDeviceUnavailableNow(address, a2dpCodec, false /*deviceSwitch*/);
}
}
/*package*/ void onMakeLeAudioDeviceUnavailableNow(String address, int device, int codec) {
synchronized (mDevicesLock) {
- makeLeAudioDeviceUnavailableNow(address, device, codec);
+ makeLeAudioDeviceUnavailableNow(address, device, codec, false /*deviceSwitch*/);
}
}
/*package*/ void onMakeHearingAidDeviceUnavailableNow(String address) {
synchronized (mDevicesLock) {
- makeHearingAidDeviceUnavailable(address);
+ makeHearingAidDeviceUnavailable(address, false /*deviceSwitch*/);
}
}
@@ -1180,7 +1184,8 @@
}
if (!handleDeviceConnection(wdcs.mAttributes,
- wdcs.mState == AudioService.CONNECTION_STATE_CONNECTED, wdcs.mForTest, null)) {
+ wdcs.mState == AudioService.CONNECTION_STATE_CONNECTED, wdcs.mForTest,
+ null, false /*deviceSwitch*/)) {
// change of connection state failed, bailout
mmi.set(MediaMetrics.Property.EARLY_RETURN, "change of connection state failed")
.record();
@@ -1788,14 +1793,15 @@
*/
/*package*/ boolean handleDeviceConnection(@NonNull AudioDeviceAttributes attributes,
boolean connect, boolean isForTesting,
- @Nullable BluetoothDevice btDevice) {
+ @Nullable BluetoothDevice btDevice,
+ boolean deviceSwitch) {
int device = attributes.getInternalType();
String address = attributes.getAddress();
String deviceName = attributes.getName();
if (AudioService.DEBUG_DEVICES) {
Slog.i(TAG, "handleDeviceConnection(" + connect + " dev:"
+ Integer.toHexString(device) + " address:" + address
- + " name:" + deviceName + ")");
+ + " name:" + deviceName + ", deviceSwitch: " + deviceSwitch + ")");
}
MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "handleDeviceConnection")
.set(MediaMetrics.Property.ADDRESS, address)
@@ -1829,7 +1835,8 @@
res = AudioSystem.AUDIO_STATUS_OK;
} else {
res = mAudioSystem.setDeviceConnectionState(attributes,
- AudioSystem.DEVICE_STATE_AVAILABLE, AudioSystem.AUDIO_FORMAT_DEFAULT);
+ AudioSystem.DEVICE_STATE_AVAILABLE, AudioSystem.AUDIO_FORMAT_DEFAULT,
+ false /*deviceSwitch*/);
}
if (res != AudioSystem.AUDIO_STATUS_OK) {
final String reason = "not connecting device 0x" + Integer.toHexString(device)
@@ -1856,7 +1863,8 @@
status = true;
} else if (!connect && isConnected) {
mAudioSystem.setDeviceConnectionState(attributes,
- AudioSystem.DEVICE_STATE_UNAVAILABLE, AudioSystem.AUDIO_FORMAT_DEFAULT);
+ AudioSystem.DEVICE_STATE_UNAVAILABLE, AudioSystem.AUDIO_FORMAT_DEFAULT,
+ deviceSwitch);
// always remove even if disconnection failed
mConnectedDevices.remove(deviceKey);
mDeviceBroker.postCheckCommunicationDeviceRemoval(attributes);
@@ -2030,7 +2038,7 @@
}
}
if (disconnect) {
- mDeviceBroker.onSetBtScoActiveDevice(null);
+ mDeviceBroker.onSetBtScoActiveDevice(null, false /*deviceSwitch*/);
}
}
@@ -2068,7 +2076,8 @@
|| info.mProfile == BluetoothProfile.LE_AUDIO_BROADCAST)
&& info.mIsLeOutput)
|| info.mProfile == BluetoothProfile.HEARING_AID
- || info.mProfile == BluetoothProfile.A2DP)) {
+ || info.mProfile == BluetoothProfile.A2DP)
+ && !info.mIsDeviceSwitch) {
@AudioService.ConnectionState int asState =
(info.mState == BluetoothProfile.STATE_CONNECTED)
? AudioService.CONNECTION_STATE_CONNECTED
@@ -2124,7 +2133,7 @@
AudioDeviceAttributes ada = new AudioDeviceAttributes(
AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, address, name);
final int res = mAudioSystem.setDeviceConnectionState(ada,
- AudioSystem.DEVICE_STATE_AVAILABLE, codec);
+ AudioSystem.DEVICE_STATE_AVAILABLE, codec, false);
// TODO: log in MediaMetrics once distinction between connection failure and
// double connection is made.
@@ -2362,7 +2371,7 @@
}
@GuardedBy("mDevicesLock")
- private void makeA2dpDeviceUnavailableNow(String address, int codec) {
+ private void makeA2dpDeviceUnavailableNow(String address, int codec, boolean deviceSwitch) {
MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "a2dp." + address)
.set(MediaMetrics.Property.ENCODING, AudioSystem.audioFormatToString(codec))
.set(MediaMetrics.Property.EVENT, "makeA2dpDeviceUnavailableNow");
@@ -2393,7 +2402,7 @@
AudioDeviceAttributes ada = new AudioDeviceAttributes(
AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, address);
final int res = mAudioSystem.setDeviceConnectionState(ada,
- AudioSystem.DEVICE_STATE_UNAVAILABLE, codec);
+ AudioSystem.DEVICE_STATE_UNAVAILABLE, codec, deviceSwitch);
if (res != AudioSystem.AUDIO_STATUS_OK) {
AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent(
@@ -2404,7 +2413,8 @@
} else {
AudioService.sDeviceLogger.enqueue((new EventLogger.StringEvent(
"A2DP device addr=" + Utils.anonymizeBluetoothAddress(address)
- + " made unavailable")).printSlog(EventLogger.Event.ALOGI, TAG));
+ + " made unavailable, deviceSwitch" + deviceSwitch))
+ .printSlog(EventLogger.Event.ALOGI, TAG));
}
mApmConnectedDevices.remove(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP);
@@ -2440,7 +2450,7 @@
final int res = mAudioSystem.setDeviceConnectionState(new AudioDeviceAttributes(
AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, address),
AudioSystem.DEVICE_STATE_AVAILABLE,
- AudioSystem.AUDIO_FORMAT_DEFAULT);
+ AudioSystem.AUDIO_FORMAT_DEFAULT, false);
if (res != AudioSystem.AUDIO_STATUS_OK) {
AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent(
"APM failed to make available A2DP source device addr="
@@ -2465,7 +2475,7 @@
AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, address);
mAudioSystem.setDeviceConnectionState(ada,
AudioSystem.DEVICE_STATE_UNAVAILABLE,
- AudioSystem.AUDIO_FORMAT_DEFAULT);
+ AudioSystem.AUDIO_FORMAT_DEFAULT, false);
// always remove regardless of the result
mConnectedDevices.remove(
DeviceInfo.makeDeviceListKey(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, address));
@@ -2485,7 +2495,7 @@
DEVICE_OUT_HEARING_AID, address, name);
final int res = mAudioSystem.setDeviceConnectionState(ada,
AudioSystem.DEVICE_STATE_AVAILABLE,
- AudioSystem.AUDIO_FORMAT_DEFAULT);
+ AudioSystem.AUDIO_FORMAT_DEFAULT, false);
if (asDeviceConnectionFailure() && res != AudioSystem.AUDIO_STATUS_OK) {
AudioService.sDeviceLogger.enqueueAndSlog(
"APM failed to make available HearingAid addr=" + address
@@ -2515,12 +2525,12 @@
}
@GuardedBy("mDevicesLock")
- private void makeHearingAidDeviceUnavailable(String address) {
+ private void makeHearingAidDeviceUnavailable(String address, boolean deviceSwitch) {
AudioDeviceAttributes ada = new AudioDeviceAttributes(
DEVICE_OUT_HEARING_AID, address);
mAudioSystem.setDeviceConnectionState(ada,
AudioSystem.DEVICE_STATE_UNAVAILABLE,
- AudioSystem.AUDIO_FORMAT_DEFAULT);
+ AudioSystem.AUDIO_FORMAT_DEFAULT, deviceSwitch);
// always remove regardless of return code
mConnectedDevices.remove(
DeviceInfo.makeDeviceListKey(DEVICE_OUT_HEARING_AID, address));
@@ -2622,7 +2632,7 @@
AudioDeviceAttributes ada = new AudioDeviceAttributes(device, address, name);
final int res = mAudioSystem.setDeviceConnectionState(ada,
- AudioSystem.DEVICE_STATE_AVAILABLE, codec);
+ AudioSystem.DEVICE_STATE_AVAILABLE, codec, false /*deviceSwitch*/);
if (res != AudioSystem.AUDIO_STATUS_OK) {
AudioService.sDeviceLogger.enqueueAndSlog(
"APM failed to make available LE Audio device addr=" + address
@@ -2669,13 +2679,13 @@
@GuardedBy("mDevicesLock")
private void makeLeAudioDeviceUnavailableNow(String address, int device,
- @AudioSystem.AudioFormatNativeEnumForBtCodec int codec) {
+ @AudioSystem.AudioFormatNativeEnumForBtCodec int codec, boolean deviceSwitch) {
AudioDeviceAttributes ada = null;
if (device != AudioSystem.DEVICE_NONE) {
ada = new AudioDeviceAttributes(device, address);
final int res = mAudioSystem.setDeviceConnectionState(ada,
AudioSystem.DEVICE_STATE_UNAVAILABLE,
- codec);
+ codec, deviceSwitch);
if (res != AudioSystem.AUDIO_STATUS_OK) {
AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent(
@@ -2685,7 +2695,8 @@
} else {
AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent(
"LE Audio device addr=" + Utils.anonymizeBluetoothAddress(address)
- + " made unavailable").printSlog(EventLogger.Event.ALOGI, TAG));
+ + " made unavailable, deviceSwitch" + deviceSwitch)
+ .printSlog(EventLogger.Event.ALOGI, TAG));
}
mConnectedDevices.remove(DeviceInfo.makeDeviceListKey(device, address));
}
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 86871ea..813e661 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -63,6 +63,7 @@
import static com.android.media.audio.Flags.disablePrescaleAbsoluteVolume;
import static com.android.media.audio.Flags.deferWearPermissionUpdates;
import static com.android.media.audio.Flags.equalScoLeaVcIndexRange;
+import static com.android.media.audio.Flags.optimizeBtDeviceSwitch;
import static com.android.media.audio.Flags.replaceStreamBtSco;
import static com.android.media.audio.Flags.ringMyCar;
import static com.android.media.audio.Flags.ringerModeAffectsAlarm;
@@ -585,6 +586,9 @@
// protects mRingerMode
private final Object mSettingsLock = new Object();
+ // protects VolumeStreamState / VolumeGroupState operations
+ private final Object mVolumeStateLock = new Object();
+
/** Maximum volume index values for audio streams */
protected static int[] MAX_STREAM_VOLUME = new int[] {
5, // STREAM_VOICE_CALL
@@ -1611,7 +1615,7 @@
private void initVolumeStreamStates() {
int numStreamTypes = AudioSystem.getNumStreamTypes();
- synchronized (VolumeStreamState.class) {
+ synchronized (mVolumeStateLock) {
for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
final VolumeStreamState streamState = getVssForStream(streamType);
if (streamState == null) {
@@ -2419,7 +2423,7 @@
private void checkAllAliasStreamVolumes() {
synchronized (mSettingsLock) {
- synchronized (VolumeStreamState.class) {
+ synchronized (mVolumeStateLock) {
int numStreamTypes = AudioSystem.getNumStreamTypes();
for (int streamType = 0; streamType < numStreamTypes; streamType++) {
int streamAlias = sStreamVolumeAlias.get(streamType, /*valueIfKeyNotFound=*/-1);
@@ -2501,7 +2505,7 @@
private void onUpdateVolumeStatesForAudioDevice(int device, String caller) {
final int numStreamTypes = AudioSystem.getNumStreamTypes();
synchronized (mSettingsLock) {
- synchronized (VolumeStreamState.class) {
+ synchronized (mVolumeStateLock) {
for (int streamType = 0; streamType < numStreamTypes; streamType++) {
updateVolumeStates(device, streamType, caller);
}
@@ -2770,7 +2774,7 @@
updateDefaultVolumes();
synchronized (mSettingsLock) {
- synchronized (VolumeStreamState.class) {
+ synchronized (mVolumeStateLock) {
getVssForStreamOrDefault(AudioSystem.STREAM_DTMF)
.setAllIndexes(getVssForStreamOrDefault(dtmfStreamAlias), caller);
getVssForStreamOrDefault(AudioSystem.STREAM_ACCESSIBILITY).setSettingName(
@@ -3232,8 +3236,10 @@
// Each stream will read its own persisted settings
// Broadcast the sticky intents
- broadcastRingerMode(AudioManager.RINGER_MODE_CHANGED_ACTION, mRingerModeExternal);
- broadcastRingerMode(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION, mRingerMode);
+ synchronized (mSettingsLock) {
+ broadcastRingerMode(AudioManager.RINGER_MODE_CHANGED_ACTION, mRingerModeExternal);
+ broadcastRingerMode(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION, mRingerMode);
+ }
// Broadcast vibrate settings
broadcastVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER);
@@ -4235,7 +4241,7 @@
private void muteAliasStreams(int streamAlias, boolean state) {
// Locking mSettingsLock to avoid inversion when calling doMute -> updateVolumeGroupIndex
synchronized (mSettingsLock) {
- synchronized (VolumeStreamState.class) {
+ synchronized (mVolumeStateLock) {
List<Integer> streamsToMute = new ArrayList<>();
for (int streamIdx = 0; streamIdx < mStreamStates.size(); streamIdx++) {
final VolumeStreamState vss = mStreamStates.valueAt(streamIdx);
@@ -4279,7 +4285,7 @@
// Locking mSettingsLock to avoid inversion when calling vss.mute -> vss.doMute ->
// vss.updateVolumeGroupIndex
synchronized (mSettingsLock) {
- synchronized (VolumeStreamState.class) {
+ synchronized (mVolumeStateLock) {
final VolumeStreamState streamState = getVssForStreamOrDefault(streamAlias);
// if unmuting causes a change, it was muted
wasMuted = streamState.mute(false, "onUnmuteStreamOnSingleVolDevice");
@@ -4455,7 +4461,7 @@
/** @see AudioManager#getVolumeGroupVolumeIndex(int) */
public int getVolumeGroupVolumeIndex(int groupId) {
super.getVolumeGroupVolumeIndex_enforcePermission();
- synchronized (VolumeStreamState.class) {
+ synchronized (mVolumeStateLock) {
if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
Log.e(TAG, "No volume group for id " + groupId);
return 0;
@@ -4472,7 +4478,7 @@
MODIFY_AUDIO_SETTINGS_PRIVILEGED, MODIFY_AUDIO_ROUTING })
public int getVolumeGroupMaxVolumeIndex(int groupId) {
super.getVolumeGroupMaxVolumeIndex_enforcePermission();
- synchronized (VolumeStreamState.class) {
+ synchronized (mVolumeStateLock) {
if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
Log.e(TAG, "No volume group for id " + groupId);
return 0;
@@ -4487,7 +4493,7 @@
MODIFY_AUDIO_SETTINGS_PRIVILEGED, MODIFY_AUDIO_ROUTING })
public int getVolumeGroupMinVolumeIndex(int groupId) {
super.getVolumeGroupMinVolumeIndex_enforcePermission();
- synchronized (VolumeStreamState.class) {
+ synchronized (mVolumeStateLock) {
if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
Log.e(TAG, "No volume group for id " + groupId);
return 0;
@@ -4632,7 +4638,7 @@
@android.annotation.EnforcePermission(QUERY_AUDIO_STATE)
public int getLastAudibleVolumeForVolumeGroup(int groupId) {
super.getLastAudibleVolumeForVolumeGroup_enforcePermission();
- synchronized (VolumeStreamState.class) {
+ synchronized (mVolumeStateLock) {
if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
Log.e(TAG, ": no volume group found for id " + groupId);
return 0;
@@ -4644,7 +4650,7 @@
/** @see AudioManager#isVolumeGroupMuted(int) */
public boolean isVolumeGroupMuted(int groupId) {
- synchronized (VolumeStreamState.class) {
+ synchronized (mVolumeStateLock) {
if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
Log.e(TAG, ": no volume group found for id " + groupId);
return false;
@@ -4990,6 +4996,8 @@
+ cacheGetStreamMinMaxVolume());
pw.println("\tandroid.media.audio.Flags.cacheGetStreamVolume:"
+ cacheGetStreamVolume());
+ pw.println("\tcom.android.media.audio.optimizeBtDeviceSwitch:"
+ + optimizeBtDeviceSwitch());
}
private void dumpAudioMode(PrintWriter pw) {
@@ -5470,7 +5478,7 @@
}
streamType = replaceBtScoStreamWithVoiceCall(streamType, "isStreamMute");
- synchronized (VolumeStreamState.class) {
+ synchronized (mVolumeStateLock) {
ensureValidStreamType(streamType);
return getVssForStreamOrDefault(streamType).mIsMuted;
}
@@ -5651,7 +5659,7 @@
}
private int getStreamVolume(int streamType, int device) {
- synchronized (VolumeStreamState.class) {
+ synchronized (mVolumeStateLock) {
final VolumeStreamState vss = getVssForStreamOrDefault(streamType);
int index = vss.getIndex(device);
@@ -5695,7 +5703,7 @@
vib.setMinVolumeIndex((vss.mIndexMin + 5) / 10);
vib.setMaxVolumeIndex((vss.mIndexMax + 5) / 10);
- synchronized (VolumeStreamState.class) {
+ synchronized (mVolumeStateLock) {
final int index;
if (isFixedVolumeDevice(ada.getInternalType())) {
index = (vss.mIndexMax + 5) / 10;
@@ -6263,7 +6271,7 @@
// ring and notifications volume should never be 0 when not silenced
if (sStreamVolumeAlias.get(streamType) == AudioSystem.STREAM_RING
|| sStreamVolumeAlias.get(streamType) == AudioSystem.STREAM_NOTIFICATION) {
- synchronized (VolumeStreamState.class) {
+ synchronized (mVolumeStateLock) {
for (int i = 0; i < vss.mIndexMap.size(); i++) {
int device = vss.mIndexMap.keyAt(i);
int value = vss.mIndexMap.valueAt(i);
@@ -7023,7 +7031,7 @@
}
streamState.readSettings();
- synchronized (VolumeStreamState.class) {
+ synchronized (mVolumeStateLock) {
// unmute stream that was muted but is not affect by mute anymore
if (streamState.mIsMuted && ((!isStreamAffectedByMute(streamType) &&
!isStreamMutedByRingerOrZenMode(streamType)) || mUseFixedVolume)) {
@@ -8056,14 +8064,14 @@
public Set<Integer> getDeviceSetForStream(int stream) {
stream = replaceBtScoStreamWithVoiceCall(stream, "getDeviceSetForStream");
ensureValidStreamType(stream);
- synchronized (VolumeStreamState.class) {
+ synchronized (mVolumeStateLock) {
return getVssForStreamOrDefault(stream).observeDevicesForStream_syncVSS(true);
}
}
private void onObserveDevicesForAllStreams(int skipStream) {
synchronized (mSettingsLock) {
- synchronized (VolumeStreamState.class) {
+ synchronized (mVolumeStateLock) {
for (int stream = 0; stream < mStreamStates.size(); stream++) {
final VolumeStreamState vss = mStreamStates.valueAt(stream);
if (vss != null && vss.getStreamType() != skipStream) {
@@ -8645,7 +8653,7 @@
private void readVolumeGroupsSettings(boolean userSwitch) {
synchronized (mSettingsLock) {
- synchronized (VolumeStreamState.class) {
+ synchronized (mVolumeStateLock) {
if (DEBUG_VOL) {
Log.d(TAG, "readVolumeGroupsSettings userSwitch=" + userSwitch);
}
@@ -8703,7 +8711,7 @@
// NOTE: Locking order for synchronized objects related to volume management:
// 1 mSettingsLock
- // 2 VolumeStreamState.class
+ // 2 mVolumeStateLock
private class VolumeGroupState {
private final AudioVolumeGroup mAudioVolumeGroup;
private final SparseIntArray mIndexMap = new SparseIntArray(8);
@@ -8797,7 +8805,7 @@
* Mute/unmute the volume group
* @param muted the new mute state
*/
- @GuardedBy("AudioService.VolumeStreamState.class")
+ @GuardedBy("AudioService.this.mVolumeStateLock")
public boolean mute(boolean muted) {
if (!isMutable()) {
// Non mutable volume group
@@ -8821,7 +8829,7 @@
public void adjustVolume(int direction, int flags) {
synchronized (mSettingsLock) {
- synchronized (AudioService.VolumeStreamState.class) {
+ synchronized (mVolumeStateLock) {
int device = getDeviceForVolume();
int previousIndex = getIndex(device);
if (isMuteAdjust(direction) && !isMutable()) {
@@ -8875,14 +8883,14 @@
}
public int getVolumeIndex() {
- synchronized (AudioService.VolumeStreamState.class) {
+ synchronized (mVolumeStateLock) {
return getIndex(getDeviceForVolume());
}
}
public void setVolumeIndex(int index, int flags) {
synchronized (mSettingsLock) {
- synchronized (AudioService.VolumeStreamState.class) {
+ synchronized (mVolumeStateLock) {
if (mUseFixedVolume) {
return;
}
@@ -8891,7 +8899,7 @@
}
}
- @GuardedBy("AudioService.VolumeStreamState.class")
+ @GuardedBy("AudioService.this.mVolumeStateLock")
private void setVolumeIndex(int index, int device, int flags) {
// Update cache & persist (muted by volume 0 shall be persisted)
updateVolumeIndex(index, device);
@@ -8904,7 +8912,7 @@
}
}
- @GuardedBy("AudioService.VolumeStreamState.class")
+ @GuardedBy("AudioService.this.mVolumeStateLock")
public void updateVolumeIndex(int index, int device) {
// Filter persistency if already exist and the index has not changed
if (mIndexMap.indexOfKey(device) < 0 || mIndexMap.get(device) != index) {
@@ -8922,7 +8930,7 @@
}
}
- @GuardedBy("AudioService.VolumeStreamState.class")
+ @GuardedBy("AudioService.this.mVolumeStateLock")
private void setVolumeIndexInt(int index, int device, int flags) {
// Reflect mute state of corresponding stream by forcing index to 0 if muted
// Only set audio policy BT SCO stream volume to 0 when the stream is actually muted.
@@ -8955,14 +8963,14 @@
mAudioSystem.setVolumeIndexForAttributes(mAudioAttributes, index, muted, device);
}
- @GuardedBy("AudioService.VolumeStreamState.class")
+ @GuardedBy("AudioService.this.mVolumeStateLock")
private int getIndex(int device) {
int index = mIndexMap.get(device, -1);
// there is always an entry for AudioSystem.DEVICE_OUT_DEFAULT
return (index != -1) ? index : mIndexMap.get(AudioSystem.DEVICE_OUT_DEFAULT);
}
- @GuardedBy("AudioService.VolumeStreamState.class")
+ @GuardedBy("AudioService.this.mVolumeStateLock")
private boolean hasIndexForDevice(int device) {
return (mIndexMap.get(device, -1) != -1);
}
@@ -8989,7 +8997,7 @@
public void applyAllVolumes(boolean userSwitch) {
String caller = "from vgs";
- synchronized (AudioService.VolumeStreamState.class) {
+ synchronized (mVolumeStateLock) {
// apply device specific volumes first
for (int i = 0; i < mIndexMap.size(); i++) {
int device = mIndexMap.keyAt(i);
@@ -9092,25 +9100,27 @@
if (mUseFixedVolume || mHasValidStreamType) {
return;
}
- if (DEBUG_VOL) {
- Log.v(TAG, "persistVolumeGroup: storing index " + getIndex(device) + " for group "
- + mAudioVolumeGroup.name()
- + ", device " + AudioSystem.getOutputDeviceName(device)
- + " and User=" + getCurrentUserId()
- + " mSettingName: " + mSettingName);
- }
+ synchronized (mVolumeStateLock) {
+ if (DEBUG_VOL) {
+ Log.v(TAG, "persistVolumeGroup: storing index " + getIndex(device)
+ + " for group " + mAudioVolumeGroup.name()
+ + ", device " + AudioSystem.getOutputDeviceName(device)
+ + " and User=" + getCurrentUserId()
+ + " mSettingName: " + mSettingName);
+ }
- boolean success = mSettings.putSystemIntForUser(mContentResolver,
- getSettingNameForDevice(device),
- getIndex(device),
- getVolumePersistenceUserId());
- if (!success) {
- Log.e(TAG, "persistVolumeGroup failed for group " + mAudioVolumeGroup.name());
+ boolean success = mSettings.putSystemIntForUser(mContentResolver,
+ getSettingNameForDevice(device),
+ getIndex(device),
+ getVolumePersistenceUserId());
+ if (!success) {
+ Log.e(TAG, "persistVolumeGroup failed for group " + mAudioVolumeGroup.name());
+ }
}
}
public void readSettings() {
- synchronized (AudioService.VolumeStreamState.class) {
+ synchronized (mVolumeStateLock) {
// force maximum volume on all streams if fixed volume property is set
if (mUseFixedVolume) {
mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, mIndexMax);
@@ -9144,7 +9154,7 @@
}
}
- @GuardedBy("AudioService.VolumeStreamState.class")
+ @GuardedBy("AudioService.this.mVolumeStateLock")
private int getValidIndex(int index) {
if (index < mIndexMin) {
return mIndexMin;
@@ -9218,7 +9228,7 @@
// 1 mScoclient OR mSafeMediaVolumeState
// 2 mSetModeLock
// 3 mSettingsLock
- // 4 VolumeStreamState.class
+ // 4 mVolumeStateLock
/*package*/ class VolumeStreamState {
private final int mStreamType;
private VolumeGroupState mVolumeGroupState = null;
@@ -9427,7 +9437,7 @@
*
* This is a reference to the local list, do not modify.
*/
- @GuardedBy("VolumeStreamState.class")
+ @GuardedBy("mVolumeStateLock")
@NonNull
public Set<Integer> observeDevicesForStream_syncVSS(
boolean checkOthers) {
@@ -9495,7 +9505,7 @@
public void readSettings() {
synchronized (mSettingsLock) {
- synchronized (VolumeStreamState.class) {
+ synchronized (mVolumeStateLock) {
// force maximum volume on all streams if fixed volume property is set
if (mUseFixedVolume) {
mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, mIndexMax);
@@ -9515,7 +9525,7 @@
}
}
}
- synchronized (VolumeStreamState.class) {
+ synchronized (mVolumeStateLock) {
for (int device : AudioSystem.DEVICE_OUT_ALL_SET) {
// retrieve current volume for device
@@ -9548,7 +9558,7 @@
* will send the non-zero index together with muted state. Otherwise, index 0 will be sent
* to native for signalising a muted stream.
**/
- @GuardedBy("VolumeStreamState.class")
+ @GuardedBy("mVolumeStateLock")
private void setStreamVolumeIndex(int index, int device) {
// Only set audio policy BT SCO stream volume to 0 when the stream is actually muted.
// This allows RX path muting by the audio HAL only when explicitly muted but not when
@@ -9570,8 +9580,8 @@
mAudioSystem.setStreamVolumeIndexAS(mStreamType, index, muted, device);
}
- // must be called while synchronized VolumeStreamState.class
- @GuardedBy("VolumeStreamState.class")
+ // must be called while synchronized mVolumeStateLock
+ @GuardedBy("mVolumeStateLock")
/*package*/ void applyDeviceVolume_syncVSS(int device) {
int index;
if (isFullyMuted() && !ringMyCar()) {
@@ -9597,7 +9607,7 @@
}
public void applyAllVolumes() {
- synchronized (VolumeStreamState.class) {
+ synchronized (mVolumeStateLock) {
// apply device specific volumes first
int index;
boolean isAbsoluteVolume = false;
@@ -9659,7 +9669,7 @@
final boolean isCurrentDevice;
final StringBuilder aliasStreamIndexes = new StringBuilder();
synchronized (mSettingsLock) {
- synchronized (VolumeStreamState.class) {
+ synchronized (mVolumeStateLock) {
oldIndex = getIndex(device);
index = getValidIndex(index, hasModifyAudioSettings);
// for STREAM_SYSTEM_ENFORCED, do not sync aliased streams on the enforced index
@@ -9777,7 +9787,7 @@
}
public int getIndex(int device) {
- synchronized (VolumeStreamState.class) {
+ synchronized (mVolumeStateLock) {
int index = mIndexMap.get(device, -1);
if (index == -1) {
// there is always an entry for AudioSystem.DEVICE_OUT_DEFAULT
@@ -9788,7 +9798,7 @@
}
public @NonNull VolumeInfo getVolumeInfo(int device) {
- synchronized (VolumeStreamState.class) {
+ synchronized (mVolumeStateLock) {
int index = mIndexMap.get(device, -1);
if (index == -1) {
// there is always an entry for AudioSystem.DEVICE_OUT_DEFAULT
@@ -9805,7 +9815,7 @@
}
public boolean hasIndexForDevice(int device) {
- synchronized (VolumeStreamState.class) {
+ synchronized (mVolumeStateLock) {
return (mIndexMap.get(device, -1) != -1);
}
}
@@ -9837,8 +9847,8 @@
* @param srcStream
* @param caller
*/
- // must be sync'd on mSettingsLock before VolumeStreamState.class
- @GuardedBy("VolumeStreamState.class")
+ // must be sync'd on mSettingsLock before mVolumeStateLock
+ @GuardedBy("mVolumeStateLock")
public void setAllIndexes(VolumeStreamState srcStream, String caller) {
if (srcStream == null || mStreamType == srcStream.mStreamType) {
return;
@@ -9862,8 +9872,8 @@
}
}
- // must be sync'd on mSettingsLock before VolumeStreamState.class
- @GuardedBy("VolumeStreamState.class")
+ // must be sync'd on mSettingsLock before mVolumeStateLock
+ @GuardedBy("mVolumeStateLock")
public void setAllIndexesToMax() {
for (int i = 0; i < mIndexMap.size(); i++) {
mIndexMap.put(mIndexMap.keyAt(i), mIndexMax);
@@ -9876,7 +9886,7 @@
// vss.setIndex which grabs this lock after VSS.class. Locking order needs to be
// preserved
synchronized (mSettingsLock) {
- synchronized (VolumeStreamState.class) {
+ synchronized (mVolumeStateLock) {
if (mVolumeGroupState != null) {
int groupIndex = (getIndex(device) + 5) / 10;
if (DEBUG_VOL) {
@@ -9908,7 +9918,7 @@
*/
public boolean mute(boolean state, String source) {
boolean changed = false;
- synchronized (VolumeStreamState.class) {
+ synchronized (mVolumeStateLock) {
changed = mute(state, true, source);
}
if (changed) {
@@ -9924,7 +9934,7 @@
*/
public boolean muteInternally(boolean state) {
boolean changed = false;
- synchronized (VolumeStreamState.class) {
+ synchronized (mVolumeStateLock) {
if (state != mIsMutedInternally) {
changed = true;
mIsMutedInternally = state;
@@ -9939,7 +9949,7 @@
return changed;
}
- @GuardedBy("VolumeStreamState.class")
+ @GuardedBy("mVolumeStateLock")
public boolean isFullyMuted() {
return mIsMuted || mIsMutedInternally;
}
@@ -9960,7 +9970,7 @@
*/
public boolean mute(boolean state, boolean apply, String src) {
boolean changed;
- synchronized (VolumeStreamState.class) {
+ synchronized (mVolumeStateLock) {
changed = state != mIsMuted;
if (changed) {
sMuteLogger.enqueue(
@@ -9994,7 +10004,7 @@
}
public void doMute() {
- synchronized (VolumeStreamState.class) {
+ synchronized (mVolumeStateLock) {
// If associated to volume group, update group cache
updateVolumeGroupIndex(getDeviceForStream(mStreamType), /* forceMuteState= */true);
@@ -10015,7 +10025,7 @@
}
public void checkFixedVolumeDevices() {
- synchronized (VolumeStreamState.class) {
+ synchronized (mVolumeStateLock) {
// ignore settings for fixed volume devices: volume should always be at max or 0
if (sStreamVolumeAlias.get(mStreamType) == AudioSystem.STREAM_MUSIC) {
for (int i = 0; i < mIndexMap.size(); i++) {
@@ -10186,8 +10196,7 @@
}
/*package*/ void setDeviceVolume(VolumeStreamState streamState, int device) {
-
- synchronized (VolumeStreamState.class) {
+ synchronized (mVolumeStateLock) {
sendMsg(mAudioHandler, SoundDoseHelper.MSG_CSD_UPDATE_ATTENUATION, SENDMSG_QUEUE,
device, (isAbsoluteVolumeDevice(device) || isA2dpAbsoluteVolumeDevice(device)
|| AudioSystem.isLeAudioDeviceType(device) ? 1 : 0),
@@ -12191,7 +12200,7 @@
mCameraSoundForced = cameraSoundForced;
if (cameraSoundForcedChanged) {
if (!mIsSingleVolume) {
- synchronized (VolumeStreamState.class) {
+ synchronized (mVolumeStateLock) {
final VolumeStreamState s = getVssForStreamOrDefault(
AudioSystem.STREAM_SYSTEM_ENFORCED);
if (cameraSoundForced) {
diff --git a/services/core/java/com/android/server/audio/AudioSystemAdapter.java b/services/core/java/com/android/server/audio/AudioSystemAdapter.java
index e86c34c..a6267c1 100644
--- a/services/core/java/com/android/server/audio/AudioSystemAdapter.java
+++ b/services/core/java/com/android/server/audio/AudioSystemAdapter.java
@@ -367,9 +367,9 @@
* @return
*/
public int setDeviceConnectionState(AudioDeviceAttributes attributes, int state,
- int codecFormat) {
+ int codecFormat, boolean deviceSwitch) {
invalidateRoutingCache();
- return AudioSystem.setDeviceConnectionState(attributes, state, codecFormat);
+ return AudioSystem.setDeviceConnectionState(attributes, state, codecFormat, deviceSwitch);
}
/**
diff --git a/services/core/java/com/android/server/audio/BtHelper.java b/services/core/java/com/android/server/audio/BtHelper.java
index 9221169..844e352 100644
--- a/services/core/java/com/android/server/audio/BtHelper.java
+++ b/services/core/java/com/android/server/audio/BtHelper.java
@@ -26,6 +26,8 @@
import static android.media.AudioManager.AUDIO_DEVICE_CATEGORY_UNKNOWN;
import static android.media.AudioManager.AUDIO_DEVICE_CATEGORY_WATCH;
+import static com.android.media.audio.Flags.optimizeBtDeviceSwitch;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.bluetooth.BluetoothA2dp;
@@ -393,8 +395,11 @@
+ "received with null profile proxy for device: "
+ btDevice)).printLog(TAG));
return;
+
}
- onSetBtScoActiveDevice(btDevice);
+ boolean deviceSwitch = optimizeBtDeviceSwitch()
+ && btDevice != null && mBluetoothHeadsetDevice != null;
+ onSetBtScoActiveDevice(btDevice, deviceSwitch);
} else if (action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) {
int btState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1);
onScoAudioStateChanged(btState);
@@ -814,7 +819,7 @@
if (device == null) {
continue;
}
- onSetBtScoActiveDevice(device);
+ onSetBtScoActiveDevice(device, false /*deviceSwitch*/);
}
} else {
Log.e(TAG, "onHeadsetProfileConnected: Null BluetoothAdapter");
@@ -907,7 +912,8 @@
}
@GuardedBy("mDeviceBroker.mDeviceStateLock")
- private boolean handleBtScoActiveDeviceChange(BluetoothDevice btDevice, boolean isActive) {
+ private boolean handleBtScoActiveDeviceChange(BluetoothDevice btDevice, boolean isActive,
+ boolean deviceSwitch) {
if (btDevice == null) {
return true;
}
@@ -919,12 +925,12 @@
if (isActive) {
audioDevice = btHeadsetDeviceToAudioDevice(btDevice);
result = mDeviceBroker.handleDeviceConnection(
- audioDevice, true /*connect*/, btDevice);
+ audioDevice, true /*connect*/, btDevice, false /*deviceSwitch*/);
} else {
AudioDeviceAttributes ada = mResolvedScoAudioDevices.get(btDevice);
if (ada != null) {
result = mDeviceBroker.handleDeviceConnection(
- ada, false /*connect*/, btDevice);
+ ada, false /*connect*/, btDevice, deviceSwitch);
} else {
// Disconnect all possible audio device types if the disconnected device type is
// unknown
@@ -935,7 +941,8 @@
};
for (int outDeviceType : outDeviceTypes) {
result |= mDeviceBroker.handleDeviceConnection(new AudioDeviceAttributes(
- outDeviceType, address, name), false /*connect*/, btDevice);
+ outDeviceType, address, name), false /*connect*/, btDevice,
+ deviceSwitch);
}
}
}
@@ -944,7 +951,7 @@
// handleDeviceConnection() && result to make sure the method get executed
result = mDeviceBroker.handleDeviceConnection(new AudioDeviceAttributes(
inDevice, address, name),
- isActive, btDevice) && result;
+ isActive, btDevice, deviceSwitch) && result;
if (result) {
if (isActive) {
mResolvedScoAudioDevices.put(btDevice, audioDevice);
@@ -961,18 +968,18 @@
}
@GuardedBy("mDeviceBroker.mDeviceStateLock")
- /*package */ void onSetBtScoActiveDevice(BluetoothDevice btDevice) {
+ /*package */ void onSetBtScoActiveDevice(BluetoothDevice btDevice, boolean deviceSwitch) {
Log.i(TAG, "onSetBtScoActiveDevice: " + getAnonymizedAddress(mBluetoothHeadsetDevice)
- + " -> " + getAnonymizedAddress(btDevice));
+ + " -> " + getAnonymizedAddress(btDevice) + ", deviceSwitch: " + deviceSwitch);
final BluetoothDevice previousActiveDevice = mBluetoothHeadsetDevice;
if (Objects.equals(btDevice, previousActiveDevice)) {
return;
}
- if (!handleBtScoActiveDeviceChange(previousActiveDevice, false)) {
+ if (!handleBtScoActiveDeviceChange(previousActiveDevice, false, deviceSwitch)) {
Log.w(TAG, "onSetBtScoActiveDevice() failed to remove previous device "
+ getAnonymizedAddress(previousActiveDevice));
}
- if (!handleBtScoActiveDeviceChange(btDevice, true)) {
+ if (!handleBtScoActiveDeviceChange(btDevice, true, false /*deviceSwitch*/)) {
Log.e(TAG, "onSetBtScoActiveDevice() failed to add new device "
+ getAnonymizedAddress(btDevice));
// set mBluetoothHeadsetDevice to null when failing to add new device
diff --git a/services/core/java/com/android/server/biometrics/BiometricCameraManagerImpl.java b/services/core/java/com/android/server/biometrics/BiometricCameraManagerImpl.java
index 000ee54..9f36467 100644
--- a/services/core/java/com/android/server/biometrics/BiometricCameraManagerImpl.java
+++ b/services/core/java/com/android/server/biometrics/BiometricCameraManagerImpl.java
@@ -20,12 +20,16 @@
import android.annotation.NonNull;
import android.hardware.SensorPrivacyManager;
+import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraManager;
+import android.util.Log;
import java.util.concurrent.ConcurrentHashMap;
public class BiometricCameraManagerImpl implements BiometricCameraManager {
+ private static final String TAG = "BiometricCameraManager";
+
private final CameraManager mCameraManager;
private final SensorPrivacyManager mSensorPrivacyManager;
private final ConcurrentHashMap<String, Boolean> mIsCameraAvailable = new ConcurrentHashMap<>();
@@ -52,12 +56,18 @@
@Override
public boolean isAnyCameraUnavailable() {
- for (String cameraId : mIsCameraAvailable.keySet()) {
- if (!mIsCameraAvailable.get(cameraId)) {
- return true;
+ try {
+ for (String cameraId : mCameraManager.getCameraIdList()) {
+ if (!mIsCameraAvailable.getOrDefault(cameraId, true)) {
+ return true;
+ }
}
+ return false;
+ } catch (CameraAccessException e) {
+ Log.e(TAG, "Camera exception thrown when trying to determine availability: ", e);
+ //If face HAL is unable to get access to a camera, it will return an error.
+ return false;
}
- return false;
}
@Override
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 0aa7227..258c955 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -812,7 +812,7 @@
handleMinimalPostProcessingAllowedSettingChange();
if (mFlags.isDisplayContentModeManagementEnabled()) {
- updateMirrorBuiltInDisplaySettingLocked();
+ updateMirrorBuiltInDisplaySettingLocked(/*shouldSendDisplayChangeEvent=*/ true);
}
final UserManager userManager = getUserManager();
@@ -868,7 +868,7 @@
updateHdrConversionModeSettingsLocked();
}
if (mFlags.isDisplayContentModeManagementEnabled()) {
- updateMirrorBuiltInDisplaySettingLocked();
+ updateMirrorBuiltInDisplaySettingLocked(/*shouldSendDisplayChangeEvent=*/ false);
}
}
@@ -1237,8 +1237,11 @@
}
if (Settings.Secure.getUriFor(MIRROR_BUILT_IN_DISPLAY).equals(uri)) {
- if (mFlags.isDisplayContentModeManagementEnabled()) {
- updateMirrorBuiltInDisplaySettingLocked();
+ synchronized (mSyncRoot) {
+ if (mFlags.isDisplayContentModeManagementEnabled()) {
+ updateMirrorBuiltInDisplaySettingLocked(/*shouldSendDisplayChangeEvent=*/
+ true);
+ }
}
return;
}
@@ -1258,18 +1261,19 @@
1, UserHandle.USER_CURRENT) != 0);
}
- private void updateMirrorBuiltInDisplaySettingLocked() {
- synchronized (mSyncRoot) {
- ContentResolver resolver = mContext.getContentResolver();
- final boolean mirrorBuiltInDisplay = Settings.Secure.getIntForUser(resolver,
- MIRROR_BUILT_IN_DISPLAY, 0, UserHandle.USER_CURRENT) != 0;
- if (mMirrorBuiltInDisplay == mirrorBuiltInDisplay) {
- return;
- }
- mMirrorBuiltInDisplay = mirrorBuiltInDisplay;
- if (mFlags.isDisplayContentModeManagementEnabled()) {
- mLogicalDisplayMapper.forEachLocked(this::updateCanHostTasksIfNeededLocked);
- }
+ private void updateMirrorBuiltInDisplaySettingLocked(boolean shouldSendDisplayChangeEvent) {
+ ContentResolver resolver = mContext.getContentResolver();
+ final boolean mirrorBuiltInDisplay = Settings.Secure.getIntForUser(resolver,
+ MIRROR_BUILT_IN_DISPLAY, 0, UserHandle.USER_CURRENT) != 0;
+ if (mMirrorBuiltInDisplay == mirrorBuiltInDisplay) {
+ return;
+ }
+ mMirrorBuiltInDisplay = mirrorBuiltInDisplay;
+ if (mFlags.isDisplayContentModeManagementEnabled()) {
+ mLogicalDisplayMapper.forEachLocked(logicalDisplay -> {
+ updateCanHostTasksIfNeededLocked(logicalDisplay,
+ shouldSendDisplayChangeEvent);
+ });
}
}
@@ -2380,7 +2384,7 @@
new BrightnessPair(brightnessDefault, brightnessDefault));
if (mFlags.isDisplayContentModeManagementEnabled()) {
- updateCanHostTasksIfNeededLocked(display);
+ updateCanHostTasksIfNeededLocked(display, /*shouldSendDisplayChangeEvent=*/ false);
}
DisplayManagerGlobal.invalidateLocalDisplayInfoCaches();
@@ -2614,7 +2618,8 @@
// Blank or unblank the display immediately to match the state requested
// by the display power controller (if known).
DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
- if ((info.flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0) {
+ if ((info.flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0
+ || android.companion.virtualdevice.flags.Flags.correctVirtualDisplayPowerState()) {
final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(device);
if (display == null) {
return null;
@@ -2702,8 +2707,9 @@
}
}
- private void updateCanHostTasksIfNeededLocked(LogicalDisplay display) {
- if (display.setCanHostTasksLocked(!mMirrorBuiltInDisplay)) {
+ private void updateCanHostTasksIfNeededLocked(LogicalDisplay display,
+ boolean shouldSendDisplayChangeEvent) {
+ if (display.setCanHostTasksLocked(!mMirrorBuiltInDisplay) && shouldSendDisplayChangeEvent) {
sendDisplayEventIfEnabledLocked(display,
DisplayManagerGlobal.EVENT_DISPLAY_BASIC_CHANGED);
}
@@ -5574,7 +5580,9 @@
final DisplayDevice displayDevice = mLogicalDisplayMapper.getDisplayLocked(
id).getPrimaryDisplayDeviceLocked();
final int flags = displayDevice.getDisplayDeviceInfoLocked().flags;
- if ((flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0) {
+ if ((flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0
+ || android.companion.virtualdevice.flags.Flags
+ .correctVirtualDisplayPowerState()) {
final DisplayPowerController displayPowerController =
mDisplayPowerControllers.get(id);
if (displayPowerController != null) {
diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
index 4779b69..e7939bb 100644
--- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
@@ -371,7 +371,15 @@
mCallback = callback;
mProjection = projection;
mMediaProjectionCallback = mediaProjectionCallback;
- mDisplayState = Display.STATE_ON;
+ if (android.companion.virtualdevice.flags.Flags.correctVirtualDisplayPowerState()) {
+ // The display's power state depends on the power state of the state of its
+ // display / power group, which we don't know here. Initializing to UNKNOWN allows
+ // the first call to requestDisplayStateLocked() to set the correct state.
+ // This also triggers VirtualDisplay.Callback to tell the owner the initial state.
+ mDisplayState = Display.STATE_UNKNOWN;
+ } else {
+ mDisplayState = Display.STATE_ON;
+ }
mPendingChanges |= PENDING_SURFACE_CHANGE;
mDisplayIdToMirror = virtualDisplayConfig.getDisplayIdToMirror();
mIsWindowManagerMirroring = virtualDisplayConfig.isWindowManagerMirroringEnabled();
@@ -564,14 +572,23 @@
mInfo.yDpi = mDensityDpi;
mInfo.presentationDeadlineNanos = 1000000000L / (int) getRefreshRate(); // 1 frame
mInfo.flags = 0;
- if ((mFlags & VIRTUAL_DISPLAY_FLAG_PUBLIC) == 0) {
- mInfo.flags |= DisplayDeviceInfo.FLAG_PRIVATE
- | DisplayDeviceInfo.FLAG_NEVER_BLANK;
- }
- if ((mFlags & VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) != 0) {
- mInfo.flags &= ~DisplayDeviceInfo.FLAG_NEVER_BLANK;
+ if (android.companion.virtualdevice.flags.Flags.correctVirtualDisplayPowerState()) {
+ if ((mFlags & VIRTUAL_DISPLAY_FLAG_PUBLIC) == 0) {
+ mInfo.flags |= DisplayDeviceInfo.FLAG_PRIVATE;
+ }
+ if ((mFlags & VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) == 0) {
+ mInfo.flags |= DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY;
+ }
} else {
- mInfo.flags |= DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY;
+ if ((mFlags & VIRTUAL_DISPLAY_FLAG_PUBLIC) == 0) {
+ mInfo.flags |= DisplayDeviceInfo.FLAG_PRIVATE
+ | DisplayDeviceInfo.FLAG_NEVER_BLANK;
+ }
+ if ((mFlags & VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) != 0) {
+ mInfo.flags &= ~DisplayDeviceInfo.FLAG_NEVER_BLANK;
+ } else {
+ mInfo.flags |= DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY;
+ }
}
if ((mFlags & VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP) != 0) {
mInfo.flags |= DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP;
diff --git a/services/core/java/com/android/server/display/feature/display_flags.aconfig b/services/core/java/com/android/server/display/feature/display_flags.aconfig
index 70143f1..acdc0e0 100644
--- a/services/core/java/com/android/server/display/feature/display_flags.aconfig
+++ b/services/core/java/com/android/server/display/feature/display_flags.aconfig
@@ -456,9 +456,8 @@
flag {
name: "enable_display_content_mode_management"
namespace: "lse_desktop_experience"
- description: "Enable switching the content mode of connected displays between mirroring and extened. Also change the default content mode to extended mode."
+ description: "Enable switching the content mode of connected displays between mirroring and extended. Also change the default content mode to extended mode."
bug: "378385869"
- is_fixed_read_only: true
}
flag {
diff --git a/services/core/java/com/android/server/dreams/DreamManagerService.java b/services/core/java/com/android/server/dreams/DreamManagerService.java
index 2af74f6..7e8bb28 100644
--- a/services/core/java/com/android/server/dreams/DreamManagerService.java
+++ b/services/core/java/com/android/server/dreams/DreamManagerService.java
@@ -569,8 +569,7 @@
}
private void requestDreamInternal() {
- if (isDreamingInternal() && !dreamIsFrontmost() && mController.bringDreamToFront()
- && !isDozingInternal()) {
+ if (isDreamingInternal() && !dreamIsFrontmost() && mController.bringDreamToFront()) {
return;
}
diff --git a/services/core/java/com/android/server/hdmi/AudioDeviceVolumeManagerWrapper.java b/services/core/java/com/android/server/hdmi/AudioDeviceVolumeManagerWrapper.java
index 9484204..ab86433 100644
--- a/services/core/java/com/android/server/hdmi/AudioDeviceVolumeManagerWrapper.java
+++ b/services/core/java/com/android/server/hdmi/AudioDeviceVolumeManagerWrapper.java
@@ -58,9 +58,9 @@
void setDeviceAbsoluteVolumeBehavior(
@NonNull AudioDeviceAttributes device,
@NonNull VolumeInfo volume,
+ boolean handlesVolumeAdjustment,
@NonNull @CallbackExecutor Executor executor,
- @NonNull AudioDeviceVolumeManager.OnAudioDeviceVolumeChangedListener vclistener,
- boolean handlesVolumeAdjustment);
+ @NonNull AudioDeviceVolumeManager.OnAudioDeviceVolumeChangedListener vclistener);
/**
* Wrapper for {@link AudioDeviceVolumeManager#setDeviceAbsoluteVolumeAdjustOnlyBehavior(
@@ -69,7 +69,7 @@
void setDeviceAbsoluteVolumeAdjustOnlyBehavior(
@NonNull AudioDeviceAttributes device,
@NonNull VolumeInfo volume,
+ boolean handlesVolumeAdjustment,
@NonNull @CallbackExecutor Executor executor,
- @NonNull AudioDeviceVolumeManager.OnAudioDeviceVolumeChangedListener vclistener,
- boolean handlesVolumeAdjustment);
+ @NonNull AudioDeviceVolumeManager.OnAudioDeviceVolumeChangedListener vclistener);
}
diff --git a/services/core/java/com/android/server/hdmi/DefaultAudioDeviceVolumeManagerWrapper.java b/services/core/java/com/android/server/hdmi/DefaultAudioDeviceVolumeManagerWrapper.java
index ff99ace..10cbb00 100644
--- a/services/core/java/com/android/server/hdmi/DefaultAudioDeviceVolumeManagerWrapper.java
+++ b/services/core/java/com/android/server/hdmi/DefaultAudioDeviceVolumeManagerWrapper.java
@@ -61,21 +61,21 @@
public void setDeviceAbsoluteVolumeBehavior(
@NonNull AudioDeviceAttributes device,
@NonNull VolumeInfo volume,
+ boolean handlesVolumeAdjustment,
@NonNull @CallbackExecutor Executor executor,
- @NonNull AudioDeviceVolumeManager.OnAudioDeviceVolumeChangedListener vclistener,
- boolean handlesVolumeAdjustment) {
- mAudioDeviceVolumeManager.setDeviceAbsoluteVolumeBehavior(device, volume, executor,
- vclistener, handlesVolumeAdjustment);
+ @NonNull AudioDeviceVolumeManager.OnAudioDeviceVolumeChangedListener vclistener) {
+ mAudioDeviceVolumeManager.setDeviceAbsoluteVolumeBehavior(device, volume,
+ handlesVolumeAdjustment, executor, vclistener);
}
@Override
public void setDeviceAbsoluteVolumeAdjustOnlyBehavior(
@NonNull AudioDeviceAttributes device,
@NonNull VolumeInfo volume,
+ boolean handlesVolumeAdjustment,
@NonNull @CallbackExecutor Executor executor,
- @NonNull AudioDeviceVolumeManager.OnAudioDeviceVolumeChangedListener vclistener,
- boolean handlesVolumeAdjustment) {
+ @NonNull AudioDeviceVolumeManager.OnAudioDeviceVolumeChangedListener vclistener) {
mAudioDeviceVolumeManager.setDeviceAbsoluteVolumeAdjustOnlyBehavior(device, volume,
- executor, vclistener, handlesVolumeAdjustment);
+ handlesVolumeAdjustment, executor, vclistener);
}
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 89f0d0e..6d973ac 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -4798,15 +4798,15 @@
Slog.d(TAG, "Enabling absolute volume behavior");
for (AudioDeviceAttributes device : getAvbCapableAudioOutputDevices()) {
getAudioDeviceVolumeManager().setDeviceAbsoluteVolumeBehavior(
- device, volumeInfo, mServiceThreadExecutor,
- mAbsoluteVolumeChangedListener, true);
+ device, volumeInfo, true, mServiceThreadExecutor,
+ mAbsoluteVolumeChangedListener);
}
} else if (tv() != null) {
Slog.d(TAG, "Enabling adjust-only absolute volume behavior");
for (AudioDeviceAttributes device : getAvbCapableAudioOutputDevices()) {
getAudioDeviceVolumeManager().setDeviceAbsoluteVolumeAdjustOnlyBehavior(
- device, volumeInfo, mServiceThreadExecutor,
- mAbsoluteVolumeChangedListener, true);
+ device, volumeInfo, true, mServiceThreadExecutor,
+ mAbsoluteVolumeChangedListener);
}
}
diff --git a/services/core/java/com/android/server/input/InputManagerInternal.java b/services/core/java/com/android/server/input/InputManagerInternal.java
index 87f693c..1ace41c 100644
--- a/services/core/java/com/android/server/input/InputManagerInternal.java
+++ b/services/core/java/com/android/server/input/InputManagerInternal.java
@@ -344,4 +344,42 @@
*/
public abstract void applyBackupPayload(Map<Integer, byte[]> payload, int userId)
throws XmlPullParserException, IOException;
+
+ /**
+ * An interface for filtering pointer motion event before cursor position is determined.
+ * <p>
+ * Different from {@code android.view.InputFilter}, this filter can filter motion events at
+ * an early stage of the input pipeline, but only called for pointer's relative motion events.
+ * Unless the user really needs to filter events before the cursor position in the display is
+ * determined, use {@code android.view.InputFilter} instead.
+ */
+ public interface AccessibilityPointerMotionFilter {
+ /**
+ * Called everytime pointer's relative motion event happens.
+ * The returned dx and dy will be used to move the cursor in the display.
+ * <p>
+ * This call happens on the input hot path and it is extremely performance sensitive. It
+ * also must not call back into native code.
+ *
+ * @param dx delta x of the event in pixels.
+ * @param dy delta y of the event in pixels.
+ * @param currentX the cursor x coordinate on the screen before the motion event.
+ * @param currentY the cursor y coordinate on the screen before the motion event.
+ * @param displayId the display ID of the current cursor.
+ * @return an array of length 2, delta x and delta y after filtering the motion. The delta
+ * values are in pixels and must be between 0 and original delta.
+ */
+ @NonNull
+ float[] filterPointerMotionEvent(float dx, float dy, float currentX, float currentY,
+ int displayId);
+ }
+
+ /**
+ * Registers an {@code AccessibilityCursorFilter}.
+ *
+ * @param filter The filter to register. If a filter is already registered, the old filter is
+ * unregistered. {@code null} unregisters the filter that is already registered.
+ */
+ public abstract void registerAccessibilityPointerMotionFilter(
+ @Nullable AccessibilityPointerMotionFilter filter);
}
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 8624f42..0e37238 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -25,8 +25,8 @@
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
import static com.android.hardware.input.Flags.enableCustomizableInputGestures;
-import static com.android.hardware.input.Flags.touchpadVisualizer;
import static com.android.hardware.input.Flags.keyEventActivityDetection;
+import static com.android.hardware.input.Flags.touchpadVisualizer;
import static com.android.hardware.input.Flags.useKeyGestureEventHandler;
import static com.android.server.policy.WindowManagerPolicy.ACTION_PASS_TO_USER;
@@ -193,15 +193,11 @@
private static final int MSG_SYSTEM_READY = 5;
private static final int DEFAULT_VIBRATION_MAGNITUDE = 192;
- private static final AdditionalDisplayInputProperties
- DEFAULT_ADDITIONAL_DISPLAY_INPUT_PROPERTIES = new AdditionalDisplayInputProperties();
private final NativeInputManagerService mNative;
private final Context mContext;
private final InputManagerHandler mHandler;
- @UserIdInt
- private int mCurrentUserId = UserHandle.USER_SYSTEM;
private DisplayManagerInternal mDisplayManagerInternal;
private WindowManagerInternal mWindowManagerInternal;
@@ -289,7 +285,7 @@
final Object mKeyEventActivityLock = new Object();
@GuardedBy("mKeyEventActivityLock")
- private List<IKeyEventActivityListener> mKeyEventActivityListenersToNotify =
+ private final List<IKeyEventActivityListener> mKeyEventActivityListenersToNotify =
new ArrayList<>();
// Rate limit for key event activity detection. Prevent the listener from being notified
@@ -460,6 +456,14 @@
private boolean mShowKeyPresses = false;
private boolean mShowRotaryInput = false;
+ /**
+ * A lock for the accessibility pointer motion filter. Don't call native methods while holding
+ * this lock.
+ */
+ private final Object mAccessibilityPointerMotionFilterLock = new Object();
+ private InputManagerInternal.AccessibilityPointerMotionFilter
+ mAccessibilityPointerMotionFilter = null;
+
/** Point of injection for test dependencies. */
@VisibleForTesting
static class Injector {
@@ -2593,6 +2597,23 @@
// Native callback.
@SuppressWarnings("unused")
+ final float[] filterPointerMotion(float dx, float dy, float currentX, float currentY,
+ int displayId) {
+ // This call happens on the input hot path and it is extremely performance sensitive.
+ // This must not call back into native code. This is called while the
+ // PointerChoreographer's lock is held.
+ synchronized (mAccessibilityPointerMotionFilterLock) {
+ if (mAccessibilityPointerMotionFilter == null) {
+ throw new IllegalStateException(
+ "filterCursor is invoked but no callback is registered.");
+ }
+ return mAccessibilityPointerMotionFilter.filterPointerMotionEvent(dx, dy, currentX,
+ currentY, displayId);
+ }
+ }
+
+ // Native callback.
+ @SuppressWarnings("unused")
@VisibleForTesting
public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {
notifyKeyActivityListeners(event);
@@ -3215,7 +3236,6 @@
}
private void handleCurrentUserChanged(@UserIdInt int userId) {
- mCurrentUserId = userId;
mKeyGestureController.setCurrentUserId(userId);
}
@@ -3828,6 +3848,12 @@
payload.get(BACKUP_CATEGORY_INPUT_GESTURES), userId);
}
}
+
+ @Override
+ public void registerAccessibilityPointerMotionFilter(
+ AccessibilityPointerMotionFilter filter) {
+ InputManagerService.this.registerAccessibilityPointerMotionFilter(filter);
+ }
}
@Override
@@ -4014,6 +4040,26 @@
mPointerIconCache.setAccessibilityScaleFactor(displayId, scaleFactor);
}
+ void registerAccessibilityPointerMotionFilter(
+ InputManagerInternal.AccessibilityPointerMotionFilter filter) {
+ // `#filterPointerMotion` expects that when it's called, `mAccessibilityPointerMotionFilter`
+ // is not null.
+ // Also, to avoid potential lock contention, we shouldn't call native method while holding
+ // the lock here. Native code calls `#filterPointerMotion` while PointerChoreographer's
+ // lock is held.
+ // Thus, we must set filter before we enable the filter in native, and reset the filter
+ // after we disable the filter.
+ // This also ensures the previously installed filter isn't called after the filter is
+ // updated.
+ mNative.setAccessibilityPointerMotionFilterEnabled(false);
+ synchronized (mAccessibilityPointerMotionFilterLock) {
+ mAccessibilityPointerMotionFilter = filter;
+ }
+ if (filter != null) {
+ mNative.setAccessibilityPointerMotionFilterEnabled(true);
+ }
+ }
+
interface KeyboardBacklightControllerInterface {
default void incrementKeyboardBacklight(int deviceId) {}
default void decrementKeyboardBacklight(int deviceId) {}
diff --git a/services/core/java/com/android/server/input/NativeInputManagerService.java b/services/core/java/com/android/server/input/NativeInputManagerService.java
index f34338a..32409d3 100644
--- a/services/core/java/com/android/server/input/NativeInputManagerService.java
+++ b/services/core/java/com/android/server/input/NativeInputManagerService.java
@@ -315,6 +315,16 @@
*/
boolean setKernelWakeEnabled(int deviceId, boolean enabled);
+ /**
+ * Set whether the accessibility pointer motion filter is enabled.
+ * <p>
+ * Once enabled, {@link InputManagerService#filterPointerMotion} is called for evety motion
+ * event from pointer devices.
+ *
+ * @param enabled {@code true} if the filter is enabled, {@code false} otherwise.
+ */
+ void setAccessibilityPointerMotionFilterEnabled(boolean enabled);
+
/** The native implementation of InputManagerService methods. */
class NativeImpl implements NativeInputManagerService {
/** Pointer to native input manager service object, used by native code. */
@@ -628,5 +638,8 @@
@Override
public native boolean setKernelWakeEnabled(int deviceId, boolean enabled);
+
+ @Override
+ public native void setAccessibilityPointerMotionFilterEnabled(boolean enabled);
}
}
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 334e7b5..508bc2f 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -365,7 +365,7 @@
return mCurrentImeUserId;
}
- /**
+ /**
* Figures out the target IME user ID associated with the given {@code displayId}.
*
* @param displayId the display ID to be queried about
@@ -1332,8 +1332,8 @@
// Do not reset the default (current) IME when it is a 3rd-party IME
String selectedMethodId = bindingController.getSelectedMethodId();
final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
- if (selectedMethodId != null && settings.getMethodMap().get(selectedMethodId) != null
- && !settings.getMethodMap().get(selectedMethodId).isSystem()) {
+ final InputMethodInfo selectedImi = settings.getMethodMap().get(selectedMethodId);
+ if (selectedImi != null && !selectedImi.isSystem()) {
return;
}
final List<InputMethodInfo> suitableImes = InputMethodInfoUtils.getDefaultEnabledImes(
diff --git a/services/core/java/com/android/server/notification/NotificationRecordLogger.java b/services/core/java/com/android/server/notification/NotificationRecordLogger.java
index 6c0035b..f680ce7 100644
--- a/services/core/java/com/android/server/notification/NotificationRecordLogger.java
+++ b/services/core/java/com/android/server/notification/NotificationRecordLogger.java
@@ -514,11 +514,14 @@
final int fsi_state;
final boolean is_locked;
final int age_in_minutes;
+ final boolean is_promoted_ongoing;
+ final boolean has_promotable_characteristics;
@DurationMillisLong long post_duration_millis; // Not final; calculated at the end.
NotificationReported(NotificationRecordPair p,
NotificationReportedEvent eventType, int position, int buzzBeepBlink,
InstanceId groupId) {
+ final Notification notification = p.r.getSbn().getNotification();
this.event_id = eventType.getId();
this.uid = p.r.getUid();
this.package_name = p.r.getSbn().getPackageName();
@@ -527,8 +530,8 @@
this.channel_id_hash = p.getChannelIdHash();
this.group_id_hash = p.getGroupIdHash();
this.group_instance_id = (groupId == null) ? 0 : groupId.getId();
- this.is_group_summary = p.r.getSbn().getNotification().isGroupSummary();
- this.category = p.r.getSbn().getNotification().category;
+ this.is_group_summary = notification.isGroupSummary();
+ this.category = notification.category;
this.style = p.getStyle();
this.num_people = p.getNumPeople();
this.position = position;
@@ -542,22 +545,18 @@
this.assistant_ranking_score = p.r.getRankingScore();
this.is_ongoing = p.r.getSbn().isOngoing();
this.is_foreground_service = NotificationRecordLogger.isForegroundService(p.r);
- this.timeout_millis = p.r.getSbn().getNotification().getTimeoutAfter();
+ this.timeout_millis = notification.getTimeoutAfter();
this.is_non_dismissible = NotificationRecordLogger.isNonDismissible(p.r);
-
- final boolean hasFullScreenIntent =
- p.r.getSbn().getNotification().fullScreenIntent != null;
-
- final boolean hasFsiRequestedButDeniedFlag = (p.r.getSbn().getNotification().flags
- & Notification.FLAG_FSI_REQUESTED_BUT_DENIED) != 0;
-
+ final boolean hasFullScreenIntent = notification.fullScreenIntent != null;
+ final boolean hasFsiRequestedButDeniedFlag =
+ (notification.flags & Notification.FLAG_FSI_REQUESTED_BUT_DENIED) != 0;
this.fsi_state = NotificationRecordLogger.getFsiState(
hasFullScreenIntent, hasFsiRequestedButDeniedFlag, eventType);
-
this.is_locked = p.r.isLocked();
-
this.age_in_minutes = NotificationRecordLogger.getAgeInMinutes(
- p.r.getSbn().getPostTime(), p.r.getSbn().getNotification().getWhen());
+ p.r.getSbn().getPostTime(), notification.getWhen());
+ this.is_promoted_ongoing = notification.isPromotedOngoing();
+ this.has_promotable_characteristics = notification.hasPromotableCharacteristics();
}
}
diff --git a/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java b/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java
index fc0a776..e0e3fba 100644
--- a/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java
+++ b/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java
@@ -78,7 +78,9 @@
notificationReported.post_duration_millis,
notificationReported.fsi_state,
notificationReported.is_locked,
- notificationReported.age_in_minutes);
+ notificationReported.age_in_minutes,
+ notificationReported.is_promoted_ongoing,
+ notificationReported.has_promotable_characteristics);
}
@Override
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index f7a4d3d..889df51 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -157,6 +157,12 @@
static final int RULE_LIMIT_PER_PACKAGE = 100;
private static final Duration DELETED_RULE_KEPT_FOR = Duration.ofDays(30);
+ /**
+ * Amount of time since last activation after which implicit rules that have never been
+ * customized by the user are automatically cleaned up.
+ */
+ private static final Duration IMPLICIT_RULE_KEPT_FOR = Duration.ofDays(30);
+
private static final int MAX_ICON_RESOURCE_NAME_LENGTH = 1000;
/**
@@ -534,7 +540,7 @@
ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID);
if (sleepingRule != null
&& !sleepingRule.enabled
- && sleepingRule.canBeUpdatedByApp() /* meaning it's not user-customized */) {
+ && !sleepingRule.isUserModified()) {
config.automaticRules.remove(ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID);
}
}
@@ -864,7 +870,7 @@
// We don't try to preserve system-owned rules because their conditionIds (used as
// deletedRuleKey) are not stable. This is almost moot anyway because an app cannot
// delete a system-owned rule.
- if (origin == ORIGIN_APP && !ruleToRemove.canBeUpdatedByApp()
+ if (origin == ORIGIN_APP && ruleToRemove.isUserModified()
&& !PACKAGE_ANDROID.equals(ruleToRemove.pkg)) {
String deletedKey = ZenModeConfig.deletedRuleKey(ruleToRemove);
if (deletedKey != null) {
@@ -1282,7 +1288,7 @@
// * the request comes from an origin that can always update values, like the user, or
// * the rule has not yet been user modified, and thus can be updated by the app.
boolean updateValues = isNew || doesOriginAlwaysUpdateValues(origin)
- || rule.canBeUpdatedByApp();
+ || !rule.isUserModified();
// For all other values, if updates are not allowed, we discard the update.
if (!updateValues) {
@@ -1914,6 +1920,7 @@
* <ul>
* <li>Rule instances whose owner is not installed.
* <li>Deleted rules that were deleted more than 30 days ago.
+ * <li>Implicit rules that haven't been used in 30 days (and have not been customized).
* </ul>
*/
private void cleanUpZenRules() {
@@ -1932,6 +1939,10 @@
}
}
+ if (Flags.modesUi() && Flags.modesCleanupImplicit()) {
+ deleteUnusedImplicitRules(newConfig.automaticRules);
+ }
+
if (!newConfig.equals(mConfig)) {
setConfigLocked(newConfig, null, ORIGIN_SYSTEM,
"cleanUpZenRules", Process.SYSTEM_UID);
@@ -1957,6 +1968,29 @@
}
}
+ private void deleteUnusedImplicitRules(ArrayMap<String, ZenRule> ruleList) {
+ if (ruleList == null) {
+ return;
+ }
+ Instant deleteIfUnusedSince = mClock.instant().minus(IMPLICIT_RULE_KEPT_FOR);
+
+ for (int i = ruleList.size() - 1; i >= 0; i--) {
+ ZenRule rule = ruleList.valueAt(i);
+ if (isImplicitRuleId(rule.id) && !rule.isUserModified()) {
+ if (rule.lastActivation == null) {
+ // This rule existed before we started tracking activation time. It *might* be
+ // in use. Set lastActivation=now so it has some time (IMPLICIT_RULE_KEPT_FOR)
+ // before being removed if truly unused.
+ rule.lastActivation = mClock.instant();
+ }
+
+ if (rule.lastActivation.isBefore(deleteIfUnusedSince)) {
+ ruleList.removeAt(i);
+ }
+ }
+ }
+ }
+
/**
* @return a copy of the zen mode configuration
*/
@@ -2091,6 +2125,20 @@
}
}
+ // Update last activation for rules that are being activated.
+ if (Flags.modesUi() && Flags.modesCleanupImplicit()) {
+ Instant now = mClock.instant();
+ if (!mConfig.isManualActive() && config.isManualActive()) {
+ config.manualRule.lastActivation = now;
+ }
+ for (ZenRule rule : config.automaticRules.values()) {
+ ZenRule previousRule = mConfig.automaticRules.get(rule.id);
+ if (rule.isActive() && (previousRule == null || !previousRule.isActive())) {
+ rule.lastActivation = now;
+ }
+ }
+ }
+
mConfig = config;
dispatchOnConfigChanged();
updateAndApplyConsolidatedPolicyAndDeviceEffects(origin, reason);
diff --git a/services/core/java/com/android/server/pm/BackgroundInstallControlService.java b/services/core/java/com/android/server/pm/BackgroundInstallControlService.java
index d538bb8..c3af578 100644
--- a/services/core/java/com/android/server/pm/BackgroundInstallControlService.java
+++ b/services/core/java/com/android/server/pm/BackgroundInstallControlService.java
@@ -176,16 +176,13 @@
if (Flags.bicClient()) {
mService.enforceCallerPermissions();
}
- if (!Build.IS_DEBUGGABLE) {
- return mService.getBackgroundInstalledPackages(flags, userId);
- }
// The debug.transparency.bg-install-apps (only works for debuggable builds)
// is used to set mock list of background installed apps for testing.
// The list of apps' names is delimited by ",".
// TODO: Remove after migrating test to new background install method using
// {@link BackgroundInstallControlCallbackHelperTest}.installPackage b/310983905
String propertyString = SystemProperties.get("debug.transparency.bg-install-apps");
- if (TextUtils.isEmpty(propertyString)) {
+ if (TextUtils.isEmpty(propertyString) || !Build.IS_DEBUGGABLE) {
return mService.getBackgroundInstalledPackages(flags, userId);
} else {
return mService.getMockBackgroundInstalledPackages(propertyString);
@@ -219,10 +216,27 @@
PackageManager.PackageInfoFlags.of(flags), userId);
initBackgroundInstalledPackages();
+ if(Build.IS_DEBUGGABLE) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("Tracked background installed package size: ")
+ .append(mBackgroundInstalledPackages.size())
+ .append("\n");
+ for (int i = 0; i < mBackgroundInstalledPackages.size(); ++i) {
+ int installingUserId = mBackgroundInstalledPackages.keyAt(i);
+ mBackgroundInstalledPackages.get(installingUserId).forEach(pkgName ->
+ sb.append("userId: ").append(installingUserId)
+ .append(", name: ").append(pkgName).append("\n"));
+ }
+ Slog.d(TAG, "Tracked background installed package: " + sb.toString());
+ }
+
ListIterator<PackageInfo> iter = packages.listIterator();
while (iter.hasNext()) {
String packageName = iter.next().packageName;
if (!mBackgroundInstalledPackages.contains(userId, packageName)) {
+ if(Build.IS_DEBUGGABLE) {
+ Slog.d(TAG, packageName + " is not tracked, removing");
+ }
iter.remove();
}
}
@@ -284,6 +298,9 @@
}
void handlePackageAdd(String packageName, int userId) {
+ if(Build.IS_DEBUGGABLE) {
+ Slog.d(TAG, "handlePackageAdd: checking " + packageName);
+ }
ApplicationInfo appInfo = null;
try {
appInfo =
@@ -302,7 +319,7 @@
installerPackageName = installInfo.getInstallingPackageName();
initiatingPackageName = installInfo.getInitiatingPackageName();
} catch (PackageManager.NameNotFoundException e) {
- Slog.w(TAG, "Package's installer not found " + packageName);
+ Slog.w(TAG, "Package's installer not found: " + packageName);
return;
}
@@ -314,6 +331,10 @@
VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT,
userId)
!= PERMISSION_GRANTED) {
+ if(Build.IS_DEBUGGABLE) {
+ Slog.d(TAG, "handlePackageAdd " + packageName + ": installer doesn't "
+ + "have INSTALL_PACKAGES permission, skipping");
+ }
return;
}
@@ -324,6 +345,10 @@
if (installedByAdb(initiatingPackageName)
|| wasForegroundInstallation(installerPackageName, userId, installTimestamp)) {
+ if(Build.IS_DEBUGGABLE) {
+ Slog.d(TAG, "handlePackageAdd " + packageName + ": is installed by ADB or was "
+ + "foreground installation, skipping");
+ }
return;
}
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index 15688c0..2811747 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -204,6 +204,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
@@ -1023,6 +1024,7 @@
*/
void installPackagesTraced(List<InstallRequest> requests, MoveInfo moveInfo) {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackages");
+ boolean pendingForDexopt = false;
boolean success = false;
final Map<String, Boolean> createdAppId = new ArrayMap<>(requests.size());
final Map<String, Settings.VersionInfo> versionInfos = new ArrayMap<>(requests.size());
@@ -1036,17 +1038,41 @@
if (reconciledPackages == null) {
return;
}
+
if (renameAndUpdatePaths(requests)) {
// rename before dexopt because art will encoded the path in the odex/vdex file
if (Flags.improveInstallFreeze()) {
- prepPerformDexoptIfNeeded(reconciledPackages);
- }
- if (commitInstallPackages(reconciledPackages)) {
- success = true;
+ pendingForDexopt = true;
+ final Runnable actionsAfterDexopt = () ->
+ doPostDexopt(reconciledPackages, requests,
+ createdAppId, moveInfo, acquireTime);
+ prepPerformDexoptIfNeeded(reconciledPackages, actionsAfterDexopt);
+ } else {
+ if (commitInstallPackages(reconciledPackages)) {
+ success = true;
+ }
}
}
}
} finally {
+ if (!pendingForDexopt) {
+ completeInstallProcess(requests, createdAppId, success);
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ doPostInstall(requests, moveInfo);
+ releaseWakeLock(acquireTime, requests.size());
+ }
+ }
+ }
+
+ void doPostDexopt(List<ReconciledPackage> reconciledPackages,
+ List<InstallRequest> requests, Map<String, Boolean> createdAppId,
+ MoveInfo moveInfo, long acquireTime) {
+ boolean success = false;
+ try {
+ if (commitInstallPackages(reconciledPackages)) {
+ success = true;
+ }
+ } finally {
completeInstallProcess(requests, createdAppId, success);
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
doPostInstall(requests, moveInfo);
@@ -1123,7 +1149,7 @@
throws PackageManagerException {
final int userId = installRequest.getUserId();
if (userId != UserHandle.USER_ALL && userId != UserHandle.USER_CURRENT
- && !mPm.mUserManager.exists(userId)) {
+ && !ArrayUtils.contains(allUsers, userId)) {
throw new PackageManagerException(PackageManagerException.INTERNAL_ERROR_MISSING_USER,
"User " + userId + " doesn't exist or has been removed");
}
@@ -1155,7 +1181,9 @@
}
}
- private void prepPerformDexoptIfNeeded(List<ReconciledPackage> reconciledPackages) {
+ private void prepPerformDexoptIfNeeded(List<ReconciledPackage> reconciledPackages,
+ Runnable actionsAfterDexopt) {
+ List<CompletableFuture<Void>> completableFutures = new ArrayList<>();
for (ReconciledPackage reconciledPkg : reconciledPackages) {
final InstallRequest request = reconciledPkg.mInstallRequest;
// prepare profiles
@@ -1171,6 +1199,7 @@
mSharedLibraries.executeSharedLibrariesUpdate(request.getParsedPackage(), ps,
null, null, reconciledPkg.mCollectedSharedLibraryInfos, allUsers);
}
+
try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) {
final int[] newUsers = getNewUsers(request, allUsers);
// Hardcode previousAppId to 0 to disable any data migration (http://b/221088088)
@@ -1182,11 +1211,22 @@
}
} catch (PackageManagerException e) {
request.setError(e.error, e.getMessage());
- return;
+ break;
}
request.setKeepArtProfile(true);
- // TODO(b/388159696): Use performDexoptIfNeededAsync.
- DexOptHelper.performDexoptIfNeeded(request, mDexManager, null /* installLock */);
+
+ CompletableFuture<Void> future =
+ DexOptHelper.performDexoptIfNeededAsync(request, mDexManager);
+ completableFutures.add(future);
+ }
+
+ if (!completableFutures.isEmpty()) {
+ CompletableFuture<Void> allFutures =
+ CompletableFuture.allOf(
+ completableFutures.toArray(CompletableFuture[]::new));
+ var unused = allFutures.thenRun(() -> mPm.mHandler.post(actionsAfterDexopt));
+ } else {
+ actionsAfterDexopt.run();
}
}
@@ -2759,6 +2799,7 @@
| Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
}
+ // run synchronous dexopt if the freeze improvement is not supported
DexOptHelper.performDexoptIfNeeded(
installRequest, mDexManager, mPm.mInstallLock.getRawLock());
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index e1fcc66..2d0bb25 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -805,22 +805,20 @@
}
}
- if (Flags.recoverabilityDetection()) {
- if (params.rollbackImpactLevel == PackageManager.ROLLBACK_USER_IMPACT_HIGH
- || params.rollbackImpactLevel
- == PackageManager.ROLLBACK_USER_IMPACT_ONLY_MANUAL) {
- if ((params.installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) == 0) {
- throw new IllegalArgumentException(
- "Can't set rollbackImpactLevel when rollback is not enabled");
- }
- if (mContext.checkCallingOrSelfPermission(Manifest.permission.MANAGE_ROLLBACKS)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException(
- "Setting rollbackImpactLevel requires the MANAGE_ROLLBACKS permission");
- }
- } else if (params.rollbackImpactLevel < 0) {
- throw new IllegalArgumentException("rollbackImpactLevel can't be negative.");
+ if (params.rollbackImpactLevel == PackageManager.ROLLBACK_USER_IMPACT_HIGH
+ || params.rollbackImpactLevel
+ == PackageManager.ROLLBACK_USER_IMPACT_ONLY_MANUAL) {
+ if ((params.installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) == 0) {
+ throw new IllegalArgumentException(
+ "Can't set rollbackImpactLevel when rollback is not enabled");
}
+ if (mContext.checkCallingOrSelfPermission(Manifest.permission.MANAGE_ROLLBACKS)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException(
+ "Setting rollbackImpactLevel requires the MANAGE_ROLLBACKS permission");
+ }
+ } else if (params.rollbackImpactLevel < 0) {
+ throw new IllegalArgumentException("rollbackImpactLevel can't be negative.");
}
boolean isApex = (params.installFlags & PackageManager.INSTALL_APEX) != 0;
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index aa235c2..cf598e8 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -3561,9 +3561,6 @@
sessionParams.setEnableRollback(true, rollbackStrategy);
break;
case "--rollback-impact-level":
- if (!Flags.recoverabilityDetection()) {
- throw new IllegalArgumentException("Unknown option " + opt);
- }
int rollbackImpactLevel = Integer.parseInt(peekNextArg());
if (rollbackImpactLevel < PackageManager.ROLLBACK_USER_IMPACT_LOW
|| rollbackImpactLevel
@@ -4775,11 +4772,9 @@
pw.println(" --full: cause the app to be installed as a non-ephemeral full app");
pw.println(" --enable-rollback: enable rollbacks for the upgrade.");
pw.println(" 0=restore (default), 1=wipe, 2=retain");
- if (Flags.recoverabilityDetection()) {
- pw.println(
- " --rollback-impact-level: set device impact required for rollback.");
- pw.println(" 0=low (default), 1=high, 2=manual only");
- }
+ pw.println(
+ " --rollback-impact-level: set device impact required for rollback.");
+ pw.println(" 0=low (default), 1=high, 2=manual only");
pw.println(" --install-location: force the install location:");
pw.println(" 0=auto, 1=internal only, 2=prefer external");
pw.println(" --install-reason: indicates why the app is being installed:");
diff --git a/services/core/java/com/android/server/pm/VerifyingSession.java b/services/core/java/com/android/server/pm/VerifyingSession.java
index dd60a15..8510ee7 100644
--- a/services/core/java/com/android/server/pm/VerifyingSession.java
+++ b/services/core/java/com/android/server/pm/VerifyingSession.java
@@ -179,8 +179,7 @@
// Perform package verification and enable rollback (unless we are simply moving the
// package).
if (!mOriginInfo.mExisting) {
- final boolean verifyForRollback = Flags.recoverabilityDetection()
- ? !isARollback() : true;
+ final boolean verifyForRollback = !isARollback();
if (!isApex() && !isArchivedInstallation() && verifyForRollback) {
// TODO(b/182426975): treat APEX as APK when APK verification is concerned
sendApkVerificationRequest(pkgLite);
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 4153cd1..76c5240 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -1163,15 +1163,6 @@
}
}
- private boolean shouldShowHub() {
- final boolean hubEnabled = Settings.Secure.getIntForUser(
- mContext.getContentResolver(), Settings.Secure.GLANCEABLE_HUB_ENABLED,
- 1, mCurrentUserId) == 1;
-
- return mUserManagerInternal.isUserUnlocked(mCurrentUserId) && hubEnabled
- && mDreamManagerInternal.dreamConditionActive();
- }
-
@VisibleForTesting
void powerPress(long eventTime, int count, int displayId) {
// SideFPS still needs to know about suppressed power buttons, in case it needs to block
@@ -1270,10 +1261,9 @@
// show hub.
boolean keyguardAvailable = !mLockPatternUtils.isLockScreenDisabled(
mCurrentUserId);
- if (shouldShowHub() && keyguardAvailable) {
- // If the hub can be launched, send a message to keyguard. We do not know if
- // the hub is already running or not, keyguard handles turning screen off if
- // it is.
+ if (mUserManagerInternal.isUserUnlocked(mCurrentUserId) && hubEnabled
+ && keyguardAvailable && mDreamManagerInternal.dreamConditionActive()) {
+ // If the hub can be launched, send a message to keyguard.
Bundle options = new Bundle();
options.putBoolean(EXTRA_TRIGGER_HUB, true);
lockNow(options);
@@ -1334,14 +1324,14 @@
* @param isScreenOn Whether the screen is currently on.
* @param noDreamAction The action to perform if dreaming is not possible.
*/
- private boolean attemptToDreamFromShortPowerButtonPress(
+ private void attemptToDreamFromShortPowerButtonPress(
boolean isScreenOn, Runnable noDreamAction) {
if (mShortPressOnPowerBehavior != SHORT_PRESS_POWER_DREAM_OR_SLEEP
&& mShortPressOnPowerBehavior != SHORT_PRESS_POWER_HUB_OR_DREAM_OR_SLEEP) {
// If the power button behavior isn't one that should be able to trigger the dream, give
// up.
noDreamAction.run();
- return false;
+ return;
}
final DreamManagerInternal dreamManagerInternal = getDreamManagerInternal();
@@ -1349,7 +1339,7 @@
Slog.d(TAG, "Can't start dreaming when attempting to dream from short power"
+ " press (isScreenOn=" + isScreenOn + ")");
noDreamAction.run();
- return false;
+ return;
}
synchronized (mLock) {
@@ -1360,8 +1350,6 @@
}
dreamManagerInternal.requestDream();
-
- return true;
}
/**
@@ -6410,17 +6398,6 @@
event.getDisplayId(), event.getKeyCode(), "wakeUpFromWakeKey")) {
return;
}
-
- if (!shouldShowHub()
- && mShortPressOnPowerBehavior == SHORT_PRESS_POWER_HUB_OR_DREAM_OR_SLEEP
- && event.getKeyCode() == KEYCODE_POWER
- && attemptToDreamFromShortPowerButtonPress(false, () -> {})) {
- // In the case that we should wake to dream and successfully initiate dreaming, do not
- // continue waking up. Doing so will exit the dream state and cause UI to react
- // accordingly.
- return;
- }
-
wakeUpFromWakeKey(
event.getEventTime(),
event.getKeyCode(),
diff --git a/services/core/java/com/android/server/rollback/Rollback.java b/services/core/java/com/android/server/rollback/Rollback.java
index ab756f2..5347ca4 100644
--- a/services/core/java/com/android/server/rollback/Rollback.java
+++ b/services/core/java/com/android/server/rollback/Rollback.java
@@ -29,7 +29,6 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
-import android.content.pm.Flags;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
@@ -965,9 +964,7 @@
ipw.println("-stateDescription: " + mStateDescription);
ipw.println("-timestamp: " + getTimestamp());
ipw.println("-rollbackLifetimeMillis: " + getRollbackLifetimeMillis());
- if (Flags.recoverabilityDetection()) {
- ipw.println("-rollbackImpactLevel: " + info.getRollbackImpactLevel());
- }
+ ipw.println("-rollbackImpactLevel: " + info.getRollbackImpactLevel());
ipw.println("-isStaged: " + isStaged());
ipw.println("-originalSessionId: " + getOriginalSessionId());
ipw.println("-packages:");
diff --git a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
index 2e6be5b..9ed52d8 100644
--- a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
+++ b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
@@ -1244,17 +1244,12 @@
rollback.makeAvailable();
mPackageHealthObserver.notifyRollbackAvailable(rollback.info);
- if (Flags.recoverabilityDetection()) {
- if (rollback.info.getRollbackImpactLevel() == PackageManager.ROLLBACK_USER_IMPACT_LOW) {
- // TODO(zezeozue): Provide API to explicitly start observing instead
- // of doing this for all rollbacks. If we do this for all rollbacks,
- // should document in PackageInstaller.SessionParams#setEnableRollback
- // After enabling and committing any rollback, observe packages and
- // prepare to rollback if packages crashes too frequently.
- mPackageWatchdog.startExplicitHealthCheck(rollback.getPackageNames(),
- mRollbackLifetimeDurationInMillis, mPackageHealthObserver);
- }
- } else {
+ if (rollback.info.getRollbackImpactLevel() == PackageManager.ROLLBACK_USER_IMPACT_LOW) {
+ // TODO(zezeozue): Provide API to explicitly start observing instead
+ // of doing this for all rollbacks. If we do this for all rollbacks,
+ // should document in PackageInstaller.SessionParams#setEnableRollback
+ // After enabling and committing any rollback, observe packages and
+ // prepare to rollback if packages crashes too frequently.
mPackageWatchdog.startExplicitHealthCheck(rollback.getPackageNames(),
mRollbackLifetimeDurationInMillis, mPackageHealthObserver);
}
diff --git a/services/core/java/com/android/server/rollback/RollbackStore.java b/services/core/java/com/android/server/rollback/RollbackStore.java
index 50db1e4..6dc4032 100644
--- a/services/core/java/com/android/server/rollback/RollbackStore.java
+++ b/services/core/java/com/android/server/rollback/RollbackStore.java
@@ -197,9 +197,7 @@
json.put("isStaged", rollback.isStaged());
json.put("causePackages", versionedPackagesToJson(rollback.getCausePackages()));
json.put("committedSessionId", rollback.getCommittedSessionId());
- if (Flags.recoverabilityDetection()) {
- json.put("rollbackImpactLevel", rollback.getRollbackImpactLevel());
- }
+ json.put("rollbackImpactLevel", rollback.getRollbackImpactLevel());
return json;
}
@@ -211,11 +209,9 @@
versionedPackagesFromJson(json.getJSONArray("causePackages")),
json.getInt("committedSessionId"));
- if (Flags.recoverabilityDetection()) {
- // to make it backward compatible.
- rollbackInfo.setRollbackImpactLevel(json.optInt("rollbackImpactLevel",
- PackageManager.ROLLBACK_USER_IMPACT_LOW));
- }
+ // to make it backward compatible.
+ rollbackInfo.setRollbackImpactLevel(json.optInt("rollbackImpactLevel",
+ PackageManager.ROLLBACK_USER_IMPACT_LOW));
return rollbackInfo;
}
diff --git a/services/core/java/com/android/server/vibrator/VibratorManagerService.java b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
index 804cf46..9de46c8 100644
--- a/services/core/java/com/android/server/vibrator/VibratorManagerService.java
+++ b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
@@ -2715,6 +2715,8 @@
addPrebakedToComposition(composition);
} else if ("primitives".equals(nextArg)) {
addPrimitivesToComposition(composition);
+ } else if ("envelope".equals(nextArg)) {
+ addEnvelopeToComposition(composition);
} else {
// nextArg is not an effect, finish reading.
break;
@@ -2745,6 +2747,121 @@
composition.addEffect(VibrationEffect.createOneShot(duration, amplitude));
}
+ private interface EnvelopeBuilder {
+ void setInitialSharpness(float sharpness);
+ void addControlPoint(float intensity, float sharpness, long duration);
+ void reset(float initialSharpness);
+ VibrationEffect build();
+ }
+
+ private static class BasicEnveloperBuilderWrapper implements EnvelopeBuilder {
+ private VibrationEffect.BasicEnvelopeBuilder mBuilder =
+ new VibrationEffect.BasicEnvelopeBuilder();
+
+ @Override
+ public void setInitialSharpness(float sharpness) {
+ mBuilder.setInitialSharpness(sharpness);
+ }
+
+ @Override
+ public void addControlPoint(float intensity, float sharpness, long duration) {
+ mBuilder.addControlPoint(intensity, sharpness, duration);
+ }
+
+ @Override
+ public void reset(float initialSharpness) {
+ mBuilder = new VibrationEffect.BasicEnvelopeBuilder();
+ mBuilder.setInitialSharpness(initialSharpness);
+ }
+
+ @Override
+ public VibrationEffect build() {
+ return mBuilder.build();
+ }
+ }
+
+ private static class AdvancedEnveloperBuilderWrapper implements EnvelopeBuilder {
+ private VibrationEffect.WaveformEnvelopeBuilder mBuilder =
+ new VibrationEffect.WaveformEnvelopeBuilder();
+
+ @Override
+ public void setInitialSharpness(float sharpness) {
+ mBuilder.setInitialFrequencyHz(sharpness);
+ }
+
+ @Override
+ public void addControlPoint(float intensity, float sharpness, long duration) {
+ mBuilder.addControlPoint(intensity, sharpness, duration);
+ }
+
+ @Override
+ public void reset(float initialSharpness) {
+ mBuilder = new VibrationEffect.WaveformEnvelopeBuilder();
+ mBuilder.setInitialFrequencyHz(initialSharpness);
+ }
+
+ @Override
+ public VibrationEffect build() {
+ return mBuilder.build();
+ }
+ }
+
+ private void addEnvelopeToComposition(VibrationEffect.Composition composition) {
+ getNextArgRequired(); // consume "envelope"
+ int repeat = -1;
+ float initialSharpness = Float.NaN;
+ VibrationEffect preamble = null;
+ boolean isAdvanced = false;
+ String nextOption;
+ while ((nextOption = getNextOption()) != null) {
+ switch (nextOption) {
+ case "-a" -> isAdvanced = true;
+ case "-i" -> initialSharpness = Float.parseFloat(getNextArgRequired());
+ case "-r" -> repeat = Integer.parseInt(getNextArgRequired());
+ }
+ }
+
+ EnvelopeBuilder builder = isAdvanced ? new AdvancedEnveloperBuilderWrapper()
+ : new BasicEnveloperBuilderWrapper();
+
+ if (!Float.isNaN(initialSharpness)) {
+ builder.setInitialSharpness(initialSharpness);
+ }
+
+ int duration, pos = 0;
+ float intensity, sharpness = 0f;
+ String nextArg;
+ while ((nextArg = peekNextArg()) != null) {
+ if (pos > 0 && pos == repeat) {
+ preamble = builder.build();
+ builder.reset(sharpness);
+ }
+ try {
+ duration = Integer.parseInt(nextArg);
+ getNextArgRequired(); // consume the duration
+ } catch (NumberFormatException e) {
+ // nextArg is not a duration, finish reading.
+ break;
+ }
+ intensity = Float.parseFloat(getNextArgRequired());
+ sharpness = Float.parseFloat(getNextArgRequired());
+ builder.addControlPoint(intensity, sharpness, duration);
+ pos++;
+ }
+
+ if (repeat >= 0) {
+ if (preamble == null) {
+ composition.addEffect(VibrationEffect.createRepeatingEffect(builder.build()));
+ } else {
+ composition.addEffect(
+ VibrationEffect.createRepeatingEffect(preamble, builder.build()));
+ }
+ return;
+ }
+
+ composition.addEffect(builder.build());
+ }
+
private void addWaveformToComposition(VibrationEffect.Composition composition) {
boolean hasAmplitudes = false;
boolean hasFrequencies = false;
@@ -2979,6 +3096,20 @@
pw.println(" between values; otherwise each entry is a fixed step.");
pw.println(" Duration is in milliseconds; amplitude is a scale of 1-255;");
pw.println(" frequency is an absolute value in hertz;");
+ pw.print(" envelope [-a] [-i initial sharpness] [-r index] ");
+ pw.println("[<duration1> <intensity1> <sharpness1>]...");
+ pw.println(" Generates a vibration pattern based on a series of duration, ");
+ pw.println(" intensity, and sharpness values. The total vibration time is ");
+ pw.println(" the sum of all durations; Ignored when device is on ");
+ pw.println(" DND (Do Not Disturb) mode; touch feedback strength user setting ");
+ pw.println(" will be used to scale amplitude.");
+ pw.println(" If -a is provided, the waveform will use the advanced APIs to ");
+ pw.println(" generate the vibration pattern and the input parameters ");
+ pw.println(" become [<duration1> <amplitude1> <frequency1>].");
+ pw.println(" If -i is provided, the waveform will have an initial sharpness ");
+ pw.println(" it will start from.");
+ pw.println(" If -r is provided, the waveform loops back to the specified index");
+ pw.println(" (e.g. 0 loops from the beginning).");
pw.println(" prebaked [-w delay] [-b] <effect-id>");
pw.println(" Vibrates with prebaked effect; ignored when device is on DND ");
pw.println(" (Do Not Disturb) mode; touch feedback strength user setting ");
diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
index 6cc17d4..a941838 100644
--- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
@@ -857,8 +857,7 @@
info.mWindowsDrawnDelayMs = info.calculateDelay(timestampNs);
info.mIsDrawn = true;
final TransitionInfoSnapshot infoSnapshot = new TransitionInfoSnapshot(info);
- if (info.mLoggedTransitionStarting || (!r.mDisplayContent.mOpeningApps.contains(r)
- && !r.mTransitionController.isCollecting(r))) {
+ if (info.mLoggedTransitionStarting || !r.mTransitionController.isCollecting(r)) {
done(false /* abort */, info, "notifyWindowsDrawn", timestampNs);
}
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index c37b5a0..ebadeac 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -159,7 +159,6 @@
import static com.android.server.wm.ActivityRecordProto.IN_SIZE_COMPAT_MODE;
import static com.android.server.wm.ActivityRecordProto.IS_ANIMATING;
import static com.android.server.wm.ActivityRecordProto.IS_USER_FULLSCREEN_OVERRIDE_ENABLED;
-import static com.android.server.wm.ActivityRecordProto.IS_WAITING_FOR_TRANSITION_START;
import static com.android.server.wm.ActivityRecordProto.LAST_ALL_DRAWN;
import static com.android.server.wm.ActivityRecordProto.LAST_DROP_INPUT_MODE;
import static com.android.server.wm.ActivityRecordProto.LAST_SURFACE_SHOWING;
@@ -290,6 +289,7 @@
import android.content.pm.UserProperties;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Insets;
import android.graphics.PixelFormat;
@@ -330,7 +330,6 @@
import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;
import android.view.WindowInsets;
-import android.view.WindowInsets.Type;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.view.WindowManager.TransitionOldType;
@@ -354,7 +353,6 @@
import com.android.internal.content.ReferrerIntent;
import com.android.internal.os.TimeoutRecord;
import com.android.internal.os.TransferPipe;
-import com.android.internal.policy.AttributeCache;
import com.android.internal.policy.PhoneWindow;
import com.android.internal.protolog.ProtoLog;
import com.android.internal.util.XmlUtils;
@@ -481,6 +479,8 @@
final String processName; // process where this component wants to run
final String taskAffinity; // as per ActivityInfo.taskAffinity
final boolean stateNotNeeded; // As per ActivityInfo.flags
+ @Nullable
+ final WindowStyle mWindowStyle;
@VisibleForTesting
int mHandoverLaunchDisplayId = INVALID_DISPLAY; // Handover launch display id to next activity.
@VisibleForTesting
@@ -1519,17 +1519,7 @@
this.task = newTask;
if (shouldStartChangeTransition(newParent, oldParent)) {
- if (mTransitionController.isShellTransitionsEnabled()) {
- // For Shell transition, call #initializeChangeTransition directly to take the
- // screenshot at the Activity level. And Shell will be in charge of handling the
- // surface reparent and crop.
- initializeChangeTransition(getBounds());
- } else {
- // For legacy app transition, we want to take a screenshot of the Activity surface,
- // but animate the change transition on TaskFragment level to get the correct window
- // crop.
- newParent.initializeChangeTransition(getBounds(), getSurfaceControl());
- }
+ mTransitionController.collectVisibleChange(this);
}
super.onParentChanged(newParent, oldParent);
@@ -1557,16 +1547,6 @@
mLastReportedPictureInPictureMode = inPinnedWindowingMode();
}
- // When the associated task is {@code null}, the {@link ActivityRecord} can no longer
- // access visual elements like the {@link DisplayContent}. We must remove any associations
- // such as animations.
- if (task == null) {
- // It is possible we have been marked as a closing app earlier. We must remove ourselves
- // from this list so we do not participate in any future animations.
- if (getDisplayContent() != null) {
- getDisplayContent().mClosingApps.remove(this);
- }
- }
final Task rootTask = getRootTask();
if (task == mLastParentBeforePip && task != null) {
// Notify the TaskFragmentOrganizer that the activity is reparented back from pip.
@@ -1749,14 +1729,6 @@
return;
}
prevDc.onRunningActivityChanged();
-
- if (prevDc.mOpeningApps.remove(this)) {
- // Transfer opening transition to new display.
- mDisplayContent.mOpeningApps.add(this);
- mDisplayContent.executeAppTransition();
- }
-
- prevDc.mClosingApps.remove(this);
prevDc.getDisplayPolicy().removeRelaunchingApp(this);
if (prevDc.mFocusedApp == this) {
@@ -1956,22 +1928,17 @@
? android.R.style.Theme : android.R.style.Theme_Holo;
}
- final AttributeCache.Entry ent = AttributeCache.instance().get(packageName,
- realTheme, com.android.internal.R.styleable.Window, mUserId);
-
- if (ent != null) {
- final boolean styleTranslucent = ent.array.getBoolean(
- com.android.internal.R.styleable.Window_windowIsTranslucent, false);
- final boolean styleFloating = ent.array.getBoolean(
- com.android.internal.R.styleable.Window_windowIsFloating, false);
- mOccludesParent = !(styleTranslucent || styleFloating)
+ final WindowStyle style = mAtmService.getWindowStyle(packageName, realTheme, mUserId);
+ mWindowStyle = style;
+ if (style != null) {
+ mOccludesParent = !(style.isTranslucent() || style.isFloating())
// This style is propagated to the main window attributes with
// FLAG_SHOW_WALLPAPER from PhoneWindow#generateLayout.
- || ent.array.getBoolean(R.styleable.Window_windowShowWallpaper, false);
+ || style.showWallpaper();
mStyleFillsParent = mOccludesParent;
- mNoDisplay = ent.array.getBoolean(R.styleable.Window_windowNoDisplay, false);
- mOptOutEdgeToEdge = PhoneWindow.isOptingOutEdgeToEdgeEnforcement(
- aInfo.applicationInfo, false /* local */, ent.array);
+ mNoDisplay = style.noDisplay();
+ mOptOutEdgeToEdge = style.optOutEdgeToEdge() && PhoneWindow.isOptOutEdgeToEdgeEnabled(
+ aInfo.applicationInfo, false /* local */);
} else {
mStyleFillsParent = mOccludesParent = true;
mNoDisplay = false;
@@ -2302,21 +2269,17 @@
return false;
}
- final AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
- com.android.internal.R.styleable.Window, mWmService.mCurrentUserId);
- if (ent == null) {
+ final WindowStyle style = theme == this.theme
+ ? mWindowStyle : mAtmService.getWindowStyle(pkg, theme, mUserId);
+ if (style == null) {
// Whoops! App doesn't exist. Um. Okay. We'll just pretend like we didn't
// see that.
return false;
}
- final boolean windowIsTranslucent = ent.array.getBoolean(
- com.android.internal.R.styleable.Window_windowIsTranslucent, false);
- final boolean windowIsFloating = ent.array.getBoolean(
- com.android.internal.R.styleable.Window_windowIsFloating, false);
- final boolean windowShowWallpaper = ent.array.getBoolean(
- com.android.internal.R.styleable.Window_windowShowWallpaper, false);
- final boolean windowDisableStarting = ent.array.getBoolean(
- com.android.internal.R.styleable.Window_windowDisablePreview, false);
+ final boolean windowIsTranslucent = style.isTranslucent();
+ final boolean windowIsFloating = style.isFloating();
+ final boolean windowShowWallpaper = style.showWallpaper();
+ final boolean windowDisableStarting = style.disablePreview();
ProtoLog.v(WM_DEBUG_STARTING_WINDOW,
"Translucent=%s Floating=%s ShowWallpaper=%s Disable=%s",
windowIsTranslucent, windowIsFloating, windowShowWallpaper,
@@ -4392,7 +4355,6 @@
ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, "Removing app token: %s", this);
- getDisplayContent().mOpeningApps.remove(this);
getDisplayContent().mUnknownAppVisibilityController.appRemovedOrHidden(this);
mWmService.mSnapshotController.onAppRemoved(this);
mAtmService.mStartingProcessActivities.remove(this);
@@ -4404,20 +4366,9 @@
mAppCompatController.getTransparentPolicy().stop();
// Defer removal of this activity when either a child is animating, or app transition is on
- // going. App transition animation might be applied on the parent task not on the activity,
- // but the actual frame buffer is associated with the activity, so we have to keep the
- // activity while a parent is animating.
- boolean delayed = isAnimating(TRANSITION | PARENTS | CHILDREN,
- ANIMATION_TYPE_APP_TRANSITION | ANIMATION_TYPE_WINDOW_ANIMATION);
- if (getDisplayContent().mClosingApps.contains(this)) {
- delayed = true;
- } else if (getDisplayContent().mAppTransition.isTransitionSet()) {
- getDisplayContent().mClosingApps.add(this);
- delayed = true;
- } else if (mTransitionController.inTransition()) {
- delayed = true;
- }
-
+ // going. The handleCompleteDeferredRemoval will continue the removal.
+ final boolean delayed = isAnimating(CHILDREN, ANIMATION_TYPE_WINDOW_ANIMATION)
+ || mTransitionController.inTransition();
// Don't commit visibility if it is waiting to animate. It will be set post animation.
if (!delayed) {
commitVisibility(false /* visible */, true /* performLayout */);
@@ -5552,9 +5503,6 @@
mAtmService.mBackNavigationController.onAppVisibilityChanged(this, visible);
- final DisplayContent displayContent = getDisplayContent();
- displayContent.mOpeningApps.remove(this);
- displayContent.mClosingApps.remove(this);
setVisibleRequested(visible);
mLastDeferHidingClient = deferHidingClient;
@@ -5567,13 +5515,6 @@
setClientVisible(false);
}
} else {
- if (!appTransition.isTransitionSet()
- && appTransition.isReady()) {
- // Add the app mOpeningApps if transition is unset but ready. This means
- // we're doing a screen freeze, and the unfreeze will wait for all opening
- // apps to be ready.
- displayContent.mOpeningApps.add(this);
- }
startingMoved = false;
// If the token is currently hidden (should be the common case), or has been
// stopped, then we need to set up to wait for its windows to be ready.
@@ -6775,7 +6716,7 @@
setAppLayoutChanges(FINISH_LAYOUT_REDO_ANIM, "checkAppWindowsReadyToShow");
// We can now show all of the drawn windows!
- if (!getDisplayContent().mOpeningApps.contains(this) && canShowWindows()) {
+ if (canShowWindows()) {
showAllWindowsLocked();
}
}
@@ -7187,14 +7128,10 @@
if (theme == 0) {
return false;
}
- final AttributeCache.Entry ent = AttributeCache.instance().get(packageName, theme,
- R.styleable.Window, mWmService.mCurrentUserId);
- if (ent != null) {
- if (ent.array.hasValue(R.styleable.Window_windowSplashScreenBehavior)) {
- return ent.array.getInt(R.styleable.Window_windowSplashScreenBehavior,
- SPLASH_SCREEN_BEHAVIOR_DEFAULT)
- == SPLASH_SCREEN_BEHAVIOR_ICON_PREFERRED;
- }
+ final WindowStyle style = theme == this.theme
+ ? mWindowStyle : mAtmService.getWindowStyle(packageName, theme, mUserId);
+ if (style != null) {
+ return style.mSplashScreenBehavior == SPLASH_SCREEN_BEHAVIOR_ICON_PREFERRED;
}
return false;
}
@@ -7449,15 +7386,6 @@
return boundsLayer;
}
- @Override
- boolean isWaitingForTransitionStart() {
- final DisplayContent dc = getDisplayContent();
- return dc != null && dc.mAppTransition.isTransitionSet()
- && (dc.mOpeningApps.contains(this)
- || dc.mClosingApps.contains(this)
- || dc.mChangingContainers.contains(this));
- }
-
boolean isTransitionForward() {
return (mStartingData != null && mStartingData.mIsTransitionForward)
|| mDisplayContent.isNextTransitionForward();
@@ -9561,7 +9489,6 @@
writeNameToProto(proto, NAME);
super.dumpDebug(proto, WINDOW_TOKEN, logLevel);
proto.write(LAST_SURFACE_SHOWING, mLastSurfaceShowing);
- proto.write(IS_WAITING_FOR_TRANSITION_START, isWaitingForTransitionStart());
proto.write(IS_ANIMATING, isAnimating(TRANSITION | PARENTS | CHILDREN,
ANIMATION_TYPE_APP_TRANSITION | ANIMATION_TYPE_WINDOW_ANIMATION));
proto.write(FILLS_PARENT, fillsParent());
@@ -9876,6 +9803,68 @@
int mBackgroundColor;
}
+ static class WindowStyle {
+ private static final int FLAG_IS_TRANSLUCENT = 1;
+ private static final int FLAG_IS_FLOATING = 1 << 1;
+ private static final int FLAG_SHOW_WALLPAPER = 1 << 2;
+ private static final int FLAG_NO_DISPLAY = 1 << 3;
+ private static final int FLAG_DISABLE_PREVIEW = 1 << 4;
+ private static final int FLAG_OPT_OUT_EDGE_TO_EDGE = 1 << 5;
+
+ final int mFlags;
+
+ @SplashScreenBehavior
+ final int mSplashScreenBehavior;
+
+ WindowStyle(TypedArray array) {
+ int flags = 0;
+ if (array.getBoolean(R.styleable.Window_windowIsTranslucent, false)) {
+ flags |= FLAG_IS_TRANSLUCENT;
+ }
+ if (array.getBoolean(R.styleable.Window_windowIsFloating, false)) {
+ flags |= FLAG_IS_FLOATING;
+ }
+ if (array.getBoolean(R.styleable.Window_windowShowWallpaper, false)) {
+ flags |= FLAG_SHOW_WALLPAPER;
+ }
+ if (array.getBoolean(R.styleable.Window_windowNoDisplay, false)) {
+ flags |= FLAG_NO_DISPLAY;
+ }
+ if (array.getBoolean(R.styleable.Window_windowDisablePreview, false)) {
+ flags |= FLAG_DISABLE_PREVIEW;
+ }
+ if (array.getBoolean(R.styleable.Window_windowOptOutEdgeToEdgeEnforcement, false)) {
+ flags |= FLAG_OPT_OUT_EDGE_TO_EDGE;
+ }
+ mFlags = flags;
+ mSplashScreenBehavior = array.getInt(R.styleable.Window_windowSplashScreenBehavior, 0);
+ }
+
+ boolean isTranslucent() {
+ return (mFlags & FLAG_IS_TRANSLUCENT) != 0;
+ }
+
+ boolean isFloating() {
+ return (mFlags & FLAG_IS_FLOATING) != 0;
+ }
+
+ boolean showWallpaper() {
+ return (mFlags & FLAG_SHOW_WALLPAPER) != 0;
+ }
+
+ boolean noDisplay() {
+ return (mFlags & FLAG_NO_DISPLAY) != 0;
+ }
+
+ boolean disablePreview() {
+ return (mFlags & FLAG_DISABLE_PREVIEW) != 0;
+ }
+
+ boolean optOutEdgeToEdge() {
+ return (mFlags & FLAG_OPT_OUT_EDGE_TO_EDGE) != 0;
+ }
+ }
+
static class Builder {
private final ActivityTaskManagerService mAtmService;
private WindowProcessController mCallerApp;
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 819e117..4e2fade 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -286,6 +286,7 @@
import com.android.server.uri.NeededUriGrants;
import com.android.server.uri.UriGrantsManagerInternal;
import com.android.server.wallpaper.WallpaperManagerInternal;
+import com.android.server.wm.utils.WindowStyleCache;
import com.android.wm.shell.Flags;
import java.io.BufferedReader;
@@ -500,6 +501,8 @@
boolean mSuppressResizeConfigChanges;
+ private final WindowStyleCache<ActivityRecord.WindowStyle> mWindowStyleCache =
+ new WindowStyleCache<>(ActivityRecord.WindowStyle::new);
final UpdateConfigurationResult mTmpUpdateConfigurationResult =
new UpdateConfigurationResult();
@@ -5570,6 +5573,16 @@
return mUserManagerInternal;
}
+ @Nullable
+ ActivityRecord.WindowStyle getWindowStyle(String packageName, int theme, int userId) {
+ if (!com.android.window.flags.Flags.cacheWindowStyle()) {
+ final AttributeCache.Entry ent = AttributeCache.instance().get(packageName,
+ theme, com.android.internal.R.styleable.Window, userId);
+ return ent != null ? new ActivityRecord.WindowStyle(ent.array) : null;
+ }
+ return mWindowStyleCache.get(packageName, theme, userId);
+ }
+
AppWarnings getAppWarningsLocked() {
return mAppWarnings;
}
@@ -6518,6 +6531,7 @@
mCompatModePackages.handlePackageUninstalledLocked(name);
mPackageConfigPersister.onPackageUninstall(name, userId);
}
+ mWindowStyleCache.invalidatePackage(name);
}
@Override
@@ -6534,6 +6548,7 @@
if (mRootWindowContainer == null) return;
mRootWindowContainer.updateActivityApplicationInfo(aInfo);
}
+ mWindowStyleCache.invalidatePackage(aInfo.packageName);
}
@Override
diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
index 6a5adca..463a92f 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
@@ -145,6 +145,7 @@
import android.view.Display;
import android.webkit.URLUtil;
import android.window.ActivityWindowInfo;
+import android.window.DesktopExperienceFlags;
import android.window.DesktopModeFlags;
import com.android.internal.R;
@@ -899,108 +900,9 @@
lockTaskController.startLockTaskMode(task, false, 0 /* blank UID */);
}
- try {
- if (!proc.hasThread()) {
- throw new RemoteException();
- }
- List<ResultInfo> results = null;
- List<ReferrerIntent> newIntents = null;
- if (andResume) {
- // We don't need to deliver new intents and/or set results if activity is going
- // to pause immediately after launch.
- results = r.results;
- newIntents = r.newIntents;
- }
- if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
- "Launching: " + r + " savedState=" + r.getSavedState()
- + " with results=" + results + " newIntents=" + newIntents
- + " andResume=" + andResume);
- EventLogTags.writeWmRestartActivity(r.mUserId, System.identityHashCode(r),
- task.mTaskId, r.shortComponentName);
- updateHomeProcessIfNeeded(r);
- mService.getPackageManagerInternalLocked().notifyPackageUse(
- r.intent.getComponent().getPackageName(), NOTIFY_PACKAGE_USE_ACTIVITY);
- mService.getAppWarningsLocked().onStartActivity(r);
-
- final Configuration procConfig = proc.prepareConfigurationForLaunchingActivity();
- final Configuration overrideConfig = r.getMergedOverrideConfiguration();
- r.setLastReportedConfiguration(procConfig, overrideConfig);
-
- final ActivityWindowInfo activityWindowInfo = r.getActivityWindowInfo();
- r.setLastReportedActivityWindowInfo(activityWindowInfo);
-
- logIfTransactionTooLarge(r.intent, r.getSavedState());
-
- final TaskFragment organizedTaskFragment = r.getOrganizedTaskFragment();
- if (organizedTaskFragment != null) {
- // Sending TaskFragmentInfo to client to ensure the info is updated before
- // the activity creation.
- mService.mTaskFragmentOrganizerController.dispatchPendingInfoChangedEvent(
- organizedTaskFragment);
- }
-
- // Create activity launch transaction.
- final boolean isTransitionForward = r.isTransitionForward();
- final IBinder fragmentToken = r.getTaskFragment().getFragmentToken();
- final int deviceId = getDeviceIdForDisplayId(r.getDisplayId());
- final LaunchActivityItem launchActivityItem = new LaunchActivityItem(r.token,
- r.intent, System.identityHashCode(r), r.info,
- procConfig, overrideConfig, deviceId,
- r.getFilteredReferrer(r.launchedFromPackage), task.voiceInteractor,
- proc.getReportedProcState(), r.getSavedState(), r.getPersistentSavedState(),
- results, newIntents, r.takeSceneTransitionInfo(), isTransitionForward,
- proc.createProfilerInfoIfNeeded(), r.assistToken, activityClientController,
- r.shareableActivityToken, r.getLaunchedFromBubble(), fragmentToken,
- r.initialCallerInfoAccessToken, activityWindowInfo);
-
- // Set desired final state.
- final ActivityLifecycleItem lifecycleItem;
- if (andResume) {
- lifecycleItem = new ResumeActivityItem(r.token, isTransitionForward,
- r.shouldSendCompatFakeFocus());
- } else if (r.isVisibleRequested()) {
- lifecycleItem = new PauseActivityItem(r.token);
- } else {
- lifecycleItem = new StopActivityItem(r.token);
- }
-
- // Schedule transaction.
- if (shouldDispatchLaunchActivityItemIndependently(r.info.packageName, r.getUid())) {
- // LaunchActivityItem has @UnsupportedAppUsage usages.
- // Guard with targetSDK on Android 15+.
- // To not bundle the transaction, dispatch the pending before schedule new
- // transaction.
- mService.getLifecycleManager().dispatchPendingTransaction(proc.getThread());
- }
- mService.getLifecycleManager().scheduleTransactionItems(
- proc.getThread(),
- // Immediately dispatch the transaction, so that if it fails, the server can
- // restart the process and retry now.
- true /* shouldDispatchImmediately */,
- launchActivityItem, lifecycleItem);
-
- if (procConfig.seq > mRootWindowContainer.getConfiguration().seq) {
- // If the seq is increased, there should be something changed (e.g. registered
- // activity configuration).
- proc.setLastReportedConfiguration(procConfig);
- }
- if ((proc.mInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0
- && mService.mHasHeavyWeightFeature) {
- // This may be a heavy-weight process! Note that the package manager will ensure
- // that only activity can run in the main process of the .apk, which is the only
- // thing that will be considered heavy-weight.
- if (proc.mName.equals(proc.mInfo.packageName)) {
- if (mService.mHeavyWeightProcess != null
- && mService.mHeavyWeightProcess != proc) {
- Slog.w(TAG, "Starting new heavy weight process " + proc
- + " when already running "
- + mService.mHeavyWeightProcess);
- }
- mService.setHeavyWeightProcess(r);
- }
- }
-
- } catch (RemoteException e) {
+ final RemoteException e = tryRealStartActivityInner(
+ task, r, proc, activityClientController, andResume);
+ if (e != null) {
if (r.launchFailed) {
// This is the second time we failed -- finish activity and give up.
Slog.e(TAG, "Second failure launching "
@@ -1023,7 +925,7 @@
r.launchFailed = false;
- // TODO(lifecycler): Resume or pause requests are done as part of launch transaction,
+ // Resume or pause requests are done as part of launch transaction,
// so updating the state should be done accordingly.
if (andResume && readyToResume()) {
// As part of the process of launching, ActivityThread also performs
@@ -1063,6 +965,122 @@
return true;
}
+ /** @return {@link RemoteException} if the app process failed to handle the activity start. */
+ @Nullable
+ private RemoteException tryRealStartActivityInner(
+ @NonNull Task task,
+ @NonNull ActivityRecord r,
+ @NonNull WindowProcessController proc,
+ @Nullable IActivityClientController activityClientController,
+ boolean andResume) {
+ if (!proc.hasThread()) {
+ return new RemoteException();
+ }
+ List<ResultInfo> results = null;
+ List<ReferrerIntent> newIntents = null;
+ if (andResume) {
+ // We don't need to deliver new intents and/or set results if activity is going
+ // to pause immediately after launch.
+ results = r.results;
+ newIntents = r.newIntents;
+ }
+ if (DEBUG_SWITCH) {
+ Slog.v(TAG_SWITCH,
+ "Launching: " + r + " savedState=" + r.getSavedState()
+ + " with results=" + results + " newIntents=" + newIntents
+ + " andResume=" + andResume);
+ }
+ EventLogTags.writeWmRestartActivity(r.mUserId, System.identityHashCode(r),
+ task.mTaskId, r.shortComponentName);
+ updateHomeProcessIfNeeded(r);
+ mService.getPackageManagerInternalLocked().notifyPackageUse(
+ r.intent.getComponent().getPackageName(), NOTIFY_PACKAGE_USE_ACTIVITY);
+ mService.getAppWarningsLocked().onStartActivity(r);
+
+ final Configuration procConfig = proc.prepareConfigurationForLaunchingActivity();
+ final Configuration overrideConfig = r.getMergedOverrideConfiguration();
+ r.setLastReportedConfiguration(procConfig, overrideConfig);
+
+ final ActivityWindowInfo activityWindowInfo = r.getActivityWindowInfo();
+ r.setLastReportedActivityWindowInfo(activityWindowInfo);
+
+ logIfTransactionTooLarge(r.intent, r.getSavedState());
+
+ final TaskFragment organizedTaskFragment = r.getOrganizedTaskFragment();
+ if (organizedTaskFragment != null) {
+ // Sending TaskFragmentInfo to client to ensure the info is updated before
+ // the activity creation.
+ mService.mTaskFragmentOrganizerController.dispatchPendingInfoChangedEvent(
+ organizedTaskFragment);
+ }
+
+ // Create activity launch transaction.
+ final boolean isTransitionForward = r.isTransitionForward();
+ final IBinder fragmentToken = r.getTaskFragment().getFragmentToken();
+ final int deviceId = getDeviceIdForDisplayId(r.getDisplayId());
+ final LaunchActivityItem launchActivityItem = new LaunchActivityItem(r.token,
+ r.intent, System.identityHashCode(r), r.info,
+ procConfig, overrideConfig, deviceId,
+ r.getFilteredReferrer(r.launchedFromPackage), task.voiceInteractor,
+ proc.getReportedProcState(), r.getSavedState(), r.getPersistentSavedState(),
+ results, newIntents, r.takeSceneTransitionInfo(), isTransitionForward,
+ proc.createProfilerInfoIfNeeded(), r.assistToken, activityClientController,
+ r.shareableActivityToken, r.getLaunchedFromBubble(), fragmentToken,
+ r.initialCallerInfoAccessToken, activityWindowInfo);
+
+ // Set desired final state.
+ final ActivityLifecycleItem lifecycleItem;
+ if (andResume) {
+ lifecycleItem = new ResumeActivityItem(r.token, isTransitionForward,
+ r.shouldSendCompatFakeFocus());
+ } else if (r.isVisibleRequested()) {
+ lifecycleItem = new PauseActivityItem(r.token);
+ } else {
+ lifecycleItem = new StopActivityItem(r.token);
+ }
+
+ // Schedule transaction.
+ if (shouldDispatchLaunchActivityItemIndependently(r.info.packageName, r.getUid())) {
+ // LaunchActivityItem has @UnsupportedAppUsage usages.
+ // Guard with targetSDK on Android 15+.
+ // To not bundle the transaction, dispatch the pending before schedule new
+ // transaction.
+ mService.getLifecycleManager().dispatchPendingTransaction(proc.getThread());
+ }
+ try {
+ mService.getLifecycleManager().scheduleTransactionItems(
+ proc.getThread(),
+ // Immediately dispatch the transaction, so that if it fails, the server can
+ // restart the process and retry now.
+ true /* shouldDispatchImmediately */,
+ launchActivityItem, lifecycleItem);
+ } catch (RemoteException e) {
+ return e;
+ }
+
+ if (procConfig.seq > mRootWindowContainer.getConfiguration().seq) {
+ // If the seq is increased, there should be something changed (e.g. registered
+ // activity configuration).
+ proc.setLastReportedConfiguration(procConfig);
+ }
+ if ((proc.mInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0
+ && mService.mHasHeavyWeightFeature) {
+ // This may be a heavy-weight process! Note that the package manager will ensure
+ // that only activity can run in the main process of the .apk, which is the only
+ // thing that will be considered heavy-weight.
+ if (proc.mName.equals(proc.mInfo.packageName)) {
+ if (mService.mHeavyWeightProcess != null
+ && mService.mHeavyWeightProcess != proc) {
+ Slog.w(TAG, "Starting new heavy weight process " + proc
+ + " when already running "
+ + mService.mHeavyWeightProcess);
+ }
+ mService.setHeavyWeightProcess(r);
+ }
+ }
+ return null;
+ }
+
void updateHomeProcessIfNeeded(@NonNull ActivityRecord r) {
if (!r.isActivityTypeHome()) return;
// Make sure that we use the bottom most activity from the same package, because the home
@@ -2916,6 +2934,8 @@
/** The helper to calculate whether a container is opaque. */
static class OpaqueContainerHelper implements Predicate<ActivityRecord> {
+ private final boolean mEnableMultipleDesktopsBackend =
+ DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue();
private ActivityRecord mStarting;
private boolean mIgnoringInvisibleActivity;
private boolean mIgnoringKeyguard;
@@ -2938,7 +2958,7 @@
mIgnoringKeyguard = ignoringKeyguard;
final boolean isOpaque;
- if (!Flags.enableMultipleDesktopsBackend()) {
+ if (!mEnableMultipleDesktopsBackend) {
isOpaque = container.getActivity(this,
true /* traverseTopToBottom */, null /* boundary */) != null;
} else {
@@ -2949,13 +2969,16 @@
}
private boolean isOpaqueInner(@NonNull WindowContainer<?> container) {
- // If it's a leaf task fragment, then opacity is calculated based on its activities.
- if (container.asTaskFragment() != null
- && ((TaskFragment) container).isLeafTaskFragment()) {
+ final boolean isActivity = container.asActivityRecord() != null;
+ final boolean isLeafTaskFragment = container.asTaskFragment() != null
+ && ((TaskFragment) container).isLeafTaskFragment();
+ if (isActivity || isLeafTaskFragment) {
+ // When it is an activity or leaf task fragment, then opacity is calculated based
+ // on itself or its activities.
return container.getActivity(this,
true /* traverseTopToBottom */, null /* boundary */) != null;
}
- // When not a leaf, it's considered opaque if any of its opaque children fill this
+ // Otherwise, it's considered opaque if any of its opaque children fill this
// container, unless the children are adjacent fragments, in which case as long as they
// are all opaque then |container| is also considered opaque, even if the adjacent
// task fragment aren't filling.
diff --git a/services/core/java/com/android/server/wm/AppCompatLetterboxPolicy.java b/services/core/java/com/android/server/wm/AppCompatLetterboxPolicy.java
index dff072e..57811e2 100644
--- a/services/core/java/com/android/server/wm/AppCompatLetterboxPolicy.java
+++ b/services/core/java/com/android/server/wm/AppCompatLetterboxPolicy.java
@@ -16,12 +16,14 @@
package com.android.server.wm;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.content.res.Configuration.ORIENTATION_UNDEFINED;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
+import static android.window.DesktopModeFlags.EXCLUDE_CAPTION_FROM_APP_BOUNDS;
import static com.android.server.wm.AppCompatConfiguration.LETTERBOX_BACKGROUND_WALLPAPER;
import static com.android.server.wm.AppCompatConfiguration.letterboxBackgroundTypeToString;
@@ -48,6 +50,8 @@
*/
class AppCompatLetterboxPolicy {
+ private static final int DIFF_TOLERANCE_PX = 1;
+
@NonNull
private final ActivityRecord mActivityRecord;
@NonNull
@@ -56,6 +60,9 @@
private final AppCompatRoundedCorners mAppCompatRoundedCorners;
@NonNull
private final AppCompatConfiguration mAppCompatConfiguration;
+ // Convenience temporary object to save allocation when calculating Rect.
+ @NonNull
+ private final Rect mTmpRect = new Rect();
private boolean mLastShouldShowLetterboxUi;
@@ -71,7 +78,7 @@
: new LegacyLetterboxPolicyState();
// TODO (b/358334569) Improve cutout logic dependency on app compat.
mAppCompatRoundedCorners = new AppCompatRoundedCorners(mActivityRecord,
- this::isLetterboxedNotForDisplayCutout);
+ this::ieEligibleForRoundedCorners);
mAppCompatConfiguration = appCompatConfiguration;
}
@@ -84,7 +91,7 @@
mLetterboxPolicyState.stop();
}
- /** @return {@value true} if the letterbox policy is running and the activity letterboxed. */
+ /** @return {@code true} if the letterbox policy is running and the activity letterboxed. */
boolean isRunning() {
return mLetterboxPolicyState.isRunning();
}
@@ -130,7 +137,7 @@
* <li>The activity is in fullscreen.
* <li>The activity is portrait-only.
* <li>The activity doesn't have a starting window (education should only be displayed
- * once the starting window is removed in {@link #removeStartingWindow}).
+ * once the starting window is removed in {@link ActivityRecord#removeStartingWindow}).
* </ul>
*/
boolean isEligibleForLetterboxEducation() {
@@ -294,16 +301,40 @@
}
}
+ private boolean ieEligibleForRoundedCorners(@NonNull WindowState mainWindow) {
+ return isLetterboxedNotForDisplayCutout(mainWindow)
+ && !isFreeformActivityMatchParentAppBoundsHeight();
+ }
+
private boolean isLetterboxedNotForDisplayCutout(@NonNull WindowState mainWindow) {
return shouldShowLetterboxUi(mainWindow)
&& !mainWindow.isLetterboxedForDisplayCutout();
}
+ private boolean isFreeformActivityMatchParentAppBoundsHeight() {
+ if (!EXCLUDE_CAPTION_FROM_APP_BOUNDS.isTrue()) {
+ return false;
+ }
+ final Task task = mActivityRecord.getTask();
+ if (task == null) {
+ return false;
+ }
+ final Rect parentAppBounds = task.getWindowConfiguration().getAppBounds();
+ if (parentAppBounds == null) {
+ return false;
+ }
+
+ mLetterboxPolicyState.getLetterboxInnerBounds(mTmpRect);
+ final int diff = parentAppBounds.height() - mTmpRect.height();
+ // Compare bounds with tolerance of 1 px to account for rounding error calculations.
+ return task.getWindowingMode() == WINDOWING_MODE_FREEFORM && diff <= DIFF_TOLERANCE_PX;
+ }
+
private static boolean shouldNotLayoutLetterbox(@Nullable WindowState w) {
if (w == null) {
return true;
}
- final int type = w.mAttrs.type;
+ final int type = w.getAttrs().type;
// Allow letterbox to be displayed early for base application or application starting
// windows even if it is not on the top z order to prevent flickering when the
// letterboxed window is brought to the top
diff --git a/services/core/java/com/android/server/wm/AppCompatRoundedCorners.java b/services/core/java/com/android/server/wm/AppCompatRoundedCorners.java
index 92d76e5..8165638 100644
--- a/services/core/java/com/android/server/wm/AppCompatRoundedCorners.java
+++ b/services/core/java/com/android/server/wm/AppCompatRoundedCorners.java
@@ -35,12 +35,12 @@
@NonNull
private final ActivityRecord mActivityRecord;
@NonNull
- private final Predicate<WindowState> mIsLetterboxedNotForDisplayCutout;
+ private final Predicate<WindowState> mRoundedCornersWindowCondition;
AppCompatRoundedCorners(@NonNull ActivityRecord activityRecord,
- @NonNull Predicate<WindowState> isLetterboxedNotForDisplayCutout) {
+ @NonNull Predicate<WindowState> roundedCornersWindowCondition) {
mActivityRecord = activityRecord;
- mIsLetterboxedNotForDisplayCutout = isLetterboxedNotForDisplayCutout;
+ mRoundedCornersWindowCondition = roundedCornersWindowCondition;
}
void updateRoundedCornersIfNeeded(@NonNull final WindowState mainWindow) {
@@ -136,7 +136,7 @@
private boolean requiresRoundedCorners(@NonNull final WindowState mainWindow) {
final AppCompatLetterboxOverrides letterboxOverrides = mActivityRecord
.mAppCompatController.getLetterboxOverrides();
- return mIsLetterboxedNotForDisplayCutout.test(mainWindow)
+ return mRoundedCornersWindowCondition.test(mainWindow)
&& letterboxOverrides.isLetterboxActivityCornersRounded();
}
diff --git a/services/core/java/com/android/server/wm/AppCompatSandboxingPolicy.java b/services/core/java/com/android/server/wm/AppCompatSandboxingPolicy.java
index 26cf32b..6a46f57 100644
--- a/services/core/java/com/android/server/wm/AppCompatSandboxingPolicy.java
+++ b/services/core/java/com/android/server/wm/AppCompatSandboxingPolicy.java
@@ -15,6 +15,8 @@
*/
package com.android.server.wm;
+import static android.window.DesktopModeFlags.EXCLUDE_CAPTION_FROM_APP_BOUNDS;
+
import static com.android.server.wm.AppCompatUtils.isInDesktopMode;
import android.annotation.NonNull;
@@ -22,8 +24,6 @@
import android.content.res.Configuration;
import android.graphics.Rect;
-import com.android.window.flags.Flags;
-
/**
* Encapsulate logic related to sandboxing for app compatibility.
*/
@@ -48,7 +48,7 @@
*/
void sandboxBoundsIfNeeded(@NonNull Configuration resolvedConfig,
@WindowingMode int windowingMode) {
- if (!Flags.excludeCaptionFromAppBounds()) {
+ if (!EXCLUDE_CAPTION_FROM_APP_BOUNDS.isTrue()) {
return;
}
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index d98ad8b..12d4a21 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -89,7 +89,6 @@
import static com.android.internal.R.styleable.WindowAnimation_wallpaperOpenEnterAnimation;
import static com.android.internal.R.styleable.WindowAnimation_wallpaperOpenExitAnimation;
import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_ANIM;
-import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_APP_TRANSITIONS;
import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_APP_TRANSITIONS_ANIM;
import static com.android.server.wm.AppTransitionProto.APP_TRANSITION_STATE;
import static com.android.server.wm.AppTransitionProto.LAST_USED_APP_TRANSITION;
@@ -1554,26 +1553,6 @@
}
private void handleAppTransitionTimeout() {
- synchronized (mService.mGlobalLock) {
- final DisplayContent dc = mDisplayContent;
- if (dc == null) {
- return;
- }
- notifyAppTransitionTimeoutLocked();
- if (isTransitionSet() || !dc.mOpeningApps.isEmpty() || !dc.mClosingApps.isEmpty()
- || !dc.mChangingContainers.isEmpty()) {
- ProtoLog.v(WM_DEBUG_APP_TRANSITIONS,
- "*** APP TRANSITION TIMEOUT. displayId=%d isTransitionSet()=%b "
- + "mOpeningApps.size()=%d mClosingApps.size()=%d "
- + "mChangingApps.size()=%d",
- dc.getDisplayId(), dc.mAppTransition.isTransitionSet(),
- dc.mOpeningApps.size(), dc.mClosingApps.size(),
- dc.mChangingContainers.size());
-
- setTimeout();
- mService.mWindowPlacerLocked.performSurfacePlacement();
- }
- }
}
private static void doAnimationCallback(@NonNull IRemoteCallback callback) {
diff --git a/services/core/java/com/android/server/wm/BackNavigationController.java b/services/core/java/com/android/server/wm/BackNavigationController.java
index 094ad18..d652ea1 100644
--- a/services/core/java/com/android/server/wm/BackNavigationController.java
+++ b/services/core/java/com/android/server/wm/BackNavigationController.java
@@ -281,6 +281,10 @@
} else if (hasTranslucentActivity(currentActivity, prevActivities)) {
// skip if one of participant activity is translucent
backType = BackNavigationInfo.TYPE_CALLBACK;
+ } else if (!allActivitiesHaveProcesses(prevActivities)) {
+ // Skip if one of previous activity has no process. Restart process can be slow, and
+ // the final hierarchy could be different.
+ backType = BackNavigationInfo.TYPE_CALLBACK;
} else if (prevActivities.size() > 0
&& requestOverride == SystemOverrideOnBackInvokedCallback.OVERRIDE_UNDEFINED) {
if ((!isOccluded || isAllActivitiesCanShowWhenLocked(prevActivities))
@@ -603,6 +607,17 @@
return false;
}
+ private static boolean allActivitiesHaveProcesses(
+ @NonNull ArrayList<ActivityRecord> prevActivities) {
+ for (int i = prevActivities.size() - 1; i >= 0; --i) {
+ final ActivityRecord test = prevActivities.get(i);
+ if (!test.hasProcess()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
private static boolean isAllActivitiesCanShowWhenLocked(
@NonNull ArrayList<ActivityRecord> prevActivities) {
for (int i = prevActivities.size() - 1; i >= 0; --i) {
diff --git a/services/core/java/com/android/server/wm/ConfigurationContainer.java b/services/core/java/com/android/server/wm/ConfigurationContainer.java
index 05dcbb7..aaa18ad 100644
--- a/services/core/java/com/android/server/wm/ConfigurationContainer.java
+++ b/services/core/java/com/android/server/wm/ConfigurationContainer.java
@@ -257,10 +257,12 @@
// This should be the only place override the configuration for ActivityRecord. Override
// the value if not calculated yet.
Rect outAppBounds = inOutConfig.windowConfiguration.getAppBounds();
+ Rect outConfigBounds = new Rect(outAppBounds);
if (outAppBounds == null || outAppBounds.isEmpty()) {
inOutConfig.windowConfiguration.setAppBounds(
newParentConfiguration.windowConfiguration.getBounds());
outAppBounds = inOutConfig.windowConfiguration.getAppBounds();
+ outConfigBounds.set(outAppBounds);
if (task != null) {
task = task.getCreatedByOrganizerTask();
if (task != null && (task.mOffsetYForInsets != 0 || task.mOffsetXForInsets != 0)) {
@@ -279,6 +281,12 @@
outAppBounds.inset(decor.mOverrideNonDecorInsets);
}
}
+ if (!outConfigBounds.intersect(decor.mOverrideConfigFrame)) {
+ if (inOutConfig.windowConfiguration.getWindowingMode()
+ == WINDOWING_MODE_MULTI_WINDOW) {
+ outAppBounds.inset(decor.mOverrideConfigInsets);
+ }
+ }
if (task != null && (task.mOffsetYForInsets != 0 || task.mOffsetXForInsets != 0)) {
outAppBounds.offset(-task.mOffsetXForInsets, -task.mOffsetYForInsets);
}
@@ -289,10 +297,10 @@
}
density *= DisplayMetrics.DENSITY_DEFAULT_SCALE;
if (inOutConfig.screenWidthDp == Configuration.SCREEN_WIDTH_DP_UNDEFINED) {
- inOutConfig.screenWidthDp = (int) (outAppBounds.width() / density + 0.5f);
+ inOutConfig.screenWidthDp = (int) (outConfigBounds.width() / density + 0.5f);
}
if (inOutConfig.screenHeightDp == Configuration.SCREEN_HEIGHT_DP_UNDEFINED) {
- inOutConfig.screenHeightDp = (int) (outAppBounds.height() / density + 0.5f);
+ inOutConfig.screenHeightDp = (int) (outConfigBounds.height() / density + 0.5f);
}
if (inOutConfig.smallestScreenWidthDp == Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED
&& parentWindowingMode == WINDOWING_MODE_FULLSCREEN) {
diff --git a/services/core/java/com/android/server/wm/DesktopModeLaunchParamsModifier.java b/services/core/java/com/android/server/wm/DesktopModeLaunchParamsModifier.java
index ac98792..b6f74a0 100644
--- a/services/core/java/com/android/server/wm/DesktopModeLaunchParamsModifier.java
+++ b/services/core/java/com/android/server/wm/DesktopModeLaunchParamsModifier.java
@@ -75,8 +75,8 @@
return RESULT_SKIP;
}
if (com.android.window.flags.Flags.fixLayoutExistingTask()
- && task.getOrganizedTask() != null) {
- appendLog("task is organized, skipping");
+ && task.getCreatedByOrganizerTask() != null) {
+ appendLog("has created-by-organizer-task, skipping");
return RESULT_SKIP;
}
@@ -111,6 +111,11 @@
return RESULT_SKIP;
}
+ if ((options == null || options.getLaunchBounds() == null) && task.hasOverrideBounds()) {
+ appendLog("current task has bounds set, not overriding");
+ return RESULT_SKIP;
+ }
+
DesktopModeBoundsCalculator.updateInitialBounds(task, layout, activity, options,
outParams.mBounds, this::appendLog);
appendLog("final desktop mode task bounds set to %s", outParams.mBounds);
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 703ce7d..fd322a5 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -108,7 +108,6 @@
import static com.android.server.wm.ActivityRecord.State.RESUMED;
import static com.android.server.wm.ActivityTaskManagerService.POWER_MODE_REASON_CHANGE_DISPLAY;
import static com.android.server.wm.DisplayContentProto.APP_TRANSITION;
-import static com.android.server.wm.DisplayContentProto.CLOSING_APPS;
import static com.android.server.wm.DisplayContentProto.CURRENT_FOCUS;
import static com.android.server.wm.DisplayContentProto.DISPLAY_FRAMES;
import static com.android.server.wm.DisplayContentProto.DISPLAY_INFO;
@@ -125,7 +124,6 @@
import static com.android.server.wm.DisplayContentProto.IS_SLEEPING;
import static com.android.server.wm.DisplayContentProto.KEEP_CLEAR_AREAS;
import static com.android.server.wm.DisplayContentProto.MIN_SIZE_OF_RESIZEABLE_TASK_DP;
-import static com.android.server.wm.DisplayContentProto.OPENING_APPS;
import static com.android.server.wm.DisplayContentProto.RESUMED_ACTIVITY;
import static com.android.server.wm.DisplayContentProto.ROOT_DISPLAY_AREA;
import static com.android.server.wm.DisplayContentProto.SLEEP_TOKENS;
@@ -196,7 +194,6 @@
import android.os.UserManager;
import android.os.WorkSource;
import android.provider.Settings;
-import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.DisplayMetrics;
import android.util.DisplayUtils;
@@ -367,15 +364,7 @@
final AppTransition mAppTransition;
- final ArraySet<ActivityRecord> mOpeningApps = new ArraySet<>();
- final ArraySet<ActivityRecord> mClosingApps = new ArraySet<>();
- final ArraySet<WindowContainer> mChangingContainers = new ArraySet<>();
final UnknownAppVisibilityController mUnknownAppVisibilityController;
- /**
- * If a container is closing when resizing, keeps track of its starting bounds when it is
- * removed from {@link #mChangingContainers}.
- */
- final ArrayMap<WindowContainer, Rect> mClosingChangingContainers = new ArrayMap<>();
private MetricsLogger mMetricsLogger;
@@ -1910,17 +1899,10 @@
return false;
}
if (checkOpening) {
- if (mTransitionController.isShellTransitionsEnabled()) {
- if (!mTransitionController.isCollecting(r)) {
- return false;
- }
- } else {
- if (!mAppTransition.isTransitionSet() || !mOpeningApps.contains(r)) {
- // Apply normal rotation animation in case of the activity set different
- // requested orientation without activity switch, or the transition is unset due
- // to starting window was transferred ({@link #mSkipAppTransitionAnimation}).
- return false;
- }
+ if (!mTransitionController.isCollecting(r)) {
+ // Apply normal rotation animation in case the activity changes requested
+ // orientation without activity switch.
+ return false;
}
if (r.isState(RESUMED) && !r.getTask().mInResumeTopActivity) {
// If the activity is executing or has done the lifecycle callback, use normal
@@ -3256,7 +3238,12 @@
}
}
- private boolean allowContentModeSwitch() {
+ /**
+ * Note that we only allow displays that are able to show system decorations to use the content
+ * mode switch; however, not all displays that are able to show system decorations are allowed
+ * to use the content mode switch.
+ */
+ boolean allowContentModeSwitch() {
// The default display should always show system decorations.
if (isDefaultDisplay) {
return false;
@@ -3372,10 +3359,6 @@
void removeImmediately() {
mDeferredRemoval = false;
try {
- // Clear all transitions & screen frozen states when removing display.
- mOpeningApps.clear();
- mClosingApps.clear();
- mChangingContainers.clear();
mUnknownAppVisibilityController.clear();
mAppTransition.removeAppTransitionTimeoutCallbacks();
mTransitionController.unregisterLegacyListener(mFixedRotationTransitionListener);
@@ -3567,12 +3550,6 @@
if (mFocusedApp != null) {
mFocusedApp.writeNameToProto(proto, FOCUSED_APP);
}
- for (int i = mOpeningApps.size() - 1; i >= 0; i--) {
- mOpeningApps.valueAt(i).writeIdentifierToProto(proto, OPENING_APPS);
- }
- for (int i = mClosingApps.size() - 1; i >= 0; i--) {
- mClosingApps.valueAt(i).writeIdentifierToProto(proto, CLOSING_APPS);
- }
final Task focusedRootTask = getFocusedRootTask();
if (focusedRootTask != null) {
@@ -4831,19 +4808,6 @@
}
}
- if (!mOpeningApps.isEmpty() || !mClosingApps.isEmpty() || !mChangingContainers.isEmpty()) {
- pw.println();
- if (mOpeningApps.size() > 0) {
- pw.print(" mOpeningApps="); pw.println(mOpeningApps);
- }
- if (mClosingApps.size() > 0) {
- pw.print(" mClosingApps="); pw.println(mClosingApps);
- }
- if (mChangingContainers.size() > 0) {
- pw.print(" mChangingApps="); pw.println(mChangingContainers);
- }
- }
-
mUnknownAppVisibilityController.dump(pw, " ");
}
diff --git a/services/core/java/com/android/server/wm/DisplayWindowSettings.java b/services/core/java/com/android/server/wm/DisplayWindowSettings.java
index 539fc12..1173875 100644
--- a/services/core/java/com/android/server/wm/DisplayWindowSettings.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowSettings.java
@@ -247,12 +247,7 @@
void setShouldShowSystemDecorsLocked(@NonNull DisplayContent dc, boolean shouldShow) {
final boolean changed = (shouldShow != shouldShowSystemDecorsLocked(dc));
-
- final DisplayInfo displayInfo = dc.getDisplayInfo();
- final SettingsProvider.SettingsEntry overrideSettings =
- mSettingsProvider.getOverrideSettings(displayInfo);
- overrideSettings.mShouldShowSystemDecors = shouldShow;
- mSettingsProvider.updateOverrideSettings(displayInfo, overrideSettings);
+ setShouldShowSystemDecorsInternalLocked(dc, shouldShow);
if (enableDisplayContentModeManagement()) {
if (dc.isDefaultDisplay || dc.isPrivate() || !changed) {
@@ -269,6 +264,15 @@
}
}
+ void setShouldShowSystemDecorsInternalLocked(@NonNull DisplayContent dc,
+ boolean shouldShow) {
+ final DisplayInfo displayInfo = dc.getDisplayInfo();
+ final SettingsProvider.SettingsEntry overrideSettings =
+ mSettingsProvider.getOverrideSettings(displayInfo);
+ overrideSettings.mShouldShowSystemDecors = shouldShow;
+ mSettingsProvider.updateOverrideSettings(displayInfo, overrideSettings);
+ }
+
boolean isHomeSupportedLocked(@NonNull DisplayContent dc) {
if (dc.getDisplayId() == Display.DEFAULT_DISPLAY) {
// Default display should show home.
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index c93efd3..40f16c1 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -2775,6 +2775,12 @@
return;
}
+ if (enableDisplayContentModeManagement() && display.allowContentModeSwitch()) {
+ mWindowManager.mDisplayWindowSettings
+ .setShouldShowSystemDecorsInternalLocked(display,
+ display.mDisplay.canHostTasks());
+ }
+
startSystemDecorations(display, "displayAdded");
// Drop any cached DisplayInfos associated with this display id - the values are now
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 3abab8b..6b3499a 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -166,6 +166,7 @@
import android.view.SurfaceControl;
import android.view.WindowInsets;
import android.view.WindowManager;
+import android.window.DesktopExperienceFlags;
import android.window.DesktopModeFlags;
import android.window.ITaskOrganizer;
import android.window.PictureInPictureSurfaceTransaction;
@@ -2027,7 +2028,7 @@
}
if (shouldStartChangeTransition(prevWinMode, mTmpPrevBounds)) {
- initializeChangeTransition(mTmpPrevBounds);
+ mTransitionController.collectVisibleChange(this);
}
// If the configuration supports persistent bounds (eg. Freeform), keep track of the
@@ -2378,7 +2379,7 @@
// configurations and let its parent (organized task) to control it;
final Task rootTask = getRootTask();
boolean shouldInheritBounds = rootTask != this && rootTask.isOrganized();
- if (Flags.enableMultipleDesktopsBackend()) {
+ if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue()) {
// Only inherit from organized parent when this task is not organized.
shouldInheritBounds &= !isOrganized();
}
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index 74059c1..a698a9e 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -2779,9 +2779,7 @@
}
// If this TaskFragment is closing while resizing, crop to the starting bounds instead.
- final Rect bounds = isClosingWhenResizing()
- ? mDisplayContent.mClosingChangingContainers.get(this)
- : getBounds();
+ final Rect bounds = getBounds();
final int width = bounds.width();
final int height = bounds.height();
if (!forceUpdate && width == mLastSurfaceSize.x && height == mLastSurfaceSize.y) {
diff --git a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
index e3a5b66..6c7d979 100644
--- a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
+++ b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
@@ -384,7 +384,7 @@
// an existing task.
adjustBoundsToAvoidConflictInDisplayArea(taskDisplayArea, outParams.mBounds);
}
- } else {
+ } else if (task == null || !task.hasOverrideBounds()) {
if (source != null && source.inFreeformWindowingMode()
&& resolvedMode == WINDOWING_MODE_FREEFORM
&& outParams.mBounds.isEmpty()
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index c1ef208..a8b9fed 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -292,12 +292,6 @@
return false;
}
- boolean isWallpaperTargetAnimating() {
- return mWallpaperTarget != null && mWallpaperTarget.isAnimating(TRANSITION | PARENTS)
- && (mWallpaperTarget.mActivityRecord == null
- || !mWallpaperTarget.mActivityRecord.isWaitingForTransitionStart());
- }
-
void hideDeferredWallpapersIfNeededLegacy() {
for (int i = mWallpaperTokens.size() - 1; i >= 0; i--) {
final WallpaperWindowToken token = mWallpaperTokens.get(i);
@@ -837,14 +831,6 @@
// Use the old target if new target is hidden but old target
// is not. If they're both hidden, still use the new target.
mWallpaperTarget = prevWallpaperTarget;
- } else if (newTargetHidden == oldTargetHidden
- && !mDisplayContent.mOpeningApps.contains(wallpaperTarget.mActivityRecord)
- && (mDisplayContent.mOpeningApps.contains(prevWallpaperTarget.mActivityRecord)
- || mDisplayContent.mClosingApps.contains(prevWallpaperTarget.mActivityRecord))) {
- // If they're both hidden (or both not hidden), prefer the one that's currently in
- // opening or closing app list, this allows transition selection logic to better
- // determine the wallpaper status of opening/closing apps.
- mWallpaperTarget = prevWallpaperTarget;
}
result.setWallpaperTarget(wallpaperTarget);
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 95cdf46..45202a2 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -34,7 +34,6 @@
import static android.view.SurfaceControl.Transaction;
import static android.view.WindowInsets.Type.InsetsType;
import static android.view.WindowManager.LayoutParams.INVALID_WINDOW_TYPE;
-import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.window.TaskFragmentAnimationParams.DEFAULT_ANIMATION_BACKGROUND_COLOR;
import static android.window.DesktopModeFlags.ENABLE_CAPTION_COMPAT_INSET_FORCE_CONSUMPTION;
@@ -901,10 +900,6 @@
*/
@CallSuper
void removeImmediately() {
- final DisplayContent dc = getDisplayContent();
- if (dc != null) {
- dc.mClosingChangingContainers.remove(this);
- }
while (!mChildren.isEmpty()) {
final E child = mChildren.getLast();
child.removeImmediately();
@@ -1116,10 +1111,6 @@
if (asWindowState() == null) {
mTransitionController.collect(this);
}
- // Cancel any change transition queued-up for this container on the old display when
- // this container is moved from the old display.
- mDisplayContent.mClosingChangingContainers.remove(this);
- mDisplayContent.mChangingContainers.remove(this);
}
mDisplayContent = dc;
if (dc != null && dc != this && mPendingTransaction != null) {
@@ -1268,14 +1259,6 @@
}
/**
- * @return {@code true} when the container is waiting the app transition start, {@code false}
- * otherwise.
- */
- boolean isWaitingForTransitionStart() {
- return false;
- }
-
- /**
* @return {@code true} if in this subtree of the hierarchy we have an
* {@code ActivityRecord#isAnimating(TRANSITION)}, {@code false} otherwise.
*/
@@ -1302,13 +1285,6 @@
return isAnimating(0 /* self only */);
}
- /**
- * @return {@code true} if the container is in changing app transition.
- */
- boolean isChangingAppTransition() {
- return mDisplayContent != null && mDisplayContent.mChangingContainers.contains(this);
- }
-
boolean inTransition() {
return mTransitionController.inTransition(this);
}
@@ -1427,12 +1403,6 @@
return setVisibleRequested(newVisReq);
}
- /** Whether this window is closing while resizing. */
- boolean isClosingWhenResizing() {
- return mDisplayContent != null
- && mDisplayContent.mClosingChangingContainers.containsKey(this);
- }
-
void writeIdentifierToProto(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
proto.write(HASH_CODE, System.identityHashCode(this));
@@ -3044,36 +3014,6 @@
|| (getParent() != null && getParent().inPinnedWindowingMode());
}
- /**
- * Initializes a change transition.
- *
- * For now, this will only be called for the following cases:
- * 1. {@link Task} is changing windowing mode between fullscreen and freeform.
- * 2. {@link TaskFragment} is organized and is changing window bounds.
- * 3. {@link ActivityRecord} is reparented into an organized {@link TaskFragment}. (The
- * transition will happen on the {@link TaskFragment} for this case).
- *
- * This shouldn't be called on other {@link WindowContainer} unless there is a valid
- * use case.
- *
- * @param startBounds The original bounds (on screen) of the surface we are snapshotting.
- */
- void initializeChangeTransition(Rect startBounds, @Nullable SurfaceControl freezeTarget) {
- if (mDisplayContent.mTransitionController.isShellTransitionsEnabled()) {
- mDisplayContent.mTransitionController.collectVisibleChange(this);
- return;
- }
- mDisplayContent.prepareAppTransition(TRANSIT_CHANGE);
- mDisplayContent.mChangingContainers.add(this);
- // Calculate the relative position in parent container.
- final Rect parentBounds = getParent().getBounds();
- mTmpPoint.set(startBounds.left - parentBounds.left, startBounds.top - parentBounds.top);
- }
-
- void initializeChangeTransition(Rect startBounds) {
- initializeChangeTransition(startBounds, null /* freezeTarget */);
- }
-
ArraySet<WindowContainer> getAnimationSources() {
return mSurfaceAnimationSources;
}
@@ -3166,8 +3106,7 @@
getAnimationPosition(mTmpPoint);
mTmpRect.offsetTo(0, 0);
- final boolean isChanging = AppTransition.isChangeTransitOld(transit) && enter
- && isChangingAppTransition();
+ final boolean isChanging = AppTransition.isChangeTransitOld(transit);
if (isChanging) {
final float durationScale = mWmService.getTransitionAnimationScaleLocked();
@@ -3519,9 +3458,6 @@
&& (mSurfaceAnimator.getAnimationType() & typesToCheck) > 0) {
return true;
}
- if ((flags & TRANSITION) != 0 && isWaitingForTransitionStart()) {
- return true;
- }
return false;
}
@@ -3603,13 +3539,7 @@
return;
}
- if (isClosingWhenResizing()) {
- // This container is closing while resizing, keep its surface at the starting position
- // to prevent animation flicker.
- getRelativePosition(mDisplayContent.mClosingChangingContainers.get(this), mTmpPos);
- } else {
- getRelativePosition(mTmpPos);
- }
+ getRelativePosition(mTmpPos);
final int deltaRotation = getRelativeDisplayRotation();
if (mTmpPos.equals(mLastSurfacePosition) && deltaRotation == mLastDeltaRotation) {
return;
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index 4c53ba5..4b4736e 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -1060,7 +1060,7 @@
effects |= applyChanges(taskFragment, c);
if (taskFragment.shouldStartChangeTransition(mTmpBounds0, mTmpBounds1)) {
- taskFragment.initializeChangeTransition(mTmpBounds0);
+ mTransitionController.collectVisibleChange(taskFragment);
}
taskFragment.continueOrganizedTaskFragmentSurfaceUpdate();
return effects;
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 5897241..9f1289b2 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -3272,13 +3272,6 @@
mDestroying = false;
destroyedSomething = true;
}
-
- // Since mDestroying will affect ActivityRecord#allDrawn, we need to perform another
- // traversal in case we are waiting on this window to start the transition.
- if (getDisplayContent().mAppTransition.isTransitionSet()
- && getDisplayContent().mOpeningApps.contains(mActivityRecord)) {
- mWmService.mWindowPlacerLocked.requestTraversal();
- }
}
return destroyedSomething;
diff --git a/services/core/java/com/android/server/wm/utils/WindowStyleCache.java b/services/core/java/com/android/server/wm/utils/WindowStyleCache.java
new file mode 100644
index 0000000..a253c2c
--- /dev/null
+++ b/services/core/java/com/android/server/wm/utils/WindowStyleCache.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2025 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.wm.utils;
+
+import android.content.res.TypedArray;
+import android.util.ArrayMap;
+import android.util.SparseArray;
+
+import com.android.internal.R;
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.policy.AttributeCache;
+
+import java.util.function.Function;
+
+/**
+ * A wrapper of AttributeCache to preserve more dedicated style caches.
+ * @param <T> The type of style cache.
+ */
+public class WindowStyleCache<T> {
+ @GuardedBy("itself")
+ private final ArrayMap<String, SparseArray<T>> mCache = new ArrayMap<>();
+ private final Function<TypedArray, T> mEntryFactory;
+
+ public WindowStyleCache(Function<TypedArray, T> entryFactory) {
+ mEntryFactory = entryFactory;
+ }
+
+ /** Returns the cached entry. */
+ public T get(String packageName, int theme, int userId) {
+ SparseArray<T> themeMap;
+ synchronized (mCache) {
+ themeMap = mCache.get(packageName);
+ if (themeMap != null) {
+ T style = themeMap.get(theme);
+ if (style != null) {
+ return style;
+ }
+ }
+ }
+
+ final AttributeCache attributeCache = AttributeCache.instance();
+ if (attributeCache == null) {
+ return null;
+ }
+ final AttributeCache.Entry ent = attributeCache.get(packageName, theme,
+ R.styleable.Window, userId);
+ if (ent == null) {
+ return null;
+ }
+
+ final T style = mEntryFactory.apply(ent.array);
+ synchronized (mCache) {
+ if (themeMap == null) {
+ mCache.put(packageName, themeMap = new SparseArray<>());
+ }
+ themeMap.put(theme, style);
+ }
+ return style;
+ }
+
+ /** Called when the package is updated or removed. */
+ public void invalidatePackage(String packageName) {
+ synchronized (mCache) {
+ mCache.remove(packageName);
+ }
+ }
+}
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index f07e672..a8c49e1 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -47,6 +47,7 @@
#include <dispatcher/Entry.h>
#include <include/gestures.h>
#include <input/Input.h>
+#include <input/InputFlags.h>
#include <input/PointerController.h>
#include <input/PrintTools.h>
#include <input/SpriteController.h>
@@ -124,6 +125,7 @@
jmethodID notifyStylusGestureStarted;
jmethodID notifyVibratorState;
jmethodID filterInputEvent;
+ jmethodID filterPointerMotion;
jmethodID interceptKeyBeforeQueueing;
jmethodID interceptMotionBeforeQueueingNonInteractive;
jmethodID interceptKeyBeforeDispatching;
@@ -451,6 +453,8 @@
void notifyPointerDisplayIdChanged(ui::LogicalDisplayId displayId,
const vec2& position) override;
void notifyMouseCursorFadedOnTyping() override;
+ std::optional<vec2> filterPointerMotionForAccessibility(
+ const vec2& current, const vec2& delta, const ui::LogicalDisplayId& displayId) override;
/* --- InputFilterPolicyInterface implementation --- */
void notifyStickyModifierStateChanged(uint32_t modifierState,
@@ -663,7 +667,7 @@
}
void NativeInputManager::setDisplayTopology(JNIEnv* env, jobject topologyGraph) {
- if (!com::android::input::flags::connected_displays_cursor()) {
+ if (!InputFlags::connectedDisplaysCursorEnabled()) {
return;
}
@@ -938,6 +942,27 @@
checkAndClearExceptionFromCallback(env, "notifyStickyModifierStateChanged");
}
+std::optional<vec2> NativeInputManager::filterPointerMotionForAccessibility(
+ const vec2& current, const vec2& delta, const ui::LogicalDisplayId& displayId) {
+ JNIEnv* env = jniEnv();
+ ScopedFloatArrayRO filtered(env,
+ jfloatArray(
+ env->CallObjectMethod(mServiceObj,
+ gServiceClassInfo.filterPointerMotion,
+ delta.x, delta.y, current.x,
+ current.y, displayId.val())));
+ if (checkAndClearExceptionFromCallback(env, "filterPointerMotionForAccessibilityLocked")) {
+ ALOGE("Disabling accessibility pointer motion filter due to an error. "
+ "The filter state in Java and PointerChoreographer would no longer be in sync.");
+ return std::nullopt;
+ }
+ LOG_ALWAYS_FATAL_IF(filtered.size() != 2,
+ "Accessibility pointer motion filter is misbehaving. Returned array size "
+ "%zu should be 2.",
+ filtered.size());
+ return vec2{filtered[0], filtered[1]};
+}
+
sp<SurfaceControl> NativeInputManager::getParentSurfaceForPointers(ui::LogicalDisplayId displayId) {
JNIEnv* env = jniEnv();
jlong nativeSurfaceControlPtr =
@@ -3271,6 +3296,12 @@
return im->getInputManager()->getReader().setKernelWakeEnabled(deviceId, enabled);
}
+static void nativeSetAccessibilityPointerMotionFilterEnabled(JNIEnv* env, jobject nativeImplObj,
+ jboolean enabled) {
+ NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
+ im->getInputManager()->getChoreographer().setAccessibilityPointerMotionFilterEnabled(enabled);
+}
+
// ----------------------------------------------------------------------------
static const JNINativeMethod gInputManagerMethods[] = {
@@ -3398,6 +3429,8 @@
{"setInputMethodConnectionIsActive", "(Z)V", (void*)nativeSetInputMethodConnectionIsActive},
{"getLastUsedInputDeviceId", "()I", (void*)nativeGetLastUsedInputDeviceId},
{"setKernelWakeEnabled", "(IZ)Z", (void*)nativeSetKernelWakeEnabled},
+ {"setAccessibilityPointerMotionFilterEnabled", "(Z)V",
+ (void*)nativeSetAccessibilityPointerMotionFilterEnabled},
};
#define FIND_CLASS(var, className) \
@@ -3482,6 +3515,8 @@
GET_METHOD_ID(gServiceClassInfo.filterInputEvent, clazz,
"filterInputEvent", "(Landroid/view/InputEvent;I)Z");
+ GET_METHOD_ID(gServiceClassInfo.filterPointerMotion, clazz, "filterPointerMotion", "(FFFFI)[F");
+
GET_METHOD_ID(gServiceClassInfo.interceptKeyBeforeQueueing, clazz,
"interceptKeyBeforeQueueing", "(Landroid/view/KeyEvent;I)I");
diff --git a/services/credentials/java/com/android/server/credentials/CredentialManagerServiceImpl.java b/services/credentials/java/com/android/server/credentials/CredentialManagerServiceImpl.java
index 40554ac..7edf646 100644
--- a/services/credentials/java/com/android/server/credentials/CredentialManagerServiceImpl.java
+++ b/services/credentials/java/com/android/server/credentials/CredentialManagerServiceImpl.java
@@ -21,11 +21,16 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.credentials.CredentialManager;
import android.credentials.CredentialProviderInfo;
+import android.credentials.flags.Flags;
import android.service.credentials.CredentialProviderInfoFactory;
+import android.service.credentials.CredentialProviderService;
import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
@@ -78,14 +83,16 @@
mInfo = providerInfo;
}
- @Override // from PerUserSystemService when a new setting based service is to be created
+ @Override // from PerUserSystemService when a new service is to be created
@GuardedBy("mLock")
protected ServiceInfo newServiceInfoLocked(@NonNull ComponentName serviceComponent)
- throws PackageManager.NameNotFoundException {
+ throws PackageManager.NameNotFoundException, SecurityException, NullPointerException {
+ boolean isSystemProvider = false;
if (mInfo != null) {
Slog.i(TAG, "newServiceInfoLocked, mInfo not null : "
+ mInfo.getServiceInfo().getComponentName().flattenToString() + " , "
+ serviceComponent.flattenToString());
+ isSystemProvider = mInfo.isSystemProvider();
} else {
Slog.i(TAG, "newServiceInfoLocked, mInfo null, "
+ serviceComponent.flattenToString());
@@ -94,7 +101,7 @@
getPrimaryProvidersForUserId(mMaster.getContext(), mUserId);
mInfo = CredentialProviderInfoFactory.create(
getContext(), serviceComponent,
- mUserId, /*isSystemProvider=*/false,
+ mUserId, isSystemProvider,
primaryProviders.contains(serviceComponent));
return mInfo.getServiceInfo();
}
@@ -148,15 +155,63 @@
* @param packageName package of the app being updated.
*/
@GuardedBy("mLock")
+ @SuppressWarnings("GuardedBy") // ErrorProne requires this.mMaster.mLock which is the case
+ // because this method is called by this.mMaster anyway
protected void handlePackageUpdateLocked(@NonNull String packageName) {
if (mInfo != null && mInfo.getServiceInfo() != null
&& mInfo.getServiceInfo().getComponentName()
.getPackageName().equals(packageName)) {
- try {
- newServiceInfoLocked(mInfo.getServiceInfo().getComponentName());
- } catch (PackageManager.NameNotFoundException e) {
- Slog.e(TAG, "Issue while updating serviceInfo: " + e.getMessage());
+ if (Flags.packageUpdateFixEnabled()) {
+ try {
+ updateCredentialProviderInfo(mInfo.getServiceInfo().getComponentName(),
+ mInfo.isSystemProvider());
+ } catch (SecurityException | PackageManager.NameNotFoundException
+ | NullPointerException e) {
+ Slog.w(TAG, "Unable to update provider, must be removed: " + e.getMessage());
+ mMaster.handleServiceRemovedMultiModeLocked(mInfo.getComponentName(), mUserId);
+ }
+ } else {
+ try {
+ newServiceInfoLocked(mInfo.getServiceInfo().getComponentName());
+ } catch (PackageManager.NameNotFoundException e) {
+ Slog.e(TAG, "Issue while updating serviceInfo: " + e.getMessage());
+ }
}
}
}
+
+ @GuardedBy("mLock")
+ private void updateCredentialProviderInfo(ComponentName componentName, boolean isSystemProvider)
+ throws SecurityException, PackageManager.NameNotFoundException {
+ Slog.d(TAG, "Updating credential provider: " + componentName.flattenToString());
+ if (!isValidCredentialProviderInfo(componentName, mUserId, isSystemProvider)) {
+ throw new SecurityException("Service has not been set up correctly");
+ }
+ newServiceInfoLocked(componentName);
+ }
+
+ private boolean isValidCredentialProviderInfo(ComponentName componentName, int userId,
+ boolean isSystemProvider) {
+ Context context = getContext();
+ if (context == null) {
+ return false;
+ }
+ String serviceInterface = CredentialProviderService.SERVICE_INTERFACE;
+ if (isSystemProvider) {
+ serviceInterface = CredentialProviderService.SYSTEM_SERVICE_INTERFACE;
+ }
+ final List<ResolveInfo> resolveInfos =
+ context.getPackageManager()
+ .queryIntentServicesAsUser(
+ new Intent(serviceInterface),
+ PackageManager.ResolveInfoFlags.of(PackageManager.GET_META_DATA),
+ userId);
+ for (ResolveInfo resolveInfo : resolveInfos) {
+ final ServiceInfo serviceInfo = resolveInfo.serviceInfo;
+ if (serviceInfo.getComponentName().equals(componentName)) {
+ return true;
+ }
+ }
+ return false;
+ }
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java
index bbbfe0b..5b7e7f1 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java
@@ -65,6 +65,7 @@
import android.util.SparseArray;
import android.util.Xml;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.XmlUtils;
import com.android.modules.utils.TypedXmlPullParser;
import com.android.modules.utils.TypedXmlSerializer;
@@ -120,11 +121,13 @@
/**
* Map of <userId, Map<policyKey, policyState>>
*/
+ @GuardedBy("mLock")
private final SparseArray<Map<PolicyKey, PolicyState<?>>> mLocalPolicies;
/**
* Map of <policyKey, policyState>
*/
+ @GuardedBy("mLock")
private final Map<PolicyKey, PolicyState<?>> mGlobalPolicies;
/**
@@ -152,6 +155,7 @@
mAdminPolicySize = new SparseArray<>();
}
+ @GuardedBy("mLock")
private void forceEnforcementRefreshIfUserRestrictionLocked(
@NonNull PolicyDefinition<?> policyDefinition) {
try {
@@ -185,6 +189,7 @@
return false;
}
+ @GuardedBy("mLock")
private void forceEnforcementRefreshLocked(PolicyDefinition<Boolean> policyDefinition) {
Binder.withCleanCallingIdentity(() -> {
// Sync global state
@@ -296,6 +301,7 @@
*
* <p>Passing a {@code null} value means the policy set by this admin should be removed.
*/
+ @GuardedBy("mLock")
private <V> void setNonCoexistableLocalPolicyLocked(
PolicyDefinition<V> policyDefinition,
PolicyState<V> localPolicyState,
@@ -440,6 +446,7 @@
/**
* Enforces the new policy and notifies relevant admins.
*/
+ @GuardedBy("mLock")
private <V> void onLocalPolicyChangedLocked(
@NonNull PolicyDefinition<V> policyDefinition,
@NonNull EnforcingAdmin enforcingAdmin,
@@ -600,6 +607,7 @@
/**
* Enforces the new policy globally and notifies relevant admins.
*/
+ @GuardedBy("mLock")
private <V> void onGlobalPolicyChangedLocked(
@NonNull PolicyDefinition<V> policyDefinition,
@NonNull EnforcingAdmin enforcingAdmin) {
@@ -627,6 +635,7 @@
*
* <p>Returns {@code true} if the policy is enforced successfully on all users.
*/
+ @GuardedBy("mLock")
private <V> boolean applyGlobalPolicyOnUsersWithLocalPoliciesLocked(
@NonNull PolicyDefinition<V> policyDefinition,
@NonNull EnforcingAdmin enforcingAdmin,
@@ -930,6 +939,7 @@
removePoliciesForAdmin(oldAdmin);
}
+ @GuardedBy("mLock")
private Set<UserRestrictionPolicyKey> getUserRestrictionPolicyKeysForAdminLocked(
Map<PolicyKey, PolicyState<?>> policies,
EnforcingAdmin admin) {
@@ -949,6 +959,7 @@
return keys;
}
+ @GuardedBy("mLock")
private <V> boolean hasLocalPolicyLocked(PolicyDefinition<V> policyDefinition, int userId) {
if (policyDefinition.isGlobalOnlyPolicy()) {
return false;
@@ -963,6 +974,7 @@
.getPoliciesSetByAdmins().isEmpty();
}
+ @GuardedBy("mLock")
private <V> boolean hasGlobalPolicyLocked(PolicyDefinition<V> policyDefinition) {
if (policyDefinition.isLocalOnlyPolicy()) {
return false;
@@ -974,6 +986,7 @@
.isEmpty();
}
+ @GuardedBy("mLock")
@NonNull
private <V> PolicyState<V> getLocalPolicyStateLocked(
PolicyDefinition<V> policyDefinition, int userId) {
@@ -993,6 +1006,7 @@
return getPolicyStateLocked(mLocalPolicies.get(userId), policyDefinition);
}
+ @GuardedBy("mLock")
private <V> void removeLocalPolicyStateLocked(
PolicyDefinition<V> policyDefinition, int userId) {
if (!mLocalPolicies.contains(userId)) {
@@ -1001,6 +1015,7 @@
mLocalPolicies.get(userId).remove(policyDefinition.getPolicyKey());
}
+ @GuardedBy("mLock")
@NonNull
private <V> PolicyState<V> getGlobalPolicyStateLocked(PolicyDefinition<V> policyDefinition) {
if (policyDefinition.isLocalOnlyPolicy()) {
@@ -1015,10 +1030,12 @@
return getPolicyStateLocked(mGlobalPolicies, policyDefinition);
}
+ @GuardedBy("mLock")
private <V> void removeGlobalPolicyStateLocked(PolicyDefinition<V> policyDefinition) {
mGlobalPolicies.remove(policyDefinition.getPolicyKey());
}
+ @GuardedBy("mLock")
private static <V> PolicyState<V> getPolicyStateLocked(
Map<PolicyKey, PolicyState<?>> policies, PolicyDefinition<V> policyDefinition) {
try {
@@ -1089,6 +1106,7 @@
}
// TODO(b/261430877): Finalise the decision on which admins to send the updates to.
+ @GuardedBy("mLock")
private <V> void sendPolicyChangedToAdminsLocked(
PolicyState<V> policyState,
EnforcingAdmin callingAdmin,
@@ -1378,6 +1396,7 @@
});
}
+ @GuardedBy("mLock")
private <V> void enforcePolicyOnUserLocked(int userId, PolicyState<V> policyState) {
if (!policyState.getPolicyDefinition().isInheritable()) {
return;
@@ -1509,6 +1528,7 @@
* Called after an admin policy has been added to start binding to the admin if a connection
* was not already established.
*/
+ @GuardedBy("mLock")
private void updateDeviceAdminServiceOnPolicyAddLocked(@NonNull EnforcingAdmin enforcingAdmin) {
int userId = enforcingAdmin.getUserId();
@@ -1537,6 +1557,7 @@
* Called after an admin policy has been removed to stop binding to the admin if they no longer
* have any policies set.
*/
+ @GuardedBy("mLock")
private void updateDeviceAdminServiceOnPolicyRemoveLocked(
@NonNull EnforcingAdmin enforcingAdmin) {
if (doesAdminHavePoliciesLocked(enforcingAdmin)) {
@@ -1562,6 +1583,7 @@
/* actionForLog= */ "policy-removed");
}
+ @GuardedBy("mLock")
private boolean doesAdminHavePoliciesLocked(@NonNull EnforcingAdmin enforcingAdmin) {
for (PolicyKey policy : mGlobalPolicies.keySet()) {
PolicyState<?> policyState = mGlobalPolicies.get(policy);
@@ -1785,6 +1807,7 @@
}
}
+ @GuardedBy("mLock")
<V> void reapplyAllPoliciesOnBootLocked() {
for (PolicyKey policy : mGlobalPolicies.keySet()) {
PolicyState<?> policyState = mGlobalPolicies.get(policy);
@@ -1919,6 +1942,7 @@
}
}
+ @GuardedBy("mLock")
void writeToFileLocked() {
Log.d(TAG, "Writing to " + mFile);
@@ -1931,7 +1955,7 @@
out.startDocument(null, true);
// Actual content
- writeInner(out);
+ writeInnerLocked(out);
out.endDocument();
out.flush();
@@ -1948,16 +1972,19 @@
}
}
+ @GuardedBy("mLock")
// TODO(b/256846294): Add versioning to read/write
- void writeInner(TypedXmlSerializer serializer) throws IOException {
- writeLocalPoliciesInner(serializer);
- writeGlobalPoliciesInner(serializer);
- writeEnforcingAdminsInner(serializer);
- writeEnforcingAdminSizeInner(serializer);
- writeMaxPolicySizeInner(serializer);
+ void writeInnerLocked(TypedXmlSerializer serializer) throws IOException {
+ writeLocalPoliciesInnerLocked(serializer);
+ writeGlobalPoliciesInnerLocked(serializer);
+ writeEnforcingAdminsInnerLocked(serializer);
+ writeEnforcingAdminSizeInnerLocked(serializer);
+ writeMaxPolicySizeInnerLocked(serializer);
}
- private void writeLocalPoliciesInner(TypedXmlSerializer serializer) throws IOException {
+ @GuardedBy("mLock")
+ private void writeLocalPoliciesInnerLocked(TypedXmlSerializer serializer)
+ throws IOException {
if (mLocalPolicies != null) {
for (int i = 0; i < mLocalPolicies.size(); i++) {
int userId = mLocalPolicies.keyAt(i);
@@ -1981,7 +2008,9 @@
}
}
- private void writeGlobalPoliciesInner(TypedXmlSerializer serializer) throws IOException {
+ @GuardedBy("mLock")
+ private void writeGlobalPoliciesInnerLocked(TypedXmlSerializer serializer)
+ throws IOException {
if (mGlobalPolicies != null) {
for (Map.Entry<PolicyKey, PolicyState<?>> policy : mGlobalPolicies.entrySet()) {
serializer.startTag(/* namespace= */ null, TAG_GLOBAL_POLICY_ENTRY);
@@ -1999,7 +2028,9 @@
}
}
- private void writeEnforcingAdminsInner(TypedXmlSerializer serializer) throws IOException {
+ @GuardedBy("mLock")
+ private void writeEnforcingAdminsInnerLocked(TypedXmlSerializer serializer)
+ throws IOException {
if (mEnforcingAdmins != null) {
for (int i = 0; i < mEnforcingAdmins.size(); i++) {
int userId = mEnforcingAdmins.keyAt(i);
@@ -2012,7 +2043,8 @@
}
}
- private void writeEnforcingAdminSizeInner(TypedXmlSerializer serializer)
+ @GuardedBy("mLock")
+ private void writeEnforcingAdminSizeInnerLocked(TypedXmlSerializer serializer)
throws IOException {
if (mAdminPolicySize != null) {
for (int i = 0; i < mAdminPolicySize.size(); i++) {
@@ -2034,7 +2066,8 @@
}
}
- private void writeMaxPolicySizeInner(TypedXmlSerializer serializer)
+ @GuardedBy("mLock")
+ private void writeMaxPolicySizeInnerLocked(TypedXmlSerializer serializer)
throws IOException {
serializer.startTag(/* namespace= */ null, TAG_MAX_POLICY_SIZE_LIMIT);
serializer.attributeInt(
@@ -2042,6 +2075,7 @@
serializer.endTag(/* namespace= */ null, TAG_MAX_POLICY_SIZE_LIMIT);
}
+ @GuardedBy("mLock")
void readFromFileLocked() {
if (!mFile.exists()) {
Log.d(TAG, "" + mFile + " doesn't exist");
@@ -2055,7 +2089,7 @@
input = f.openRead();
TypedXmlPullParser parser = Xml.resolvePullParser(input);
- readInner(parser);
+ readInnerLocked(parser);
} catch (XmlPullParserException | IOException | ClassNotFoundException e) {
Slogf.wtf(TAG, "Error parsing resources file", e);
@@ -2064,7 +2098,8 @@
}
}
- private void readInner(TypedXmlPullParser parser)
+ @GuardedBy("mLock")
+ private void readInnerLocked(TypedXmlPullParser parser)
throws IOException, XmlPullParserException, ClassNotFoundException {
int outerDepth = parser.getDepth();
while (XmlUtils.nextElementWithin(parser, outerDepth)) {
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 2bbd69c..e158310 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -1279,12 +1279,6 @@
if (!Flags.refactorCrashrecovery()) {
// Initialize RescueParty.
CrashRecoveryAdaptor.rescuePartyRegisterHealthObserver(mSystemContext);
- if (!Flags.recoverabilityDetection()) {
- // Now that we have the bare essentials of the OS up and running, take
- // note that we just booted, which might send out a rescue party if
- // we're stuck in a runtime restart loop.
- CrashRecoveryAdaptor.packageWatchdogNoteBoot(mSystemContext);
- }
}
@@ -1558,14 +1552,6 @@
boolean enableVrService = context.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE);
- if (!Flags.recoverabilityDetection()) {
- // For debugging RescueParty
- if (Build.IS_DEBUGGABLE
- && SystemProperties.getBoolean("debug.crash_system", false)) {
- throw new RuntimeException();
- }
- }
-
try {
final String SECONDARY_ZYGOTE_PRELOAD = "SecondaryZygotePreload";
// We start the preload ~1s before the webview factory preparation, to
@@ -3091,13 +3077,11 @@
CrashRecoveryAdaptor.initializeCrashrecoveryModuleService(mSystemServiceManager);
t.traceEnd();
} else {
- if (Flags.recoverabilityDetection()) {
- // Now that we have the essential services needed for mitigations, register the boot
- // with package watchdog.
- // Note that we just booted, which might send out a rescue party if we're stuck in a
- // runtime restart loop.
- CrashRecoveryAdaptor.packageWatchdogNoteBoot(mSystemContext);
- }
+ // Now that we have the essential services needed for mitigations, register the boot
+ // with package watchdog.
+ // Note that we just booted, which might send out a rescue party if we're stuck in a
+ // runtime restart loop.
+ CrashRecoveryAdaptor.packageWatchdogNoteBoot(mSystemContext);
}
t.traceBegin("MakeDisplayManagerServiceReady");
@@ -3511,12 +3495,10 @@
* are updated outside of OTA; and to avoid breaking dependencies from system into apexes.
*/
private void startApexServices(@NonNull TimingsTraceAndSlog t) {
- if (Flags.recoverabilityDetection()) {
- // For debugging RescueParty
- if (Build.IS_DEBUGGABLE
- && SystemProperties.getBoolean("debug.crash_system", false)) {
- throw new RuntimeException();
- }
+ // For debugging RescueParty
+ if (Build.IS_DEBUGGABLE
+ && SystemProperties.getBoolean("debug.crash_system", false)) {
+ throw new RuntimeException();
}
t.traceBegin("startApexServices");
diff --git a/services/supervision/java/com/android/server/supervision/SupervisionService.java b/services/supervision/java/com/android/server/supervision/SupervisionService.java
index a96c477..f731b50 100644
--- a/services/supervision/java/com/android/server/supervision/SupervisionService.java
+++ b/services/supervision/java/com/android/server/supervision/SupervisionService.java
@@ -17,6 +17,8 @@
package com.android.server.supervision;
import static android.Manifest.permission.INTERACT_ACROSS_USERS;
+import static android.Manifest.permission.MANAGE_USERS;
+import static android.Manifest.permission.QUERY_USERS;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static com.android.internal.util.Preconditions.checkCallAuthorization;
@@ -79,6 +81,25 @@
}
/**
+ * Creates an {@link Intent} that can be used with {@link Context#startActivity(Intent)} to
+ * launch the activity to verify supervision credentials.
+ *
+ * <p>A valid {@link Intent} is always returned if supervision is enabled at the time this
+ * method is called, the launched activity still need to perform validity checks as the
+ * supervision state can change when it's launched. A null intent is returned if supervision is
+ * disabled at the time of this method call.
+ *
+ * <p>A result code of {@link android.app.Activity#RESULT_OK} indicates successful verification
+ * of the supervision credentials.
+ */
+ @Override
+ @Nullable
+ public Intent createConfirmSupervisionCredentialsIntent() {
+ // TODO(b/392961554): Implement createAuthenticationIntent API
+ throw new UnsupportedOperationException();
+ }
+
+ /**
* Returns whether supervision is enabled for the given user.
*
* <p>Supervision is automatically enabled when the supervision app becomes the profile owner or
@@ -86,6 +107,7 @@
*/
@Override
public boolean isSupervisionEnabledForUser(@UserIdInt int userId) {
+ enforceAnyPermission(QUERY_USERS, MANAGE_USERS);
if (UserHandle.getUserId(Binder.getCallingUid()) != userId) {
enforcePermission(INTERACT_ACROSS_USERS);
}
@@ -96,6 +118,7 @@
@Override
public void setSupervisionEnabledForUser(@UserIdInt int userId, boolean enabled) {
+ // TODO(b/395630828): Ensure that this method can only be called by the system.
if (UserHandle.getUserId(Binder.getCallingUid()) != userId) {
enforcePermission(INTERACT_ACROSS_USERS);
}
@@ -181,8 +204,8 @@
* Ensures that supervision is enabled when the supervision app is the profile owner.
*
* <p>The state syncing with the DevicePolicyManager can only enable supervision and never
- * disable. Supervision can only be disabled explicitly via calls to the
- * {@link #setSupervisionEnabledForUser} method.
+ * disable. Supervision can only be disabled explicitly via calls to the {@link
+ * #setSupervisionEnabledForUser} method.
*/
private void syncStateWithDevicePolicyManager(@UserIdInt int userId) {
final DevicePolicyManagerInternal dpmInternal = mInjector.getDpmInternal();
@@ -221,6 +244,17 @@
mContext.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED);
}
+ /** Enforces that the caller has at least one of the given permission. */
+ private void enforceAnyPermission(String... permissions) {
+ boolean authorized = false;
+ for (String permission : permissions) {
+ if (mContext.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED) {
+ authorized = true;
+ }
+ }
+ checkCallAuthorization(authorized);
+ }
+
/** Provides local services in a lazy manner. */
static class Injector {
private final Context mContext;
@@ -280,7 +314,7 @@
}
@VisibleForTesting
- @SuppressLint("MissingPermission") // not needed for a system service
+ @SuppressLint("MissingPermission")
void registerProfileOwnerListener() {
IntentFilter poIntentFilter = new IntentFilter();
poIntentFilter.addAction(DevicePolicyManager.ACTION_PROFILE_OWNER_CHANGED);
diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/InputMethodServiceTest.java b/services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/InputMethodServiceTest.java
index 5d64cb6..2d3f723 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/InputMethodServiceTest.java
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/InputMethodServiceTest.java
@@ -34,12 +34,12 @@
import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeTrue;
+import android.app.ActivityManager;
import android.app.Instrumentation;
import android.content.res.Configuration;
import android.graphics.Insets;
+import android.os.Build;
import android.os.RemoteException;
-import android.platform.test.annotations.RequiresFlagsDisabled;
-import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.provider.Settings;
import android.server.wm.WindowManagerStateHelper;
@@ -86,25 +86,36 @@
"android:id/input_method_nav_back";
private static final String INPUT_METHOD_NAV_IME_SWITCHER_ID =
"android:id/input_method_nav_ime_switcher";
- private static final long TIMEOUT_IN_SECONDS = 3;
- private static final String ENABLE_SHOW_IME_WITH_HARD_KEYBOARD_CMD =
- "settings put secure " + Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD + " 1";
- private static final String DISABLE_SHOW_IME_WITH_HARD_KEYBOARD_CMD =
- "settings put secure " + Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD + " 0";
+
+ /** Timeout until the uiObject should be found. */
+ private static final long TIMEOUT_MS = 5000L * Build.HW_TIMEOUT_MULTIPLIER;
+
+ /** Timeout until the event is expected. */
+ private static final long EXPECT_TIMEOUT_MS = 3000L * Build.HW_TIMEOUT_MULTIPLIER;
+
+ /** Timeout during which the event is not expected. */
+ private static final long NOT_EXCEPT_TIMEOUT_MS = 2000L * Build.HW_TIMEOUT_MULTIPLIER;
+
+ /** Command to set showing the IME when a hardware keyboard is connected. */
+ private static final String SET_SHOW_IME_WITH_HARD_KEYBOARD_CMD =
+ "settings put secure " + Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD;
+ /** Command to get verbose ImeTracker logging state. */
+ private static final String GET_VERBOSE_IME_TRACKER_LOGGING_CMD =
+ "getprop persist.debug.imetracker";
+ /** Command to set verbose ImeTracker logging state. */
+ private static final String SET_VERBOSE_IME_TRACKER_LOGGING_CMD =
+ "setprop persist.debug.imetracker";
/** The ids of the subtypes of SimpleIme. */
private static final int[] SUBTYPE_IDS = new int[]{1, 2};
- private final WindowManagerStateHelper mWmState = new WindowManagerStateHelper();
+ private final WindowManagerStateHelper mWmState = new WindowManagerStateHelper();
private final GestureNavSwitchHelper mGestureNavSwitchHelper = new GestureNavSwitchHelper();
private final DeviceFlagsValueProvider mFlagsValueProvider = new DeviceFlagsValueProvider();
@Rule
- public final CheckFlagsRule mCheckFlagsRule = new CheckFlagsRule(mFlagsValueProvider);
-
- @Rule
public final TestName mName = new TestName();
private Instrumentation mInstrumentation;
@@ -114,7 +125,8 @@
private String mInputMethodId;
private TestActivity mActivity;
private InputMethodServiceWrapper mInputMethodService;
- private boolean mShowImeWithHardKeyboardEnabled;
+ private boolean mOriginalVerboseImeTrackerLoggingEnabled;
+ private boolean mOriginalShowImeWithHardKeyboardEnabled;
@Before
public void setUp() throws Exception {
@@ -123,9 +135,12 @@
mImm = mInstrumentation.getContext().getSystemService(InputMethodManager.class);
mTargetPackageName = mInstrumentation.getTargetContext().getPackageName();
mInputMethodId = getInputMethodId();
+ mOriginalVerboseImeTrackerLoggingEnabled = getVerboseImeTrackerLogging();
+ if (!mOriginalVerboseImeTrackerLoggingEnabled) {
+ setVerboseImeTrackerLogging(true);
+ }
prepareIme();
prepareActivity();
- mInstrumentation.waitForIdleSync();
mUiDevice.freezeRotation();
mUiDevice.setOrientationNatural();
// Waits for input binding ready.
@@ -148,17 +163,18 @@
.that(mInputMethodService.getCurrentInputViewStarted()).isFalse();
});
// Save the original value of show_ime_with_hard_keyboard from Settings.
- mShowImeWithHardKeyboardEnabled =
+ mOriginalShowImeWithHardKeyboardEnabled =
mInputMethodService.getShouldShowImeWithHardKeyboardForTesting();
}
@After
public void tearDown() throws Exception {
mUiDevice.unfreezeRotation();
+ if (!mOriginalVerboseImeTrackerLoggingEnabled) {
+ setVerboseImeTrackerLogging(false);
+ }
// Change back the original value of show_ime_with_hard_keyboard in Settings.
- executeShellCommand(mShowImeWithHardKeyboardEnabled
- ? ENABLE_SHOW_IME_WITH_HARD_KEYBOARD_CMD
- : DISABLE_SHOW_IME_WITH_HARD_KEYBOARD_CMD);
+ setShowImeWithHardKeyboard(mOriginalShowImeWithHardKeyboardEnabled);
executeShellCommand("ime disable " + mInputMethodId);
}
@@ -170,7 +186,7 @@
public void testShowHideKeyboard_byUserAction() {
waitUntilActivityReadyForInputInjection(mActivity);
- setShowImeWithHardKeyboard(true /* enabled */);
+ setShowImeWithHardKeyboard(true /* enable */);
// Performs click on EditText to bring up the IME.
Log.i(TAG, "Click on EditText");
@@ -201,14 +217,12 @@
*/
@Test
public void testShowHideKeyboard_byInputMethodManager() {
- setShowImeWithHardKeyboard(true /* enabled */);
+ setShowImeWithHardKeyboard(true /* enable */);
- // Triggers to show IME via public API.
verifyInputViewStatusOnMainSync(
() -> assertThat(mActivity.showImeWithInputMethodManager(0 /* flags */)).isTrue(),
EVENT_SHOW, true /* eventExpected */, true /* shown */, "IME is shown");
- // Triggers to hide IME via public API.
verifyInputViewStatusOnMainSync(
() -> assertThat(mActivity.hideImeWithInputMethodManager(0 /* flags */)).isTrue(),
EVENT_HIDE, true /* eventExpected */, false /* shown */, "IME is not shown");
@@ -219,14 +233,12 @@
*/
@Test
public void testShowHideKeyboard_byInsetsController() {
- setShowImeWithHardKeyboard(true /* enabled */);
+ setShowImeWithHardKeyboard(true /* enable */);
- // Triggers to show IME via public API.
verifyInputViewStatusOnMainSync(
() -> mActivity.showImeWithWindowInsetsController(),
EVENT_SHOW, true /* eventExpected */, true /* shown */, "IME is shown");
- // Triggers to hide IME via public API.
verifyInputViewStatusOnMainSync(
() -> mActivity.hideImeWithWindowInsetsController(),
EVENT_HIDE, true /* eventExpected */, false /* shown */, "IME is not shown");
@@ -234,53 +246,18 @@
/**
* This checks the result of calling IMS#requestShowSelf and IMS#requestHideSelf.
- *
- * <p>With the refactor in b/298172246, all calls to IMMS#{show,hide}MySoftInputLocked
- * will be just apply the requested visibility (by using the callback). Therefore, we will
- * lose flags like HIDE_IMPLICIT_ONLY.
*/
@Test
public void testShowHideSelf() {
- setShowImeWithHardKeyboard(true /* enabled */);
+ setShowImeWithHardKeyboard(true /* enable */);
- // IME request to show itself without any flags, expect shown.
- Log.i(TAG, "Call IMS#requestShowSelf(0)");
verifyInputViewStatusOnMainSync(
() -> mInputMethodService.requestShowSelf(0 /* flags */),
EVENT_SHOW, true /* eventExpected */, true /* shown */, "IME is shown");
- if (!mFlagsValueProvider.getBoolean(Flags.FLAG_REFACTOR_INSETS_CONTROLLER)) {
- // IME request to hide itself with flag HIDE_IMPLICIT_ONLY, expect not hide (shown).
- Log.i(TAG, "Call IMS#requestHideSelf(InputMethodManager.HIDE_IMPLICIT_ONLY)");
- verifyInputViewStatusOnMainSync(
- () -> mInputMethodService.requestHideSelf(
- InputMethodManager.HIDE_IMPLICIT_ONLY),
- EVENT_HIDE, false /* eventExpected */, true /* shown */,
- "IME is still shown after HIDE_IMPLICIT_ONLY");
- }
-
- // IME request to hide itself without any flags, expect hidden.
- Log.i(TAG, "Call IMS#requestHideSelf(0)");
verifyInputViewStatusOnMainSync(
() -> mInputMethodService.requestHideSelf(0 /* flags */),
EVENT_HIDE, true /* eventExpected */, false /* shown */, "IME is not shown");
-
- if (!mFlagsValueProvider.getBoolean(Flags.FLAG_REFACTOR_INSETS_CONTROLLER)) {
- // IME request to show itself with flag SHOW_IMPLICIT, expect shown.
- Log.i(TAG, "Call IMS#requestShowSelf(InputMethodManager.SHOW_IMPLICIT)");
- verifyInputViewStatusOnMainSync(
- () -> mInputMethodService.requestShowSelf(InputMethodManager.SHOW_IMPLICIT),
- EVENT_SHOW, true /* eventExpected */, true /* shown */,
- "IME is shown with SHOW_IMPLICIT");
-
- // IME request to hide itself with flag HIDE_IMPLICIT_ONLY, expect hidden.
- Log.i(TAG, "Call IMS#requestHideSelf(InputMethodManager.HIDE_IMPLICIT_ONLY)");
- verifyInputViewStatusOnMainSync(
- () -> mInputMethodService.requestHideSelf(
- InputMethodManager.HIDE_IMPLICIT_ONLY),
- EVENT_HIDE, true /* eventExpected */, false /* shown */,
- "IME is not shown after HIDE_IMPLICIT_ONLY");
- }
}
/**
@@ -289,28 +266,25 @@
*/
@Test
public void testOnEvaluateInputViewShown_showImeWithHardKeyboard() {
- setShowImeWithHardKeyboard(true /* enabled */);
+ setShowImeWithHardKeyboard(true /* enable */);
final var config = mInputMethodService.getResources().getConfiguration();
final var initialConfig = new Configuration(config);
try {
config.keyboard = Configuration.KEYBOARD_QWERTY;
config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO;
- eventually(() ->
- assertWithMessage("InputView should show with visible hardware keyboard")
- .that(mInputMethodService.onEvaluateInputViewShown()).isTrue());
+ assertWithMessage("InputView should show with visible hardware keyboard")
+ .that(mInputMethodService.onEvaluateInputViewShown()).isTrue();
config.keyboard = Configuration.KEYBOARD_NOKEYS;
config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO;
- eventually(() ->
- assertWithMessage("InputView should show without hardware keyboard")
- .that(mInputMethodService.onEvaluateInputViewShown()).isTrue());
+ assertWithMessage("InputView should show without hardware keyboard")
+ .that(mInputMethodService.onEvaluateInputViewShown()).isTrue();
config.keyboard = Configuration.KEYBOARD_QWERTY;
config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_YES;
- eventually(() ->
- assertWithMessage("InputView should show with hidden hardware keyboard")
- .that(mInputMethodService.onEvaluateInputViewShown()).isTrue());
+ assertWithMessage("InputView should show with hidden hardware keyboard")
+ .that(mInputMethodService.onEvaluateInputViewShown()).isTrue();
} finally {
mInputMethodService.getResources()
.updateConfiguration(initialConfig, null /* metrics */, null /* compat */);
@@ -323,28 +297,25 @@
*/
@Test
public void testOnEvaluateInputViewShown_disableShowImeWithHardKeyboard() {
- setShowImeWithHardKeyboard(false /* enabled */);
+ setShowImeWithHardKeyboard(false /* enable */);
final var config = mInputMethodService.getResources().getConfiguration();
final var initialConfig = new Configuration(config);
try {
config.keyboard = Configuration.KEYBOARD_QWERTY;
config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO;
- eventually(() ->
- assertWithMessage("InputView should not show with visible hardware keyboard")
- .that(mInputMethodService.onEvaluateInputViewShown()).isFalse());
+ assertWithMessage("InputView should not show with visible hardware keyboard")
+ .that(mInputMethodService.onEvaluateInputViewShown()).isFalse();
config.keyboard = Configuration.KEYBOARD_NOKEYS;
config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO;
- eventually(() ->
- assertWithMessage("InputView should show without hardware keyboard")
- .that(mInputMethodService.onEvaluateInputViewShown()).isTrue());
+ assertWithMessage("InputView should show without hardware keyboard")
+ .that(mInputMethodService.onEvaluateInputViewShown()).isTrue();
config.keyboard = Configuration.KEYBOARD_QWERTY;
config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_YES;
- eventually(() ->
- assertWithMessage("InputView should show with hidden hardware keyboard")
- .that(mInputMethodService.onEvaluateInputViewShown()).isTrue());
+ assertWithMessage("InputView should show with hidden hardware keyboard")
+ .that(mInputMethodService.onEvaluateInputViewShown()).isTrue();
} finally {
mInputMethodService.getResources()
.updateConfiguration(initialConfig, null /* metrics */, null /* compat */);
@@ -357,7 +328,7 @@
*/
@Test
public void testShowSoftInput_disableShowImeWithHardKeyboard() {
- setShowImeWithHardKeyboard(false /* enabled */);
+ setShowImeWithHardKeyboard(false /* enable */);
final var config = mInputMethodService.getResources().getConfiguration();
final var initialConfig = new Configuration(config);
@@ -386,49 +357,17 @@
}
/**
- * This checks that an explicit show request results in the IME being shown.
- */
- @Test
- public void testShowSoftInputExplicitly() {
- setShowImeWithHardKeyboard(true /* enabled */);
-
- // When InputMethodService#onEvaluateInputViewShown() returns true and flag is EXPLICIT, the
- // IME should be shown.
- verifyInputViewStatusOnMainSync(
- () -> assertThat(mActivity.showImeWithInputMethodManager(0 /* flags */)).isTrue(),
- EVENT_SHOW, true /* eventExpected */, true /* shown */, "IME is shown");
- }
-
- /**
- * This checks that an implicit show request results in the IME being shown.
- */
- @Test
- public void testShowSoftInputImplicitly() {
- setShowImeWithHardKeyboard(true /* enabled */);
-
- // When InputMethodService#onEvaluateInputViewShown() returns true and flag is IMPLICIT,
- // the IME should be shown.
- verifyInputViewStatusOnMainSync(() -> assertThat(
- mActivity.showImeWithInputMethodManager(InputMethodManager.SHOW_IMPLICIT)).isTrue(),
- EVENT_SHOW, true /* eventExpected */, true /* shown */, "IME is shown");
- }
-
- /**
* This checks that an explicit show request when the IME is not previously shown,
* and it should be shown in fullscreen mode, results in the IME being shown.
*/
@Test
public void testShowSoftInputExplicitly_fullScreenMode() {
- setShowImeWithHardKeyboard(true /* enabled */);
+ setShowImeWithHardKeyboard(true /* enable */);
// Set orientation landscape to enable fullscreen mode.
setOrientation(2);
- eventually(() -> assertWithMessage("No longer in natural orientation")
- .that(mUiDevice.isNaturalOrientation()).isFalse());
- // Wait for the TestActivity to be recreated.
eventually(() -> assertWithMessage("Activity was re-created after rotation")
.that(TestActivity.getInstance()).isNotEqualTo(mActivity));
- // Get the new TestActivity.
mActivity = TestActivity.getInstance();
assertWithMessage("Re-created activity is not null").that(mActivity).isNotNull();
// Wait for the new EditText to be served by InputMethodManager.
@@ -442,34 +381,40 @@
/**
* This checks that an implicit show request when the IME is not previously shown,
- * and it should be shown in fullscreen mode, results in the IME not being shown.
+ * and it should be shown in fullscreen mode behaves like an explicit show request, resulting
+ * in the IME being shown. This is due to the refactor in b/298172246, causing us to lose flag
+ * information like {@link InputMethodManager#SHOW_IMPLICIT}.
*
- * <p>With the refactor in b/298172246, all calls from InputMethodManager#{show,hide}SoftInput
- * will be redirected to InsetsController#{show,hide}. Therefore, we will lose flags like
- * SHOW_IMPLICIT.
+ * <p>Previously, an implicit show request when the IME is not previously shown,
+ * and it should be shown in fullscreen mode, would result in the IME not being shown.
*/
@Test
- @RequiresFlagsDisabled(Flags.FLAG_REFACTOR_INSETS_CONTROLLER)
public void testShowSoftInputImplicitly_fullScreenMode() {
- setShowImeWithHardKeyboard(true /* enabled */);
+ setShowImeWithHardKeyboard(true /* enable */);
// Set orientation landscape to enable fullscreen mode.
setOrientation(2);
- eventually(() -> assertWithMessage("No longer in natural orientation")
- .that(mUiDevice.isNaturalOrientation()).isFalse());
- // Wait for the TestActivity to be recreated.
eventually(() -> assertWithMessage("Activity was re-created after rotation")
.that(TestActivity.getInstance()).isNotEqualTo(mActivity));
- // Get the new TestActivity.
mActivity = TestActivity.getInstance();
assertWithMessage("Re-created activity is not null").that(mActivity).isNotNull();
// Wait for the new EditText to be served by InputMethodManager.
eventually(() -> assertWithMessage("Has an input connection to the re-created Activity")
.that(mImm.hasActiveInputConnection(mActivity.getEditText())).isTrue());
- verifyInputViewStatusOnMainSync(() -> assertThat(
- mActivity.showImeWithInputMethodManager(InputMethodManager.SHOW_IMPLICIT)).isTrue(),
- EVENT_SHOW, false /* eventExpected */, false /* shown */, "IME is not shown");
+ if (mFlagsValueProvider.getBoolean(Flags.FLAG_REFACTOR_INSETS_CONTROLLER)) {
+ verifyInputViewStatusOnMainSync(() -> assertThat(
+ mActivity.showImeWithInputMethodManager(
+ InputMethodManager.SHOW_IMPLICIT))
+ .isTrue(),
+ EVENT_SHOW, true /* eventExpected */, true /* shown */, "IME is shown");
+ } else {
+ verifyInputViewStatusOnMainSync(() -> assertThat(
+ mActivity.showImeWithInputMethodManager(
+ InputMethodManager.SHOW_IMPLICIT))
+ .isTrue(),
+ EVENT_SHOW, false /* eventExpected */, false /* shown */, "IME is not shown");
+ }
}
/**
@@ -478,7 +423,7 @@
*/
@Test
public void testShowSoftInputExplicitly_withHardKeyboard() {
- setShowImeWithHardKeyboard(false /* enabled */);
+ setShowImeWithHardKeyboard(false /* enable */);
final var config = mInputMethodService.getResources().getConfiguration();
final var initialConfig = new Configuration(config);
@@ -497,17 +442,17 @@
}
/**
- * This checks that an implicit show request when a hardware keyboard is connected,
- * results in the IME not being shown.
+ * This checks that an implicit show request when a hardware keyboard is connected behaves
+ * like an explicit show request, resulting in the IME being shown. This is due to the
+ * refactor in b/298172246, causing us to lose flag information like
+ * {@link InputMethodManager#SHOW_IMPLICIT}.
*
- * <p>With the refactor in b/298172246, all calls from InputMethodManager#{show,hide}SoftInput
- * will be redirected to InsetsController#{show,hide}. Therefore, we will lose flags like
- * SHOW_IMPLICIT.
+ * <p>Previously, an implicit show request when a hardware keyboard is connected would
+ * result in the IME not being shown.
*/
@Test
- @RequiresFlagsDisabled(Flags.FLAG_REFACTOR_INSETS_CONTROLLER)
public void testShowSoftInputImplicitly_withHardKeyboard() {
- setShowImeWithHardKeyboard(false /* enabled */);
+ setShowImeWithHardKeyboard(false /* enable */);
final var config = mInputMethodService.getResources().getConfiguration();
final var initialConfig = new Configuration(config);
@@ -516,10 +461,20 @@
config.keyboard = Configuration.KEYBOARD_QWERTY;
config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_YES;
- verifyInputViewStatusOnMainSync(() ->assertThat(
- mActivity.showImeWithInputMethodManager(InputMethodManager.SHOW_IMPLICIT))
- .isTrue(),
- EVENT_SHOW, false /* eventExpected */, false /* shown */, "IME is not shown");
+ if (mFlagsValueProvider.getBoolean(Flags.FLAG_REFACTOR_INSETS_CONTROLLER)) {
+ verifyInputViewStatusOnMainSync(() -> assertThat(
+ mActivity.showImeWithInputMethodManager(
+ InputMethodManager.SHOW_IMPLICIT))
+ .isTrue(),
+ EVENT_SHOW, true /* eventExpected */, true /* shown */, "IME is shown");
+ } else {
+ verifyInputViewStatusOnMainSync(() -> assertThat(
+ mActivity.showImeWithInputMethodManager(
+ InputMethodManager.SHOW_IMPLICIT))
+ .isTrue(),
+ EVENT_SHOW, false /* eventExpected */, false /* shown */,
+ "IME is not shown");
+ }
} finally {
mInputMethodService.getResources()
.updateConfiguration(initialConfig, null /* metrics */, null /* compat */);
@@ -532,7 +487,7 @@
*/
@Test
public void testShowSoftInputExplicitly_thenConfigurationChanged() {
- setShowImeWithHardKeyboard(false /* enabled */);
+ setShowImeWithHardKeyboard(false /* enable */);
final var config = mInputMethodService.getResources().getConfiguration();
final var initialConfig = new Configuration(config);
@@ -565,17 +520,17 @@
/**
* This checks that an implicit show request followed by connecting a hardware keyboard
- * and a configuration change, does not trigger IMS#onFinishInputView,
- * but results in the IME being hidden.
+ * and a configuration change behaves like an explicit show request, resulting in the IME
+ * still being shown. This is due to the refactor in b/298172246, causing us to lose flag
+ * information like {@link InputMethodManager#SHOW_IMPLICIT}.
*
- * <p>With the refactor in b/298172246, all calls from InputMethodManager#{show,hide}SoftInput
- * will be redirected to InsetsController#{show,hide}. Therefore, we will lose flags like
- * SHOW_IMPLICIT.
+ * <p>Previously, an implicit show request followed by connecting a hardware keyboard
+ * and a configuration change, would not trigger IMS#onFinishInputView, but resulted in the
+ * IME being hidden.
*/
@Test
- @RequiresFlagsDisabled(Flags.FLAG_REFACTOR_INSETS_CONTROLLER)
public void testShowSoftInputImplicitly_thenConfigurationChanged() {
- setShowImeWithHardKeyboard(false /* enabled */);
+ setShowImeWithHardKeyboard(false /* enable */);
final var config = mInputMethodService.getResources().getConfiguration();
final var initialConfig = new Configuration(config);
@@ -596,16 +551,23 @@
// Simulate a fake configuration change to avoid the recreation of TestActivity.
config.orientation = Configuration.ORIENTATION_LANDSCAPE;
- // Normally, IMS#onFinishInputView will be called when finishing the input view by
- // the user. But if IMS#hideWindow is called when receiving a new configuration change,
- // we don't expect that it's user-driven to finish the lifecycle of input view with
- // IMS#onFinishInputView, because the input view will be re-initialized according
- // to the last #mShowInputRequested state. So in this case we treat the input view as
- // still alive.
- verifyInputViewStatusOnMainSync(
- () -> mInputMethodService.onConfigurationChanged(config),
- EVENT_CONFIG, true /* eventExpected */, true /* inputViewStarted */,
- false /* shown */, "IME is not shown after a configuration change");
+ if (mFlagsValueProvider.getBoolean(Flags.FLAG_REFACTOR_INSETS_CONTROLLER)) {
+ verifyInputViewStatusOnMainSync(
+ () -> mInputMethodService.onConfigurationChanged(config),
+ EVENT_CONFIG, true /* eventExpected */, true /* shown */,
+ "IME is still shown after a configuration change");
+ } else {
+ // Normally, IMS#onFinishInputView will be called when finishing the input view by
+ // the user. But if IMS#hideWindow is called when receiving a new configuration
+ // change, we don't expect that it's user-driven to finish the lifecycle of input
+ // view with IMS#onFinishInputView, because the input view will be re-initialized
+ // according to the last #mShowInputRequested state. So in this case we treat the
+ // input view as still alive.
+ verifyInputViewStatusOnMainSync(
+ () -> mInputMethodService.onConfigurationChanged(config),
+ EVENT_CONFIG, true /* eventExpected */, true /* inputViewStarted */,
+ false /* shown */, "IME is not shown after a configuration change");
+ }
} finally {
mInputMethodService.getResources()
.updateConfiguration(initialConfig, null /* metrics */, null /* compat */);
@@ -619,7 +581,7 @@
*/
@Test
public void testShowSoftInputExplicitly_thenShowSoftInputImplicitly_withHardKeyboard() {
- setShowImeWithHardKeyboard(false /* enabled */);
+ setShowImeWithHardKeyboard(false /* enable */);
final var config = mInputMethodService.getResources().getConfiguration();
final var initialConfig = new Configuration(config);
@@ -628,12 +590,10 @@
config.keyboard = Configuration.KEYBOARD_QWERTY;
config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_YES;
- // Explicit show request.
verifyInputViewStatusOnMainSync(() -> assertThat(
mActivity.showImeWithInputMethodManager(0 /* flags */)).isTrue(),
EVENT_SHOW, true /* eventExpected */, true /* shown */, "IME is shown");
- // Implicit show request.
verifyInputViewStatusOnMainSync(() -> assertThat(
mActivity.showImeWithInputMethodManager(
InputMethodManager.SHOW_IMPLICIT)).isTrue(),
@@ -654,17 +614,18 @@
/**
* This checks that a forced show request directly followed by an explicit show request,
- * and then a hide not always request, still results in the IME being shown
- * (i.e. the explicit show request retains the forced state).
+ * and then a not always hide request behaves like a normal hide request, resulting in the
+ * IME being hidden (i.e. the explicit show request does not retain the forced state). This is
+ * due to the refactor in b/298172246, causing us to lose flag information like
+ * {@link InputMethodManager#SHOW_FORCED}.
*
- * <p>With the refactor in b/298172246, all calls from InputMethodManager#{show,hide}SoftInput
- * will be redirected to InsetsController#{show,hide}. Therefore, we will lose flags like
- * HIDE_NOT_ALWAYS.
+ * <p>Previously, a forced show request directly followed by an explicit show request,
+ * and then a not always hide request, would result in the IME still being shown
+ * (i.e. the explicit show request would retain the forced state).
*/
@Test
- @RequiresFlagsDisabled(Flags.FLAG_REFACTOR_INSETS_CONTROLLER)
public void testShowSoftInputForced_testShowSoftInputExplicitly_thenHideSoftInputNotAlways() {
- setShowImeWithHardKeyboard(true /* enabled */);
+ setShowImeWithHardKeyboard(true /* enable */);
verifyInputViewStatusOnMainSync(() -> assertThat(
mActivity.showImeWithInputMethodManager(InputMethodManager.SHOW_FORCED)).isTrue(),
@@ -674,11 +635,123 @@
mActivity.showImeWithInputMethodManager(0 /* flags */)).isTrue(),
EVENT_SHOW, false /* eventExpected */, true /* shown */, "IME is still shown");
- verifyInputViewStatusOnMainSync(() -> assertThat(
- mActivity.hideImeWithInputMethodManager(InputMethodManager.HIDE_NOT_ALWAYS))
- .isTrue(),
- EVENT_HIDE, false /* eventExpected */, true /* shown */,
- "IME is still shown after HIDE_NOT_ALWAYS");
+ if (mFlagsValueProvider.getBoolean(Flags.FLAG_REFACTOR_INSETS_CONTROLLER)) {
+ verifyInputViewStatusOnMainSync(() -> assertThat(mActivity
+ .hideImeWithInputMethodManager(InputMethodManager.HIDE_NOT_ALWAYS))
+ .isTrue(),
+ EVENT_HIDE, true /* eventExpected */, false /* shown */,
+ "IME is not shown after HIDE_NOT_ALWAYS");
+ } else {
+ verifyInputViewStatusOnMainSync(() -> assertThat(mActivity
+ .hideImeWithInputMethodManager(InputMethodManager.HIDE_NOT_ALWAYS))
+ .isTrue(),
+ EVENT_HIDE, false /* eventExpected */, true /* shown */,
+ "IME is still shown after HIDE_NOT_ALWAYS");
+ }
+ }
+
+ /**
+ * This checks that an explicit show request followed by an implicit only hide request
+ * behaves like a normal hide request, resulting in the IME being hidden. This is due to
+ * the refactor in b/298172246, causing us to lose flag information like
+ * {@link InputMethodManager#SHOW_IMPLICIT} and {@link InputMethodManager#HIDE_IMPLICIT_ONLY}.
+ *
+ * <p>Previously, an explicit show request followed by an implicit only hide request
+ * would result in the IME still being shown.
+ */
+ @Test
+ public void testShowSoftInputExplicitly_thenHideSoftInputImplicitOnly() {
+ setShowImeWithHardKeyboard(true /* enable */);
+
+ verifyInputViewStatusOnMainSync(
+ () -> mActivity.showImeWithInputMethodManager(0 /* flags */),
+ EVENT_SHOW, true /* eventExpected */, true /* shown */, "IME is shown");
+
+ if (mFlagsValueProvider.getBoolean(Flags.FLAG_REFACTOR_INSETS_CONTROLLER)) {
+ verifyInputViewStatusOnMainSync(
+ () -> mActivity.hideImeWithInputMethodManager(
+ InputMethodManager.HIDE_IMPLICIT_ONLY),
+ EVENT_HIDE, true /* eventExpected */, false /* shown */,
+ "IME is not shown after HIDE_IMPLICIT_ONLY");
+ } else {
+ verifyInputViewStatusOnMainSync(
+ () -> mActivity.hideImeWithInputMethodManager(
+ InputMethodManager.HIDE_IMPLICIT_ONLY),
+ EVENT_HIDE, false /* eventExpected */, true /* shown */,
+ "IME is still shown after HIDE_IMPLICIT_ONLY");
+ }
+ }
+
+ /**
+ * This checks that an implicit show request followed by an implicit only hide request
+ * results in the IME being hidden.
+ */
+ @Test
+ public void testShowSoftInputImplicitly_thenHideSoftInputImplicitOnly() {
+ setShowImeWithHardKeyboard(true /* enable */);
+
+ verifyInputViewStatusOnMainSync(
+ () -> mActivity.showImeWithInputMethodManager(InputMethodManager.SHOW_IMPLICIT),
+ EVENT_SHOW, true /* eventExpected */, true /* shown */,
+ "IME is shown with SHOW_IMPLICIT");
+
+ verifyInputViewStatusOnMainSync(
+ () -> mActivity.hideImeWithInputMethodManager(
+ InputMethodManager.HIDE_IMPLICIT_ONLY),
+ EVENT_HIDE, true /* eventExpected */, false /* shown */,
+ "IME is not shown after HIDE_IMPLICIT_ONLY");
+ }
+
+ /**
+ * This checks that an explicit show self request followed by an implicit only hide self request
+ * behaves like a normal hide self request, resulting in the IME being hidden. This is due to
+ * the refactor in b/298172246, causing us to lose flag information like
+ * {@link InputMethodManager#SHOW_IMPLICIT} and {@link InputMethodManager#HIDE_IMPLICIT_ONLY}.
+ *
+ * <p>Previously, an explicit show self request followed by an implicit only hide self request
+ * would result in the IME still being shown.
+ */
+ @Test
+ public void testShowSelfExplicitly_thenHideSelfImplicitOnly() {
+ setShowImeWithHardKeyboard(true /* enable */);
+
+ verifyInputViewStatusOnMainSync(
+ () -> mInputMethodService.requestShowSelf(0 /* flags */),
+ EVENT_SHOW, true /* eventExpected */, true /* shown */, "IME is shown");
+
+ if (mFlagsValueProvider.getBoolean(Flags.FLAG_REFACTOR_INSETS_CONTROLLER)) {
+ verifyInputViewStatusOnMainSync(
+ () -> mInputMethodService.requestHideSelf(
+ InputMethodManager.HIDE_IMPLICIT_ONLY),
+ EVENT_HIDE, true /* eventExpected */, false /* shown */,
+ "IME is not shown after HIDE_IMPLICIT_ONLY");
+ } else {
+ verifyInputViewStatusOnMainSync(
+ () -> mInputMethodService.requestHideSelf(
+ InputMethodManager.HIDE_IMPLICIT_ONLY),
+ EVENT_HIDE, false /* eventExpected */, true /* shown */,
+ "IME is still shown after HIDE_IMPLICIT_ONLY");
+ }
+ }
+
+ /**
+ * This checks that an implicit show self request followed by an implicit only hide self request
+ * results in the IME being hidden.
+ */
+ @Test
+ public void testShowSelfImplicitly_thenHideSelfImplicitOnly() {
+ setShowImeWithHardKeyboard(true /* enable */);
+
+ verifyInputViewStatusOnMainSync(
+ () -> mInputMethodService.requestShowSelf(InputMethodManager.SHOW_IMPLICIT),
+ EVENT_SHOW, true /* eventExpected */, true /* shown */,
+ "IME is shown with SHOW_IMPLICIT");
+
+ verifyInputViewStatusOnMainSync(
+ () -> mInputMethodService.requestHideSelf(
+ InputMethodManager.HIDE_IMPLICIT_ONLY),
+ EVENT_HIDE, true /* eventExpected */, false /* shown */,
+ "IME is not shown after HIDE_IMPLICIT_ONLY");
}
/**
@@ -686,7 +759,7 @@
*/
@Test
public void testFullScreenMode() {
- setShowImeWithHardKeyboard(true /* enabled */);
+ setShowImeWithHardKeyboard(true /* enable */);
Log.i(TAG, "Set orientation natural");
verifyFullscreenMode(() -> setOrientation(0), false /* eventExpected */,
@@ -723,25 +796,22 @@
public void testShowHideImeNavigationBar_doesDrawImeNavBar() {
assumeTrue("Must have a navigation bar", hasNavigationBar());
- setShowImeWithHardKeyboard(true /* enabled */);
+ setShowImeWithHardKeyboard(true /* enable */);
- // Show IME
verifyInputViewStatusOnMainSync(
() -> {
- setDrawsImeNavBarAndSwitcherButton(true /* enabled */);
+ setDrawsImeNavBarAndSwitcherButton(true /* enable */);
mActivity.showImeWithWindowInsetsController();
},
EVENT_SHOW, true /* eventExpected */, true /* shown */, "IME is shown");
assertWithMessage("IME navigation bar is initially shown")
.that(mInputMethodService.isImeNavigationBarShownForTesting()).isTrue();
- // Try to hide IME nav bar
mInstrumentation.runOnMainSync(() -> setShowImeNavigationBar(false /* show */));
mInstrumentation.waitForIdleSync();
assertWithMessage("IME navigation bar is not shown after hide request")
.that(mInputMethodService.isImeNavigationBarShownForTesting()).isFalse();
- // Try to show IME nav bar
mInstrumentation.runOnMainSync(() -> setShowImeNavigationBar(true /* show */));
mInstrumentation.waitForIdleSync();
assertWithMessage("IME navigation bar is shown after show request")
@@ -758,25 +828,22 @@
public void testShowHideImeNavigationBar_doesNotDrawImeNavBar() {
assumeTrue("Must have a navigation bar", hasNavigationBar());
- setShowImeWithHardKeyboard(true /* enabled */);
+ setShowImeWithHardKeyboard(true /* enable */);
- // Show IME
verifyInputViewStatusOnMainSync(
() -> {
- setDrawsImeNavBarAndSwitcherButton(false /* enabled */);
+ setDrawsImeNavBarAndSwitcherButton(false /* enable */);
mActivity.showImeWithWindowInsetsController();
},
EVENT_SHOW, true /* eventExpected */, true /* shown */, "IME is shown");
assertWithMessage("IME navigation bar is initially not shown")
.that(mInputMethodService.isImeNavigationBarShownForTesting()).isFalse();
- // Try to hide IME nav bar
mInstrumentation.runOnMainSync(() -> setShowImeNavigationBar(false /* show */));
mInstrumentation.waitForIdleSync();
assertWithMessage("IME navigation bar is not shown after hide request")
.that(mInputMethodService.isImeNavigationBarShownForTesting()).isFalse();
- // Try to show IME nav bar
mInstrumentation.runOnMainSync(() -> setShowImeNavigationBar(true /* show */));
mInstrumentation.waitForIdleSync();
assertWithMessage("IME navigation bar is not shown after show request")
@@ -792,7 +859,7 @@
waitUntilActivityReadyForInputInjection(mActivity);
- setShowImeWithHardKeyboard(true /* enabled */);
+ setShowImeWithHardKeyboard(true /* enable */);
try (var ignored = mGestureNavSwitchHelper.withGestureNavigationMode()) {
verifyInputViewStatusOnMainSync(
@@ -818,7 +885,7 @@
waitUntilActivityReadyForInputInjection(mActivity);
- setShowImeWithHardKeyboard(true /* enabled */);
+ setShowImeWithHardKeyboard(true /* enable */);
try (var ignored = mGestureNavSwitchHelper.withGestureNavigationMode()) {
verifyInputViewStatusOnMainSync(
@@ -844,7 +911,7 @@
waitUntilActivityReadyForInputInjection(mActivity);
- setShowImeWithHardKeyboard(true /* enabled */);
+ setShowImeWithHardKeyboard(true /* enable */);
final var info = mImm.getCurrentInputMethodInfo();
assertWithMessage("InputMethodInfo is not null").that(info).isNotNull();
@@ -855,7 +922,7 @@
try (var ignored = mGestureNavSwitchHelper.withGestureNavigationMode()) {
verifyInputViewStatusOnMainSync(
() -> {
- setDrawsImeNavBarAndSwitcherButton(true /* enabled */);
+ setDrawsImeNavBarAndSwitcherButton(true /* enable */);
mActivity.showImeWithWindowInsetsController();
},
EVENT_SHOW, true /* eventExpected */, true /* shown */, "IME is shown");
@@ -884,7 +951,7 @@
waitUntilActivityReadyForInputInjection(mActivity);
- setShowImeWithHardKeyboard(true /* enabled */);
+ setShowImeWithHardKeyboard(true /* enable */);
final var info = mImm.getCurrentInputMethodInfo();
assertWithMessage("InputMethodInfo is not null").that(info).isNotNull();
@@ -893,7 +960,7 @@
try (var ignored = mGestureNavSwitchHelper.withGestureNavigationMode()) {
verifyInputViewStatusOnMainSync(
() -> {
- setDrawsImeNavBarAndSwitcherButton(true /* enabled */);
+ setDrawsImeNavBarAndSwitcherButton(true /* enable */);
mActivity.showImeWithWindowInsetsController();
},
EVENT_SHOW, true /* eventExpected */, true /* shown */, "IME is shown");
@@ -956,7 +1023,8 @@
runnable.run();
}
mInstrumentation.waitForIdleSync();
- eventCalled = latch.await(TIMEOUT_IN_SECONDS, TimeUnit.SECONDS);
+ eventCalled = latch.await(eventExpected ? EXPECT_TIMEOUT_MS : NOT_EXCEPT_TIMEOUT_MS,
+ TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
fail("Interrupted while waiting for latch: " + e.getMessage());
return;
@@ -1016,10 +1084,8 @@
verifyInputViewStatus(runnable, EVENT_CONFIG, eventExpected, false /* shown */,
"IME is not shown");
if (eventExpected) {
- // Wait for the TestActivity to be recreated.
eventually(() -> assertWithMessage("Activity was re-created after rotation")
.that(TestActivity.getInstance()).isNotEqualTo(mActivity));
- // Get the new TestActivity.
mActivity = TestActivity.getInstance();
assertWithMessage("Re-created activity is not null").that(mActivity).isNotNull();
// Wait for the new EditText to be served by InputMethodManager.
@@ -1062,6 +1128,7 @@
private void prepareActivity() {
mActivity = TestActivity.startSync(mInstrumentation);
+ mInstrumentation.waitForIdleSync();
Log.i(TAG, "Finish preparing activity with editor.");
}
@@ -1086,21 +1153,51 @@
* @param enable the value to be set.
*/
private void setShowImeWithHardKeyboard(boolean enable) {
+ if (mInputMethodService == null) {
+ // If the IME is no longer around, reset the setting unconditionally.
+ executeShellCommand(SET_SHOW_IME_WITH_HARD_KEYBOARD_CMD + " " + (enable ? "1" : "0"));
+ return;
+ }
+
final boolean currentEnabled =
mInputMethodService.getShouldShowImeWithHardKeyboardForTesting();
if (currentEnabled != enable) {
- executeShellCommand(enable
- ? ENABLE_SHOW_IME_WITH_HARD_KEYBOARD_CMD
- : DISABLE_SHOW_IME_WITH_HARD_KEYBOARD_CMD);
+ executeShellCommand(SET_SHOW_IME_WITH_HARD_KEYBOARD_CMD + " " + (enable ? "1" : "0"));
eventually(() -> assertWithMessage("showImeWithHardKeyboard updated")
.that(mInputMethodService.getShouldShowImeWithHardKeyboardForTesting())
.isEqualTo(enable));
}
}
- private static void executeShellCommand(@NonNull String cmd) {
+ /**
+ * Gets the verbose logging state in {@link android.view.inputmethod.ImeTracker}.
+ *
+ * @return {@code true} iff verbose logging is enabled.
+ */
+ private static boolean getVerboseImeTrackerLogging() {
+ return executeShellCommand(GET_VERBOSE_IME_TRACKER_LOGGING_CMD).trim().equals("1");
+ }
+
+ /**
+ * Sets verbose logging in {@link android.view.inputmethod.ImeTracker}.
+ *
+ * @param enabled whether to enable or disable verbose logging.
+ *
+ * @implNote This must use {@link ActivityManager#notifySystemPropertiesChanged()} to listen
+ * for changes to the system property for the verbose ImeTracker logging.
+ */
+ private void setVerboseImeTrackerLogging(boolean enabled) {
+ final var context = mInstrumentation.getContext();
+ final var am = context.getSystemService(ActivityManager.class);
+
+ executeShellCommand(SET_VERBOSE_IME_TRACKER_LOGGING_CMD + " " + (enabled ? "1" : "0"));
+ am.notifySystemPropertiesChanged();
+ }
+
+ @NonNull
+ private static String executeShellCommand(@NonNull String cmd) {
Log.i(TAG, "Run command: " + cmd);
- SystemUtil.runShellCommandOrThrow(cmd);
+ return SystemUtil.runShellCommandOrThrow(cmd);
}
/**
@@ -1113,8 +1210,7 @@
@NonNull
private UiObject2 getUiObject(@NonNull BySelector bySelector) {
- final var uiObject = mUiDevice.wait(Until.findObject(bySelector),
- TimeUnit.SECONDS.toMillis(TIMEOUT_IN_SECONDS));
+ final var uiObject = mUiDevice.wait(Until.findObject(bySelector), TIMEOUT_MS);
assertWithMessage("UiObject with " + bySelector + " was found").that(uiObject).isNotNull();
return uiObject;
}
@@ -1137,10 +1233,10 @@
*
* <p>Note, neither of these are normally drawn when in three button navigation mode.
*
- * @param enabled whether the IME nav bar and IME Switcher button are drawn.
+ * @param enable whether the IME nav bar and IME Switcher button are drawn.
*/
- private void setDrawsImeNavBarAndSwitcherButton(boolean enabled) {
- final int flags = enabled ? IME_DRAWS_IME_NAV_BAR | SHOW_IME_SWITCHER_WHEN_IME_IS_SHOWN : 0;
+ private void setDrawsImeNavBarAndSwitcherButton(boolean enable) {
+ final int flags = enable ? IME_DRAWS_IME_NAV_BAR | SHOW_IME_SWITCHER_WHEN_IME_IS_SHOWN : 0;
mInputMethodService.getInputMethodInternal().onNavButtonFlagsChanged(flags);
}
diff --git a/services/tests/InputMethodSystemServerTests/test-apps/SimpleTestIme/src/com/android/apps/inputmethod/simpleime/ims/InputMethodServiceWrapper.java b/services/tests/InputMethodSystemServerTests/test-apps/SimpleTestIme/src/com/android/apps/inputmethod/simpleime/ims/InputMethodServiceWrapper.java
index 558d1a7..d4d4dca 100644
--- a/services/tests/InputMethodSystemServerTests/test-apps/SimpleTestIme/src/com/android/apps/inputmethod/simpleime/ims/InputMethodServiceWrapper.java
+++ b/services/tests/InputMethodSystemServerTests/test-apps/SimpleTestIme/src/com/android/apps/inputmethod/simpleime/ims/InputMethodServiceWrapper.java
@@ -111,12 +111,6 @@
}
@Override
- public void requestHideSelf(int flags) {
- Log.i(TAG, "requestHideSelf() " + flags);
- super.requestHideSelf(flags);
- }
-
- @Override
public void onConfigurationChanged(Configuration newConfig) {
Log.i(TAG, "onConfigurationChanged() " + newConfig);
super.onConfigurationChanged(newConfig);
diff --git a/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java b/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java
index db04d39e..eda5e86 100644
--- a/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java
@@ -23,7 +23,6 @@
import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyString;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
import static com.android.server.PackageWatchdog.MITIGATION_RESULT_SKIPPED;
import static com.android.server.PackageWatchdog.MITIGATION_RESULT_SUCCESS;
@@ -34,8 +33,6 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.ArgumentMatchers.isNull;
-import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import android.content.ContentResolver;
@@ -43,13 +40,8 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.VersionedPackage;
-import android.crashrecovery.flags.Flags;
import android.os.RecoverySystem;
import android.os.SystemProperties;
-import android.os.UserHandle;
-import android.platform.test.annotations.EnableFlags;
-import android.platform.test.flag.junit.FlagsParameterization;
-import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.DeviceConfig;
import android.provider.Settings;
@@ -60,14 +52,8 @@
import org.junit.After;
import org.junit.Before;
-import org.junit.Rule;
import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
import org.mockito.Answers;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoSession;
import org.mockito.quality.Strictness;
@@ -76,34 +62,19 @@
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* Test RescueParty.
*/
-@RunWith(Parameterized.class)
public class RescuePartyTest {
- @Rule
- public SetFlagsRule mSetFlagsRule;
private static final long CURRENT_NETWORK_TIME_MILLIS = 0L;
- private static final String FAKE_NATIVE_NAMESPACE1 = "native1";
- private static final String FAKE_NATIVE_NAMESPACE2 = "native2";
- private static final String[] FAKE_RESET_NATIVE_NAMESPACES =
- {FAKE_NATIVE_NAMESPACE1, FAKE_NATIVE_NAMESPACE2};
private static VersionedPackage sFailingPackage = new VersionedPackage("com.package.name", 1);
private static final String PROP_DISABLE_RESCUE = "persist.sys.disable_rescue";
- private static final String CALLING_PACKAGE1 = "com.package.name1";
- private static final String CALLING_PACKAGE2 = "com.package.name2";
- private static final String CALLING_PACKAGE3 = "com.package.name3";
private static final String PERSISTENT_PACKAGE = "com.persistent.package";
private static final String NON_PERSISTENT_PACKAGE = "com.nonpersistent.package";
- private static final String NAMESPACE1 = "namespace1";
- private static final String NAMESPACE2 = "namespace2";
- private static final String NAMESPACE3 = "namespace3";
- private static final String NAMESPACE4 = "namespace4";
private static final String PROP_DEVICE_CONFIG_DISABLE_FLAG =
"persist.device_config.configuration.disable_rescue_party";
private static final String PROP_DISABLE_FACTORY_RESET_FLAG =
@@ -127,22 +98,6 @@
// Mock only sysprop apis
private PackageWatchdog.BootThreshold mSpyBootThreshold;
- @Captor
- private ArgumentCaptor<DeviceConfig.MonitorCallback> mMonitorCallbackCaptor;
- @Captor
- private ArgumentCaptor<List<String>> mPackageListCaptor;
-
- @Parameters(name = "{0}")
- public static List<FlagsParameterization> getFlags() {
- return FlagsParameterization.allCombinationsOf(
- Flags.FLAG_RECOVERABILITY_DETECTION,
- Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS);
- }
-
- public RescuePartyTest(FlagsParameterization flags) {
- mSetFlagsRule = new SetFlagsRule(flags);
- }
-
@Before
public void setUp() throws Exception {
mSession =
@@ -248,7 +203,6 @@
}
@Test
- @EnableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
public void testBootLoopNoFlags() {
// this is old test where the flag needs to be disabled
noteBoot(1);
@@ -260,7 +214,6 @@
}
@Test
- @EnableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
public void testPersistentAppCrashNoFlags() {
// this is old test where the flag needs to be disabled
noteAppCrash(1, true);
@@ -396,7 +349,6 @@
}
@Test
- @EnableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
public void testHealthCheckLevelsNoFlags() {
// this is old test where the flag needs to be disabled
RescuePartyObserver observer = RescuePartyObserver.getInstance(mMockContext);
@@ -416,7 +368,6 @@
}
@Test
- @EnableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
public void testBootLoopLevelsNoFlags() {
RescuePartyObserver observer = RescuePartyObserver.getInstance(mMockContext);
@@ -425,25 +376,6 @@
}
- private void verifySettingsResets(int resetMode, String[] resetNamespaces,
- HashMap<String, Integer> configResetVerifiedTimesMap) {
- verifyOnlySettingsReset(resetMode);
- }
-
- private void verifyOnlySettingsReset(int resetMode) {
- verify(() -> Settings.Global.resetToDefaultsAsUser(mMockContentResolver, null,
- resetMode, UserHandle.USER_SYSTEM));
- verify(() -> Settings.Secure.resetToDefaultsAsUser(eq(mMockContentResolver), isNull(),
- eq(resetMode), anyInt()));
- }
-
- private void verifyNoSettingsReset(int resetMode) {
- verify(() -> Settings.Global.resetToDefaultsAsUser(mMockContentResolver, null,
- resetMode, UserHandle.USER_SYSTEM), never());
- verify(() -> Settings.Secure.resetToDefaultsAsUser(eq(mMockContentResolver), isNull(),
- eq(resetMode), anyInt()), never());
- }
-
private void noteBoot(int mitigationCount) {
RescuePartyObserver.getInstance(mMockContext).onExecuteBootLoopMitigation(mitigationCount);
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/SensitiveContentProtectionManagerServiceContentTest.java b/services/tests/mockingservicestests/src/com/android/server/SensitiveContentProtectionManagerServiceContentTest.java
index 5ddd8a5..2e315ec 100644
--- a/services/tests/mockingservicestests/src/com/android/server/SensitiveContentProtectionManagerServiceContentTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/SensitiveContentProtectionManagerServiceContentTest.java
@@ -26,7 +26,10 @@
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import android.app.role.RoleManager;
+import android.companion.AssociationRequest;
import android.content.pm.PackageManagerInternal;
import android.media.projection.MediaProjectionInfo;
import android.media.projection.MediaProjectionManager;
@@ -54,6 +57,7 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.util.List;
import java.util.Set;
@SmallTest
@@ -74,6 +78,7 @@
@Mock private WindowManagerInternal mWindowManager;
@Mock private MediaProjectionManager mProjectionManager;
@Mock private PackageManagerInternal mPackageManagerInternal;
+ @Mock private RoleManager mRoleManager;
private MediaProjectionInfo mMediaProjectionInfo;
@Captor
@@ -93,7 +98,8 @@
mSensitiveContentProtectionManagerService =
new SensitiveContentProtectionManagerService(mContext);
mSensitiveContentProtectionManagerService.init(mProjectionManager, mWindowManager,
- mPackageManagerInternal, new ArraySet<>(Set.of(mExemptedScreenRecorderPackage)));
+ mPackageManagerInternal, mRoleManager,
+ new ArraySet<>(Set.of(mExemptedScreenRecorderPackage)));
verify(mProjectionManager).addCallback(mMediaProjectionCallbackCaptor.capture(), any());
mMediaPorjectionCallback = mMediaProjectionCallbackCaptor.getValue();
mMediaProjectionInfo =
@@ -152,7 +158,7 @@
String testAutofillService = mScreenRecorderPackage + "/com.example.SampleAutofillService";
int userId = Process.myUserHandle().getIdentifier();
Settings.Secure.putStringForUser(mContext.getContentResolver(),
- Settings.Secure.AUTOFILL_SERVICE, testAutofillService , userId);
+ Settings.Secure.AUTOFILL_SERVICE, testAutofillService, userId);
mMediaPorjectionCallback.onStart(mMediaProjectionInfo);
mSensitiveContentProtectionManagerService.setSensitiveContentProtection(
@@ -169,6 +175,19 @@
verify(mWindowManager, never()).addBlockScreenCaptureForApps(mPackageInfoCaptor.capture());
}
+ @Test
+ public void testAppStreamingRoleHolderExemption() {
+ when(mRoleManager.getRoleHoldersAsUser(
+ AssociationRequest.DEVICE_PROFILE_APP_STREAMING,
+ mMediaProjectionInfo.getUserHandle())).thenReturn(
+ List.of(mMediaProjectionInfo.getPackageName()));
+
+ mMediaPorjectionCallback.onStart(mMediaProjectionInfo);
+ mSensitiveContentProtectionManagerService.setSensitiveContentProtection(
+ mPackageInfo.getWindowToken(), mPackageInfo.getPkg(), mPackageInfo.getUid(), true);
+ verify(mWindowManager, never()).addBlockScreenCaptureForApps(mPackageInfoCaptor.capture());
+ }
+
private void mockDisabledViaDeveloperOption() {
Settings.Global.putInt(
mContext.getContentResolver(),
diff --git a/services/tests/mockingservicestests/src/com/android/server/SensitiveContentProtectionManagerServiceNotificationTest.java b/services/tests/mockingservicestests/src/com/android/server/SensitiveContentProtectionManagerServiceNotificationTest.java
index 32135f1..3c6e18f 100644
--- a/services/tests/mockingservicestests/src/com/android/server/SensitiveContentProtectionManagerServiceNotificationTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/SensitiveContentProtectionManagerServiceNotificationTest.java
@@ -33,6 +33,8 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.app.role.RoleManager;
+import android.companion.AssociationRequest;
import android.content.pm.PackageManagerInternal;
import android.media.projection.MediaProjectionInfo;
import android.media.projection.MediaProjectionManager;
@@ -67,6 +69,7 @@
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
+import java.util.List;
import java.util.Set;
@SmallTest
@@ -116,6 +119,9 @@
private PackageManagerInternal mPackageManagerInternal;
@Mock
+ private RoleManager mRoleManager;
+
+ @Mock
private StatusBarNotification mNotification1;
@Mock
@@ -161,7 +167,8 @@
setupSensitiveNotification();
mSensitiveContentProtectionManagerService.init(mProjectionManager, mWindowManager,
- mPackageManagerInternal, new ArraySet<>(Set.of(EXEMPTED_SCREEN_RECORDER_PACKAGE)));
+ mPackageManagerInternal, mRoleManager,
+ new ArraySet<>(Set.of(EXEMPTED_SCREEN_RECORDER_PACKAGE)));
// Obtain useful mMediaProjectionCallback
verify(mProjectionManager).addCallback(mMediaProjectionCallbackCaptor.capture(), any());
@@ -315,6 +322,18 @@
}
@Test
+ public void mediaProjectionOnStart_verifyExemptedAppStreamingPackage() {
+ MediaProjectionInfo mediaProjectionInfo = createMediaProjectionInfo();
+ when(mRoleManager.getRoleHoldersAsUser(AssociationRequest.DEVICE_PROFILE_APP_STREAMING,
+ mediaProjectionInfo.getUserHandle())).thenReturn(
+ List.of(mediaProjectionInfo.getPackageName()));
+
+ mMediaProjectionCallbackCaptor.getValue().onStart(mediaProjectionInfo);
+
+ verify(mWindowManager, never()).addBlockScreenCaptureForApps(mPackageInfoCaptor.capture());
+ }
+
+ @Test
public void mediaProjectionOnStart_verifyExemptedRecorderPackage() {
MediaProjectionInfo mediaProjectionInfo = createExemptMediaProjectionInfo();
diff --git a/services/tests/mockingservicestests/src/com/android/server/crashrecovery/Android.bp b/services/tests/mockingservicestests/src/com/android/server/crashrecovery/Android.bp
index 8eae9c7d..e030b3f 100644
--- a/services/tests/mockingservicestests/src/com/android/server/crashrecovery/Android.bp
+++ b/services/tests/mockingservicestests/src/com/android/server/crashrecovery/Android.bp
@@ -32,18 +32,18 @@
static_libs: [
"androidx.test.core",
"androidx.test.runner",
+ "flag-junit",
"mockito-target-extended-minus-junit4",
"services.core",
"truth",
- "flag-junit",
] + select(soong_config_variable("ANDROID", "release_crashrecovery_module"), {
"true": ["service-crashrecovery-pre-jarjar"],
default: [],
}),
libs: [
- "android.test.mock.stubs.system",
"android.test.base.stubs.system",
+ "android.test.mock.stubs.system",
"android.test.runner.stubs.system",
],
@@ -55,7 +55,9 @@
certificate: "platform",
platform_apis: true,
test_suites: [
- "device-tests",
"automotive-tests",
+ "device-tests",
+ "mts-crashrecovery",
],
+ min_sdk_version: "36",
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/rollback/Android.bp b/services/tests/mockingservicestests/src/com/android/server/rollback/Android.bp
index 5a802d9..36b064b 100644
--- a/services/tests/mockingservicestests/src/com/android/server/rollback/Android.bp
+++ b/services/tests/mockingservicestests/src/com/android/server/rollback/Android.bp
@@ -30,18 +30,18 @@
static_libs: [
"androidx.test.runner",
+ "flag-junit",
"mockito-target-extended-minus-junit4",
"services.core",
"truth",
- "flag-junit",
] + select(soong_config_variable("ANDROID", "release_crashrecovery_module"), {
"true": ["service-crashrecovery-pre-jarjar"],
default: [],
}),
libs: [
- "android.test.mock.stubs.system",
"android.test.base.stubs.system",
+ "android.test.mock.stubs.system",
"android.test.runner.stubs.system",
],
@@ -53,9 +53,11 @@
certificate: "platform",
platform_apis: true,
test_suites: [
- "device-tests",
"automotive-tests",
+ "device-tests",
+ "mts-crashrecovery",
],
+ min_sdk_version: "36",
}
test_module_config {
diff --git a/services/tests/mockingservicestests/src/com/android/server/rollback/RollbackPackageHealthObserverTest.java b/services/tests/mockingservicestests/src/com/android/server/rollback/RollbackPackageHealthObserverTest.java
index 347dc81..fb4d81a 100644
--- a/services/tests/mockingservicestests/src/com/android/server/rollback/RollbackPackageHealthObserverTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/rollback/RollbackPackageHealthObserverTest.java
@@ -43,7 +43,6 @@
import android.content.rollback.PackageRollbackInfo;
import android.content.rollback.RollbackInfo;
import android.content.rollback.RollbackManager;
-import android.crashrecovery.flags.Flags;
import android.os.Handler;
import android.os.MessageQueue;
import android.os.SystemProperties;
@@ -273,7 +272,6 @@
@Test
public void healthCheckFailed_impactLevelLow_onePackage()
throws PackageManager.NameNotFoundException {
- mSetFlagsRule.enableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
VersionedPackage appAFrom = new VersionedPackage(APP_A, VERSION_CODE_2);
VersionedPackage appATo = new VersionedPackage(APP_A, VERSION_CODE);
PackageRollbackInfo packageRollbackInfo = new PackageRollbackInfo(appAFrom, appATo,
@@ -304,7 +302,6 @@
@Test
public void healthCheckFailed_impactLevelHigh_onePackage()
throws PackageManager.NameNotFoundException {
- mSetFlagsRule.enableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
VersionedPackage appAFrom = new VersionedPackage(APP_A, VERSION_CODE_2);
VersionedPackage appATo = new VersionedPackage(APP_A, VERSION_CODE);
PackageRollbackInfo packageRollbackInfo = new PackageRollbackInfo(appAFrom, appATo,
@@ -335,7 +332,6 @@
@Test
public void healthCheckFailed_impactLevelManualOnly_onePackage()
throws PackageManager.NameNotFoundException {
- mSetFlagsRule.enableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
VersionedPackage appAFrom = new VersionedPackage(APP_A, VERSION_CODE_2);
VersionedPackage appATo = new VersionedPackage(APP_A, VERSION_CODE);
PackageRollbackInfo packageRollbackInfo = new PackageRollbackInfo(appAFrom, appATo,
@@ -365,7 +361,6 @@
@Test
public void healthCheckFailed_impactLevelLowAndHigh_onePackage()
throws PackageManager.NameNotFoundException {
- mSetFlagsRule.enableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
VersionedPackage appAFrom = new VersionedPackage(APP_A, VERSION_CODE_2);
VersionedPackage appATo = new VersionedPackage(APP_A, VERSION_CODE);
PackageRollbackInfo packageRollbackInfo = new PackageRollbackInfo(appAFrom, appATo,
@@ -404,7 +399,6 @@
@Test
public void execute_impactLevelLow_nativeCrash_rollback()
throws PackageManager.NameNotFoundException {
- mSetFlagsRule.enableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
int rollbackId = 1;
VersionedPackage appAFrom = new VersionedPackage(APP_A, VERSION_CODE_2);
VersionedPackage appATo = new VersionedPackage(APP_A, VERSION_CODE);
@@ -438,7 +432,6 @@
@Test
public void execute_impactLevelLow_rollbackFailedPackage()
throws PackageManager.NameNotFoundException {
- mSetFlagsRule.enableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
int rollbackId1 = 1;
VersionedPackage appAFrom = new VersionedPackage(APP_A, VERSION_CODE_2);
VersionedPackage appATo = new VersionedPackage(APP_A, VERSION_CODE);
@@ -483,7 +476,6 @@
@Test
public void execute_impactLevelLow_rollbackAll()
throws PackageManager.NameNotFoundException {
- mSetFlagsRule.enableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
int rollbackId1 = 1;
VersionedPackage appAFrom = new VersionedPackage(APP_A, VERSION_CODE_2);
VersionedPackage appATo = new VersionedPackage(APP_A, VERSION_CODE);
@@ -530,7 +522,6 @@
@Test
public void execute_impactLevelLowAndHigh_rollbackLow()
throws PackageManager.NameNotFoundException {
- mSetFlagsRule.enableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
int rollbackId1 = 1;
VersionedPackage appAFrom = new VersionedPackage(APP_A, VERSION_CODE_2);
VersionedPackage appATo = new VersionedPackage(APP_A, VERSION_CODE);
@@ -578,7 +569,6 @@
@Test
public void execute_impactLevelHigh_rollbackHigh()
throws PackageManager.NameNotFoundException {
- mSetFlagsRule.enableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
int rollbackId2 = 2;
VersionedPackage appBFrom = new VersionedPackage(APP_B, VERSION_CODE_2);
VersionedPackage appBTo = new VersionedPackage(APP_B, VERSION_CODE);
@@ -612,7 +602,6 @@
*/
@Test
public void onBootLoop_impactLevelLow_onePackage() throws PackageManager.NameNotFoundException {
- mSetFlagsRule.enableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
VersionedPackage appAFrom = new VersionedPackage(APP_A, VERSION_CODE_2);
VersionedPackage appATo = new VersionedPackage(APP_A, VERSION_CODE);
PackageRollbackInfo packageRollbackInfo = new PackageRollbackInfo(appAFrom, appATo,
@@ -637,7 +626,6 @@
@Test
public void onBootLoop_impactLevelHigh_onePackage()
throws PackageManager.NameNotFoundException {
- mSetFlagsRule.enableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
VersionedPackage appAFrom = new VersionedPackage(APP_A, VERSION_CODE_2);
VersionedPackage appATo = new VersionedPackage(APP_A, VERSION_CODE);
PackageRollbackInfo packageRollbackInfo = new PackageRollbackInfo(appAFrom, appATo,
@@ -662,7 +650,6 @@
@Test
public void onBootLoop_impactLevelHighDisableHighImpactRollback_onePackage()
throws PackageManager.NameNotFoundException {
- mSetFlagsRule.enableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
SystemProperties.set(PROP_DISABLE_HIGH_IMPACT_ROLLBACK_FLAG, Boolean.toString(true));
VersionedPackage appAFrom = new VersionedPackage(APP_A, VERSION_CODE_2);
VersionedPackage appATo = new VersionedPackage(APP_A, VERSION_CODE);
@@ -692,7 +679,6 @@
@Test
public void onBootLoop_impactLevelManualOnly_onePackage()
throws PackageManager.NameNotFoundException {
- mSetFlagsRule.enableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
VersionedPackage appAFrom = new VersionedPackage(APP_A, VERSION_CODE_2);
VersionedPackage appATo = new VersionedPackage(APP_A, VERSION_CODE);
PackageRollbackInfo packageRollbackInfo = new PackageRollbackInfo(appAFrom, appATo,
@@ -720,7 +706,6 @@
@Test
public void onBootLoop_impactLevelLowAndHigh_onePackage()
throws PackageManager.NameNotFoundException {
- mSetFlagsRule.enableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
VersionedPackage appAFrom = new VersionedPackage(APP_A, VERSION_CODE_2);
VersionedPackage appATo = new VersionedPackage(APP_A, VERSION_CODE);
PackageRollbackInfo packageRollbackInfo = new PackageRollbackInfo(appAFrom, appATo,
@@ -757,7 +742,6 @@
@Test
public void executeBootLoopMitigation_impactLevelLow_rollbackAll()
throws PackageManager.NameNotFoundException {
- mSetFlagsRule.enableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
int rollbackId1 = 1;
VersionedPackage appAFrom = new VersionedPackage(APP_A, VERSION_CODE_2);
VersionedPackage appATo = new VersionedPackage(APP_A, VERSION_CODE);
@@ -802,7 +786,6 @@
@Test
public void executeBootLoopMitigation_impactLevelLowAndHigh_rollbackLow()
throws PackageManager.NameNotFoundException {
- mSetFlagsRule.enableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
int rollbackId1 = 1;
VersionedPackage appAFrom = new VersionedPackage(APP_A, VERSION_CODE_2);
VersionedPackage appATo = new VersionedPackage(APP_A, VERSION_CODE);
@@ -847,7 +830,6 @@
@Test
public void executeBootLoopMitigation_impactLevelHigh_rollbackHigh()
throws PackageManager.NameNotFoundException {
- mSetFlagsRule.enableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
int rollbackId2 = 2;
VersionedPackage appBFrom = new VersionedPackage(APP_B, VERSION_CODE_2);
VersionedPackage appBTo = new VersionedPackage(APP_B, VERSION_CODE);
@@ -882,7 +864,6 @@
@Test
public void execute_impactLevelLowAndManual_rollbackLowImpactOnly()
throws PackageManager.NameNotFoundException, InterruptedException {
- mSetFlagsRule.enableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
int rollbackId1 = 1;
VersionedPackage appAFrom = new VersionedPackage(APP_A, VERSION_CODE_2);
VersionedPackage appATo = new VersionedPackage(APP_A, VERSION_CODE);
@@ -928,7 +909,6 @@
@Test
public void execute_impactLevelManual_rollbackLowImpactOnly()
throws PackageManager.NameNotFoundException {
- mSetFlagsRule.enableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
int rollbackId1 = 1;
VersionedPackage appAFrom = new VersionedPackage(APP_A, VERSION_CODE_2);
VersionedPackage appATo = new VersionedPackage(APP_A, VERSION_CODE);
@@ -962,7 +942,6 @@
@Test
public void executeBootLoopMitigation_impactLevelHighMultiplePackage_rollbackHigh()
throws PackageManager.NameNotFoundException {
- mSetFlagsRule.enableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
int rollbackId1 = 1;
VersionedPackage appBFrom = new VersionedPackage(APP_B, VERSION_CODE_2);
VersionedPackage appBTo = new VersionedPackage(APP_B, VERSION_CODE);
@@ -1008,7 +987,6 @@
@Test
public void executeBootLoopMitigation_impactLevelHighKillSwitchTrue_rollbackHigh()
throws PackageManager.NameNotFoundException {
- mSetFlagsRule.enableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
SystemProperties.set(PROP_DISABLE_HIGH_IMPACT_ROLLBACK_FLAG, Boolean.toString(true));
int rollbackId1 = 1;
VersionedPackage appBFrom = new VersionedPackage(APP_B, VERSION_CODE_2);
diff --git a/services/tests/powerstatstests/res/raw/battery-history.zip b/services/tests/powerstatstests/res/raw/battery-history.zip
new file mode 100644
index 0000000..ed82ac0
--- /dev/null
+++ b/services/tests/powerstatstests/res/raw/battery-history.zip
Binary files differ
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsProviderPerfTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsProviderPerfTest.java
new file mode 100644
index 0000000..8fc8c9f
--- /dev/null
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsProviderPerfTest.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2025 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.power.stats;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.os.BatteryConsumer;
+import android.os.BatteryUsageStats;
+import android.os.BatteryUsageStatsQuery;
+import android.os.ConditionVariable;
+import android.os.FileUtils;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.LargeTest;
+
+import com.android.internal.os.Clock;
+import com.android.internal.os.CpuScalingPolicies;
+import com.android.internal.os.CpuScalingPolicyReader;
+import com.android.internal.os.MonotonicClock;
+import com.android.internal.os.PowerProfile;
+import com.android.server.power.stats.processor.MultiStatePowerAttributor;
+
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.file.Files;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+@android.platform.test.annotations.DisabledOnRavenwood(reason = "Performance test")
+@Ignore("Performance experiment. Comment out @Ignore to run")
+public class BatteryUsageStatsProviderPerfTest {
+ @Rule
+ public final PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+ private final Clock mClock = new MockClock();
+ private MonotonicClock mMonotonicClock;
+ private PowerProfile mPowerProfile;
+ private CpuScalingPolicies mCpuScalingPolicies;
+ private File mDirectory;
+ private Handler mHandler;
+ private MockBatteryStatsImpl mBatteryStats;
+
+ @Before
+ public void setup() throws Exception {
+ Context context = InstrumentationRegistry.getContext();
+ mPowerProfile = new PowerProfile(context);
+ mCpuScalingPolicies = new CpuScalingPolicyReader().read();
+
+ HandlerThread mHandlerThread = new HandlerThread("batterystats-handler");
+ mHandlerThread.start();
+ mHandler = new Handler(mHandlerThread.getLooper());
+
+ // Extract accumulated battery history to ensure consistent iterations
+ mDirectory = Files.createTempDirectory("BatteryUsageStatsProviderPerfTest").toFile();
+ File historyDirectory = new File(mDirectory, "battery-history");
+ historyDirectory.mkdir();
+
+ long maxMonotonicTime = 0;
+
+ // To recreate battery-history.zip if necessary, perform these commands:
+ // cd /tmp
+ // mkdir battery-history
+ // adb pull /data/system/battery-history
+ // zip battery-history.zip battery-history/*
+ // cp battery-history.zip \
+ // $ANDROID_BUILD_TOP/frameworks/base/services/tests/powerstatstests/res/raw
+ Resources resources = context.getResources();
+ int resId = resources.getIdentifier("battery-history", "raw", context.getPackageName());
+ try (InputStream in = resources.openRawResource(resId)) {
+ try (ZipInputStream zis = new ZipInputStream(in)) {
+ ZipEntry ze;
+ while ((ze = zis.getNextEntry()) != null) {
+ if (!ze.getName().endsWith(".bh")) {
+ continue;
+ }
+ File file = new File(mDirectory, ze.getName());
+ try (OutputStream out = new FileOutputStream(
+ file)) {
+ FileUtils.copy(zis, out);
+ }
+ long timestamp = Long.parseLong(file.getName().replace(".bh", ""));
+ if (timestamp > maxMonotonicTime) {
+ maxMonotonicTime = timestamp;
+ }
+ }
+ }
+ }
+
+ mMonotonicClock = new MonotonicClock(maxMonotonicTime + 1000000000, mClock);
+ mBatteryStats = new MockBatteryStatsImpl(mClock, mDirectory);
+ }
+
+ @Test
+ public void getBatteryUsageStats_accumulated() {
+ BatteryUsageStatsQuery query = new BatteryUsageStatsQuery.Builder()
+ .setMaxStatsAgeMs(0)
+ .includePowerStateData()
+ .includeScreenStateData()
+ .includeProcessStateData()
+ .accumulated()
+ .build();
+
+ double expectedCpuPower = 0;
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ state.pauseTiming();
+
+ waitForBackgroundThread();
+
+ BatteryUsageStatsProvider provider = createBatteryUsageStatsProvider();
+ state.resumeTiming();
+
+ BatteryUsageStats stats = provider.getBatteryUsageStats(mBatteryStats, query);
+ waitForBackgroundThread();
+
+ state.pauseTiming();
+
+ double cpuConsumedPower = stats.getAggregateBatteryConsumer(
+ BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE)
+ .getConsumedPower(BatteryConsumer.POWER_COMPONENT_CPU);
+ assertThat(cpuConsumedPower).isNonZero();
+ if (expectedCpuPower == 0) {
+ expectedCpuPower = cpuConsumedPower;
+ } else {
+ // Verify that all iterations produce the same result
+ assertThat(cpuConsumedPower).isEqualTo(expectedCpuPower);
+ }
+ state.resumeTiming();
+ }
+ }
+
+ private BatteryUsageStatsProvider createBatteryUsageStatsProvider() {
+ Context context = InstrumentationRegistry.getContext();
+
+ PowerStatsStore store = new PowerStatsStore(mDirectory, mHandler);
+ store.reset();
+
+ MultiStatePowerAttributor powerAttributor = new MultiStatePowerAttributor(context, store,
+ mPowerProfile, mCpuScalingPolicies, mPowerProfile::getBatteryCapacity);
+ return new BatteryUsageStatsProvider(context, powerAttributor, mPowerProfile,
+ mCpuScalingPolicies, store, 10000000, mClock, mMonotonicClock);
+ }
+
+ private void waitForBackgroundThread() {
+ ConditionVariable done = new ConditionVariable();
+ mHandler.post(done::open);
+ done.block();
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/autoclick/AutoclickTypePanelTest.java b/services/tests/servicestests/src/com/android/server/accessibility/autoclick/AutoclickTypePanelTest.java
index 00cc726..b6d8e87 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/autoclick/AutoclickTypePanelTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/autoclick/AutoclickTypePanelTest.java
@@ -63,6 +63,7 @@
private LinearLayout mDoubleClickButton;
private LinearLayout mDragButton;
private LinearLayout mScrollButton;
+ private LinearLayout mPauseButton;
private @AutoclickType int mActiveClickType = AUTOCLICK_TYPE_LEFT_CLICK;
@@ -91,6 +92,7 @@
contentView.findViewById(R.id.accessibility_autoclick_double_click_layout);
mScrollButton = contentView.findViewById(R.id.accessibility_autoclick_scroll_layout);
mDragButton = contentView.findViewById(R.id.accessibility_autoclick_drag_layout);
+ mPauseButton = contentView.findViewById(R.id.accessibility_autoclick_pause_layout);
}
@Test
@@ -106,6 +108,7 @@
assertThat(mDoubleClickButton.getVisibility()).isEqualTo(View.GONE);
assertThat(mDragButton.getVisibility()).isEqualTo(View.GONE);
assertThat(mScrollButton.getVisibility()).isEqualTo(View.GONE);
+ assertThat(mPauseButton.getVisibility()).isEqualTo(View.VISIBLE);
}
@Test
@@ -124,6 +127,9 @@
assertThat(mDoubleClickButton.getVisibility()).isEqualTo(View.VISIBLE);
assertThat(mDragButton.getVisibility()).isEqualTo(View.VISIBLE);
assertThat(mScrollButton.getVisibility()).isEqualTo(View.VISIBLE);
+
+ // Pause button is always visible.
+ assertThat(mPauseButton.getVisibility()).isEqualTo(View.VISIBLE);
}
@Test
@@ -142,6 +148,9 @@
assertThat(mLeftClickButton.getVisibility()).isEqualTo(View.GONE);
assertThat(mDoubleClickButton.getVisibility()).isEqualTo(View.GONE);
assertThat(mDragButton.getVisibility()).isEqualTo(View.GONE);
+
+ // Pause button is always visible.
+ assertThat(mPauseButton.getVisibility()).isEqualTo(View.VISIBLE);
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/audio/AudioDeviceInventoryTest.java b/services/tests/servicestests/src/com/android/server/audio/AudioDeviceInventoryTest.java
index b5a538f..c7da274 100644
--- a/services/tests/servicestests/src/com/android/server/audio/AudioDeviceInventoryTest.java
+++ b/services/tests/servicestests/src/com/android/server/audio/AudioDeviceInventoryTest.java
@@ -103,7 +103,7 @@
// NOTE: for now this is only when flag asDeviceConnectionFailure is true
if (asDeviceConnectionFailure()) {
when(mSpyAudioSystem.setDeviceConnectionState(ada, AudioSystem.DEVICE_STATE_AVAILABLE,
- AudioSystem.AUDIO_FORMAT_DEFAULT))
+ AudioSystem.AUDIO_FORMAT_DEFAULT, false /*deviceSwitch*/))
.thenReturn(AudioSystem.AUDIO_STATUS_ERROR);
runWithBluetoothPrivilegedPermission(
() -> mDevInventory.onSetBtActiveDevice(/*btInfo*/ btInfo,
@@ -115,7 +115,7 @@
// test that the device is added when AudioSystem returns AUDIO_STATUS_OK
// when setDeviceConnectionState is called for the connection
when(mSpyAudioSystem.setDeviceConnectionState(ada, AudioSystem.DEVICE_STATE_AVAILABLE,
- AudioSystem.AUDIO_FORMAT_DEFAULT))
+ AudioSystem.AUDIO_FORMAT_DEFAULT, false /*deviceSwitch*/))
.thenReturn(AudioSystem.AUDIO_STATUS_OK);
runWithBluetoothPrivilegedPermission(
() -> mDevInventory.onSetBtActiveDevice(/*btInfo*/ btInfo,
diff --git a/services/tests/servicestests/src/com/android/server/audio/NoOpAudioSystemAdapter.java b/services/tests/servicestests/src/com/android/server/audio/NoOpAudioSystemAdapter.java
index ce59a86..39e7d72 100644
--- a/services/tests/servicestests/src/com/android/server/audio/NoOpAudioSystemAdapter.java
+++ b/services/tests/servicestests/src/com/android/server/audio/NoOpAudioSystemAdapter.java
@@ -51,9 +51,9 @@
// Overrides of AudioSystemAdapter
@Override
public int setDeviceConnectionState(AudioDeviceAttributes attributes, int state,
- int codecFormat) {
- Log.i(TAG, String.format("setDeviceConnectionState(0x%s, %d, 0x%s",
- attributes.toString(), state, Integer.toHexString(codecFormat)));
+ int codecFormat, boolean deviceSwitch) {
+ Log.i(TAG, String.format("setDeviceConnectionState(0x%s, %d, 0x%s %b",
+ attributes.toString(), state, Integer.toHexString(codecFormat), deviceSwitch));
return AudioSystem.AUDIO_STATUS_OK;
}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/BaseAbsoluteVolumeBehaviorTest.java b/services/tests/servicestests/src/com/android/server/hdmi/BaseAbsoluteVolumeBehaviorTest.java
index fca0cfb..b2d48a7 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/BaseAbsoluteVolumeBehaviorTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/BaseAbsoluteVolumeBehaviorTest.java
@@ -16,6 +16,7 @@
package com.android.server.hdmi;
+import static android.content.pm.PackageManager.FEATURE_HDMI_CEC;
import static android.hardware.hdmi.HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM;
import static com.android.server.hdmi.HdmiCecKeycode.CEC_KEYCODE_VOLUME_UP;
@@ -25,6 +26,7 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.TruthJUnit.assume;
+import static org.junit.Assume.assumeTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -122,6 +124,9 @@
@Before
public void setUp() throws RemoteException {
+ assumeTrue("Test requires FEATURE_HDMI_CEC",
+ InstrumentationRegistry.getTargetContext().getPackageManager()
+ .hasSystemFeature(FEATURE_HDMI_CEC));
MockitoAnnotations.initMocks(this);
mContextSpy = spy(new ContextWrapper(
@@ -432,7 +437,7 @@
.setMaxVolumeIndex(AudioStatus.MAX_VOLUME)
.setMinVolumeIndex(AudioStatus.MIN_VOLUME)
.build()),
- any(), any(), anyBoolean());
+ anyBoolean(), any(), any());
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/BaseTvToAudioSystemAvbTest.java b/services/tests/servicestests/src/com/android/server/hdmi/BaseTvToAudioSystemAvbTest.java
index ec44a91..f44517a 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/BaseTvToAudioSystemAvbTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/BaseTvToAudioSystemAvbTest.java
@@ -112,7 +112,7 @@
.setMaxVolumeIndex(AudioStatus.MAX_VOLUME)
.setMinVolumeIndex(AudioStatus.MIN_VOLUME)
.build()),
- any(), any(), anyBoolean());
+ anyBoolean(), any(), any());
}
@@ -135,7 +135,7 @@
.setMaxVolumeIndex(AudioStatus.MAX_VOLUME)
.setMinVolumeIndex(AudioStatus.MIN_VOLUME)
.build()),
- any(), any(), anyBoolean());
+ anyBoolean(), any(), any());
}
@Test
@@ -160,7 +160,7 @@
.setMaxVolumeIndex(AudioStatus.MAX_VOLUME)
.setMinVolumeIndex(AudioStatus.MIN_VOLUME)
.build()),
- any(), any(), anyBoolean());
+ anyBoolean(), any(), any());
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/FakeAudioFramework.java b/services/tests/servicestests/src/com/android/server/hdmi/FakeAudioFramework.java
index 7294ba6..90f94cb 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/FakeAudioFramework.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/FakeAudioFramework.java
@@ -183,9 +183,9 @@
public void setDeviceAbsoluteVolumeBehavior(
@NonNull AudioDeviceAttributes device,
@NonNull VolumeInfo volume,
+ boolean handlesVolumeAdjustment,
@NonNull @CallbackExecutor Executor executor,
- @NonNull OnAudioDeviceVolumeChangedListener vclistener,
- boolean handlesVolumeAdjustment) {
+ @NonNull OnAudioDeviceVolumeChangedListener vclistener) {
setVolumeBehaviorHelper(device, AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
}
@@ -193,9 +193,9 @@
public void setDeviceAbsoluteVolumeAdjustOnlyBehavior(
@NonNull AudioDeviceAttributes device,
@NonNull VolumeInfo volume,
+ boolean handlesVolumeAdjustment,
@NonNull @CallbackExecutor Executor executor,
- @NonNull OnAudioDeviceVolumeChangedListener vclistener,
- boolean handlesVolumeAdjustment) {
+ @NonNull OnAudioDeviceVolumeChangedListener vclistener) {
setVolumeBehaviorHelper(device,
AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY);
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java
index 4c1544f..67efb9e 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java
@@ -488,33 +488,33 @@
ZenModeConfig.ZenRule rule = new ZenModeConfig.ZenRule();
rule.zenPolicy = null;
rule.zenDeviceEffects = null;
- assertThat(rule.canBeUpdatedByApp()).isTrue();
+ assertThat(rule.isUserModified()).isFalse();
rule.userModifiedFields = 1;
- assertThat(rule.canBeUpdatedByApp()).isFalse();
+ assertThat(rule.isUserModified()).isTrue();
}
@Test
public void testCanBeUpdatedByApp_policyModified() throws Exception {
ZenModeConfig.ZenRule rule = new ZenModeConfig.ZenRule();
rule.zenPolicy = new ZenPolicy();
- assertThat(rule.canBeUpdatedByApp()).isTrue();
+ assertThat(rule.isUserModified()).isFalse();
rule.zenPolicyUserModifiedFields = 1;
- assertThat(rule.canBeUpdatedByApp()).isFalse();
+ assertThat(rule.isUserModified()).isTrue();
}
@Test
public void testCanBeUpdatedByApp_deviceEffectsModified() throws Exception {
ZenModeConfig.ZenRule rule = new ZenModeConfig.ZenRule();
rule.zenDeviceEffects = new ZenDeviceEffects.Builder().build();
- assertThat(rule.canBeUpdatedByApp()).isTrue();
+ assertThat(rule.isUserModified()).isFalse();
rule.zenDeviceEffectsUserModifiedFields = 1;
- assertThat(rule.canBeUpdatedByApp()).isFalse();
+ assertThat(rule.isUserModified()).isTrue();
}
@Test
@@ -563,6 +563,9 @@
rule.deletionInstant = Instant.ofEpochMilli(1701790147000L);
if (Flags.modesUi()) {
rule.disabledOrigin = ZenModeConfig.ORIGIN_USER_IN_SYSTEMUI;
+ if (Flags.modesCleanupImplicit()) {
+ rule.lastActivation = Instant.ofEpochMilli(456);
+ }
}
config.automaticRules.put(rule.id, rule);
@@ -600,6 +603,9 @@
assertEquals(rule.deletionInstant, ruleActual.deletionInstant);
if (Flags.modesUi()) {
assertEquals(rule.disabledOrigin, ruleActual.disabledOrigin);
+ if (Flags.modesCleanupImplicit()) {
+ assertEquals(rule.lastActivation, ruleActual.lastActivation);
+ }
}
if (Flags.backupRestoreLogging()) {
verify(logger).logItemsBackedUp(DATA_TYPE_ZEN_RULES, 2);
@@ -633,6 +639,9 @@
rule.deletionInstant = Instant.ofEpochMilli(1701790147000L);
if (Flags.modesUi()) {
rule.disabledOrigin = ZenModeConfig.ORIGIN_USER_IN_SYSTEMUI;
+ if (Flags.modesCleanupImplicit()) {
+ rule.lastActivation = Instant.ofEpochMilli(789);
+ }
}
Parcel parcel = Parcel.obtain();
@@ -664,6 +673,9 @@
assertEquals(rule.deletionInstant, parceled.deletionInstant);
if (Flags.modesUi()) {
assertEquals(rule.disabledOrigin, parceled.disabledOrigin);
+ if (Flags.modesCleanupImplicit()) {
+ assertEquals(rule.lastActivation, parceled.lastActivation);
+ }
}
assertEquals(rule, parceled);
@@ -746,6 +758,9 @@
rule.deletionInstant = Instant.ofEpochMilli(1701790147000L);
if (Flags.modesUi()) {
rule.disabledOrigin = ZenModeConfig.ORIGIN_APP;
+ if (Flags.modesCleanupImplicit()) {
+ rule.lastActivation = Instant.ofEpochMilli(123);
+ }
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
@@ -781,6 +796,9 @@
assertEquals(rule.deletionInstant, fromXml.deletionInstant);
if (Flags.modesUi()) {
assertEquals(rule.disabledOrigin, fromXml.disabledOrigin);
+ if (Flags.modesCleanupImplicit()) {
+ assertEquals(rule.lastActivation, fromXml.lastActivation);
+ }
}
}
@@ -908,7 +926,7 @@
ZenModeConfig.ZenRule rule = new ZenModeConfig.ZenRule();
rule.userModifiedFields |= AutomaticZenRule.FIELD_NAME;
assertThat(rule.userModifiedFields).isEqualTo(1);
- assertThat(rule.canBeUpdatedByApp()).isFalse();
+ assertThat(rule.isUserModified()).isTrue();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
writeRuleXml(rule, baos);
@@ -916,7 +934,7 @@
ZenModeConfig.ZenRule fromXml = readRuleXml(bais);
assertThat(fromXml.userModifiedFields).isEqualTo(rule.userModifiedFields);
- assertThat(fromXml.canBeUpdatedByApp()).isFalse();
+ assertThat(fromXml.isUserModified()).isTrue();
}
@Test
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeDiffTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeDiffTest.java
index 8a5f80cb3..6d0bf8b 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeDiffTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeDiffTest.java
@@ -475,7 +475,8 @@
// "Metadata" fields are never compared.
Set<String> exemptFields = new LinkedHashSet<>(
Set.of("userModifiedFields", "zenPolicyUserModifiedFields",
- "zenDeviceEffectsUserModifiedFields", "deletionInstant", "disabledOrigin"));
+ "zenDeviceEffectsUserModifiedFields", "deletionInstant", "disabledOrigin",
+ "lastActivation"));
// Flagged fields are only compared if their flag is on.
if (Flags.modesUi()) {
exemptFields.add(RuleDiff.FIELD_SNOOZING); // Obsolete.
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
index 4d2f105..0ab11e0 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
@@ -23,6 +23,7 @@
import static android.app.AutomaticZenRule.TYPE_THEATER;
import static android.app.AutomaticZenRule.TYPE_UNKNOWN;
import static android.app.Flags.FLAG_BACKUP_RESTORE_LOGGING;
+import static android.app.Flags.FLAG_MODES_CLEANUP_IMPLICIT;
import static android.app.Flags.FLAG_MODES_MULTIUSER;
import static android.app.Flags.FLAG_MODES_UI;
import static android.app.NotificationManager.AUTOMATIC_RULE_STATUS_ACTIVATED;
@@ -124,7 +125,10 @@
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.withSettings;
+import static java.time.temporal.ChronoUnit.DAYS;
+
import android.Manifest;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.app.AlarmManager;
@@ -219,7 +223,6 @@
import java.io.StringWriter;
import java.time.Instant;
import java.time.ZoneOffset;
-import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.LinkedList;
@@ -2233,8 +2236,7 @@
mZenModeHelper.mConfig.automaticRules.put(implicitRuleBeforeModesUi.id,
implicitRuleBeforeModesUi);
// Plus one other normal rule.
- ZenRule anotherRule = newZenRule("other_pkg", Instant.now(), null);
- anotherRule.id = "other_rule";
+ ZenRule anotherRule = newZenRule("other_rule", "other_pkg", Instant.now());
anotherRule.iconResName = "other_icon";
anotherRule.type = TYPE_IMMERSIVE;
mZenModeHelper.mConfig.automaticRules.put(anotherRule.id, anotherRule);
@@ -2271,8 +2273,7 @@
implicitRuleWithModesUi);
// Plus one other normal rule.
- ZenRule anotherRule = newZenRule("other_pkg", Instant.now(), null);
- anotherRule.id = "other_rule";
+ ZenRule anotherRule = newZenRule("other_rule", "other_pkg", Instant.now());
anotherRule.iconResName = "other_icon";
anotherRule.type = TYPE_IMMERSIVE;
mZenModeHelper.mConfig.automaticRules.put(anotherRule.id, anotherRule);
@@ -4611,7 +4612,7 @@
assertThat(rule.getDeviceEffects().shouldDisplayGrayscale()).isTrue();
ZenRule storedRule = mZenModeHelper.mConfig.automaticRules.get(ruleId);
- assertThat(storedRule.canBeUpdatedByApp()).isTrue();
+ assertThat(storedRule.isUserModified()).isFalse();
}
@Test
@@ -4719,7 +4720,7 @@
STATE_DISALLOW);
ZenRule storedRule = mZenModeHelper.mConfig.automaticRules.get(ruleId);
- assertThat(storedRule.canBeUpdatedByApp()).isFalse();
+ assertThat(storedRule.isUserModified()).isTrue();
assertThat(storedRule.zenPolicyUserModifiedFields).isEqualTo(
ZenPolicy.FIELD_ALLOW_CHANNELS
| ZenPolicy.FIELD_PRIORITY_CATEGORY_REMINDERS
@@ -4761,7 +4762,7 @@
assertThat(rule.getDeviceEffects().shouldDisplayGrayscale()).isTrue();
ZenRule storedRule = mZenModeHelper.mConfig.automaticRules.get(ruleId);
- assertThat(storedRule.canBeUpdatedByApp()).isFalse();
+ assertThat(storedRule.isUserModified()).isTrue();
assertThat(storedRule.zenDeviceEffectsUserModifiedFields).isEqualTo(
ZenDeviceEffects.FIELD_GRAYSCALE);
}
@@ -5713,8 +5714,8 @@
// Start with deleted rules from 2 different packages.
Instant now = Instant.ofEpochMilli(1701796461000L);
- ZenRule pkg1Rule = newZenRule("pkg1", now.minus(1, ChronoUnit.DAYS), now);
- ZenRule pkg2Rule = newZenRule("pkg2", now.minus(2, ChronoUnit.DAYS), now);
+ ZenRule pkg1Rule = newDeletedZenRule("1", "pkg1", now.minus(1, DAYS), now);
+ ZenRule pkg2Rule = newDeletedZenRule("2", "pkg2", now.minus(2, DAYS), now);
mZenModeHelper.mConfig.deletedRules.put(ZenModeConfig.deletedRuleKey(pkg1Rule), pkg1Rule);
mZenModeHelper.mConfig.deletedRules.put(ZenModeConfig.deletedRuleKey(pkg2Rule), pkg2Rule);
@@ -5832,9 +5833,9 @@
@Test
public void testRuleCleanup() throws Exception {
Instant now = Instant.ofEpochMilli(1701796461000L);
- Instant yesterday = now.minus(1, ChronoUnit.DAYS);
- Instant aWeekAgo = now.minus(7, ChronoUnit.DAYS);
- Instant twoMonthsAgo = now.minus(60, ChronoUnit.DAYS);
+ Instant yesterday = now.minus(1, DAYS);
+ Instant aWeekAgo = now.minus(7, DAYS);
+ Instant twoMonthsAgo = now.minus(60, DAYS);
mTestClock.setNowMillis(now.toEpochMilli());
when(mPackageManager.getPackageInfo(eq("good_pkg"), anyInt()))
@@ -5847,24 +5848,28 @@
config.user = 42;
mZenModeHelper.mConfigs.put(42, config);
// okay rules (not deleted, package exists, with a range of creation dates).
- config.automaticRules.put("ar1", newZenRule("good_pkg", now, null));
- config.automaticRules.put("ar2", newZenRule("good_pkg", yesterday, null));
- config.automaticRules.put("ar3", newZenRule("good_pkg", twoMonthsAgo, null));
+ config.automaticRules.put("ar1", newZenRule("ar1", "good_pkg", now));
+ config.automaticRules.put("ar2", newZenRule("ar2", "good_pkg", yesterday));
+ config.automaticRules.put("ar3", newZenRule("ar3", "good_pkg", twoMonthsAgo));
// newish rules for a missing package
- config.automaticRules.put("ar4", newZenRule("bad_pkg", yesterday, null));
+ config.automaticRules.put("ar4", newZenRule("ar4", "bad_pkg", yesterday));
// oldish rules belonging to a missing package
- config.automaticRules.put("ar5", newZenRule("bad_pkg", aWeekAgo, null));
+ config.automaticRules.put("ar5", newZenRule("ar5", "bad_pkg", aWeekAgo));
// rules deleted recently
- config.deletedRules.put("del1", newZenRule("good_pkg", twoMonthsAgo, yesterday));
- config.deletedRules.put("del2", newZenRule("good_pkg", twoMonthsAgo, aWeekAgo));
+ config.deletedRules.put("del1",
+ newDeletedZenRule("del1", "good_pkg", twoMonthsAgo, yesterday));
+ config.deletedRules.put("del2",
+ newDeletedZenRule("del2", "good_pkg", twoMonthsAgo, aWeekAgo));
// rules deleted a long time ago
- config.deletedRules.put("del3", newZenRule("good_pkg", twoMonthsAgo, twoMonthsAgo));
+ config.deletedRules.put("del3",
+ newDeletedZenRule("del3", "good_pkg", twoMonthsAgo, twoMonthsAgo));
// rules for a missing package, created recently and deleted recently
- config.deletedRules.put("del4", newZenRule("bad_pkg", yesterday, now));
+ config.deletedRules.put("del4", newDeletedZenRule("del4", "bad_pkg", yesterday, now));
// rules for a missing package, created a long time ago and deleted recently
- config.deletedRules.put("del5", newZenRule("bad_pkg", twoMonthsAgo, now));
+ config.deletedRules.put("del5", newDeletedZenRule("del5", "bad_pkg", twoMonthsAgo, now));
// rules for a missing package, created a long time ago and deleted a long time ago
- config.deletedRules.put("del6", newZenRule("bad_pkg", twoMonthsAgo, twoMonthsAgo));
+ config.deletedRules.put("del6",
+ newDeletedZenRule("del6", "bad_pkg", twoMonthsAgo, twoMonthsAgo));
mZenModeHelper.onUserSwitched(42); // copies config and cleans it up.
@@ -5874,14 +5879,115 @@
.containsExactly("del1", "del2", "del4");
}
- private static ZenRule newZenRule(String pkg, Instant createdAt, @Nullable Instant deletedAt) {
+ @Test
+ @EnableFlags({FLAG_MODES_UI, FLAG_MODES_CLEANUP_IMPLICIT})
+ public void testRuleCleanup_removesNotRecentlyUsedNotModifiedImplicitRules() throws Exception {
+ Instant now = Instant.ofEpochMilli(1701796461000L);
+ Instant yesterday = now.minus(1, DAYS);
+ Instant aWeekAgo = now.minus(7, DAYS);
+ Instant twoMonthsAgo = now.minus(60, DAYS);
+ Instant aYearAgo = now.minus(365, DAYS);
+ mTestClock.setNowMillis(now.toEpochMilli());
+ when(mPackageManager.getPackageInfo(anyString(), anyInt())).thenReturn(new PackageInfo());
+
+ // Set up a config to be loaded, containing a bunch of implicit rules
+ ZenModeConfig config = new ZenModeConfig();
+ config.user = 42;
+ mZenModeHelper.mConfigs.put(42, config);
+ // used recently
+ ZenRule usedRecently1 = newImplicitZenRule("pkg1", aYearAgo, yesterday);
+ ZenRule usedRecently2 = newImplicitZenRule("pkg2", aYearAgo, aWeekAgo);
+ config.automaticRules.put(usedRecently1.id, usedRecently1);
+ config.automaticRules.put(usedRecently2.id, usedRecently2);
+ // not used in a long time
+ ZenRule longUnused = newImplicitZenRule("pkg3", aYearAgo, twoMonthsAgo);
+ config.automaticRules.put(longUnused.id, longUnused);
+ // created a long time ago, before lastActivation tracking
+ ZenRule oldAndLastUsageUnknown = newImplicitZenRule("pkg4", twoMonthsAgo, null);
+ config.automaticRules.put(oldAndLastUsageUnknown.id, oldAndLastUsageUnknown);
+ // created a short time ago, before lastActivation tracking
+ ZenRule newAndLastUsageUnknown = newImplicitZenRule("pkg5", aWeekAgo, null);
+ config.automaticRules.put(newAndLastUsageUnknown.id, newAndLastUsageUnknown);
+ // not used in a long time, but was customized by user
+ ZenRule longUnusedButCustomized = newImplicitZenRule("pkg6", aYearAgo, twoMonthsAgo);
+ longUnusedButCustomized.zenPolicyUserModifiedFields = ZenPolicy.FIELD_CONVERSATIONS;
+ config.automaticRules.put(longUnusedButCustomized.id, longUnusedButCustomized);
+ // created a long time ago, before lastActivation tracking, and was customized by user
+ ZenRule oldAndLastUsageUnknownAndCustomized = newImplicitZenRule("pkg7", twoMonthsAgo,
+ null);
+ oldAndLastUsageUnknownAndCustomized.userModifiedFields = AutomaticZenRule.FIELD_ICON;
+ config.automaticRules.put(oldAndLastUsageUnknownAndCustomized.id,
+ oldAndLastUsageUnknownAndCustomized);
+
+ mZenModeHelper.onUserSwitched(42); // copies config and cleans it up.
+
+ // The recently used OR modified OR last-used-unknown rules stay.
+ assertThat(mZenModeHelper.mConfig.automaticRules.values())
+ .comparingElementsUsing(IGNORE_METADATA)
+ .containsExactly(usedRecently1, usedRecently2, oldAndLastUsageUnknown,
+ newAndLastUsageUnknown, longUnusedButCustomized,
+ oldAndLastUsageUnknownAndCustomized);
+ }
+
+ @Test
+ @EnableFlags({FLAG_MODES_UI, FLAG_MODES_CLEANUP_IMPLICIT})
+ public void testRuleCleanup_assignsLastActivationToImplicitRules() throws Exception {
+ Instant now = Instant.ofEpochMilli(1701796461000L);
+ Instant aWeekAgo = now.minus(7, DAYS);
+ Instant aYearAgo = now.minus(365, DAYS);
+ mTestClock.setNowMillis(now.toEpochMilli());
+ when(mPackageManager.getPackageInfo(anyString(), anyInt())).thenReturn(new PackageInfo());
+
+ // Set up a config to be loaded, containing implicit rules.
+ ZenModeConfig config = new ZenModeConfig();
+ config.user = 42;
+ mZenModeHelper.mConfigs.put(42, config);
+ // with last activation known
+ ZenRule usedRecently = newImplicitZenRule("pkg1", aYearAgo, aWeekAgo);
+ config.automaticRules.put(usedRecently.id, usedRecently);
+ // created a long time ago, with last activation unknown
+ ZenRule oldAndLastUsageUnknown = newImplicitZenRule("pkg4", aYearAgo, null);
+ config.automaticRules.put(oldAndLastUsageUnknown.id, oldAndLastUsageUnknown);
+ // created a short time ago, with last activation unknown
+ ZenRule newAndLastUsageUnknown = newImplicitZenRule("pkg5", aWeekAgo, null);
+ config.automaticRules.put(newAndLastUsageUnknown.id, newAndLastUsageUnknown);
+
+ mZenModeHelper.onUserSwitched(42); // copies config and cleans it up.
+
+ // All rules stayed.
+ usedRecently = getZenRule(usedRecently.id);
+ oldAndLastUsageUnknown = getZenRule(oldAndLastUsageUnknown.id);
+ newAndLastUsageUnknown = getZenRule(newAndLastUsageUnknown.id);
+
+ // The rules with an unknown last usage have been assigned a placeholder one.
+ assertThat(usedRecently.lastActivation).isEqualTo(aWeekAgo);
+ assertThat(oldAndLastUsageUnknown.lastActivation).isEqualTo(now);
+ assertThat(newAndLastUsageUnknown.lastActivation).isEqualTo(now);
+ }
+
+ private static ZenRule newDeletedZenRule(String id, String pkg, Instant createdAt,
+ @NonNull Instant deletedAt) {
+ ZenRule rule = newZenRule(id, pkg, createdAt);
+ rule.deletionInstant = deletedAt;
+ return rule;
+ }
+
+ private static ZenRule newImplicitZenRule(String pkg, @NonNull Instant createdAt,
+ @Nullable Instant lastActivatedAt) {
+ ZenRule implicitRule = newZenRule(implicitRuleId(pkg), pkg, createdAt);
+ implicitRule.lastActivation = lastActivatedAt;
+ return implicitRule;
+ }
+
+ private static ZenRule newZenRule(String id, String pkg, Instant createdAt) {
ZenRule rule = new ZenRule();
+ rule.id = id;
rule.pkg = pkg;
rule.creationTime = createdAt.toEpochMilli();
rule.enabled = true;
- rule.deletionInstant = deletedAt;
+ rule.deletionInstant = null;
// Plus stuff so that isValidAutomaticRule() passes
- rule.name = "A rule from " + pkg + " created on " + createdAt;
+ rule.name = "Rule " + id;
rule.conditionId = Uri.parse(rule.name);
return rule;
}
@@ -5919,11 +6025,11 @@
@Test
public void getAutomaticZenRuleState_notOwnedRule_returnsStateUnknown() {
// Assume existence of a system-owned rule that is currently ACTIVE.
- ZenRule systemRule = newZenRule("android", Instant.now(), null);
+ ZenRule systemRule = newZenRule("systemRule", "android", Instant.now());
systemRule.zenMode = ZEN_MODE_ALARMS;
systemRule.condition = new Condition(systemRule.conditionId, "on", Condition.STATE_TRUE);
ZenModeConfig config = mZenModeHelper.mConfig.copy();
- config.automaticRules.put("systemRule", systemRule);
+ config.automaticRules.put(systemRule.id, systemRule);
mZenModeHelper.setConfig(config, null, ORIGIN_INIT, "", SYSTEM_UID);
assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_ALARMS);
@@ -5935,11 +6041,11 @@
public void setAutomaticZenRuleState_idForNotOwnedRule_ignored() {
// Assume existence of an other-package-owned rule that is currently ACTIVE.
assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_OFF);
- ZenRule otherRule = newZenRule("another.package", Instant.now(), null);
+ ZenRule otherRule = newZenRule("otherRule", "another.package", Instant.now());
otherRule.zenMode = ZEN_MODE_ALARMS;
otherRule.condition = new Condition(otherRule.conditionId, "on", Condition.STATE_TRUE);
ZenModeConfig config = mZenModeHelper.mConfig.copy();
- config.automaticRules.put("otherRule", otherRule);
+ config.automaticRules.put(otherRule.id, otherRule);
mZenModeHelper.setConfig(config, null, ORIGIN_INIT, "", SYSTEM_UID);
assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_ALARMS);
@@ -5955,11 +6061,11 @@
public void setAutomaticZenRuleStateFromConditionProvider_conditionForNotOwnedRule_ignored() {
// Assume existence of an other-package-owned rule that is currently ACTIVE.
assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_OFF);
- ZenRule otherRule = newZenRule("another.package", Instant.now(), null);
+ ZenRule otherRule = newZenRule("otherRule", "another.package", Instant.now());
otherRule.zenMode = ZEN_MODE_ALARMS;
otherRule.condition = new Condition(otherRule.conditionId, "on", Condition.STATE_TRUE);
ZenModeConfig config = mZenModeHelper.mConfig.copy();
- config.automaticRules.put("otherRule", otherRule);
+ config.automaticRules.put(otherRule.id, otherRule);
mZenModeHelper.setConfig(config, null, ORIGIN_INIT, "", SYSTEM_UID);
assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_ALARMS);
@@ -7255,6 +7361,125 @@
"config: setAzrStateFromCps: cond/cond (ORIGIN_APP) from uid " + CUSTOM_PKG_UID);
}
+ @Test
+ @EnableFlags({FLAG_MODES_UI, FLAG_MODES_CLEANUP_IMPLICIT})
+ public void setAutomaticZenRuleState_updatesLastActivation() {
+ String ruleOne = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, mPkg,
+ new AutomaticZenRule.Builder("rule", CONDITION_ID)
+ .setConfigurationActivity(new ComponentName(mPkg, "cls"))
+ .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY)
+ .build(),
+ ORIGIN_APP, "reason", CUSTOM_PKG_UID);
+ String ruleTwo = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, mPkg,
+ new AutomaticZenRule.Builder("unrelated", Uri.parse("other.condition"))
+ .setConfigurationActivity(new ComponentName(mPkg, "cls"))
+ .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY)
+ .build(),
+ ORIGIN_APP, "reason", CUSTOM_PKG_UID);
+
+ assertThat(getZenRule(ruleOne).lastActivation).isNull();
+ assertThat(getZenRule(ruleTwo).lastActivation).isNull();
+
+ Instant firstActivation = Instant.ofEpochMilli(100);
+ mTestClock.setNow(firstActivation);
+ mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleOne, CONDITION_TRUE,
+ ORIGIN_APP, CUSTOM_PKG_UID);
+
+ assertThat(getZenRule(ruleOne).lastActivation).isEqualTo(firstActivation);
+ assertThat(getZenRule(ruleTwo).lastActivation).isNull();
+
+ mTestClock.setNow(Instant.ofEpochMilli(300));
+ mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleOne, CONDITION_FALSE,
+ ORIGIN_APP, CUSTOM_PKG_UID);
+
+ assertThat(getZenRule(ruleOne).lastActivation).isEqualTo(firstActivation);
+ assertThat(getZenRule(ruleTwo).lastActivation).isNull();
+
+ Instant secondActivation = Instant.ofEpochMilli(500);
+ mTestClock.setNow(secondActivation);
+ mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleOne, CONDITION_TRUE,
+ ORIGIN_APP, CUSTOM_PKG_UID);
+
+ assertThat(getZenRule(ruleOne).lastActivation).isEqualTo(secondActivation);
+ assertThat(getZenRule(ruleTwo).lastActivation).isNull();
+ }
+
+ @Test
+ @EnableFlags({FLAG_MODES_UI, FLAG_MODES_CLEANUP_IMPLICIT})
+ public void setManualZenMode_updatesLastActivation() {
+ assertThat(mZenModeHelper.mConfig.manualRule.lastActivation).isNull();
+ Instant instant = Instant.ofEpochMilli(100);
+ mTestClock.setNow(instant);
+
+ mZenModeHelper.setManualZenMode(UserHandle.CURRENT, ZEN_MODE_ALARMS, null,
+ ORIGIN_USER_IN_SYSTEMUI, "reason", "systemui", SYSTEM_UID);
+
+ assertThat(mZenModeHelper.mConfig.manualRule.lastActivation).isEqualTo(instant);
+ }
+
+ @Test
+ @EnableFlags({FLAG_MODES_UI, FLAG_MODES_CLEANUP_IMPLICIT})
+ public void applyGlobalZenModeAsImplicitZenRule_updatesLastActivation() {
+ Instant instant = Instant.ofEpochMilli(100);
+ mTestClock.setNow(instant);
+
+ mZenModeHelper.applyGlobalZenModeAsImplicitZenRule(UserHandle.CURRENT, CUSTOM_PKG_NAME,
+ CUSTOM_PKG_UID, ZEN_MODE_ALARMS);
+
+ ZenRule implicitRule = getZenRule(implicitRuleId(CUSTOM_PKG_NAME));
+ assertThat(implicitRule.lastActivation).isEqualTo(instant);
+ }
+
+ @Test
+ @EnableFlags({FLAG_MODES_UI, FLAG_MODES_CLEANUP_IMPLICIT})
+ public void setAutomaticZenRuleState_notChangingActiveState_doesNotUpdateLastActivation() {
+ String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, mPkg,
+ new AutomaticZenRule.Builder("rule", CONDITION_ID)
+ .setConfigurationActivity(new ComponentName(mPkg, "cls"))
+ .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY)
+ .build(),
+ ORIGIN_APP, "reason", CUSTOM_PKG_UID);
+
+ assertThat(getZenRule(ruleId).lastActivation).isNull();
+
+ // Manual activation comes first
+ Instant firstActivation = Instant.ofEpochMilli(100);
+ mTestClock.setNow(firstActivation);
+ mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId, CONDITION_TRUE,
+ ORIGIN_USER_IN_SYSTEMUI, SYSTEM_UID);
+
+ assertThat(getZenRule(ruleId).lastActivation).isEqualTo(firstActivation);
+
+ // Now the app says the rule should be active (assume it's on a schedule, and the app
+ // doesn't listen to broadcasts so it doesn't know an override was present). This doesn't
+ // change the activation state.
+ mTestClock.setNow(Instant.ofEpochMilli(300));
+ mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId, CONDITION_TRUE,
+ ORIGIN_APP, CUSTOM_PKG_UID);
+
+ assertThat(getZenRule(ruleId).lastActivation).isEqualTo(firstActivation);
+ }
+
+ @Test
+ @EnableFlags({FLAG_MODES_UI, FLAG_MODES_CLEANUP_IMPLICIT})
+ public void addOrUpdateRule_doesNotUpdateLastActivation() {
+ AutomaticZenRule azr = new AutomaticZenRule.Builder("rule", CONDITION_ID)
+ .setConfigurationActivity(new ComponentName(mPkg, "cls"))
+ .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY)
+ .build();
+
+ String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, mPkg, azr,
+ ORIGIN_APP, "reason", CUSTOM_PKG_UID);
+
+ assertThat(getZenRule(ruleId).lastActivation).isNull();
+
+ mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, ruleId,
+ new AutomaticZenRule.Builder(azr).setName("New name").build(), ORIGIN_APP, "reason",
+ CUSTOM_PKG_UID);
+
+ assertThat(getZenRule(ruleId).lastActivation).isNull();
+ }
+
private static void addZenRule(ZenModeConfig config, String id, String ownerPkg, int zenMode,
@Nullable ZenPolicy zenPolicy) {
ZenRule rule = new ZenRule();
@@ -7272,22 +7497,27 @@
}
private static final Correspondence<ZenRule, ZenRule> IGNORE_METADATA =
- Correspondence.transforming(zr -> {
- Parcel p = Parcel.obtain();
- try {
- zr.writeToParcel(p, 0);
- p.setDataPosition(0);
- ZenRule copy = new ZenRule(p);
- copy.creationTime = 0;
- copy.userModifiedFields = 0;
- copy.zenPolicyUserModifiedFields = 0;
- copy.zenDeviceEffectsUserModifiedFields = 0;
- return copy;
- } finally {
- p.recycle();
- }
- },
- "Ignoring timestamp and userModifiedFields");
+ Correspondence.transforming(
+ ZenModeHelperTest::cloneWithoutMetadata,
+ ZenModeHelperTest::cloneWithoutMetadata,
+ "Ignoring timestamps and userModifiedFields");
+
+ private static ZenRule cloneWithoutMetadata(ZenRule rule) {
+ Parcel p = Parcel.obtain();
+ try {
+ rule.writeToParcel(p, 0);
+ p.setDataPosition(0);
+ ZenRule copy = new ZenRule(p);
+ copy.creationTime = 0;
+ copy.userModifiedFields = 0;
+ copy.zenPolicyUserModifiedFields = 0;
+ copy.zenDeviceEffectsUserModifiedFields = 0;
+ copy.lastActivation = null;
+ return copy;
+ } finally {
+ p.recycle();
+ }
+ }
private ZenRule expectedImplicitRule(String ownerPkg, int zenMode, ZenPolicy policy,
@Nullable Boolean conditionActive) {
@@ -7693,6 +7923,10 @@
return mNowMillis;
}
+ private void setNow(Instant instant) {
+ mNowMillis = instant.toEpochMilli();
+ }
+
private void setNowMillis(long millis) {
mNowMillis = millis;
}
diff --git a/services/tests/wmtests/res/values/styles.xml b/services/tests/wmtests/res/values/styles.xml
index 6857ff99..6ded2b5 100644
--- a/services/tests/wmtests/res/values/styles.xml
+++ b/services/tests/wmtests/res/values/styles.xml
@@ -21,4 +21,14 @@
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
</style>
+
+ <style name="ActivityWindowStyleTest">
+ <item name="android:windowIsTranslucent">true</item>
+ <item name="android:windowIsFloating">true</item>
+ <item name="android:windowShowWallpaper">true</item>
+ <item name="android:windowNoDisplay">true</item>
+ <item name="android:windowDisablePreview">true</item>
+ <item name="android:windowOptOutEdgeToEdgeEnforcement">true</item>
+ <item name="android:windowSplashScreenBehavior">icon_preferred</item>
+ </style>
</resources>
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
index 9e7575f..f5bda9f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
@@ -104,7 +104,6 @@
.setTask(mTrampolineActivity.getTask())
.setComponent(createRelative(DEFAULT_COMPONENT_PACKAGE_NAME, "TopActivity"))
.build();
- mTopActivity.mDisplayContent.mOpeningApps.add(mTopActivity);
mTransition = new Transition(TRANSIT_OPEN, 0 /* flags */,
mTopActivity.mTransitionController, createTestBLASTSyncEngine());
mTransition.mParticipants.add(mTopActivity);
@@ -485,7 +484,6 @@
@Test
public void testActivityDrawnWithoutTransition() {
- mTopActivity.mDisplayContent.mOpeningApps.remove(mTopActivity);
mTransition.mParticipants.remove(mTopActivity);
onIntentStarted(mTopActivity.intent);
notifyAndVerifyActivityLaunched(mTopActivity);
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index bb29614..6923dee 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -992,6 +992,25 @@
assertEquals(persistentSavedState, activity.getPersistentSavedState());
}
+ @Test
+ public void testReadWindowStyle() {
+ final ActivityRecord activity = new ActivityBuilder(mAtm).setActivityTheme(
+ com.android.frameworks.wmtests.R.style.ActivityWindowStyleTest).build();
+ assertTrue(activity.isNoDisplay());
+ assertTrue("Fill parent because showWallpaper", activity.mStyleFillsParent);
+
+ final ActivityRecord.WindowStyle style = mAtm.getWindowStyle(
+ activity.packageName, activity.info.theme, activity.mUserId);
+ assertNotNull(style);
+ assertTrue(style.isTranslucent());
+ assertTrue(style.isFloating());
+ assertTrue(style.showWallpaper());
+ assertTrue(style.noDisplay());
+ assertTrue(style.disablePreview());
+ assertTrue(style.optOutEdgeToEdge());
+ assertEquals(1 /* icon_preferred */, style.mSplashScreenBehavior);
+ }
+
/**
* Verify that activity finish request is not performed if activity is finishing or is in
* incorrect state.
@@ -3326,16 +3345,13 @@
makeWindowVisibleAndDrawn(app);
// Put the activity in close transition.
- mDisplayContent.mOpeningApps.clear();
- mDisplayContent.mClosingApps.add(app.mActivityRecord);
- mDisplayContent.prepareAppTransition(TRANSIT_CLOSE);
+ requestTransition(app.mActivityRecord, WindowManager.TRANSIT_CLOSE);
// Remove window during transition, so it is requested to hide, but won't be committed until
// the transition is finished.
app.mActivityRecord.onRemovedFromDisplay();
app.mActivityRecord.prepareSurfaces();
- assertTrue(mDisplayContent.mClosingApps.contains(app.mActivityRecord));
assertFalse(app.mActivityRecord.isVisibleRequested());
assertTrue(app.mActivityRecord.isVisible());
assertTrue(app.mActivityRecord.isSurfaceShowing());
@@ -3353,11 +3369,6 @@
makeWindowVisibleAndDrawn(app);
app.mActivityRecord.prepareSurfaces();
- // Put the activity in close transition.
- mDisplayContent.mOpeningApps.clear();
- mDisplayContent.mClosingApps.add(app.mActivityRecord);
- mDisplayContent.prepareAppTransition(TRANSIT_CLOSE);
-
// Commit visibility before start transition.
app.mActivityRecord.commitVisibility(false, false);
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java
index 3c74ad0..a9be47d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java
@@ -509,6 +509,32 @@
assertThat(mSupervisor.mOpaqueContainerHelper.isOpaque(rootTask)).isTrue();
}
+ @Test
+ public void testOpaque_nonLeafTaskFragmentWithDirectActivity_opaque() {
+ final ActivityRecord directChildActivity = new ActivityBuilder(mAtm).setCreateTask(true)
+ .build();
+ directChildActivity.setOccludesParent(true);
+ final Task nonLeafTask = directChildActivity.getTask();
+ final TaskFragment directChildFragment = new TaskFragment(mAtm, new Binder(),
+ true /* createdByOrganizer */, false /* isEmbedded */);
+ nonLeafTask.addChild(directChildFragment, 0);
+
+ assertThat(mSupervisor.mOpaqueContainerHelper.isOpaque(nonLeafTask)).isTrue();
+ }
+
+ @Test
+ public void testOpaque_nonLeafTaskFragmentWithDirectActivity_transparent() {
+ final ActivityRecord directChildActivity = new ActivityBuilder(mAtm).setCreateTask(true)
+ .build();
+ directChildActivity.setOccludesParent(false);
+ final Task nonLeafTask = directChildActivity.getTask();
+ final TaskFragment directChildFragment = new TaskFragment(mAtm, new Binder(),
+ true /* createdByOrganizer */, false /* isEmbedded */);
+ nonLeafTask.addChild(directChildFragment, 0);
+
+ assertThat(mSupervisor.mOpaqueContainerHelper.isOpaque(nonLeafTask)).isFalse();
+ }
+
@NonNull
private TaskFragment createChildTaskFragment(@NonNull Task parent,
@WindowConfiguration.WindowingMode int windowingMode,
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java
index 018ea58..d016e735 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java
@@ -151,6 +151,10 @@
doReturn(taskBounds).when(mTaskStack.top()).getBounds();
}
+ void configureTaskAppBounds(@NonNull Rect appBounds) {
+ mTaskStack.top().getWindowConfiguration().setAppBounds(appBounds);
+ }
+
void configureTopActivityBounds(@NonNull Rect activityBounds) {
doReturn(activityBounds).when(mActivityStack.top()).getBounds();
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatLetterboxPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatLetterboxPolicyTest.java
index 0c31032..2603d78 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppCompatLetterboxPolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatLetterboxPolicyTest.java
@@ -16,7 +16,9 @@
package com.android.server.wm;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.view.InsetsSource.FLAG_INSETS_ROUNDED_CORNER;
+import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
@@ -27,6 +29,7 @@
import static org.mockito.Mockito.mock;
import android.graphics.Rect;
+import android.platform.test.annotations.EnableFlags;
import android.platform.test.annotations.Presubmit;
import android.view.InsetsSource;
import android.view.InsetsState;
@@ -40,6 +43,7 @@
import androidx.test.filters.SmallTest;
import com.android.internal.R;
+import com.android.window.flags.Flags;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -225,6 +229,53 @@
});
}
+ @Test
+ @EnableFlags(Flags.FLAG_EXCLUDE_CAPTION_FROM_APP_BOUNDS)
+ public void testGetRoundedCornersRadius_letterboxBoundsMatchHeightInFreeform_notRounded() {
+ runTestScenario((robot) -> {
+ robot.conf().setLetterboxActivityCornersRadius(15);
+ robot.configureWindowState();
+ robot.activity().createActivityWithComponent();
+ robot.setTopActivityInLetterboxAnimation(/* inLetterboxAnimation */ false);
+ robot.activity().setTopActivityVisible(/* isVisible */ true);
+ robot.setIsLetterboxedForFixedOrientationAndAspectRatio(/* inLetterbox */ true);
+ robot.conf().setLetterboxActivityCornersRounded(/* rounded */ true);
+ robot.resources().configureGetDimensionPixelSize(R.dimen.taskbar_frame_height, 20);
+
+ robot.activity().setTaskWindowingMode(WINDOWING_MODE_FREEFORM);
+ final Rect appBounds = new Rect(0, 0, 100, 500);
+ robot.configureWindowStateFrame(appBounds);
+ robot.activity().configureTaskAppBounds(appBounds);
+
+ robot.startLetterbox();
+
+ robot.checkWindowStateRoundedCornersRadius(/* expected */ 0);
+ });
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_EXCLUDE_CAPTION_FROM_APP_BOUNDS)
+ public void testGetRoundedCornersRadius_letterboxBoundsNotMatchHeightInFreeform_rounded() {
+ runTestScenario((robot) -> {
+ robot.conf().setLetterboxActivityCornersRadius(15);
+ robot.configureWindowState();
+ robot.activity().createActivityWithComponent();
+ robot.setTopActivityInLetterboxAnimation(/* inLetterboxAnimation */ false);
+ robot.activity().setTopActivityVisible(/* isVisible */ true);
+ robot.setIsLetterboxedForFixedOrientationAndAspectRatio(/* inLetterbox */ true);
+ robot.conf().setLetterboxActivityCornersRounded(/* rounded */ true);
+ robot.resources().configureGetDimensionPixelSize(R.dimen.taskbar_frame_height, 20);
+
+ robot.activity().setTaskWindowingMode(WINDOWING_MODE_FREEFORM);
+ robot.configureWindowStateFrame(new Rect(0, 0, 500, 200));
+ robot.activity().configureTaskAppBounds(new Rect(0, 0, 500, 500));
+
+ robot.startLetterbox();
+
+ robot.checkWindowStateRoundedCornersRadius(/* expected */ 15);
+ });
+ }
+
/**
* Runs a test scenario providing a Robot.
*/
@@ -265,6 +316,10 @@
spyOn(getTransparentPolicy());
}
+ void startLetterbox() {
+ getAppCompatLetterboxPolicy().start(mWindowState);
+ }
+
void configureWindowStateWithTaskBar(boolean hasInsetsRoundedCorners) {
configureWindowState(/* withTaskBar */ true, hasInsetsRoundedCorners);
}
@@ -273,6 +328,10 @@
configureWindowState(/* withTaskBar */ false, /* hasInsetsRoundedCorners */ false);
}
+ void configureWindowStateFrame(@NonNull Rect frame) {
+ doReturn(frame).when(mWindowState).getFrame();
+ }
+
void configureInsetsRoundedCorners(@NonNull RoundedCorners roundedCorners) {
mInsetsState.setRoundedCorners(roundedCorners);
}
@@ -290,6 +349,7 @@
}
mWindowState.mInvGlobalScale = 1f;
final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams();
+ attrs.type = TYPE_BASE_APPLICATION;
doReturn(mInsetsState).when(mWindowState).getInsetsState();
doReturn(attrs).when(mWindowState).getAttrs();
doReturn(true).when(mWindowState).isDrawn();
diff --git a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
index fbb123e..e081971 100644
--- a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
@@ -294,6 +294,14 @@
backNavigationInfo = startBackNavigation();
assertThat(typeToString(backNavigationInfo.getType()))
.isEqualTo(typeToString(BackNavigationInfo.TYPE_CROSS_ACTIVITY));
+
+ // reset drawing status, test previous activity has no process.
+ backNavigationInfo.onBackNavigationFinished(false);
+ mBackNavigationController.clearBackAnimations(true);
+ doReturn(false).when(testCase.recordBack).hasProcess();
+ backNavigationInfo = startBackNavigation();
+ assertThat(typeToString(backNavigationInfo.getType()))
+ .isEqualTo(typeToString(BackNavigationInfo.TYPE_CALLBACK));
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/DesktopModeHelperTest.java b/services/tests/wmtests/src/com/android/server/wm/DesktopModeHelperTest.java
index e6c3fb3..1e91bed 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DesktopModeHelperTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DesktopModeHelperTest.java
@@ -16,8 +16,6 @@
package com.android.server.wm;
-import static android.provider.Settings.Global.DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES;
-
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doReturn;
@@ -30,7 +28,6 @@
import android.platform.test.annotations.EnableFlags;
import android.platform.test.annotations.Presubmit;
import android.platform.test.flag.junit.SetFlagsRule;
-import android.provider.Settings;
import android.window.DesktopModeFlags;
import androidx.test.filters.SmallTest;
@@ -74,14 +71,12 @@
doReturn(mContext.getContentResolver()).when(mMockContext).getContentResolver();
resetDesktopModeFlagsCache();
resetEnforceDeviceRestriction();
- resetFlagOverride();
}
@After
public void tearDown() throws Exception {
resetDesktopModeFlagsCache();
resetEnforceDeviceRestriction();
- resetFlagOverride();
}
@DisableFlags({Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE,
@@ -167,7 +162,8 @@
@DisableFlags(Flags.FLAG_ENABLE_DESKTOP_MODE_THROUGH_DEV_OPTION)
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
@Test
- public void canEnterDesktopMode_DWFlagEnabled_configDevOptionOn_flagOverrideOn_returnsTrue() {
+ public void canEnterDesktopMode_DWFlagEnabled_configDevOptionOn_flagOverrideOn_returnsTrue()
+ throws Exception {
doReturn(true).when(mMockResources).getBoolean(
eq(R.bool.config_isDesktopModeDevOptionSupported)
);
@@ -246,13 +242,10 @@
cachedToggleOverride.set(/* obj= */ null, /* value= */ null);
}
- private void resetFlagOverride() {
- Settings.Global.putString(mContext.getContentResolver(),
- DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES, null);
- }
-
- private void setFlagOverride(DesktopModeFlags.ToggleOverride override) {
- Settings.Global.putInt(mContext.getContentResolver(),
- DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES, override.getSetting());
+ private void setFlagOverride(DesktopModeFlags.ToggleOverride override) throws Exception {
+ Field cachedToggleOverride = DesktopModeFlags.class.getDeclaredField(
+ "sCachedToggleOverride");
+ cachedToggleOverride.setAccessible(true);
+ cachedToggleOverride.set(/* obj= */ null, /* value= */ override);
}
}
\ No newline at end of file
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index 82435b2..d5b9751 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -164,6 +164,7 @@
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
+import java.util.function.BooleanSupplier;
/**
* Tests for the {@link DisplayContent} class.
@@ -1799,8 +1800,7 @@
final ActivityRecord app = new ActivityBuilder(mAtm).setCreateTask(true).build();
app.setVisible(false);
app.setState(ActivityRecord.State.RESUMED, "test");
- mDisplayContent.prepareAppTransition(WindowManager.TRANSIT_OPEN);
- mDisplayContent.mOpeningApps.add(app);
+ requestTransition(app, WindowManager.TRANSIT_OPEN);
final int newOrientation = getRotatedOrientation(mDisplayContent);
app.setRequestedOrientation(newOrientation);
@@ -2674,16 +2674,67 @@
public void testKeyguardGoingAwayWhileAodShown() {
mDisplayContent.getDisplayPolicy().setAwake(true);
- final WindowState appWin = newWindowBuilder("appWin", TYPE_APPLICATION).setDisplay(
- mDisplayContent).build();
- final ActivityRecord activity = appWin.mActivityRecord;
+ final KeyguardController keyguard = mAtm.mKeyguardController;
+ final ActivityRecord activity = new ActivityBuilder(mAtm).setCreateTask(true).build();
+ final int displayId = mDisplayContent.getDisplayId();
- mAtm.mKeyguardController.setKeyguardShown(appWin.getDisplayId(), true /* keyguardShowing */,
- true /* aodShowing */);
- assertFalse(activity.isVisibleRequested());
+ final BooleanSupplier keyguardShowing = () -> keyguard.isKeyguardShowing(displayId);
+ final BooleanSupplier keyguardGoingAway = () -> keyguard.isKeyguardGoingAway(displayId);
+ final BooleanSupplier appVisible = activity::isVisibleRequested;
- mAtm.mKeyguardController.keyguardGoingAway(appWin.getDisplayId(), 0 /* flags */);
- assertTrue(activity.isVisibleRequested());
+ // Begin locked and in AOD
+ keyguard.setKeyguardShown(displayId, true /* keyguard */, true /* aod */);
+ assertFalse(keyguardGoingAway.getAsBoolean());
+ assertFalse(appVisible.getAsBoolean());
+
+ // Start unlocking from AOD.
+ keyguard.keyguardGoingAway(displayId, 0x0 /* flags */);
+ assertTrue(keyguardGoingAway.getAsBoolean());
+ assertTrue(appVisible.getAsBoolean());
+
+ // Clear AOD. This does *not* clear the going-away status.
+ keyguard.setKeyguardShown(displayId, true /* keyguard */, false /* aod */);
+ assertTrue(keyguardGoingAway.getAsBoolean());
+ assertTrue(appVisible.getAsBoolean());
+
+ // Finish unlock
+ keyguard.setKeyguardShown(displayId, false /* keyguard */, false /* aod */);
+ assertFalse(keyguardGoingAway.getAsBoolean());
+ assertTrue(appVisible.getAsBoolean());
+ }
+
+ @Test
+ public void testKeyguardGoingAwayCanceledWhileAodShown() {
+ mDisplayContent.getDisplayPolicy().setAwake(true);
+
+ final KeyguardController keyguard = mAtm.mKeyguardController;
+ final ActivityRecord activity = new ActivityBuilder(mAtm).setCreateTask(true).build();
+ final int displayId = mDisplayContent.getDisplayId();
+
+ final BooleanSupplier keyguardShowing = () -> keyguard.isKeyguardShowing(displayId);
+ final BooleanSupplier keyguardGoingAway = () -> keyguard.isKeyguardGoingAway(displayId);
+ final BooleanSupplier appVisible = activity::isVisibleRequested;
+
+ // Begin locked and in AOD
+ keyguard.setKeyguardShown(displayId, true /* keyguard */, true /* aod */);
+ assertFalse(keyguardGoingAway.getAsBoolean());
+ assertFalse(appVisible.getAsBoolean());
+
+ // Start unlocking from AOD.
+ keyguard.keyguardGoingAway(displayId, 0x0 /* flags */);
+ assertTrue(keyguardGoingAway.getAsBoolean());
+ assertTrue(appVisible.getAsBoolean());
+
+ // Clear AOD. This does *not* clear the going-away status.
+ keyguard.setKeyguardShown(displayId, true /* keyguard */, false /* aod */);
+ assertTrue(keyguardGoingAway.getAsBoolean());
+ assertTrue(appVisible.getAsBoolean());
+
+ // Same API call a second time cancels the unlock, because AOD isn't changing.
+ keyguard.setKeyguardShown(displayId, true /* keyguard */, false /* aod */);
+ assertTrue(keyguardShowing.getAsBoolean());
+ assertFalse(keyguardGoingAway.getAsBoolean());
+ assertFalse(appVisible.getAsBoolean());
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
index 7ab55bf..cc2a76d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
@@ -189,11 +189,12 @@
doReturn(true).when(mTaskFragment).isVisible();
doReturn(true).when(mTaskFragment).isVisibleRequested();
+ spyOn(mTaskFragment.mTransitionController);
clearInvocations(mTransaction);
mTaskFragment.setBounds(endBounds);
// No change transition, but update the organized surface position.
- verify(mTaskFragment, never()).initializeChangeTransition(any(), any());
+ verify(mTaskFragment.mTransitionController, never()).collectVisibleChange(any());
verify(mTransaction).setPosition(mLeash, endBounds.left, endBounds.top);
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
index edffab8..cee98fb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
@@ -409,17 +409,6 @@
}
@Test
- public void testIsAnimating_TransitionFlag() {
- final TestWindowContainerBuilder builder = new TestWindowContainerBuilder(mWm);
- final TestWindowContainer root = builder.setLayer(0).build();
- final TestWindowContainer child1 = root.addChildWindow(
- builder.setWaitForTransitionStart(true));
-
- assertFalse(root.isAnimating(TRANSITION));
- assertTrue(child1.isAnimating(TRANSITION));
- }
-
- @Test
public void testIsAnimating_ParentsFlag() {
final TestWindowContainerBuilder builder = new TestWindowContainerBuilder(mWm);
final TestWindowContainer root = builder.setLayer(0).build();
@@ -1655,7 +1644,7 @@
};
TestWindowContainer(WindowManagerService wm, int layer, boolean isAnimating,
- boolean isVisible, boolean waitTransitStart, Integer orientation, WindowState ws) {
+ boolean isVisible, Integer orientation, WindowState ws) {
super(wm);
mLayer = layer;
@@ -1663,7 +1652,6 @@
mIsVisible = isVisible;
mFillsParent = true;
mOrientation = orientation;
- mWaitForTransitStart = waitTransitStart;
mWindowState = ws;
spyOn(mSurfaceAnimator);
doReturn(mIsAnimating).when(mSurfaceAnimator).isAnimating();
@@ -1729,11 +1717,6 @@
}
@Override
- boolean isWaitingForTransitionStart() {
- return mWaitForTransitStart;
- }
-
- @Override
WindowState asWindowState() {
return mWindowState;
}
@@ -1744,7 +1727,6 @@
private int mLayer;
private boolean mIsAnimating;
private boolean mIsVisible;
- private boolean mIsWaitTransitStart;
private Integer mOrientation;
private WindowState mWindowState;
@@ -1782,14 +1764,9 @@
return this;
}
- TestWindowContainerBuilder setWaitForTransitionStart(boolean waitTransitStart) {
- mIsWaitTransitStart = waitTransitStart;
- return this;
- }
-
TestWindowContainer build() {
return new TestWindowContainer(mWm, mLayer, mIsAnimating, mIsVisible,
- mIsWaitTransitStart, mOrientation, mWindowState);
+ mOrientation, mWindowState);
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
index 1dfb20a..d228970 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
@@ -19,6 +19,7 @@
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.content.pm.ActivityInfo.INSETS_DECOUPLED_CONFIGURATION_ENFORCED;
+import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_INSETS_DECOUPLED_CONFIGURATION;
import static android.content.res.Configuration.GRAMMATICAL_GENDER_NOT_SPECIFIED;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
@@ -33,9 +34,11 @@
import static com.android.server.wm.ActivityRecord.State.STARTED;
import static com.android.server.wm.ActivityRecord.State.STOPPED;
import static com.android.server.wm.ActivityRecord.State.STOPPING;
+import static com.android.server.wm.ConfigurationContainer.applySizeOverrideIfNeeded;
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;
@@ -58,6 +61,7 @@
import android.graphics.Rect;
import android.os.LocaleList;
import android.os.RemoteException;
+import android.platform.test.annotations.EnableFlags;
import android.platform.test.annotations.Presubmit;
import org.junit.Before;
@@ -453,6 +457,56 @@
assertEquals(topDisplayArea, mWpc.getTopActivityDisplayArea());
}
+ @Test
+ @EnableFlags(com.android.window.flags.Flags.FLAG_INSETS_DECOUPLED_CONFIGURATION)
+ public void testOverrideConfigurationApplied() {
+ final DisplayContent displayContent = new TestDisplayContent.Builder(mAtm, 1000, 1500)
+ .setSystemDecorations(true).setDensityDpi(160).build();
+ final DisplayPolicy displayPolicy = displayContent.getDisplayPolicy();
+ // Setup the decor insets info.
+ final DisplayPolicy.DecorInsets.Info decorInsetsInfo = new DisplayPolicy.DecorInsets.Info();
+ final Rect emptyRect = new Rect();
+ decorInsetsInfo.mNonDecorInsets.set(emptyRect);
+ decorInsetsInfo.mConfigInsets.set(emptyRect);
+ decorInsetsInfo.mOverrideConfigInsets.set(new Rect(0, 100, 0, 200));
+ decorInsetsInfo.mOverrideNonDecorInsets.set(new Rect(0, 0, 0, 200));
+ decorInsetsInfo.mNonDecorFrame.set(new Rect(0, 0, 1000, 1500));
+ decorInsetsInfo.mConfigFrame.set(new Rect(0, 0, 1000, 1500));
+ decorInsetsInfo.mOverrideConfigFrame.set(new Rect(0, 100, 1000, 1300));
+ decorInsetsInfo.mOverrideNonDecorFrame.set(new Rect(0, 0, 1000, 1300));
+ doReturn(decorInsetsInfo).when(displayPolicy)
+ .getDecorInsetsInfo(anyInt(), anyInt(), anyInt());
+
+ final Configuration newParentConfig = displayContent.getConfiguration();
+ final Configuration resolvedConfig = new Configuration();
+
+ // Mock the app info to not enforce the decoupled configuration to apply the override.
+ final ApplicationInfo appInfo = mock(ApplicationInfo.class);
+ doReturn(false).when(appInfo)
+ .isChangeEnabled(INSETS_DECOUPLED_CONFIGURATION_ENFORCED);
+ doReturn(false).when(appInfo)
+ .isChangeEnabled(OVERRIDE_ENABLE_INSETS_DECOUPLED_CONFIGURATION);
+
+ // No value should be set before override.
+ assertNull(resolvedConfig.windowConfiguration.getAppBounds());
+ applySizeOverrideIfNeeded(
+ displayContent,
+ appInfo,
+ newParentConfig,
+ resolvedConfig,
+ false /* optsOutEdgeToEdge */,
+ false /* hasFixedRotationTransform */,
+ false /* hasCompatDisplayInsets */,
+ null /* task */);
+
+ // Assert the override config insets are applied.
+ // Status bars, and all non-decor insets should be deducted for the config screen size.
+ assertEquals(1200, resolvedConfig.screenHeightDp);
+ // Only the non-decor insets should be deducted for the app bounds.
+ assertNotNull(resolvedConfig.windowConfiguration.getAppBounds());
+ assertEquals(1300, resolvedConfig.windowConfiguration.getAppBounds().height());
+ }
+
private TestDisplayContent createTestDisplayContentInContainer() {
return new TestDisplayContent.Builder(mAtm, 1000, 1500).build();
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/utils/WindowStyleCacheTest.java b/services/tests/wmtests/src/com/android/server/wm/utils/WindowStyleCacheTest.java
new file mode 100644
index 0000000..57a3401
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/utils/WindowStyleCacheTest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2025 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.wm.utils;
+
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertSame;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.internal.policy.AttributeCache;
+
+import org.junit.Test;
+
+/**
+ * Build/Install/Run:
+ * atest WmTests:WindowStyleCacheTest
+ */
+@SmallTest
+@Presubmit
+public class WindowStyleCacheTest {
+
+ @Test
+ public void testCache() {
+ final Context context = getInstrumentation().getContext();
+ AttributeCache.init(context);
+ final WindowStyleCache<TestStyle> cache = new WindowStyleCache<>(TestStyle::new);
+ final String packageName = context.getPackageName();
+ final int theme = com.android.frameworks.wmtests.R.style.ActivityWindowStyleTest;
+ final int userId = context.getUserId();
+ final TestStyle style = cache.get(packageName, theme, userId);
+ assertNotNull(style);
+ assertSame(style, cache.get(packageName, theme, userId));
+
+ cache.invalidatePackage(packageName);
+ assertNotSame(style, cache.get(packageName, theme, userId));
+ }
+
+ private static class TestStyle {
+ TestStyle(TypedArray array) {
+ }
+ }
+}
diff --git a/services/usb/java/com/android/server/usb/UsbService.java b/services/usb/java/com/android/server/usb/UsbService.java
index ec4f7e1..4395b76 100644
--- a/services/usb/java/com/android/server/usb/UsbService.java
+++ b/services/usb/java/com/android/server/usb/UsbService.java
@@ -52,6 +52,7 @@
import android.os.Looper;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
+import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
import android.service.usb.UsbServiceDumpProto;
@@ -694,6 +695,11 @@
return (getCurrentFunctions() & UsbManager.usbFunctionsFromString(function)) != 0;
}
+ @Override
+ public boolean isUvcGadgetSupportEnabled() {
+ return SystemProperties.getBoolean("ro.usb.uvc.enabled", false);
+ }
+
@android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_USB)
@Override
public long getCurrentFunctions() {
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 1a932859..58833e8 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -9786,7 +9786,6 @@
* <p>
* This config is empty by default.
*/
- @FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
public static final String KEY_CARRIER_SUPPORTED_SATELLITE_SERVICES_PER_PROVIDER_BUNDLE =
"carrier_supported_satellite_services_per_provider_bundle";
@@ -9826,7 +9825,6 @@
*
* The default value is false.
*/
- @FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
public static final String KEY_SATELLITE_ATTACH_SUPPORTED_BOOL =
"satellite_attach_supported_bool";
@@ -9848,7 +9846,6 @@
* <p>
* The default value is 180 seconds.
*/
- @FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
public static final String KEY_SATELLITE_CONNECTION_HYSTERESIS_SEC_INT =
"satellite_connection_hysteresis_sec_int";
@@ -9863,7 +9860,6 @@
* See SignalStrength#MAX_LTE_RSRP and SignalStrength#MIN_LTE_RSRP. Any signal level outside
* these boundaries is considered invalid.
*/
- @FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
public static final String KEY_NTN_LTE_RSRP_THRESHOLDS_INT_ARRAY =
"ntn_lte_rsrp_thresholds_int_array";
@@ -9883,7 +9879,6 @@
* This key is considered invalid if the format is violated. If the key is invalid or
* not configured, a default value set will apply.
*/
- @FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
public static final String KEY_NTN_LTE_RSRQ_THRESHOLDS_INT_ARRAY =
"ntn_lte_rsrq_thresholds_int_array";
@@ -9901,7 +9896,6 @@
* This key is considered invalid if the format is violated. If the key is invalid or
* not configured, a default value set will apply.
*/
- @FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
public static final String KEY_NTN_LTE_RSSNR_THRESHOLDS_INT_ARRAY =
"ntn_lte_rssnr_thresholds_int_array";
@@ -9926,7 +9920,6 @@
* If the key is invalid or not configured, a default value (RSRP = 1 << 0) will apply.
*
*/
- @FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
public static final String KEY_PARAMETERS_USED_FOR_NTN_LTE_SIGNAL_BAR_INT =
"parameters_used_for_ntn_lte_signal_bar_int";
@@ -10018,7 +10011,6 @@
*
* The default value is 7 days.
*/
- @FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
public static final String KEY_SATELLITE_ENTITLEMENT_STATUS_REFRESH_DAYS_INT =
"satellite_entitlement_status_refresh_days_int";
@@ -10029,7 +10021,6 @@
*
* The default value is false.
*/
- @FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
public static final String KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL =
"satellite_entitlement_supported_bool";
diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java
index 0c324e6..7de0a2a 100644
--- a/telephony/java/android/telephony/NetworkRegistrationInfo.java
+++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java
@@ -209,7 +209,6 @@
/**
* MMS service
*/
- @FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
public static final int SERVICE_TYPE_MMS = 6;
/** @hide */
@@ -713,7 +712,6 @@
*
* @return {@code true} if network is a non-terrestrial network else {@code false}.
*/
- @FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
public boolean isNonTerrestrialNetwork() {
return mIsNonTerrestrialNetwork;
}
@@ -1198,7 +1196,6 @@
* else {@code false}.
* @return The builder.
*/
- @FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
public @NonNull Builder setIsNonTerrestrialNetwork(boolean isNonTerrestrialNetwork) {
mIsNonTerrestrialNetwork = isNonTerrestrialNetwork;
return this;
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 127bbff..35dd8b2 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -16,7 +16,6 @@
package android.telephony;
-import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -36,7 +35,6 @@
import android.telephony.NetworkRegistrationInfo.NRState;
import android.text.TextUtils;
-import com.android.internal.telephony.flags.Flags;
import com.android.telephony.Rlog;
import java.lang.annotation.Retention;
@@ -2262,7 +2260,6 @@
*
* @return {@code true} if device is connected to a non-terrestrial network else {@code false}.
*/
- @FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
public boolean isUsingNonTerrestrialNetwork() {
synchronized (mNetworkRegistrationInfos) {
for (NetworkRegistrationInfo nri : mNetworkRegistrationInfos) {
diff --git a/telephony/java/android/telephony/TelephonyDisplayInfo.java b/telephony/java/android/telephony/TelephonyDisplayInfo.java
index bb4ce6e..4411873 100644
--- a/telephony/java/android/telephony/TelephonyDisplayInfo.java
+++ b/telephony/java/android/telephony/TelephonyDisplayInfo.java
@@ -16,15 +16,12 @@
package android.telephony;
-import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.os.Parcel;
import android.os.Parcelable;
import android.telephony.Annotation.NetworkType;
import android.telephony.Annotation.OverrideNetworkType;
-import com.android.internal.telephony.flags.Flags;
-
import java.util.Objects;
/**
@@ -97,10 +94,8 @@
private final boolean mIsRoaming;
- @FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
private final boolean mIsNtn;
- @FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
private final boolean mIsSatelliteConstrainedData;
/**
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 504605d..41569de 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -7080,7 +7080,8 @@
*/
@Deprecated
public boolean isVoiceCapable() {
- return hasCapability(PackageManager.FEATURE_TELEPHONY_CALLING,
+ if (mContext == null) return true;
+ return mContext.getResources().getBoolean(
com.android.internal.R.bool.config_voice_capable);
}
@@ -7104,7 +7105,8 @@
* @see SubscriptionInfo#getServiceCapabilities()
*/
public boolean isDeviceVoiceCapable() {
- return isVoiceCapable();
+ return hasCapability(PackageManager.FEATURE_TELEPHONY_CALLING,
+ com.android.internal.R.bool.config_voice_capable);
}
/**
diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java
index 22624e2..7eb1eb9 100644
--- a/telephony/java/android/telephony/data/ApnSetting.java
+++ b/telephony/java/android/telephony/data/ApnSetting.java
@@ -126,7 +126,6 @@
/** APN type for ENTERPRISE. */
public static final int TYPE_ENTERPRISE = ApnTypes.ENTERPRISE;
/** APN type for RCS (Rich Communication Services). */
- @FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
public static final int TYPE_RCS = ApnTypes.RCS;
/** APN type for OEM_PAID networks (Automotive PANS) */
@FlaggedApi(Flags.FLAG_OEM_PAID_PRIVATE)
@@ -379,7 +378,6 @@
* modem components or carriers. Non-system apps should use the integer variants instead.
* @hide
*/
- @FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
@SystemApi
public static final String TYPE_RCS_STRING = "rcs";
diff --git a/telephony/java/android/telephony/satellite/SatelliteManager.java b/telephony/java/android/telephony/satellite/SatelliteManager.java
index b7b209b..1309654 100644
--- a/telephony/java/android/telephony/satellite/SatelliteManager.java
+++ b/telephony/java/android/telephony/satellite/SatelliteManager.java
@@ -755,7 +755,6 @@
* @hide
*/
@SystemApi
- @FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
public static final int EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T911 = 2;
/**
@@ -821,6 +820,25 @@
"android.telephony.METADATA_SATELLITE_MANUAL_CONNECT_P2P_SUPPORT";
/**
+ * A boolean value indicating whether application is optimized to utilize low bandwidth
+ * satellite data.
+ * The applications that are optimized for low bandwidth satellite data should set this
+ * property to {@code true} in the manifest to indicate to platform about the same.
+ * {@code
+ * <application>
+ * <meta-data
+ * android:name="android.telephony.PROPERTY_SATELLITE_DATA_OPTIMIZED"
+ * android:value="true"/>
+ * </application>
+ * }
+ * <p>
+ * When {@code true}, satellite data optimized network is available for applications.
+ */
+ @FlaggedApi(Flags.FLAG_SATELLITE_25Q4_APIS)
+ public static final String PROPERTY_SATELLITE_DATA_OPTIMIZED =
+ "android.telephony.PROPERTY_SATELLITE_DATA_OPTIMIZED";
+
+ /**
* Registers a {@link SatelliteStateChangeListener} to receive callbacks when the satellite
* state may have changed.
*
@@ -1555,7 +1573,6 @@
* @hide
*/
@SystemApi
- @FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
public static final int SATELLITE_COMMUNICATION_RESTRICTION_REASON_GEOLOCATION = 1;
/**
@@ -1565,7 +1582,6 @@
* @hide
*/
@SystemApi
- @FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
public static final int SATELLITE_COMMUNICATION_RESTRICTION_REASON_ENTITLEMENT = 2;
/** @hide */
@@ -2738,7 +2754,6 @@
*/
@SystemApi
@RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
- @FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
public void requestAttachEnabledForCarrier(int subId, boolean enableSatellite,
@NonNull @CallbackExecutor Executor executor,
@SatelliteResult @NonNull Consumer<Integer> resultListener) {
@@ -2775,7 +2790,6 @@
*/
@SystemApi
@RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
- @FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
public void requestIsAttachEnabledForCarrier(int subId,
@NonNull @CallbackExecutor Executor executor,
@NonNull OutcomeReceiver<Boolean, SatelliteException> callback) {
@@ -2803,7 +2817,6 @@
*/
@SystemApi
@RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
- @FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
public void addAttachRestrictionForCarrier(int subId,
@SatelliteCommunicationRestrictionReason int reason,
@NonNull @CallbackExecutor Executor executor,
@@ -2851,7 +2864,6 @@
*/
@SystemApi
@RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
- @FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
public void removeAttachRestrictionForCarrier(int subId,
@SatelliteCommunicationRestrictionReason int reason,
@NonNull @CallbackExecutor Executor executor,
@@ -2899,7 +2911,6 @@
@SystemApi
@RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
@SatelliteCommunicationRestrictionReason
- @FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
@NonNull public Set<Integer> getAttachRestrictionReasonsForCarrier(int subId) {
if (!SubscriptionManager.isValidSubscriptionId(subId)) {
throw new IllegalArgumentException("Invalid subscription ID");
@@ -3298,7 +3309,6 @@
*/
@SystemApi
@RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
- @FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
@NonNull public List<String> getSatellitePlmnsForCarrier(int subId) {
if (!SubscriptionManager.isValidSubscriptionId(subId)) {
throw new IllegalArgumentException("Invalid subscription ID");
@@ -3840,6 +3850,35 @@
}
}
+ /**
+ * Get list of application packages name that are optimized for low bandwidth satellite data.
+ *
+ * @return List of application packages name with data optimized network property.
+ *
+ * {@link #PROPERTY_SATELLITE_DATA_OPTIMIZED}
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+ @FlaggedApi(Flags.FLAG_SATELLITE_25Q4_APIS)
+ public @NonNull List<String> getSatelliteDataOptimizedApps() {
+ List<String> appsNames = new ArrayList<>();
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null) {
+ appsNames = telephony.getSatelliteDataOptimizedApps();
+ } else {
+ throw new IllegalStateException("telephony service is null.");
+ }
+ } catch (RemoteException ex) {
+ loge("getSatelliteDataOptimizedApps() RemoteException:" + ex);
+ ex.rethrowAsRuntimeException();
+ }
+
+ return appsNames;
+ }
+
@Nullable
private static ITelephony getITelephony() {
ITelephony binder = ITelephony.Stub.asInterface(TelephonyFrameworkInitializer
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 08c0030..1c6652d 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -3596,4 +3596,15 @@
* @hide
*/
int getCarrierIdFromIdentifier(in CarrierIdentifier carrierIdentifier);
+
+
+ /**
+ * Get list of applications that are optimized for low bandwidth satellite data.
+ *
+ * @return List of Application Name with data optimized network property.
+ * {@link #PROPERTY_SATELLITE_DATA_OPTIMIZED}
+ */
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+ + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+ List<String> getSatelliteDataOptimizedApps();
}
diff --git a/tests/AppJankTest/res/values/strings.xml b/tests/AppJankTest/res/values/strings.xml
new file mode 100644
index 0000000..ab2d18f
--- /dev/null
+++ b/tests/AppJankTest/res/values/strings.xml
@@ -0,0 +1,3 @@
+<resources>
+ <string name="continue_test">Continue Test</string>
+</resources>
\ 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
index fe9f636..3498974 100644
--- a/tests/AppJankTest/src/android/app/jank/tests/IntegrationTests.java
+++ b/tests/AppJankTest/src/android/app/jank/tests/IntegrationTests.java
@@ -209,7 +209,8 @@
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);
+ mDevice.wait(Until.findObject(By.text(mEmptyActivity.getString(R.string.continue_test))),
+ WAIT_FOR_TIMEOUT_MS);
assertTrue(jankTracker.shouldTrack());
}
diff --git a/tests/AppJankTest/src/android/app/jank/tests/JankTrackerActivity.java b/tests/AppJankTest/src/android/app/jank/tests/JankTrackerActivity.java
index 80ab6ad3..6867582 100644
--- a/tests/AppJankTest/src/android/app/jank/tests/JankTrackerActivity.java
+++ b/tests/AppJankTest/src/android/app/jank/tests/JankTrackerActivity.java
@@ -18,15 +18,41 @@
import android.app.Activity;
import android.os.Bundle;
+import android.widget.EditText;
public class JankTrackerActivity extends Activity {
+ private static final int CONTINUE_TEST_DELAY_MS = 4000;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.jank_tracker_activity_layout);
}
+
+ /**
+ * In IntegrationTests#jankTrackingResumed_whenActivityBecomesVisibleAgain this activity is
+ * placed into the background and then resumed via an intent. The test waits until the
+ * `continue_test` string is visible on the screen before validating that Jank tracking has
+ * resumed.
+ *
+ * <p>The 4 second delay allows JankTracker to re-register its callbacks and start receiving
+ * JankData before the test proceeds.
+ */
+ @Override
+ protected void onResume() {
+ super.onResume();
+ getActivityThread().getHandler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ EditText editTextView = findViewById(R.id.edit_text);
+ if (editTextView != null) {
+ editTextView.setText(R.string.continue_test);
+ }
+ }
+ }, CONTINUE_TEST_DELAY_MS);
+ }
}
diff --git a/tests/Internal/Android.bp b/tests/Internal/Android.bp
index e294da1..3556406 100644
--- a/tests/Internal/Android.bp
+++ b/tests/Internal/Android.bp
@@ -45,6 +45,7 @@
"junit",
"androidx.test.rules",
"platform-test-annotations",
+ "truth",
],
manifest: "ApplicationSharedMemoryTest32/AndroidManifest.xml",
test_config: "ApplicationSharedMemoryTest32/AndroidTest.xml",
diff --git a/tests/Internal/src/com/android/internal/os/ApplicationSharedMemoryTest.java b/tests/Internal/src/com/android/internal/os/ApplicationSharedMemoryTest.java
index d03ad5c..5ce0ede 100644
--- a/tests/Internal/src/com/android/internal/os/ApplicationSharedMemoryTest.java
+++ b/tests/Internal/src/com/android/internal/os/ApplicationSharedMemoryTest.java
@@ -16,24 +16,24 @@
package com.android.internal.os;
-import java.io.IOException;
+import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assert.fail;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
import static org.junit.Assume.assumeTrue;
import android.platform.test.annotations.Presubmit;
import androidx.test.filters.SmallTest;
+import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
-import org.junit.Before;
import java.io.FileDescriptor;
+import java.io.IOException;
/** Tests for {@link TimeoutRecord}. */
@SmallTest
@@ -77,6 +77,8 @@
try {
instance.setLatestNetworkTimeUnixEpochMillisAtZeroElapsedRealtimeMillis(17);
fail("Attempted mutation in an app process should throw");
+ instance.writeSystemFeaturesCache(new int[] {1, 2, 3, 4, 5});
+ fail("Attempted feature mutation in an app process should throw");
} catch (Exception expected) {
}
}
@@ -121,4 +123,56 @@
} catch (Exception expected) {
}
}
+
+ /** If system feature caching is enabled, it should be auto-written into app shared memory. */
+ @Test
+ public void canReadSystemFeatures() throws IOException {
+ assumeTrue(android.content.pm.Flags.cacheSdkSystemFeatures());
+ ApplicationSharedMemory instance = ApplicationSharedMemory.getInstance();
+ assertThat(instance.readSystemFeaturesCache()).isNotEmpty();
+ }
+
+ @Test
+ public void systemFeaturesShareMemory() throws IOException {
+ ApplicationSharedMemory instance1 = ApplicationSharedMemory.create();
+
+ int[] featureVersions = new int[] {1, 2, 3, 4, 5};
+ instance1.writeSystemFeaturesCache(featureVersions);
+ assertThat(featureVersions).isEqualTo(instance1.readSystemFeaturesCache());
+
+ ApplicationSharedMemory instance2 =
+ ApplicationSharedMemory.fromFileDescriptor(
+ instance1.getReadOnlyFileDescriptor(), /* mutable= */ false);
+ assertThat(featureVersions).isEqualTo(instance2.readSystemFeaturesCache());
+ }
+
+ @Test
+ public void systemFeaturesAreWriteOnce() throws IOException {
+ ApplicationSharedMemory instance1 = ApplicationSharedMemory.create();
+
+ try {
+ instance1.writeSystemFeaturesCache(new int[5000]);
+ fail("Cannot write an overly large system feature version buffer.");
+ } catch (IllegalArgumentException expected) {
+ }
+
+ int[] featureVersions = new int[] {1, 2, 3, 4, 5};
+ instance1.writeSystemFeaturesCache(featureVersions);
+
+ int[] newFeatureVersions = new int[] {1, 2, 3, 4, 5, 6, 7};
+ try {
+ instance1.writeSystemFeaturesCache(newFeatureVersions);
+ fail("Cannot update system features after first write.");
+ } catch (IllegalStateException expected) {
+ }
+
+ ApplicationSharedMemory instance2 =
+ ApplicationSharedMemory.fromFileDescriptor(
+ instance1.getReadOnlyFileDescriptor(), /* mutable= */ false);
+ try {
+ instance2.writeSystemFeaturesCache(newFeatureVersions);
+ fail("Cannot update system features for read-only ashmem.");
+ } catch (IllegalStateException expected) {
+ }
+ }
}
diff --git a/tests/PackageWatchdog/Android.bp b/tests/PackageWatchdog/Android.bp
index 8be74eacc..44e545b 100644
--- a/tests/PackageWatchdog/Android.bp
+++ b/tests/PackageWatchdog/Android.bp
@@ -26,12 +26,12 @@
name: "PackageWatchdogTest",
srcs: ["src/**/*.java"],
static_libs: [
- "junit",
- "mockito-target-extended-minus-junit4",
+ "PlatformProperties",
+ "androidx.test.rules",
"flag-junit",
"frameworks-base-testutils",
- "androidx.test.rules",
- "PlatformProperties",
+ "junit",
+ "mockito-target-extended-minus-junit4",
"services.core",
"services.net",
"truth",
@@ -49,5 +49,9 @@
"libstaticjvmtiagent",
],
platform_apis: true,
- test_suites: ["device-tests"],
+ test_suites: [
+ "device-tests",
+ "mts-crashrecovery",
+ ],
+ min_sdk_version: "36",
}
diff --git a/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java b/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java
index 8ac3433..c2ab055 100644
--- a/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java
+++ b/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java
@@ -48,8 +48,6 @@
import android.os.Handler;
import android.os.SystemProperties;
import android.os.test.TestLooper;
-import android.platform.test.annotations.DisableFlags;
-import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.DeviceConfig;
import android.util.AtomicFile;
@@ -135,7 +133,6 @@
@Before
public void setUp() throws Exception {
- mSetFlagsRule.enableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
MockitoAnnotations.initMocks(this);
new File(InstrumentationRegistry.getContext().getFilesDir(),
"package-watchdog.xml").delete();
@@ -305,90 +302,6 @@
}
@Test
- @DisableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
- public void testBootLoopWithRescuePartyAndRollbackObserver() throws Exception {
- PackageWatchdog watchdog = createWatchdog();
- RescuePartyObserver rescuePartyObserver = setUpRescuePartyObserver(watchdog);
- RollbackPackageHealthObserver rollbackObserver =
- setUpRollbackPackageHealthObserver(watchdog);
-
- verify(rescuePartyObserver, never()).onExecuteBootLoopMitigation(1);
- verify(rollbackObserver, never()).onExecuteBootLoopMitigation(1);
- for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT; i++) {
- watchdog.noteBoot();
- }
- mTestLooper.dispatchAll();
- verify(rescuePartyObserver).onExecuteBootLoopMitigation(1);
- verify(rescuePartyObserver, never()).onExecuteBootLoopMitigation(2);
- verify(rollbackObserver, never()).onExecuteBootLoopMitigation(1);
-
- watchdog.noteBoot();
-
- mTestLooper.dispatchAll();
- verify(rescuePartyObserver).onExecuteBootLoopMitigation(2);
- verify(rescuePartyObserver, never()).onExecuteBootLoopMitigation(3);
- verify(rollbackObserver, never()).onExecuteBootLoopMitigation(2);
-
- watchdog.noteBoot();
-
- mTestLooper.dispatchAll();
- verify(rescuePartyObserver, never()).onExecuteBootLoopMitigation(3);
- verify(rollbackObserver).onExecuteBootLoopMitigation(1);
- verify(rollbackObserver, never()).onExecuteBootLoopMitigation(2);
- // Update the list of available rollbacks after executing bootloop mitigation once
- when(mRollbackManager.getAvailableRollbacks()).thenReturn(List.of(ROLLBACK_INFO_HIGH,
- ROLLBACK_INFO_MANUAL));
-
- watchdog.noteBoot();
-
- mTestLooper.dispatchAll();
- verify(rescuePartyObserver).onExecuteBootLoopMitigation(3);
- verify(rescuePartyObserver, never()).onExecuteBootLoopMitigation(4);
- verify(rollbackObserver, never()).onExecuteBootLoopMitigation(2);
-
- watchdog.noteBoot();
-
- mTestLooper.dispatchAll();
- verify(rescuePartyObserver).onExecuteBootLoopMitigation(4);
- verify(rescuePartyObserver, never()).onExecuteBootLoopMitigation(5);
- verify(rollbackObserver, never()).onExecuteBootLoopMitigation(2);
-
- watchdog.noteBoot();
-
- mTestLooper.dispatchAll();
- verify(rescuePartyObserver).onExecuteBootLoopMitigation(5);
- verify(rescuePartyObserver, never()).onExecuteBootLoopMitigation(6);
- verify(rollbackObserver, never()).onExecuteBootLoopMitigation(2);
-
- watchdog.noteBoot();
-
- mTestLooper.dispatchAll();
- verify(rescuePartyObserver, never()).onExecuteBootLoopMitigation(6);
- verify(rollbackObserver).onExecuteBootLoopMitigation(2);
- verify(rollbackObserver, never()).onExecuteBootLoopMitigation(3);
- // Update the list of available rollbacks after executing bootloop mitigation
- when(mRollbackManager.getAvailableRollbacks()).thenReturn(List.of(ROLLBACK_INFO_MANUAL));
-
- watchdog.noteBoot();
-
- mTestLooper.dispatchAll();
- verify(rescuePartyObserver).onExecuteBootLoopMitigation(6);
- verify(rescuePartyObserver, never()).onExecuteBootLoopMitigation(7);
- verify(rollbackObserver, never()).onExecuteBootLoopMitigation(3);
-
- moveTimeForwardAndDispatch(PackageWatchdog.DEFAULT_DEESCALATION_WINDOW_MS + 1);
- Mockito.reset(rescuePartyObserver);
-
- for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT; i++) {
- watchdog.noteBoot();
- }
- mTestLooper.dispatchAll();
- verify(rescuePartyObserver).onExecuteBootLoopMitigation(1);
- verify(rescuePartyObserver, never()).onExecuteBootLoopMitigation(2);
- }
-
- @Test
- @EnableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
public void testBootLoopWithRescuePartyAndRollbackObserverNoFlags() throws Exception {
PackageWatchdog watchdog = createWatchdog();
RescuePartyObserver rescuePartyObserver = setUpRescuePartyObserver(watchdog);
@@ -443,80 +356,6 @@
}
@Test
- @DisableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
- public void testCrashLoopWithRescuePartyAndRollbackObserver() throws Exception {
- PackageWatchdog watchdog = createWatchdog();
- RescuePartyObserver rescuePartyObserver = setUpRescuePartyObserver(watchdog);
- RollbackPackageHealthObserver rollbackObserver =
- setUpRollbackPackageHealthObserver(watchdog);
- VersionedPackage versionedPackageA = new VersionedPackage(APP_A, VERSION_CODE);
-
- when(mMockPackageManager.getApplicationInfo(anyString(), anyInt())).then(inv -> {
- ApplicationInfo info = new ApplicationInfo();
- info.flags |= ApplicationInfo.FLAG_PERSISTENT
- | ApplicationInfo.FLAG_SYSTEM;
- return info;
- });
-
- raiseFatalFailureAndDispatch(watchdog,
- Arrays.asList(versionedPackageA), PackageWatchdog.FAILURE_REASON_APP_CRASH);
-
- // Mitigation: SCOPED_DEVICE_CONFIG_RESET
- verify(rescuePartyObserver).onExecuteHealthCheckMitigation(versionedPackageA,
- PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
- verify(rescuePartyObserver, never()).onExecuteHealthCheckMitigation(versionedPackageA,
- PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
- verify(rollbackObserver, never()).onExecuteHealthCheckMitigation(versionedPackageA,
- PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
-
- raiseFatalFailureAndDispatch(watchdog,
- Arrays.asList(versionedPackageA), PackageWatchdog.FAILURE_REASON_APP_CRASH);
-
- // Mitigation: ALL_DEVICE_CONFIG_RESET
- verify(rescuePartyObserver).onExecuteHealthCheckMitigation(versionedPackageA,
- PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
- verify(rescuePartyObserver, never()).onExecuteHealthCheckMitigation(versionedPackageA,
- PackageWatchdog.FAILURE_REASON_APP_CRASH, 3);
- verify(rollbackObserver, never()).onExecuteHealthCheckMitigation(versionedPackageA,
- PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
-
- raiseFatalFailureAndDispatch(watchdog,
- Arrays.asList(versionedPackageA), PackageWatchdog.FAILURE_REASON_APP_CRASH);
-
- // Mitigation: WARM_REBOOT
- verify(rescuePartyObserver).onExecuteHealthCheckMitigation(versionedPackageA,
- PackageWatchdog.FAILURE_REASON_APP_CRASH, 3);
- verify(rescuePartyObserver, never()).onExecuteHealthCheckMitigation(versionedPackageA,
- PackageWatchdog.FAILURE_REASON_APP_CRASH, 4);
- verify(rollbackObserver, never()).onExecuteHealthCheckMitigation(versionedPackageA,
- PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
-
- raiseFatalFailureAndDispatch(watchdog,
- Arrays.asList(versionedPackageA), PackageWatchdog.FAILURE_REASON_APP_CRASH);
-
- // Mitigation: Low impact rollback
- verify(rollbackObserver).onExecuteHealthCheckMitigation(versionedPackageA,
- PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
- verify(rescuePartyObserver, never()).onExecuteHealthCheckMitigation(versionedPackageA,
- PackageWatchdog.FAILURE_REASON_APP_CRASH, 4);
-
- // update available rollbacks to mock rollbacks being applied after the call to
- // rollbackObserver.onExecuteHealthCheckMitigation
- when(mRollbackManager.getAvailableRollbacks()).thenReturn(
- List.of(ROLLBACK_INFO_HIGH, ROLLBACK_INFO_MANUAL));
-
- raiseFatalFailureAndDispatch(watchdog,
- Arrays.asList(versionedPackageA), PackageWatchdog.FAILURE_REASON_APP_CRASH);
-
- // DEFAULT_MAJOR_USER_IMPACT_LEVEL_THRESHOLD reached. No more mitigations applied
- verify(rescuePartyObserver, never()).onExecuteHealthCheckMitigation(versionedPackageA,
- PackageWatchdog.FAILURE_REASON_APP_CRASH, 4);
- verify(rollbackObserver, never()).onExecuteHealthCheckMitigation(versionedPackageA,
- PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
- }
-
- @Test
- @EnableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
public void testCrashLoopWithRescuePartyAndRollbackObserverEnableDeprecateFlagReset()
throws Exception {
PackageWatchdog watchdog = createWatchdog();
@@ -569,123 +408,6 @@
}
@Test
- @DisableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
- public void testCrashLoopSystemUIWithRescuePartyAndRollbackObserver() throws Exception {
- PackageWatchdog watchdog = createWatchdog();
- RescuePartyObserver rescuePartyObserver = setUpRescuePartyObserver(watchdog);
- RollbackPackageHealthObserver rollbackObserver =
- setUpRollbackPackageHealthObserver(watchdog);
- String systemUi = "com.android.systemui";
- VersionedPackage versionedPackageUi = new VersionedPackage(
- systemUi, VERSION_CODE);
- RollbackInfo rollbackInfoUi = getRollbackInfo(systemUi, VERSION_CODE, 1,
- PackageManager.ROLLBACK_USER_IMPACT_LOW);
- when(mRollbackManager.getAvailableRollbacks()).thenReturn(List.of(ROLLBACK_INFO_LOW,
- ROLLBACK_INFO_HIGH, ROLLBACK_INFO_MANUAL, rollbackInfoUi));
-
- when(mMockPackageManager.getApplicationInfo(anyString(), anyInt())).then(inv -> {
- ApplicationInfo info = new ApplicationInfo();
- info.flags |= ApplicationInfo.FLAG_PERSISTENT
- | ApplicationInfo.FLAG_SYSTEM;
- return info;
- });
-
- raiseFatalFailureAndDispatch(watchdog,
- Arrays.asList(versionedPackageUi), PackageWatchdog.FAILURE_REASON_APP_CRASH);
-
- // Mitigation: SCOPED_DEVICE_CONFIG_RESET
- verify(rescuePartyObserver).onExecuteHealthCheckMitigation(versionedPackageUi,
- PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
- verify(rescuePartyObserver, never()).onExecuteHealthCheckMitigation(versionedPackageUi,
- PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
- verify(rollbackObserver, never()).onExecuteHealthCheckMitigation(versionedPackageUi,
- PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
-
- raiseFatalFailureAndDispatch(watchdog,
- Arrays.asList(versionedPackageUi), PackageWatchdog.FAILURE_REASON_APP_CRASH);
-
- // Mitigation: ALL_DEVICE_CONFIG_RESET
- verify(rescuePartyObserver).onExecuteHealthCheckMitigation(versionedPackageUi,
- PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
- verify(rescuePartyObserver, never()).onExecuteHealthCheckMitigation(versionedPackageUi,
- PackageWatchdog.FAILURE_REASON_APP_CRASH, 3);
- verify(rollbackObserver, never()).onExecuteHealthCheckMitigation(versionedPackageUi,
- PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
-
- raiseFatalFailureAndDispatch(watchdog,
- Arrays.asList(versionedPackageUi), PackageWatchdog.FAILURE_REASON_APP_CRASH);
-
- // Mitigation: WARM_REBOOT
- verify(rescuePartyObserver).onExecuteHealthCheckMitigation(versionedPackageUi,
- PackageWatchdog.FAILURE_REASON_APP_CRASH, 3);
- verify(rescuePartyObserver, never()).onExecuteHealthCheckMitigation(versionedPackageUi,
- PackageWatchdog.FAILURE_REASON_APP_CRASH, 4);
- verify(rollbackObserver, never()).onExecuteHealthCheckMitigation(versionedPackageUi,
- PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
-
- raiseFatalFailureAndDispatch(watchdog,
- Arrays.asList(versionedPackageUi), PackageWatchdog.FAILURE_REASON_APP_CRASH);
-
- // Mitigation: Low impact rollback
- verify(rollbackObserver).onExecuteHealthCheckMitigation(versionedPackageUi,
- PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
- verify(rescuePartyObserver, never()).onExecuteHealthCheckMitigation(versionedPackageUi,
- PackageWatchdog.FAILURE_REASON_APP_CRASH, 4);
- verify(rollbackObserver, never()).onExecuteHealthCheckMitigation(versionedPackageUi,
- PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
-
- // update available rollbacks to mock rollbacks being applied after the call to
- // rollbackObserver.onExecuteHealthCheckMitigation
- when(mRollbackManager.getAvailableRollbacks()).thenReturn(
- List.of(ROLLBACK_INFO_HIGH, ROLLBACK_INFO_MANUAL));
-
- raiseFatalFailureAndDispatch(watchdog,
- Arrays.asList(versionedPackageUi), PackageWatchdog.FAILURE_REASON_APP_CRASH);
-
- // Mitigation: RESET_SETTINGS_UNTRUSTED_DEFAULTS
- verify(rescuePartyObserver).onExecuteHealthCheckMitigation(versionedPackageUi,
- PackageWatchdog.FAILURE_REASON_APP_CRASH, 4);
- verify(rescuePartyObserver, never()).onExecuteHealthCheckMitigation(versionedPackageUi,
- PackageWatchdog.FAILURE_REASON_APP_CRASH, 5);
- verify(rollbackObserver, never()).onExecuteHealthCheckMitigation(versionedPackageUi,
- PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
-
- raiseFatalFailureAndDispatch(watchdog,
- Arrays.asList(versionedPackageUi), PackageWatchdog.FAILURE_REASON_APP_CRASH);
-
- // Mitigation: RESET_SETTINGS_UNTRUSTED_CHANGES
- verify(rescuePartyObserver).onExecuteHealthCheckMitigation(versionedPackageUi,
- PackageWatchdog.FAILURE_REASON_APP_CRASH, 5);
- verify(rescuePartyObserver, never()).onExecuteHealthCheckMitigation(versionedPackageUi,
- PackageWatchdog.FAILURE_REASON_APP_CRASH, 6);
- verify(rollbackObserver, never()).onExecuteHealthCheckMitigation(versionedPackageUi,
- PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
-
- raiseFatalFailureAndDispatch(watchdog,
- Arrays.asList(versionedPackageUi), PackageWatchdog.FAILURE_REASON_APP_CRASH);
-
- // Mitigation: RESET_SETTINGS_TRUSTED_DEFAULTS
- verify(rescuePartyObserver).onExecuteHealthCheckMitigation(versionedPackageUi,
- PackageWatchdog.FAILURE_REASON_APP_CRASH, 6);
- verify(rescuePartyObserver, never()).onExecuteHealthCheckMitigation(versionedPackageUi,
- PackageWatchdog.FAILURE_REASON_APP_CRASH, 7);
- verify(rollbackObserver, never()).onExecuteHealthCheckMitigation(versionedPackageUi,
- PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
-
- raiseFatalFailureAndDispatch(watchdog,
- Arrays.asList(versionedPackageUi), PackageWatchdog.FAILURE_REASON_APP_CRASH);
-
- // Mitigation: Factory reset. High impact rollbacks are performed only for boot loops.
- verify(rescuePartyObserver).onExecuteHealthCheckMitigation(versionedPackageUi,
- PackageWatchdog.FAILURE_REASON_APP_CRASH, 7);
- verify(rescuePartyObserver, never()).onExecuteHealthCheckMitigation(versionedPackageUi,
- PackageWatchdog.FAILURE_REASON_APP_CRASH, 8);
- verify(rollbackObserver, never()).onExecuteHealthCheckMitigation(versionedPackageUi,
- PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
- }
-
- @Test
- @EnableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
public void testCrashLoopSystemUIWithRescuePartyAndRollbackObserverEnableDeprecateFlagReset()
throws Exception {
PackageWatchdog watchdog = createWatchdog();
@@ -1043,8 +765,6 @@
watchdog.notifyPackageFailure(packages, failureReason);
}
mTestLooper.dispatchAll();
- if (Flags.recoverabilityDetection()) {
- moveTimeForwardAndDispatch(watchdog.DEFAULT_MITIGATION_WINDOW_MS);
- }
+ moveTimeForwardAndDispatch(watchdog.DEFAULT_MITIGATION_WINDOW_MS);
}
}
diff --git a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
index 1c50cb1..b827484 100644
--- a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
+++ b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
@@ -150,7 +150,6 @@
@Before
public void setUp() throws Exception {
- mSetFlagsRule.enableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
MockitoAnnotations.initMocks(this);
new File(InstrumentationRegistry.getContext().getFilesDir(),
"package-watchdog.xml").delete();
@@ -480,60 +479,6 @@
assertThat(observer.mHealthCheckFailedPackages).isEmpty();
}
-
- /**
- * Test package failure and notifies only least impact observers.
- */
- @Test
- public void testPackageFailureNotifyAllDifferentImpacts() throws Exception {
- mSetFlagsRule.disableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
- PackageWatchdog watchdog = createWatchdog();
- TestObserver observerNone = new TestObserver(OBSERVER_NAME_1,
- PackageHealthObserverImpact.USER_IMPACT_LEVEL_0);
- TestObserver observerHigh = new TestObserver(OBSERVER_NAME_2,
- PackageHealthObserverImpact.USER_IMPACT_LEVEL_100);
- TestObserver observerMid = new TestObserver(OBSERVER_NAME_3,
- PackageHealthObserverImpact.USER_IMPACT_LEVEL_30);
- TestObserver observerLow = new TestObserver(OBSERVER_NAME_4,
- PackageHealthObserverImpact.USER_IMPACT_LEVEL_10);
-
- // Start observing for all impact observers
- watchdog.registerHealthObserver(mTestExecutor, observerNone);
- watchdog.startExplicitHealthCheck(Arrays.asList(APP_A, APP_B, APP_C, APP_D),
- SHORT_DURATION, observerNone);
- watchdog.registerHealthObserver(mTestExecutor, observerHigh);
- watchdog.startExplicitHealthCheck(Arrays.asList(APP_A, APP_B, APP_C), SHORT_DURATION,
- observerHigh);
- watchdog.registerHealthObserver(mTestExecutor, observerMid);
- watchdog.startExplicitHealthCheck(Arrays.asList(APP_A, APP_B), SHORT_DURATION,
- observerMid);
- watchdog.registerHealthObserver(mTestExecutor, observerLow);
- watchdog.startExplicitHealthCheck(Arrays.asList(APP_A), SHORT_DURATION, observerLow);
-
- // Then fail all apps above the threshold
- raiseFatalFailureAndDispatch(watchdog,
- Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE),
- new VersionedPackage(APP_B, VERSION_CODE),
- new VersionedPackage(APP_C, VERSION_CODE),
- new VersionedPackage(APP_D, VERSION_CODE)),
- PackageWatchdog.FAILURE_REASON_UNKNOWN);
-
- // Verify least impact observers are notifed of package failures
- List<String> observerNonePackages = observerNone.mMitigatedPackages;
- List<String> observerHighPackages = observerHigh.mMitigatedPackages;
- List<String> observerMidPackages = observerMid.mMitigatedPackages;
- List<String> observerLowPackages = observerLow.mMitigatedPackages;
-
- // APP_D failure observed by only observerNone is not caught cos its impact is none
- assertThat(observerNonePackages).isEmpty();
- // APP_C failure is caught by observerHigh cos it's the lowest impact observer
- assertThat(observerHighPackages).containsExactly(APP_C);
- // APP_B failure is caught by observerMid cos it's the lowest impact observer
- assertThat(observerMidPackages).containsExactly(APP_B);
- // APP_A failure is caught by observerLow cos it's the lowest impact observer
- assertThat(observerLowPackages).containsExactly(APP_A);
- }
-
@Test
public void testPackageFailureNotifyAllDifferentImpactsRecoverability() throws Exception {
PackageWatchdog watchdog = createWatchdog();
@@ -583,84 +528,6 @@
assertThat(observerLowPackages).containsExactly(APP_A);
}
- /**
- * Test package failure and least impact observers are notified successively.
- * State transistions:
- *
- * <ul>
- * <li>(observer1:low, observer2:mid) -> {observer1}
- * <li>(observer1:high, observer2:mid) -> {observer2}
- * <li>(observer1:high, observer2:none) -> {observer1}
- * <li>(observer1:none, observer2:none) -> {}
- * <ul>
- */
- @Test
- public void testPackageFailureNotifyLeastImpactSuccessively() throws Exception {
- mSetFlagsRule.disableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
- PackageWatchdog watchdog = createWatchdog();
- TestObserver observerFirst = new TestObserver(OBSERVER_NAME_1,
- PackageHealthObserverImpact.USER_IMPACT_LEVEL_10);
- TestObserver observerSecond = new TestObserver(OBSERVER_NAME_2,
- PackageHealthObserverImpact.USER_IMPACT_LEVEL_30);
-
- // Start observing for observerFirst and observerSecond with failure handling
- watchdog.registerHealthObserver(mTestExecutor, observerFirst);
- watchdog.startExplicitHealthCheck(Arrays.asList(APP_A), LONG_DURATION, observerFirst);
- watchdog.registerHealthObserver(mTestExecutor, observerSecond);
- watchdog.startExplicitHealthCheck(Arrays.asList(APP_A), LONG_DURATION, observerSecond);
-
- // Then fail APP_A above the threshold
- raiseFatalFailureAndDispatch(watchdog,
- Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
- PackageWatchdog.FAILURE_REASON_UNKNOWN);
-
- // Verify only observerFirst is notifed
- assertThat(observerFirst.mMitigatedPackages).containsExactly(APP_A);
- assertThat(observerSecond.mMitigatedPackages).isEmpty();
-
- // After observerFirst handles failure, next action it has is high impact
- observerFirst.mImpact = PackageHealthObserverImpact.USER_IMPACT_LEVEL_100;
- observerFirst.mMitigatedPackages.clear();
- observerSecond.mMitigatedPackages.clear();
-
- // Then fail APP_A again above the threshold
- raiseFatalFailureAndDispatch(watchdog,
- Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
- PackageWatchdog.FAILURE_REASON_UNKNOWN);
-
- // Verify only observerSecond is notifed cos it has least impact
- assertThat(observerSecond.mMitigatedPackages).containsExactly(APP_A);
- assertThat(observerFirst.mMitigatedPackages).isEmpty();
-
- // After observerSecond handles failure, it has no further actions
- observerSecond.mImpact = PackageHealthObserverImpact.USER_IMPACT_LEVEL_0;
- observerFirst.mMitigatedPackages.clear();
- observerSecond.mMitigatedPackages.clear();
-
- // Then fail APP_A again above the threshold
- raiseFatalFailureAndDispatch(watchdog,
- Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
- PackageWatchdog.FAILURE_REASON_UNKNOWN);
-
- // Verify only observerFirst is notifed cos it has the only action
- assertThat(observerFirst.mMitigatedPackages).containsExactly(APP_A);
- assertThat(observerSecond.mMitigatedPackages).isEmpty();
-
- // After observerFirst handles failure, it too has no further actions
- observerFirst.mImpact = PackageHealthObserverImpact.USER_IMPACT_LEVEL_0;
- observerFirst.mMitigatedPackages.clear();
- observerSecond.mMitigatedPackages.clear();
-
- // Then fail APP_A again above the threshold
- raiseFatalFailureAndDispatch(watchdog,
- Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
- PackageWatchdog.FAILURE_REASON_UNKNOWN);
-
- // Verify no observer is notified cos no actions left
- assertThat(observerFirst.mMitigatedPackages).isEmpty();
- assertThat(observerSecond.mMitigatedPackages).isEmpty();
- }
-
@Test
public void testPackageFailureNotifyLeastImpactSuccessivelyRecoverability() throws Exception {
PackageWatchdog watchdog = createWatchdog();
@@ -727,34 +594,6 @@
assertThat(observerSecond.mMitigatedPackages).isEmpty();
}
- /**
- * Test package failure and notifies only one observer even with observer impact tie.
- */
- @Test
- public void testPackageFailureNotifyOneSameImpact() throws Exception {
- mSetFlagsRule.disableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
- PackageWatchdog watchdog = createWatchdog();
- TestObserver observer1 = new TestObserver(OBSERVER_NAME_1,
- PackageHealthObserverImpact.USER_IMPACT_LEVEL_100);
- TestObserver observer2 = new TestObserver(OBSERVER_NAME_2,
- PackageHealthObserverImpact.USER_IMPACT_LEVEL_100);
-
- // Start observing for observer1 and observer2 with failure handling
- watchdog.registerHealthObserver(mTestExecutor, observer2);
- watchdog.startExplicitHealthCheck(Arrays.asList(APP_A), SHORT_DURATION, observer2);
- watchdog.registerHealthObserver(mTestExecutor, observer1);
- watchdog.startExplicitHealthCheck(Arrays.asList(APP_A), SHORT_DURATION, observer1);
-
- // Then fail APP_A above the threshold
- raiseFatalFailureAndDispatch(watchdog,
- Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
- PackageWatchdog.FAILURE_REASON_UNKNOWN);
-
- // Verify only one observer is notifed
- assertThat(observer1.mMitigatedPackages).containsExactly(APP_A);
- assertThat(observer2.mMitigatedPackages).isEmpty();
- }
-
@Test
public void testPackageFailureNotifyOneSameImpactRecoverabilityDetection() throws Exception {
PackageWatchdog watchdog = createWatchdog();
@@ -1015,27 +854,6 @@
@Test
@RequiresFlagsDisabled(Flags.FLAG_REFACTOR_CRASHRECOVERY)
- public void testNetworkStackFailure() {
- mSetFlagsRule.disableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
- final PackageWatchdog wd = createWatchdog();
-
- // Start observing with failure handling
- TestObserver observer = new TestObserver(OBSERVER_NAME_1,
- PackageHealthObserverImpact.USER_IMPACT_LEVEL_100);
- wd.startExplicitHealthCheck(Collections.singletonList(APP_A), SHORT_DURATION, observer);
-
- // Notify of NetworkStack failure
- mConnectivityModuleCallbackCaptor.getValue().onNetworkStackFailure(APP_A);
-
- // Run handler so package failures are dispatched to observers
- mTestLooper.dispatchAll();
-
- // Verify the NetworkStack observer is notified
- assertThat(observer.mMitigatedPackages).containsExactly(APP_A);
- }
-
- @Test
- @RequiresFlagsDisabled(Flags.FLAG_REFACTOR_CRASHRECOVERY)
public void testNetworkStackFailureRecoverabilityDetection() {
final PackageWatchdog wd = createWatchdog();
@@ -1270,21 +1088,6 @@
assertThat(persistentObserver.mHealthCheckFailedPackages).isEmpty();
}
-
- /** Ensure that boot loop mitigation is done when the number of boots meets the threshold. */
- @Test
- public void testBootLoopDetection_meetsThreshold() {
- mSetFlagsRule.disableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
- PackageWatchdog watchdog = createWatchdog();
- TestObserver bootObserver = new TestObserver(OBSERVER_NAME_1);
- watchdog.registerHealthObserver(mTestExecutor, bootObserver);
- for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT; i++) {
- watchdog.noteBoot();
- }
- mTestLooper.dispatchAll();
- assertThat(bootObserver.mitigatedBootLoop()).isTrue();
- }
-
@Test
public void testBootLoopDetection_meetsThresholdRecoverability() {
PackageWatchdog watchdog = createWatchdog();
@@ -1330,27 +1133,6 @@
assertThat(bootObserver.mitigatedBootLoop()).isFalse();
}
- /**
- * Ensure that boot loop mitigation is done for the observer with the lowest user impact
- */
- @Test
- public void testBootLoopMitigationDoneForLowestUserImpact() {
- mSetFlagsRule.disableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
- PackageWatchdog watchdog = createWatchdog();
- TestObserver bootObserver1 = new TestObserver(OBSERVER_NAME_1);
- bootObserver1.setImpact(PackageHealthObserverImpact.USER_IMPACT_LEVEL_10);
- TestObserver bootObserver2 = new TestObserver(OBSERVER_NAME_2);
- bootObserver2.setImpact(PackageHealthObserverImpact.USER_IMPACT_LEVEL_30);
- watchdog.registerHealthObserver(mTestExecutor, bootObserver1);
- watchdog.registerHealthObserver(mTestExecutor, bootObserver2);
- for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT; i++) {
- watchdog.noteBoot();
- }
- mTestLooper.dispatchAll();
- assertThat(bootObserver1.mitigatedBootLoop()).isTrue();
- assertThat(bootObserver2.mitigatedBootLoop()).isFalse();
- }
-
@Test
public void testBootLoopMitigationDoneForLowestUserImpactRecoverability() {
PackageWatchdog watchdog = createWatchdog();
@@ -1368,32 +1150,6 @@
assertThat(bootObserver2.mitigatedBootLoop()).isFalse();
}
- /**
- * Ensure that the correct mitigation counts are sent to the boot loop observer.
- */
- @Test
- public void testMultipleBootLoopMitigation() {
- mSetFlagsRule.disableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
- PackageWatchdog watchdog = createWatchdog();
- TestObserver bootObserver = new TestObserver(OBSERVER_NAME_1);
- watchdog.registerHealthObserver(mTestExecutor, bootObserver);
- for (int i = 0; i < 4; i++) {
- for (int j = 0; j < PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT; j++) {
- watchdog.noteBoot();
- }
- }
-
- moveTimeForwardAndDispatch(PackageWatchdog.DEFAULT_DEESCALATION_WINDOW_MS + 1);
-
- for (int i = 0; i < 4; i++) {
- for (int j = 0; j < PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT; j++) {
- watchdog.noteBoot();
- }
- }
- mTestLooper.dispatchAll();
- assertThat(bootObserver.mBootMitigationCounts).isEqualTo(List.of(1, 2, 3, 4, 1, 2, 3, 4));
- }
-
@Test
public void testMultipleBootLoopMitigationRecoverabilityLowImpact() {
PackageWatchdog watchdog = createWatchdog();
@@ -1800,9 +1556,7 @@
watchdog.notifyPackageFailure(packages, failureReason);
}
mTestLooper.dispatchAll();
- if (Flags.recoverabilityDetection()) {
- moveTimeForwardAndDispatch(watchdog.DEFAULT_MITIGATION_WINDOW_MS);
- }
+ moveTimeForwardAndDispatch(watchdog.DEFAULT_MITIGATION_WINDOW_MS);
}
private PackageWatchdog createWatchdog() {
diff --git a/tests/utils/testutils/java/android/os/test/TestLooper.java b/tests/utils/testutils/java/android/os/test/TestLooper.java
index 83d22d9..4d379e4 100644
--- a/tests/utils/testutils/java/android/os/test/TestLooper.java
+++ b/tests/utils/testutils/java/android/os/test/TestLooper.java
@@ -18,18 +18,24 @@
import static org.junit.Assert.assertTrue;
+import android.os.Build;
import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.Looper;
import android.os.Message;
import android.os.MessageQueue;
import android.os.SystemClock;
+import android.os.TestLooperManager;
import android.util.Log;
+import androidx.test.platform.app.InstrumentationRegistry;
+
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.util.ArrayDeque;
+import java.util.Queue;
import java.util.concurrent.Executor;
/**
@@ -44,7 +50,9 @@
* The Robolectric class also allows advancing time.
*/
public class TestLooper {
- protected final Looper mLooper;
+ private final Looper mLooper;
+ private final TestLooperManager mTestLooperManager;
+ private final Clock mClock;
private static final Constructor<Looper> LOOPER_CONSTRUCTOR;
private static final Field THREAD_LOCAL_LOOPER_FIELD;
@@ -54,24 +62,46 @@
private static final Method MESSAGE_MARK_IN_USE_METHOD;
private static final String TAG = "TestLooper";
- private final Clock mClock;
-
private AutoDispatchThread mAutoDispatchThread;
+ /**
+ * Baklava introduces new {@link TestLooperManager} APIs that we can use instead of reflection.
+ */
+ private static boolean isAtLeastBaklava() {
+ Method[] methods = TestLooperManager.class.getMethods();
+ for (Method method : methods) {
+ if (method.getName().equals("peekWhen")) {
+ return true;
+ }
+ }
+ return false;
+ // TODO(shayba): delete the above, uncomment the below.
+ // SDK_INT has not yet ramped to Baklava in all 25Q2 builds.
+ // return Build.VERSION.SDK_INT >= Build.VERSION_CODES.BAKLAVA;
+ }
+
static {
try {
LOOPER_CONSTRUCTOR = Looper.class.getDeclaredConstructor(Boolean.TYPE);
LOOPER_CONSTRUCTOR.setAccessible(true);
THREAD_LOCAL_LOOPER_FIELD = Looper.class.getDeclaredField("sThreadLocal");
THREAD_LOCAL_LOOPER_FIELD.setAccessible(true);
- MESSAGE_QUEUE_MESSAGES_FIELD = MessageQueue.class.getDeclaredField("mMessages");
- MESSAGE_QUEUE_MESSAGES_FIELD.setAccessible(true);
- MESSAGE_NEXT_FIELD = Message.class.getDeclaredField("next");
- MESSAGE_NEXT_FIELD.setAccessible(true);
- MESSAGE_WHEN_FIELD = Message.class.getDeclaredField("when");
- MESSAGE_WHEN_FIELD.setAccessible(true);
- MESSAGE_MARK_IN_USE_METHOD = Message.class.getDeclaredMethod("markInUse");
- MESSAGE_MARK_IN_USE_METHOD.setAccessible(true);
+
+ if (isAtLeastBaklava()) {
+ MESSAGE_QUEUE_MESSAGES_FIELD = null;
+ MESSAGE_NEXT_FIELD = null;
+ MESSAGE_WHEN_FIELD = null;
+ MESSAGE_MARK_IN_USE_METHOD = null;
+ } else {
+ MESSAGE_QUEUE_MESSAGES_FIELD = MessageQueue.class.getDeclaredField("mMessages");
+ MESSAGE_QUEUE_MESSAGES_FIELD.setAccessible(true);
+ MESSAGE_NEXT_FIELD = Message.class.getDeclaredField("next");
+ MESSAGE_NEXT_FIELD.setAccessible(true);
+ MESSAGE_WHEN_FIELD = Message.class.getDeclaredField("when");
+ MESSAGE_WHEN_FIELD.setAccessible(true);
+ MESSAGE_MARK_IN_USE_METHOD = Message.class.getDeclaredMethod("markInUse");
+ MESSAGE_MARK_IN_USE_METHOD.setAccessible(true);
+ }
} catch (NoSuchFieldException | NoSuchMethodException e) {
throw new RuntimeException("Failed to initialize TestLooper", e);
}
@@ -106,6 +136,13 @@
throw new RuntimeException("Reflection error constructing or accessing looper", e);
}
+ if (isAtLeastBaklava()) {
+ mTestLooperManager =
+ InstrumentationRegistry.getInstrumentation().acquireLooperManager(mLooper);
+ } else {
+ mTestLooperManager = null;
+ }
+
mClock = clock;
}
@@ -117,19 +154,61 @@
return new HandlerExecutor(new Handler(getLooper()));
}
- private Message getMessageLinkedList() {
+ private Message getMessageLinkedListLegacy() {
try {
MessageQueue queue = mLooper.getQueue();
return (Message) MESSAGE_QUEUE_MESSAGES_FIELD.get(queue);
} catch (IllegalAccessException e) {
throw new RuntimeException("Access failed in TestLooper: get - MessageQueue.mMessages",
- e);
+ e);
}
}
public void moveTimeForward(long milliSeconds) {
+ if (isAtLeastBaklava()) {
+ moveTimeForwardBaklava(milliSeconds);
+ } else {
+ moveTimeForwardLegacy(milliSeconds);
+ }
+ }
+
+ private void moveTimeForwardBaklava(long milliSeconds) {
+ // Drain all Messages from the queue.
+ Queue<Message> messages = new ArrayDeque<>();
+ while (true) {
+ Message message = mTestLooperManager.poll();
+ if (message == null) {
+ break;
+ }
+ messages.add(message);
+ }
+
+ // Repost all Messages back to the queue with a new time.
+ while (true) {
+ Message message = messages.poll();
+ if (message == null) {
+ break;
+ }
+
+ // Ugly trick to reset the Message's "in use" flag.
+ // This is needed because the Message cannot be re-enqueued if it's
+ // marked in use.
+ message.copyFrom(message);
+
+ // Adjust the Message's delivery time.
+ long newWhen = message.getWhen() - milliSeconds;
+ if (newWhen < 0) {
+ newWhen = 0;
+ }
+
+ // Send the Message back to its Handler to be re-enqueued.
+ message.getTarget().sendMessageAtTime(message, newWhen);
+ }
+ }
+
+ private void moveTimeForwardLegacy(long milliSeconds) {
try {
- Message msg = getMessageLinkedList();
+ Message msg = getMessageLinkedListLegacy();
while (msg != null) {
long updatedWhen = msg.getWhen() - milliSeconds;
if (updatedWhen < 0) {
@@ -147,12 +226,12 @@
return mClock.uptimeMillis();
}
- private Message messageQueueNext() {
+ private Message messageQueueNextLegacy() {
try {
long now = currentTime();
Message prevMsg = null;
- Message msg = getMessageLinkedList();
+ Message msg = getMessageLinkedListLegacy();
if (msg != null && msg.getTarget() == null) {
// Stalled by a barrier. Find the next asynchronous message in
// the queue.
@@ -185,18 +264,46 @@
/**
* @return true if there are pending messages in the message queue
*/
- public synchronized boolean isIdle() {
- Message messageList = getMessageLinkedList();
+ public boolean isIdle() {
+ if (isAtLeastBaklava()) {
+ return isIdleBaklava();
+ } else {
+ return isIdleLegacy();
+ }
+ }
+ private boolean isIdleBaklava() {
+ Long when = mTestLooperManager.peekWhen();
+ return when != null && currentTime() >= when;
+ }
+
+ private synchronized boolean isIdleLegacy() {
+ Message messageList = getMessageLinkedListLegacy();
return messageList != null && currentTime() >= messageList.getWhen();
}
/**
* @return the next message in the Looper's message queue or null if there is none
*/
- public synchronized Message nextMessage() {
+ public Message nextMessage() {
+ if (isAtLeastBaklava()) {
+ return nextMessageBaklava();
+ } else {
+ return nextMessageLegacy();
+ }
+ }
+
+ private Message nextMessageBaklava() {
if (isIdle()) {
- return messageQueueNext();
+ return mTestLooperManager.poll();
+ } else {
+ return null;
+ }
+ }
+
+ private synchronized Message nextMessageLegacy() {
+ if (isIdle()) {
+ return messageQueueNextLegacy();
} else {
return null;
}
@@ -206,9 +313,26 @@
* Dispatch the next message in the queue
* Asserts that there is a message in the queue
*/
- public synchronized void dispatchNext() {
+ public void dispatchNext() {
+ if (isAtLeastBaklava()) {
+ dispatchNextBaklava();
+ } else {
+ dispatchNextLegacy();
+ }
+ }
+
+ private void dispatchNextBaklava() {
assertTrue(isIdle());
- Message msg = messageQueueNext();
+ Message msg = mTestLooperManager.poll();
+ if (msg == null) {
+ return;
+ }
+ msg.getTarget().dispatchMessage(msg);
+ }
+
+ private synchronized void dispatchNextLegacy() {
+ assertTrue(isIdle());
+ Message msg = messageQueueNextLegacy();
if (msg == null) {
return;
}
diff --git a/tests/vcn/Android.bp b/tests/vcn/Android.bp
index 51a300b..661ed07 100644
--- a/tests/vcn/Android.bp
+++ b/tests/vcn/Android.bp
@@ -16,13 +16,19 @@
name: "FrameworksVcnTests",
// For access hidden connectivity methods in tests
defaults: ["framework-connectivity-test-defaults"],
+
+ // TODO: b/374174952 Use 36 after Android B finalization
+ min_sdk_version: "35",
+
srcs: [
"java/**/*.java",
"java/**/*.kt",
],
platform_apis: true,
- test_suites: ["device-tests"],
- certificate: "platform",
+ test_suites: [
+ "general-tests",
+ "mts-tethering",
+ ],
static_libs: [
"android.net.vcn.flags-aconfig-java-export",
"androidx.test.rules",
diff --git a/tests/vcn/AndroidManifest.xml b/tests/vcn/AndroidManifest.xml
index a8f657c..08effbd 100644
--- a/tests/vcn/AndroidManifest.xml
+++ b/tests/vcn/AndroidManifest.xml
@@ -16,8 +16,9 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.frameworks.tests.vcn">
- <uses-sdk android:minSdkVersion="33"
- android:targetSdkVersion="33"/>
+ <!-- TODO: b/374174952 Use 36 after Android B finalization -->
+ <uses-sdk android:minSdkVersion="35" android:targetSdkVersion="35" />
+
<application>
<uses-library android:name="android.test.runner" />
</application>
diff --git a/tests/vcn/AndroidTest.xml b/tests/vcn/AndroidTest.xml
index dc521fd..9c8362f 100644
--- a/tests/vcn/AndroidTest.xml
+++ b/tests/vcn/AndroidTest.xml
@@ -14,12 +14,20 @@
limitations under the License.
-->
<configuration description="Runs VCN Tests.">
- <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
+ <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+ <option name="cleanup-apks" value="true" />
<option name="test-file-name" value="FrameworksVcnTests.apk" />
</target_preparer>
<option name="test-suite-tag" value="apct" />
<option name="test-tag" value="FrameworksVcnTests" />
+
+ <!-- Run tests in MTS only if the Tethering Mainline module is installed. -->
+ <object type="module_controller"
+ class="com.android.tradefed.testtype.suite.module.MainlineTestModuleController">
+ <option name="mainline-module-package-name" value="com.google.android.tethering" />
+ </object>
+
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="com.android.frameworks.tests.vcn" />
<option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
diff --git a/tests/vcn/java/android/net/vcn/VcnCellUnderlyingNetworkTemplateTest.java b/tests/vcn/java/android/net/vcn/VcnCellUnderlyingNetworkTemplateTest.java
index 1569613..0fa11ae 100644
--- a/tests/vcn/java/android/net/vcn/VcnCellUnderlyingNetworkTemplateTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnCellUnderlyingNetworkTemplateTest.java
@@ -23,11 +23,24 @@
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.fail;
+import android.os.Build;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
+
import org.junit.Test;
+import org.junit.runner.RunWith;
import java.util.HashSet;
import java.util.Set;
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@SmallTest
public class VcnCellUnderlyingNetworkTemplateTest extends VcnUnderlyingNetworkTemplateTestBase {
private static final Set<String> ALLOWED_PLMN_IDS = new HashSet<>();
private static final Set<Integer> ALLOWED_CARRIER_IDS = new HashSet<>();
diff --git a/tests/vcn/java/android/net/vcn/VcnConfigTest.java b/tests/vcn/java/android/net/vcn/VcnConfigTest.java
index 73a0a61..fa97de0 100644
--- a/tests/vcn/java/android/net/vcn/VcnConfigTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnConfigTest.java
@@ -29,11 +29,14 @@
import android.annotation.NonNull;
import android.content.Context;
+import android.os.Build;
import android.os.Parcel;
import android.util.ArraySet;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Before;
import org.junit.Test;
@@ -42,7 +45,10 @@
import java.util.Collections;
import java.util.Set;
-@RunWith(AndroidJUnit4.class)
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
@SmallTest
public class VcnConfigTest {
private static final String TEST_PACKAGE_NAME = VcnConfigTest.class.getPackage().getName();
diff --git a/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java b/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java
index 59dc689..990cc74 100644
--- a/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java
@@ -34,10 +34,13 @@
import android.net.ipsec.ike.IkeTunnelConnectionParams;
import android.net.vcn.persistablebundleutils.IkeSessionParamsUtilsTest;
import android.net.vcn.persistablebundleutils.TunnelConnectionParamsUtilsTest;
+import android.os.Build;
import android.os.PersistableBundle;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -49,7 +52,10 @@
import java.util.Set;
import java.util.concurrent.TimeUnit;
-@RunWith(AndroidJUnit4.class)
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
@SmallTest
public class VcnGatewayConnectionConfigTest {
// Public for use in VcnGatewayConnectionTest
diff --git a/tests/vcn/java/android/net/vcn/VcnManagerTest.java b/tests/vcn/java/android/net/vcn/VcnManagerTest.java
index 8461de6..1739fbc 100644
--- a/tests/vcn/java/android/net/vcn/VcnManagerTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnManagerTest.java
@@ -38,16 +38,28 @@
import android.net.vcn.VcnManager.VcnStatusCallback;
import android.net.vcn.VcnManager.VcnStatusCallbackBinder;
import android.net.vcn.VcnManager.VcnUnderlyingNetworkPolicyListener;
+import android.os.Build;
import android.os.ParcelUuid;
+import androidx.test.filters.SmallTest;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
+
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import java.net.UnknownHostException;
import java.util.UUID;
import java.util.concurrent.Executor;
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@SmallTest
public class VcnManagerTest {
private static final ParcelUuid SUB_GROUP = new ParcelUuid(new UUID(0, 0));
private static final String GATEWAY_CONNECTION_NAME = "gatewayConnectionName";
diff --git a/tests/vcn/java/android/net/vcn/VcnTransportInfoTest.java b/tests/vcn/java/android/net/vcn/VcnTransportInfoTest.java
index 7bc9970..52952eb 100644
--- a/tests/vcn/java/android/net/vcn/VcnTransportInfoTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnTransportInfoTest.java
@@ -30,12 +30,24 @@
import android.net.NetworkCapabilities;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
+import android.os.Build;
import android.os.Parcel;
+import androidx.test.filters.SmallTest;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
+
import org.junit.Test;
+import org.junit.runner.RunWith;
import java.util.Arrays;
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@SmallTest
public class VcnTransportInfoTest {
private static final int SUB_ID = 1;
private static final int NETWORK_ID = 5;
diff --git a/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkPolicyTest.java b/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkPolicyTest.java
index a674425..c82d200 100644
--- a/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkPolicyTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkPolicyTest.java
@@ -22,9 +22,21 @@
import static org.junit.Assert.assertNotEquals;
import android.net.NetworkCapabilities;
+import android.os.Build;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Test;
+import org.junit.runner.RunWith;
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@SmallTest
public class VcnUnderlyingNetworkPolicyTest {
private static final VcnUnderlyingNetworkPolicy DEFAULT_NETWORK_POLICY =
new VcnUnderlyingNetworkPolicy(
diff --git a/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkSpecifierTest.java b/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkSpecifierTest.java
index 2110d6e..22361cc 100644
--- a/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkSpecifierTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkSpecifierTest.java
@@ -22,14 +22,20 @@
import static org.junit.Assert.assertTrue;
import android.net.TelephonyNetworkSpecifier;
+import android.os.Build;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
-@RunWith(AndroidJUnit4.class)
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
@SmallTest
public class VcnUnderlyingNetworkSpecifierTest {
private static final int[] TEST_SUB_IDS = new int[] {1, 2, 3, 5};
diff --git a/tests/vcn/java/android/net/vcn/VcnUtilsTest.java b/tests/vcn/java/android/net/vcn/VcnUtilsTest.java
index 3ce6c8f..fb040d8 100644
--- a/tests/vcn/java/android/net/vcn/VcnUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnUtilsTest.java
@@ -30,13 +30,25 @@
import android.net.NetworkCapabilities;
import android.net.TelephonyNetworkSpecifier;
import android.net.wifi.WifiInfo;
+import android.os.Build;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
import java.util.Arrays;
import java.util.Collections;
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@SmallTest
public class VcnUtilsTest {
private static final int SUB_ID = 1;
diff --git a/tests/vcn/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplateTest.java b/tests/vcn/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplateTest.java
index 4063178..2c072e1 100644
--- a/tests/vcn/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplateTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplateTest.java
@@ -22,10 +22,23 @@
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import android.os.Build;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
+
import org.junit.Test;
+import org.junit.runner.RunWith;
import java.util.Set;
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@SmallTest
public class VcnWifiUnderlyingNetworkTemplateTest extends VcnUnderlyingNetworkTemplateTestBase {
private static final String SSID = "TestWifi";
diff --git a/tests/vcn/java/android/net/vcn/persistablebundleutils/EapSessionConfigUtilsTest.java b/tests/vcn/java/android/net/vcn/persistablebundleutils/EapSessionConfigUtilsTest.java
index bc8e9d3..01e9ac2 100644
--- a/tests/vcn/java/android/net/vcn/persistablebundleutils/EapSessionConfigUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/persistablebundleutils/EapSessionConfigUtilsTest.java
@@ -21,11 +21,14 @@
import static org.junit.Assert.assertEquals;
import android.net.eap.EapSessionConfig;
+import android.os.Build;
import android.os.PersistableBundle;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -35,7 +38,10 @@
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
-@RunWith(AndroidJUnit4.class)
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
@SmallTest
public class EapSessionConfigUtilsTest {
private static final byte[] EAP_ID = "test@android.net".getBytes(StandardCharsets.US_ASCII);
diff --git a/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeIdentificationUtilsTest.java b/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeIdentificationUtilsTest.java
index 4f3930f..821e5a6 100644
--- a/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeIdentificationUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeIdentificationUtilsTest.java
@@ -25,10 +25,13 @@
import android.net.ipsec.ike.IkeIpv6AddrIdentification;
import android.net.ipsec.ike.IkeKeyIdIdentification;
import android.net.ipsec.ike.IkeRfc822AddrIdentification;
+import android.os.Build;
import android.os.PersistableBundle;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -39,7 +42,10 @@
import javax.security.auth.x500.X500Principal;
-@RunWith(AndroidJUnit4.class)
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
@SmallTest
public class IkeIdentificationUtilsTest {
private static void verifyPersistableBundleEncodeDecodeIsLossless(IkeIdentification id) {
diff --git a/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java b/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java
index 9f7d239..7200aee 100644
--- a/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java
@@ -29,14 +29,16 @@
import android.net.eap.EapSessionConfig;
import android.net.ipsec.ike.IkeFqdnIdentification;
import android.net.ipsec.ike.IkeSessionParams;
+import android.os.Build;
import android.os.PersistableBundle;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import com.android.internal.org.bouncycastle.util.io.pem.PemObject;
import com.android.internal.org.bouncycastle.util.io.pem.PemReader;
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -52,7 +54,10 @@
import java.security.interfaces.RSAPrivateKey;
import java.util.concurrent.TimeUnit;
-@RunWith(AndroidJUnit4.class)
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
@SmallTest
public class IkeSessionParamsUtilsTest {
// Public for use in VcnGatewayConnectionConfigTest, EncryptedTunnelParamsUtilsTest
diff --git a/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeTrafficSelectorUtilsTest.java b/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeTrafficSelectorUtilsTest.java
index 28cf38a..957e785d 100644
--- a/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeTrafficSelectorUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeTrafficSelectorUtilsTest.java
@@ -20,17 +20,23 @@
import android.net.InetAddresses;
import android.net.ipsec.ike.IkeTrafficSelector;
+import android.os.Build;
import android.os.PersistableBundle;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.net.InetAddress;
-@RunWith(AndroidJUnit4.class)
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
@SmallTest
public class IkeTrafficSelectorUtilsTest {
private static final int START_PORT = 16;
diff --git a/tests/vcn/java/android/net/vcn/persistablebundleutils/SaProposalUtilsTest.java b/tests/vcn/java/android/net/vcn/persistablebundleutils/SaProposalUtilsTest.java
index 664044a..1e8f5ff 100644
--- a/tests/vcn/java/android/net/vcn/persistablebundleutils/SaProposalUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/persistablebundleutils/SaProposalUtilsTest.java
@@ -21,15 +21,21 @@
import android.net.ipsec.ike.ChildSaProposal;
import android.net.ipsec.ike.IkeSaProposal;
import android.net.ipsec.ike.SaProposal;
+import android.os.Build;
import android.os.PersistableBundle;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
-@RunWith(AndroidJUnit4.class)
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
@SmallTest
public class SaProposalUtilsTest {
/** Package private so that IkeSessionParamsUtilsTest can use it */
diff --git a/tests/vcn/java/android/net/vcn/persistablebundleutils/TunnelConnectionParamsUtilsTest.java b/tests/vcn/java/android/net/vcn/persistablebundleutils/TunnelConnectionParamsUtilsTest.java
index f9dc9eb..7d17724 100644
--- a/tests/vcn/java/android/net/vcn/persistablebundleutils/TunnelConnectionParamsUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/persistablebundleutils/TunnelConnectionParamsUtilsTest.java
@@ -20,14 +20,20 @@
import android.net.ipsec.ike.IkeSessionParams;
import android.net.ipsec.ike.IkeTunnelConnectionParams;
+import android.os.Build;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
-@RunWith(AndroidJUnit4.class)
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
@SmallTest
public class TunnelConnectionParamsUtilsTest {
// Public for use in VcnGatewayConnectionConfigTest
diff --git a/tests/vcn/java/android/net/vcn/persistablebundleutils/TunnelModeChildSessionParamsUtilsTest.java b/tests/vcn/java/android/net/vcn/persistablebundleutils/TunnelModeChildSessionParamsUtilsTest.java
index e0b5f0e..3d7348a 100644
--- a/tests/vcn/java/android/net/vcn/persistablebundleutils/TunnelModeChildSessionParamsUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/persistablebundleutils/TunnelModeChildSessionParamsUtilsTest.java
@@ -25,10 +25,13 @@
import android.net.ipsec.ike.ChildSaProposal;
import android.net.ipsec.ike.IkeTrafficSelector;
import android.net.ipsec.ike.TunnelModeChildSessionParams;
+import android.os.Build;
import android.os.PersistableBundle;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -37,7 +40,10 @@
import java.net.Inet6Address;
import java.util.concurrent.TimeUnit;
-@RunWith(AndroidJUnit4.class)
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
@SmallTest
public class TunnelModeChildSessionParamsUtilsTest {
// Package private for use in EncryptedTunnelParamsUtilsTest
diff --git a/tests/vcn/java/android/net/vcn/util/MtuUtilsTest.java b/tests/vcn/java/android/net/vcn/util/MtuUtilsTest.java
index 47638b0..99c7aa7 100644
--- a/tests/vcn/java/android/net/vcn/util/MtuUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/util/MtuUtilsTest.java
@@ -33,9 +33,12 @@
import static java.util.Collections.emptyList;
import android.net.ipsec.ike.ChildSaProposal;
+import android.os.Build;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -43,7 +46,10 @@
import java.util.Arrays;
import java.util.List;
-@RunWith(AndroidJUnit4.class)
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
@SmallTest
public class MtuUtilsTest {
private void verifyUnderlyingMtuZero(boolean isIpv4) {
diff --git a/tests/vcn/java/android/net/vcn/util/PersistableBundleUtilsTest.java b/tests/vcn/java/android/net/vcn/util/PersistableBundleUtilsTest.java
index c84e600..f7786af 100644
--- a/tests/vcn/java/android/net/vcn/util/PersistableBundleUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/util/PersistableBundleUtilsTest.java
@@ -21,10 +21,13 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import android.os.Build;
import android.os.PersistableBundle;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -35,7 +38,10 @@
import java.util.List;
import java.util.Objects;
-@RunWith(AndroidJUnit4.class)
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
@SmallTest
public class PersistableBundleUtilsTest {
private static final String TEST_KEY = "testKey";
diff --git a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
index 26a2a06..a97f9a8 100644
--- a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
+++ b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
@@ -79,6 +79,7 @@
import android.net.vcn.VcnUnderlyingNetworkPolicy;
import android.net.vcn.util.PersistableBundleUtils;
import android.net.vcn.util.PersistableBundleUtils.PersistableBundleWrapper;
+import android.os.Build;
import android.os.IBinder;
import android.os.ParcelUuid;
import android.os.PersistableBundle;
@@ -93,7 +94,6 @@
import android.util.ArraySet;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import com.android.server.VcnManagementService.VcnCallback;
import com.android.server.VcnManagementService.VcnStatusCallbackInfo;
@@ -101,6 +101,8 @@
import com.android.server.vcn.Vcn;
import com.android.server.vcn.VcnContext;
import com.android.server.vcn.VcnNetworkProvider;
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Before;
import org.junit.Rule;
@@ -117,8 +119,10 @@
import java.util.Set;
import java.util.UUID;
-/** Tests for {@link VcnManagementService}. */
-@RunWith(AndroidJUnit4.class)
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
@SmallTest
public class VcnManagementServiceTest {
@Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
diff --git a/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java b/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java
index 77f82f0..6276be2 100644
--- a/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java
+++ b/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java
@@ -54,6 +54,7 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.net.vcn.VcnManager;
+import android.os.Build;
import android.os.Handler;
import android.os.ParcelUuid;
import android.os.PersistableBundle;
@@ -69,9 +70,10 @@
import android.util.ArraySet;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import com.android.modules.utils.HandlerExecutor;
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Before;
import org.junit.Test;
@@ -87,8 +89,10 @@
import java.util.Set;
import java.util.UUID;
-/** Tests for TelephonySubscriptionTracker */
-@RunWith(AndroidJUnit4.class)
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
@SmallTest
public class TelephonySubscriptionTrackerTest {
private static final String PACKAGE_NAME =
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
index 74db6a5..6608dda 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
@@ -70,16 +70,18 @@
import android.net.vcn.VcnManager.VcnErrorCode;
import android.net.vcn.VcnTransportInfo;
import android.net.vcn.util.MtuUtils;
+import android.os.Build;
import android.os.PersistableBundle;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import com.android.server.vcn.VcnGatewayConnection.VcnChildSessionCallback;
import com.android.server.vcn.VcnGatewayConnection.VcnChildSessionConfiguration;
import com.android.server.vcn.VcnGatewayConnection.VcnIkeSession;
import com.android.server.vcn.VcnGatewayConnection.VcnNetworkAgent;
import com.android.server.vcn.routeselection.UnderlyingNetworkRecord;
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Before;
import org.junit.Test;
@@ -94,8 +96,10 @@
import java.util.List;
import java.util.function.Consumer;
-/** Tests for VcnGatewayConnection.ConnectedState */
-@RunWith(AndroidJUnit4.class)
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
@SmallTest
public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnectionTestBase {
private static final int PARALLEL_SA_COUNT = 4;
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java
index 3c70759..f6123d2 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java
@@ -26,17 +26,22 @@
import static org.mockito.Mockito.verify;
import android.net.ipsec.ike.IkeSessionParams;
+import android.os.Build;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
-/** Tests for VcnGatewayConnection.ConnectingState */
-@RunWith(AndroidJUnit4.class)
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
@SmallTest
public class VcnGatewayConnectionConnectingStateTest extends VcnGatewayConnectionTestBase {
private VcnIkeSession mIkeSession;
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectedStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectedStateTest.java
index f3eb82f..7cfaf5b 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectedStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectedStateTest.java
@@ -30,16 +30,21 @@
import static org.mockito.Mockito.verify;
import android.net.IpSecManager;
+import android.os.Build;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-/** Tests for VcnGatewayConnection.DisconnectedState */
-@RunWith(AndroidJUnit4.class)
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
@SmallTest
public class VcnGatewayConnectionDisconnectedStateTest extends VcnGatewayConnectionTestBase {
@Before
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java
index 78aefad..9132d83 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java
@@ -23,15 +23,21 @@
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
+import android.os.Build;
+
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-/** Tests for VcnGatewayConnection.DisconnectedState */
-@RunWith(AndroidJUnit4.class)
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
@SmallTest
public class VcnGatewayConnectionDisconnectingStateTest extends VcnGatewayConnectionTestBase {
@Before
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionRetryTimeoutStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionRetryTimeoutStateTest.java
index 6568cdd..d5ef4e0 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionRetryTimeoutStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionRetryTimeoutStateTest.java
@@ -27,15 +27,21 @@
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
+import android.os.Build;
+
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-/** Tests for VcnGatewayConnection.RetryTimeoutState */
-@RunWith(AndroidJUnit4.class)
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
@SmallTest
public class VcnGatewayConnectionRetryTimeoutStateTest extends VcnGatewayConnectionTestBase {
private long mFirstRetryInterval;
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java
index b9fe76a..5283322 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java
@@ -61,15 +61,17 @@
import android.net.vcn.VcnManager;
import android.net.vcn.VcnTransportInfo;
import android.net.wifi.WifiInfo;
+import android.os.Build;
import android.os.ParcelUuid;
import android.os.Process;
import android.telephony.SubscriptionInfo;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot;
import com.android.server.vcn.routeselection.UnderlyingNetworkRecord;
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Before;
import org.junit.Test;
@@ -87,8 +89,10 @@
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
-/** Tests for TelephonySubscriptionTracker */
-@RunWith(AndroidJUnit4.class)
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
@SmallTest
public class VcnGatewayConnectionTest extends VcnGatewayConnectionTestBase {
private static final int TEST_UID = Process.myUid() + 1;
diff --git a/tests/vcn/java/com/android/server/vcn/VcnNetworkProviderTest.java b/tests/vcn/java/com/android/server/vcn/VcnNetworkProviderTest.java
index e9026e2..2b92428 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnNetworkProviderTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnNetworkProviderTest.java
@@ -29,12 +29,14 @@
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkRequest;
+import android.os.Build;
import android.os.test.TestLooper;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import com.android.server.vcn.VcnNetworkProvider.NetworkRequestListener;
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Before;
import org.junit.Test;
@@ -44,8 +46,10 @@
import java.util.ArrayList;
import java.util.List;
-/** Tests for TelephonySubscriptionTracker */
-@RunWith(AndroidJUnit4.class)
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
@SmallTest
public class VcnNetworkProviderTest {
private static final int TEST_SCORE_UNSATISFIED = 0;
diff --git a/tests/vcn/java/com/android/server/vcn/VcnTest.java b/tests/vcn/java/com/android/server/vcn/VcnTest.java
index 6d26968..bd4aeba 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnTest.java
@@ -49,20 +49,26 @@
import android.net.vcn.VcnConfig;
import android.net.vcn.VcnGatewayConnectionConfig;
import android.net.vcn.VcnGatewayConnectionConfigTest;
+import android.os.Build;
import android.os.ParcelUuid;
import android.os.test.TestLooper;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.util.ArraySet;
+import androidx.test.filters.SmallTest;
+
import com.android.server.VcnManagementService.VcnCallback;
import com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot;
import com.android.server.vcn.Vcn.VcnGatewayStatusCallback;
import com.android.server.vcn.Vcn.VcnUserMobileDataStateListener;
import com.android.server.vcn.VcnNetworkProvider.NetworkRequestListener;
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import java.util.ArrayList;
@@ -73,6 +79,11 @@
import java.util.Set;
import java.util.UUID;
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@SmallTest
public class VcnTest {
private static final String PKG_NAME = VcnTest.class.getPackage().getName();
private static final ParcelUuid TEST_SUB_GROUP = new ParcelUuid(new UUID(0, 0));
diff --git a/tests/vcn/java/com/android/server/vcn/routeselection/IpSecPacketLossDetectorTest.java b/tests/vcn/java/com/android/server/vcn/routeselection/IpSecPacketLossDetectorTest.java
index c11b6bb..53a36d3 100644
--- a/tests/vcn/java/com/android/server/vcn/routeselection/IpSecPacketLossDetectorTest.java
+++ b/tests/vcn/java/com/android/server/vcn/routeselection/IpSecPacketLossDetectorTest.java
@@ -44,16 +44,22 @@
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.net.IpSecTransformState;
+import android.os.Build;
import android.os.OutcomeReceiver;
import android.os.PowerManager;
+import androidx.test.filters.SmallTest;
+
import com.android.server.vcn.routeselection.IpSecPacketLossDetector.PacketLossCalculationResult;
import com.android.server.vcn.routeselection.IpSecPacketLossDetector.PacketLossCalculator;
import com.android.server.vcn.routeselection.NetworkMetricMonitor.IpSecTransformWrapper;
import com.android.server.vcn.routeselection.NetworkMetricMonitor.NetworkMetricMonitorCallback;
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
@@ -63,6 +69,11 @@
import java.util.BitSet;
import java.util.concurrent.TimeUnit;
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@SmallTest
public class IpSecPacketLossDetectorTest extends NetworkEvaluationTestBase {
private static final String TAG = IpSecPacketLossDetectorTest.class.getSimpleName();
diff --git a/tests/vcn/java/com/android/server/vcn/routeselection/NetworkPriorityClassifierTest.java b/tests/vcn/java/com/android/server/vcn/routeselection/NetworkPriorityClassifierTest.java
index 4f34f9f..a9c637f 100644
--- a/tests/vcn/java/com/android/server/vcn/routeselection/NetworkPriorityClassifierTest.java
+++ b/tests/vcn/java/com/android/server/vcn/routeselection/NetworkPriorityClassifierTest.java
@@ -42,16 +42,28 @@
import android.net.vcn.VcnManager;
import android.net.vcn.VcnUnderlyingNetworkTemplate;
import android.net.vcn.VcnWifiUnderlyingNetworkTemplate;
+import android.os.Build;
import android.os.PersistableBundle;
import android.util.ArraySet;
+import androidx.test.filters.SmallTest;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
+
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
import java.util.Collections;
import java.util.List;
import java.util.Set;
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@SmallTest
public class NetworkPriorityClassifierTest extends NetworkEvaluationTestBase {
private UnderlyingNetworkRecord mWifiNetworkRecord;
private UnderlyingNetworkRecord mCellNetworkRecord;
diff --git a/tests/vcn/java/com/android/server/vcn/routeselection/UnderlyingNetworkControllerTest.java b/tests/vcn/java/com/android/server/vcn/routeselection/UnderlyingNetworkControllerTest.java
index e540932..99c508c 100644
--- a/tests/vcn/java/com/android/server/vcn/routeselection/UnderlyingNetworkControllerTest.java
+++ b/tests/vcn/java/com/android/server/vcn/routeselection/UnderlyingNetworkControllerTest.java
@@ -58,6 +58,7 @@
import android.net.vcn.VcnCellUnderlyingNetworkTemplateTest;
import android.net.vcn.VcnGatewayConnectionConfigTest;
import android.net.vcn.VcnUnderlyingNetworkTemplate;
+import android.os.Build;
import android.os.ParcelUuid;
import android.os.test.TestLooper;
import android.telephony.CarrierConfigManager;
@@ -65,6 +66,8 @@
import android.telephony.TelephonyManager;
import android.util.ArraySet;
+import androidx.test.filters.SmallTest;
+
import com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot;
import com.android.server.vcn.VcnContext;
import com.android.server.vcn.VcnNetworkProvider;
@@ -73,9 +76,12 @@
import com.android.server.vcn.routeselection.UnderlyingNetworkController.UnderlyingNetworkControllerCallback;
import com.android.server.vcn.routeselection.UnderlyingNetworkController.UnderlyingNetworkListener;
import com.android.server.vcn.routeselection.UnderlyingNetworkEvaluator.NetworkEvaluatorCallback;
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
@@ -89,6 +95,11 @@
import java.util.Set;
import java.util.UUID;
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@SmallTest
public class UnderlyingNetworkControllerTest {
private static final ParcelUuid SUB_GROUP = new ParcelUuid(new UUID(0, 0));
private static final int INITIAL_SUB_ID_1 = 1;
diff --git a/tests/vcn/java/com/android/server/vcn/routeselection/UnderlyingNetworkEvaluatorTest.java b/tests/vcn/java/com/android/server/vcn/routeselection/UnderlyingNetworkEvaluatorTest.java
index a315b069..27c1bc1 100644
--- a/tests/vcn/java/com/android/server/vcn/routeselection/UnderlyingNetworkEvaluatorTest.java
+++ b/tests/vcn/java/com/android/server/vcn/routeselection/UnderlyingNetworkEvaluatorTest.java
@@ -38,19 +38,30 @@
import android.net.IpSecTransform;
import android.net.vcn.VcnGatewayConnectionConfig;
+import android.os.Build;
+
+import androidx.test.filters.SmallTest;
import com.android.server.vcn.routeselection.NetworkMetricMonitor.NetworkMetricMonitorCallback;
import com.android.server.vcn.routeselection.UnderlyingNetworkEvaluator.Dependencies;
import com.android.server.vcn.routeselection.UnderlyingNetworkEvaluator.NetworkEvaluatorCallback;
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import java.util.concurrent.TimeUnit;
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@SmallTest
public class UnderlyingNetworkEvaluatorTest extends NetworkEvaluationTestBase {
private static final int PENALTY_TIMEOUT_MIN = 10;
private static final long PENALTY_TIMEOUT_MS = TimeUnit.MINUTES.toMillis(PENALTY_TIMEOUT_MIN);
diff --git a/tools/aapt2/Debug.cpp b/tools/aapt2/Debug.cpp
index e24fe07..9ef8b7d 100644
--- a/tools/aapt2/Debug.cpp
+++ b/tools/aapt2/Debug.cpp
@@ -349,20 +349,22 @@
value->value->Accept(&body_printer);
printer->Undent();
}
- printer->Println("Flag disabled values:");
- for (const auto& value : entry.flag_disabled_values) {
- printer->Print("(");
- printer->Print(value->config.to_string());
- printer->Print(") ");
- value->value->Accept(&headline_printer);
- if (options.show_sources && !value->value->GetSource().path.empty()) {
- printer->Print(" src=");
- printer->Print(value->value->GetSource().to_string());
+ if (!entry.flag_disabled_values.empty()) {
+ printer->Println("Flag disabled values:");
+ for (const auto& value : entry.flag_disabled_values) {
+ printer->Print("(");
+ printer->Print(value->config.to_string());
+ printer->Print(") ");
+ value->value->Accept(&headline_printer);
+ if (options.show_sources && !value->value->GetSource().path.empty()) {
+ printer->Print(" src=");
+ printer->Print(value->value->GetSource().to_string());
+ }
+ printer->Println();
+ printer->Indent();
+ value->value->Accept(&body_printer);
+ printer->Undent();
}
- printer->Println();
- printer->Indent();
- value->value->Accept(&body_printer);
- printer->Undent();
}
printer->Undent();
}