Merge "Fix for GestureShortcutOptionControllerTest" into main
diff --git a/res/layout/preference_volume_slider.xml b/res/layout/preference_volume_slider.xml
index 3377231..50095f4 100644
--- a/res/layout/preference_volume_slider.xml
+++ b/res/layout/preference_volume_slider.xml
@@ -42,6 +42,7 @@
                 android:layout_height="wrap_content"
                 android:layout_weight="1"
                 android:singleLine="true"
+                android:textAlignment="viewStart"
                 android:textAppearance="?android:attr/textAppearanceListItem"
                 android:ellipsize="marquee"
                 android:fadingEdge="horizontal"/>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index fb95aa3..7e363e6 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -9762,8 +9762,10 @@
     <string name="launch_by_default">Open by default</string>
 
     <string name="app_launch_open_domain_urls_title">Open supported links</string>
+    <string name="app_launch_open_in_app">In the app</string>
+    <string name="app_launch_open_in_browser">In your browser</string>
     <!-- Preference title for Supported links open in this app. [CHAR LIMIT=60] -->
-    <string name="app_launch_top_intro_message">Allow web links to open in this app</string>
+    <string name="app_launch_top_intro_message">Choose how to open web links for this app</string>
     <!-- Preference title for Links to open in this app. [CHAR LIMIT=60] -->
     <string name="app_launch_links_category">Links to open in this app</string>
 
diff --git a/res/values/themes.xml b/res/values/themes.xml
index e91ca49..64c8904 100644
--- a/res/values/themes.xml
+++ b/res/values/themes.xml
@@ -114,13 +114,7 @@
         <item name="android:windowSoftInputMode">adjustResize</item>
     </style>
 
-    <style name="Theme.AlertDialog.Base" parent="@style/Theme.AppCompat.DayNight.Dialog.Alert">
-        <item name="colorAccent">@android:color/system_primary_light</item>
-        <item name="android:colorError">@color/settings_dialog_colorError</item>
-        <item name="android:colorBackground">@android:color/system_surface_container_high_light</item>
-    </style>
-
-    <style name="Theme.AlertDialog" parent="Theme.AlertDialog.Base">
+    <style name="Theme.AlertDialog" parent="@style/Theme.AppCompat.DayNight.Dialog.Alert">
         <item name="android:windowSoftInputMode">adjustResize</item>
         <item name="android:clipToPadding">true</item>
         <item name="android:clipChildren">true</item>
diff --git a/res/xml/installed_app_launch_settings.xml b/res/xml/installed_app_launch_settings.xml
index 2268d5c..ffd73bc 100644
--- a/res/xml/installed_app_launch_settings.xml
+++ b/res/xml/installed_app_launch_settings.xml
@@ -19,9 +19,15 @@
     xmlns:settings="http://schemas.android.com/apk/res-auto"
     android:title="@string/launch_by_default">
 
-    <com.android.settingslib.widget.MainSwitchPreference
-        android:key="open_by_default_supported_links"
-        android:title="@string/app_launch_open_domain_urls_title"/>
+    <PreferenceCategory>
+        <com.android.settingslib.widget.SelectorWithWidgetPreference
+            android:key="app_launch_open_in_app"
+            android:title="@string/app_launch_open_in_app"/>
+
+        <com.android.settingslib.widget.SelectorWithWidgetPreference
+            android:key="app_launch_open_in_browser"
+            android:title="@string/app_launch_open_in_browser"/>
+    </PreferenceCategory>
 
     <PreferenceCategory
         android:layout="@layout/preference_category_no_label"
diff --git a/src/com/android/settings/applications/intentpicker/AppLaunchSettings.java b/src/com/android/settings/applications/intentpicker/AppLaunchSettings.java
index 676c35a..4b2f348 100644
--- a/src/com/android/settings/applications/intentpicker/AppLaunchSettings.java
+++ b/src/com/android/settings/applications/intentpicker/AppLaunchSettings.java
@@ -20,6 +20,7 @@
 import static android.content.pm.verify.domain.DomainVerificationUserState.DOMAIN_STATE_SELECTED;
 import static android.content.pm.verify.domain.DomainVerificationUserState.DOMAIN_STATE_VERIFIED;
 
+import android.annotation.Nullable;
 import android.app.Activity;
 import android.app.settings.SettingsEnums;
 import android.appwidget.AppWidgetManager;
@@ -35,10 +36,9 @@
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
-import android.widget.CompoundButton;
-import android.widget.CompoundButton.OnCheckedChangeListener;
 import android.widget.TextView;
 
+import androidx.annotation.NonNull;
 import androidx.annotation.VisibleForTesting;
 import androidx.appcompat.app.AlertDialog;
 import androidx.preference.Preference;
@@ -51,7 +51,7 @@
 import com.android.settings.widget.EntityHeaderController;
 import com.android.settingslib.applications.AppUtils;
 import com.android.settingslib.widget.FooterPreference;
-import com.android.settingslib.widget.MainSwitchPreference;
+import com.android.settingslib.widget.SelectorWithWidgetPreference;
 
 import java.util.HashMap;
 import java.util.List;
@@ -62,10 +62,11 @@
 
 /** The page of the Open by default */
 public class AppLaunchSettings extends AppInfoBase implements
-        Preference.OnPreferenceChangeListener, OnCheckedChangeListener {
+        Preference.OnPreferenceChangeListener, SelectorWithWidgetPreference.OnClickListener {
     private static final String TAG = "AppLaunchSettings";
     // Preference keys
-    private static final String MAIN_SWITCH_PREF_KEY = "open_by_default_supported_links";
+    private static final String OPEN_IN_APP_PREF_KEY = "app_launch_open_in_app";
+    private static final String OPEN_IN_BROWSER_PREF_KEY = "app_launch_open_in_browser";
     private static final String VERIFIED_LINKS_PREF_KEY = "open_by_default_verified_links";
     private static final String ADD_LINK_PREF_KEY = "open_by_default_add_link";
     private static final String CLEAR_DEFAULTS_PREF_KEY = "app_launch_clear_defaults";
@@ -86,7 +87,10 @@
     public static final String APP_PACKAGE_KEY = "app_package";
 
     private ClearDefaultsPreference mClearDefaultsPreference;
-    private MainSwitchPreference mMainSwitchPreference;
+    @Nullable
+    private SelectorWithWidgetPreference mOpenInAppSelector;
+    @Nullable
+    private SelectorWithWidgetPreference mOpenInBrowserSelector;
     private Preference mAddLinkPreference;
     private PreferenceCategory mMainPreferenceCategory;
     private PreferenceCategory mSelectedLinksPreferenceCategory;
@@ -168,20 +172,20 @@
     }
 
     @Override
-    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
-        IntentPickerUtils.logd("onSwitchChanged: isChecked=" + isChecked);
-        if (mMainSwitchPreference != null) { //mMainSwitchPreference synced with Switch
-            mMainSwitchPreference.setChecked(isChecked);
-        }
+    public void onRadioButtonClicked(@NonNull SelectorWithWidgetPreference selected) {
+        final boolean openSupportedLinks = selected.getKey().equals(OPEN_IN_APP_PREF_KEY);
+        IntentPickerUtils.logd("onRadioButtonClicked: openInApp =" + openSupportedLinks);
+        setOpenByDefaultPreference(openSupportedLinks /* openInApp */);
+
         if (mMainPreferenceCategory != null) {
-            mMainPreferenceCategory.setVisible(isChecked);
+            mMainPreferenceCategory.setVisible(openSupportedLinks);
         }
         if (mDomainVerificationManager != null) {
             try {
                 mDomainVerificationManager.setDomainVerificationLinkHandlingAllowed(mPackageName,
-                        isChecked);
+                        openSupportedLinks);
             } catch (PackageManager.NameNotFoundException e) {
-                Log.w(TAG, "onSwitchChanged: " + e.getMessage());
+                Log.w(TAG, "onRadioButtonClicked: " + e.getMessage());
             }
         }
     }
@@ -224,7 +228,8 @@
     }
 
     private void initMainSwitchAndCategories() {
-        mMainSwitchPreference = (MainSwitchPreference) findPreference(MAIN_SWITCH_PREF_KEY);
+        mOpenInAppSelector = findPreference(OPEN_IN_APP_PREF_KEY);
+        mOpenInBrowserSelector = findPreference(OPEN_IN_BROWSER_PREF_KEY);
         mMainPreferenceCategory = findPreference(MAIN_PREF_CATEGORY_KEY);
         mSelectedLinksPreferenceCategory = findPreference(SELECTED_LINKS_CATEGORY_KEY);
         // Initialize the "Other Default Category" section
@@ -235,14 +240,15 @@
         final DomainVerificationUserState userState =
                 IntentPickerUtils.getDomainVerificationUserState(mDomainVerificationManager,
                         mPackageName);
-        if (userState == null) {
+        if (userState == null || mOpenInAppSelector == null || mOpenInBrowserSelector == null) {
             disabledPreference();
             return false;
         }
 
         IntentPickerUtils.logd("isLinkHandlingAllowed() : " + userState.isLinkHandlingAllowed());
-        mMainSwitchPreference.updateStatus(userState.isLinkHandlingAllowed());
-        mMainSwitchPreference.addOnSwitchChangeListener(this);
+        setOpenByDefaultPreference(userState.isLinkHandlingAllowed());
+        mOpenInAppSelector.setOnClickListener(this);
+        mOpenInBrowserSelector.setOnClickListener(this);
         mMainPreferenceCategory.setVisible(userState.isLinkHandlingAllowed());
         return true;
     }
@@ -260,6 +266,12 @@
         verifiedLinksPreference.setEnabled(verifiedLinksNo > 0);
     }
 
+    private void setOpenByDefaultPreference(boolean openInApp) {
+        if (mOpenInBrowserSelector == null || mOpenInAppSelector == null) return;
+        mOpenInAppSelector.setChecked(openInApp);
+        mOpenInBrowserSelector.setChecked(!openInApp);
+    }
+
     private void showVerifiedLinksDialog() {
         final int linksNo = getLinksNumber(DOMAIN_STATE_VERIFIED);
         if (linksNo == 0) {
@@ -360,9 +372,12 @@
     }
 
     private void disabledPreference() {
-        mMainSwitchPreference.updateStatus(false);
-        mMainSwitchPreference.setSelectable(false);
-        mMainSwitchPreference.setEnabled(false);
+        if (mOpenInAppSelector == null ||mOpenInBrowserSelector == null) return;
+        setOpenByDefaultPreference(false /* openInApp */);
+        mOpenInAppSelector.setSelectable(false);
+        mOpenInAppSelector.setEnabled(false);
+        mOpenInBrowserSelector.setSelectable(false);
+        mOpenInBrowserSelector.setEnabled(false);
         mMainPreferenceCategory.setVisible(false);
     }
 
diff --git a/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionScreen.kt b/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionScreen.kt
index 0908f9e..0075068 100644
--- a/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionScreen.kt
+++ b/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionScreen.kt
@@ -48,8 +48,8 @@
     override fun getPreferenceHierarchy(context: Context) =
         preferenceHierarchy(this) {
             +PreferenceWidget("os_firmware_version", R.string.firmware_version)
-            +PreferenceWidget("security_key", R.string.security_patch)
-            +PreferenceWidget("module_version", R.string.module_version)
+            +SecurityPatchLevelPreference()
+            +MainlineModuleVersionPreference()
             +BasebandVersionPreference()
             +KernelVersionPreference()
             +SimpleBuildNumberPreference()
diff --git a/src/com/android/settings/deviceinfo/firmwareversion/MainlineModuleVersionPreference.kt b/src/com/android/settings/deviceinfo/firmwareversion/MainlineModuleVersionPreference.kt
new file mode 100644
index 0000000..fae1a94
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/firmwareversion/MainlineModuleVersionPreference.kt
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.deviceinfo.firmwareversion
+
+import android.content.Context
+import android.content.Intent
+import android.content.pm.PackageManager
+import android.text.format.DateFormat
+import android.util.Log
+import androidx.preference.Preference
+import com.android.settings.R
+import com.android.settings.flags.Flags
+import com.android.settings.utils.getLocale
+import com.android.settingslib.metadata.PreferenceAvailabilityProvider
+import com.android.settingslib.metadata.PreferenceMetadata
+import com.android.settingslib.metadata.PreferenceSummaryProvider
+import com.android.settingslib.preference.PreferenceBinding
+import java.text.ParseException
+import java.text.SimpleDateFormat
+import java.util.Date
+import java.util.TimeZone
+
+// LINT.IfChange
+class MainlineModuleVersionPreference :
+    PreferenceMetadata,
+    PreferenceSummaryProvider,
+    PreferenceAvailabilityProvider,
+    PreferenceBinding {
+
+    private var moduleVersion: String? = null
+
+    override val key: String
+        get() = "module_version"
+
+    override val title: Int
+        get() = R.string.module_version
+
+    override fun getSummary(context: Context): CharSequence? {
+        val version = getModuleVersion(context)
+        if (version.isEmpty()) return null
+
+        val locale = context.getLocale()
+        fun parseDate(pattern: String): Date? {
+            val simpleDateFormat = SimpleDateFormat(pattern, locale)
+            simpleDateFormat.timeZone = TimeZone.getDefault()
+            return try {
+                simpleDateFormat.parse(version)
+            } catch (e: ParseException) {
+                null
+            }
+        }
+
+        val date = parseDate("yyyy-MM-dd") ?: parseDate("yyyy-MM")
+        return if (date == null) {
+            Log.w(TAG, "Cannot parse mainline versionName ($version) as date")
+            version
+        } else {
+            DateFormat.format(DateFormat.getBestDateTimePattern(locale, "dMMMMyyyy"), date)
+        }
+    }
+
+    override fun intent(context: Context): Intent? {
+        val packageManager = context.packageManager
+        val intentPackage =
+            if (Flags.mainlineModuleExplicitIntent()) {
+                context.getString(R.string.config_mainline_module_update_package)
+            } else {
+                null
+            }
+        fun String.resolveIntent() =
+            Intent(this).let {
+                if (intentPackage != null) it.setPackage(intentPackage)
+                if (packageManager.resolveActivity(it, 0) != null) it else null
+            }
+
+        return MODULE_UPDATE_ACTION_V2.resolveIntent() ?: MODULE_UPDATE_ACTION.resolveIntent()
+    }
+
+    override fun isAvailable(context: Context) = getModuleVersion(context).isNotEmpty()
+
+    override fun bind(preference: Preference, metadata: PreferenceMetadata) {
+        super.bind(preference, metadata)
+        preference.isSelectable = preference.intent != null
+        preference.isCopyingEnabled = true
+    }
+
+    private fun getModuleVersion(context: Context): String =
+        moduleVersion ?: context.getVersion().also { moduleVersion = it }
+
+    private fun Context.getVersion(): String {
+        val moduleProvider =
+            getString(com.android.internal.R.string.config_defaultModuleMetadataProvider)
+        if (moduleProvider.isEmpty()) return ""
+        return try {
+            packageManager.getPackageInfo(moduleProvider, 0)?.versionName ?: ""
+        } catch (e: PackageManager.NameNotFoundException) {
+            Log.e(TAG, "Failed to get mainline version.", e)
+            ""
+        }
+    }
+
+    companion object {
+        private const val TAG = "MainlineModulePreference"
+        const val MODULE_UPDATE_ACTION = "android.settings.MODULE_UPDATE_SETTINGS"
+        const val MODULE_UPDATE_ACTION_V2 = "android.settings.MODULE_UPDATE_VERSIONS"
+    }
+}
+// LINT.ThenChange(MainlineModuleVersionPreferenceController.java)
diff --git a/src/com/android/settings/deviceinfo/firmwareversion/MainlineModuleVersionPreferenceController.java b/src/com/android/settings/deviceinfo/firmwareversion/MainlineModuleVersionPreferenceController.java
index 4c02feb..b65497f 100644
--- a/src/com/android/settings/deviceinfo/firmwareversion/MainlineModuleVersionPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/firmwareversion/MainlineModuleVersionPreferenceController.java
@@ -39,6 +39,7 @@
 import java.util.Optional;
 import java.util.TimeZone;
 
+// LINT.IfChange
 public class MainlineModuleVersionPreferenceController extends BasePreferenceController {
 
     @VisibleForTesting
@@ -141,3 +142,4 @@
         return Optional.empty();
     }
 }
+// LINT.ThenChange(MainlineModuleVersionPreference.kt)
diff --git a/src/com/android/settings/deviceinfo/firmwareversion/SecurityPatchLevelPreference.kt b/src/com/android/settings/deviceinfo/firmwareversion/SecurityPatchLevelPreference.kt
new file mode 100644
index 0000000..7af389e
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/firmwareversion/SecurityPatchLevelPreference.kt
@@ -0,0 +1,63 @@
+/*
+ * 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.settings.deviceinfo.firmwareversion
+
+import android.content.Context
+import android.content.Intent
+import android.net.Uri
+import androidx.preference.Preference
+import com.android.settings.R
+import com.android.settings.utils.getLocale
+import com.android.settingslib.DeviceInfoUtils
+import com.android.settingslib.metadata.PreferenceAvailabilityProvider
+import com.android.settingslib.metadata.PreferenceMetadata
+import com.android.settingslib.metadata.PreferenceSummaryProvider
+import com.android.settingslib.preference.PreferenceBinding
+
+// LINT.IfChange
+class SecurityPatchLevelPreference :
+    PreferenceMetadata,
+    PreferenceAvailabilityProvider,
+    PreferenceSummaryProvider,
+    PreferenceBinding {
+
+    private var currentPatch: String? = null
+
+    override val key: String
+        get() = "security_key"
+
+    override val title: Int
+        get() = R.string.security_patch
+
+    override fun intent(context: Context): Intent? =
+        Intent(Intent.ACTION_VIEW)
+            .setData(Uri.parse("https://source.android.com/docs/security/bulletin/"))
+
+    override fun isAvailable(context: Context) = context.getPatch().isNotEmpty()
+
+    override fun getSummary(context: Context) = context.getPatch()
+
+    private fun Context.getPatch(): String =
+        currentPatch
+            ?: (DeviceInfoUtils.getSecurityPatch(getLocale()) ?: "").also { currentPatch = it }
+
+    override fun bind(preference: Preference, metadata: PreferenceMetadata) {
+        super.bind(preference, metadata)
+        preference.isCopyingEnabled = true
+    }
+}
+// LINT.ThenChange(SecurityPatchLevelPreferenceController.java)
diff --git a/src/com/android/settings/deviceinfo/firmwareversion/SecurityPatchLevelPreferenceController.java b/src/com/android/settings/deviceinfo/firmwareversion/SecurityPatchLevelPreferenceController.java
index dcb5a37..b4648ee 100644
--- a/src/com/android/settings/deviceinfo/firmwareversion/SecurityPatchLevelPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/firmwareversion/SecurityPatchLevelPreferenceController.java
@@ -16,6 +16,7 @@
 
 package com.android.settings.deviceinfo.firmwareversion;
 
+// LINT.IfChange
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
@@ -73,3 +74,4 @@
         return true;
     }
 }
+// LINT.ThenChange(SecurityPatchLevelPreference.kt)
diff --git a/src/com/android/settings/notification/zen/ZenModeAutomationSettings.java b/src/com/android/settings/notification/zen/ZenModeAutomationSettings.java
index 5f31781..904b554 100644
--- a/src/com/android/settings/notification/zen/ZenModeAutomationSettings.java
+++ b/src/com/android/settings/notification/zen/ZenModeAutomationSettings.java
@@ -30,18 +30,15 @@
 import androidx.fragment.app.Fragment;
 
 import com.android.settings.R;
-import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settings.utils.ManagedServiceSettings;
 import com.android.settings.utils.ZenServiceListing;
 import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.core.lifecycle.Lifecycle;
-import com.android.settingslib.search.SearchIndexable;
 
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
-@SearchIndexable
 public class ZenModeAutomationSettings extends ZenModeSettingsBase {
     public static final String DELETE = "DELETE_RULE";
     protected final ManagedServiceSettings.Config CONFIG = getConditionProviderConfig();
@@ -133,25 +130,4 @@
                 return super.onOptionsItemSelected(item);
         }
     }
-
-    /**
-     * For Search.
-     */
-    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-            new BaseSearchIndexProvider(R.xml.zen_mode_automation_settings) {
-
-                @Override
-                public List<String> getNonIndexableKeys(Context context) {
-                    final List<String> keys = super.getNonIndexableKeys(context);
-                    keys.add(ZenModeAddAutomaticRulePreferenceController.KEY);
-                    keys.add(ZenModeAutomaticRulesPreferenceController.KEY);
-                    return keys;
-                }
-
-                @Override
-                public List<AbstractPreferenceController> createPreferenceControllers(
-                        Context context) {
-                    return buildPreferenceControllers(context, null, null, null);
-                }
-            };
 }
diff --git a/src/com/android/settings/notification/zen/ZenModeBlockedEffectsSettings.java b/src/com/android/settings/notification/zen/ZenModeBlockedEffectsSettings.java
index c2962dc..2e5d33f 100644
--- a/src/com/android/settings/notification/zen/ZenModeBlockedEffectsSettings.java
+++ b/src/com/android/settings/notification/zen/ZenModeBlockedEffectsSettings.java
@@ -29,16 +29,13 @@
 import android.os.Bundle;
 
 import com.android.settings.R;
-import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.search.Indexable;
-import com.android.settingslib.search.SearchIndexable;
 
 import java.util.ArrayList;
 import java.util.List;
 
-@SearchIndexable
 public class ZenModeBlockedEffectsSettings extends ZenModeSettingsBase implements Indexable {
 
     @Override
@@ -88,16 +85,4 @@
     public int getMetricsCategory() {
         return SettingsEnums.ZEN_WHAT_TO_BLOCK;
     }
-
-    /**
-     * For Search.
-     */
-    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-            new BaseSearchIndexProvider(R.xml.zen_mode_block_settings) {
-
-            @Override
-            public List<AbstractPreferenceController> createPreferenceControllers(Context context) {
-                return buildPreferenceControllers(context, null);
-            }
-        };
 }
diff --git a/src/com/android/settings/notification/zen/ZenModeBypassingAppsSettings.java b/src/com/android/settings/notification/zen/ZenModeBypassingAppsSettings.java
index 89a80f0..64489cb 100644
--- a/src/com/android/settings/notification/zen/ZenModeBypassingAppsSettings.java
+++ b/src/com/android/settings/notification/zen/ZenModeBypassingAppsSettings.java
@@ -25,15 +25,12 @@
 
 import com.android.settings.R;
 import com.android.settings.notification.NotificationBackend;
-import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.search.Indexable;
-import com.android.settingslib.search.SearchIndexable;
 
 import java.util.ArrayList;
 import java.util.List;
 
-@SearchIndexable
 public class ZenModeBypassingAppsSettings extends ZenModeSettingsBase implements
         Indexable {
     private final String TAG = "ZenBypassingApps";
@@ -74,17 +71,4 @@
     public int getMetricsCategory() {
         return SettingsEnums.NOTIFICATION_ZEN_MODE_OVERRIDING_APPS;
     }
-
-    /**
-     * For Search.
-     */
-    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-            new BaseSearchIndexProvider(R.xml.zen_mode_bypassing_apps) {
-
-                @Override
-                public List<AbstractPreferenceController> createPreferenceControllers(
-                        Context context) {
-                    return buildPreferenceControllers(context, null, null, null);
-                }
-            };
 }
diff --git a/src/com/android/settings/notification/zen/ZenModeCallsSettings.java b/src/com/android/settings/notification/zen/ZenModeCallsSettings.java
index 93e97b1..76c6fef 100644
--- a/src/com/android/settings/notification/zen/ZenModeCallsSettings.java
+++ b/src/com/android/settings/notification/zen/ZenModeCallsSettings.java
@@ -18,14 +18,11 @@
 
 import android.app.settings.SettingsEnums;
 import android.content.Context;
-import android.provider.SearchIndexableResource;
 
 import com.android.settings.R;
 import com.android.settings.notification.NotificationBackend;
-import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.core.lifecycle.Lifecycle;
-import com.android.settingslib.search.SearchIndexable;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -33,7 +30,6 @@
 /**
  * DND Calls Settings page to determine which priority senders can bypass DND.
  */
-@SearchIndexable
 public class ZenModeCallsSettings extends ZenModeSettingsBase {
 
     @Override
@@ -64,27 +60,4 @@
     public int getMetricsCategory() {
         return SettingsEnums.DND_CALLS;
     }
-
-    /**
-     * For Search.
-     */
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-            new BaseSearchIndexProvider() {
-        @Override
-        public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
-                boolean enabled) {
-            final ArrayList<SearchIndexableResource> result = new ArrayList<>();
-
-            final SearchIndexableResource sir = new SearchIndexableResource(context);
-            sir.xmlResId = R.xml.zen_mode_calls_settings;
-            result.add(sir);
-            return result;
-        }
-
-        @Override
-        public List<AbstractPreferenceController> createPreferenceControllers(
-                Context context) {
-            return buildPreferenceControllers(context, null);
-        }
-    };
 }
diff --git a/src/com/android/settings/notification/zen/ZenModeMessagesSettings.java b/src/com/android/settings/notification/zen/ZenModeMessagesSettings.java
index 3405c43..d05016e 100644
--- a/src/com/android/settings/notification/zen/ZenModeMessagesSettings.java
+++ b/src/com/android/settings/notification/zen/ZenModeMessagesSettings.java
@@ -18,14 +18,11 @@
 
 import android.app.settings.SettingsEnums;
 import android.content.Context;
-import android.provider.SearchIndexableResource;
 
 import com.android.settings.R;
 import com.android.settings.notification.NotificationBackend;
-import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.core.lifecycle.Lifecycle;
-import com.android.settingslib.search.SearchIndexable;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -34,7 +31,6 @@
  * DND Messages Settings page to determine which priority senders can bypass DND.
  * "Messages" include SMS, MMS, and messaging apps.
  */
-@SearchIndexable
 public class ZenModeMessagesSettings extends ZenModeSettingsBase {
 
     @Override
@@ -62,27 +58,4 @@
     public int getMetricsCategory() {
         return SettingsEnums.DND_MESSAGES;
     }
-
-    /**
-     * For Search.
-     */
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-            new BaseSearchIndexProvider() {
-        @Override
-        public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
-                boolean enabled) {
-            final ArrayList<SearchIndexableResource> result = new ArrayList<>();
-
-            final SearchIndexableResource sir = new SearchIndexableResource(context);
-            sir.xmlResId = R.xml.zen_mode_messages_settings;
-            result.add(sir);
-            return result;
-        }
-
-        @Override
-        public List<AbstractPreferenceController> createPreferenceControllers(
-                Context context) {
-            return buildPreferenceControllers(context, null);
-        }
-    };
 }
diff --git a/src/com/android/settings/notification/zen/ZenModePeopleSettings.java b/src/com/android/settings/notification/zen/ZenModePeopleSettings.java
index 2b66482..ec491d8 100644
--- a/src/com/android/settings/notification/zen/ZenModePeopleSettings.java
+++ b/src/com/android/settings/notification/zen/ZenModePeopleSettings.java
@@ -26,16 +26,13 @@
 
 import com.android.settings.R;
 import com.android.settings.notification.NotificationBackend;
-import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.search.Indexable;
-import com.android.settingslib.search.SearchIndexable;
 
 import java.util.ArrayList;
 import java.util.List;
 
-@SearchIndexable
 public class ZenModePeopleSettings extends ZenModeSettingsBase implements Indexable {
 
     @Override
@@ -74,18 +71,4 @@
     public int getMetricsCategory() {
         return SettingsEnums.DND_PEOPLE;
     }
-
-    /**
-     * For Search.
-     */
-    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-            new BaseSearchIndexProvider(R.xml.zen_mode_people_settings) {
-
-                @Override
-                public List<AbstractPreferenceController> createPreferenceControllers(
-                        Context context) {
-                    return buildPreferenceControllers(context, null, null, null,
-                            null, null);
-                }
-            };
 }
diff --git a/src/com/android/settings/notification/zen/ZenModeRestrictNotificationsSettings.java b/src/com/android/settings/notification/zen/ZenModeRestrictNotificationsSettings.java
index f121430..162f3a0 100644
--- a/src/com/android/settings/notification/zen/ZenModeRestrictNotificationsSettings.java
+++ b/src/com/android/settings/notification/zen/ZenModeRestrictNotificationsSettings.java
@@ -21,17 +21,14 @@
 import android.os.Bundle;
 
 import com.android.settings.R;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.search.Indexable;
 import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.core.lifecycle.Lifecycle;
-import com.android.settingslib.search.SearchIndexable;
+import com.android.settingslib.search.Indexable;
 import com.android.settingslib.widget.FooterPreference;
 
 import java.util.ArrayList;
 import java.util.List;
 
-@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
 public class ZenModeRestrictNotificationsSettings extends ZenModeSettingsBase implements Indexable {
 
     @Override
@@ -72,16 +69,4 @@
     public int getMetricsCategory() {
         return SettingsEnums.SETTINGS_ZEN_NOTIFICATIONS;
     }
-
-    /**
-     * For Search.
-     */
-    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-            new BaseSearchIndexProvider(R.xml.zen_mode_restrict_notifications_settings) {
-
-            @Override
-            public List<AbstractPreferenceController> createPreferenceControllers(Context context) {
-                return buildPreferenceControllers(context, null);
-            }
-        };
 }
diff --git a/src/com/android/settings/notification/zen/ZenModeSettings.java b/src/com/android/settings/notification/zen/ZenModeSettings.java
index a707e53..368528c 100644
--- a/src/com/android/settings/notification/zen/ZenModeSettings.java
+++ b/src/com/android/settings/notification/zen/ZenModeSettings.java
@@ -42,10 +42,8 @@
 import androidx.fragment.app.FragmentManager;
 
 import com.android.settings.R;
-import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.core.lifecycle.Lifecycle;
-import com.android.settingslib.search.SearchIndexable;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -55,7 +53,6 @@
 import java.util.Map.Entry;
 import java.util.function.Predicate;
 
-@SearchIndexable
 public class ZenModeSettings extends ZenModeSettingsBase {
     @Override
     public void onResume() {
@@ -354,25 +351,4 @@
             return "";
         }
     }
-
-    /**
-     * For Search.
-     */
-    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-            new BaseSearchIndexProvider(R.xml.zen_mode_settings) {
-
-                @Override
-                public List<String> getNonIndexableKeys(Context context) {
-                    List<String> keys = super.getNonIndexableKeys(context);
-                    keys.add(ZenModeDurationPreferenceController.KEY);
-                    return keys;
-                }
-
-                @Override
-                public List<AbstractPreferenceController> createPreferenceControllers(Context
-                        context) {
-                    return buildPreferenceControllers(context, null, null,
-                            null, null);
-                }
-            };
 }
diff --git a/src/com/android/settings/notification/zen/ZenModeSoundVibrationSettings.java b/src/com/android/settings/notification/zen/ZenModeSoundVibrationSettings.java
index 61e84fc..8863677 100644
--- a/src/com/android/settings/notification/zen/ZenModeSoundVibrationSettings.java
+++ b/src/com/android/settings/notification/zen/ZenModeSoundVibrationSettings.java
@@ -20,11 +20,9 @@
 import android.content.Context;
 
 import com.android.settings.R;
-import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.search.Indexable;
-import com.android.settingslib.search.SearchIndexable;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -32,7 +30,6 @@
 /**
  * Settings > Sound > Do Not Disturb > Alarms & Other Interruptions
  */
-@SearchIndexable
 public class ZenModeSoundVibrationSettings extends ZenModeSettingsBase implements Indexable {
 
     @Override
@@ -61,22 +58,4 @@
     public int getMetricsCategory() {
         return SettingsEnums.NOTIFICATION_ZEN_MODE_PRIORITY;
     }
-
-    /**
-     * For Search.
-     */
-    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-            new BaseSearchIndexProvider(R.xml.zen_mode_sound_vibration_settings) {
-
-                @Override
-                public List<String> getNonIndexableKeys(Context context) {
-                    final List<String> keys = super.getNonIndexableKeys(context);
-                    return keys;
-                }
-
-            @Override
-            public List<AbstractPreferenceController> createPreferenceControllers(Context context) {
-                return buildPreferenceControllers(context, null);
-            }
-        };
 }
diff --git a/src/com/android/settings/utils/ContextUtils.kt b/src/com/android/settings/utils/ContextUtils.kt
new file mode 100644
index 0000000..76b1390
--- /dev/null
+++ b/src/com/android/settings/utils/ContextUtils.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.utils
+
+import android.content.Context
+import java.util.Locale
+
+/** Returns the locale of context. */
+fun Context.getLocale(): Locale {
+    val configuration = resources.configuration ?: return Locale.getDefault()
+    val locales = configuration.locales
+    return if (locales.isEmpty) configuration.locale else locales.get(0)
+}
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilityButtonFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilityButtonFragmentTest.java
index e9e20a4..e40f21c 100644
--- a/tests/robotests/src/com/android/settings/accessibility/AccessibilityButtonFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilityButtonFragmentTest.java
@@ -28,6 +28,10 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.os.Bundle;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
+import android.provider.Flags;
 
 import androidx.fragment.app.FragmentActivity;
 import androidx.preference.PreferenceManager;
@@ -57,6 +61,8 @@
 public class AccessibilityButtonFragmentTest {
 
     @Rule
+    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+    @Rule
     public MockitoRule mMockitoRule = MockitoJUnit.rule();
     @Spy
     private final Context mContext = ApplicationProvider.getApplicationContext();
@@ -84,6 +90,7 @@
     }
 
     @Test
+    @DisableFlags(Flags.FLAG_A11Y_STANDALONE_GESTURE_ENABLED)
     public void onCreate_navigationGestureEnabled_setCorrectTitle() {
         when(mResources.getInteger(com.android.internal.R.integer.config_navBarInteractionMode))
                 .thenReturn(NAV_BAR_MODE_GESTURAL);
@@ -96,7 +103,20 @@
     }
 
     @Test
-    public void onCreate_navigationGestureDisabled_setCorrectTitle() {
+    @EnableFlags(Flags.FLAG_A11Y_STANDALONE_GESTURE_ENABLED)
+    public void onCreate_navigationGestureEnabled_gestureFlag_setCorrectTitle() {
+        when(mResources.getInteger(com.android.internal.R.integer.config_navBarInteractionMode))
+                .thenReturn(NAV_BAR_MODE_GESTURAL);
+
+        mFragment.onAttach(mContext);
+        mFragment.onCreate(Bundle.EMPTY);
+
+        assertThat(mFragment.getActivity().getTitle().toString()).isEqualTo(
+                mContext.getString(R.string.accessibility_button_title));
+    }
+
+    @Test
+    public void onCreate_navigationBarEnabled_setCorrectTitle() {
         when(mResources.getInteger(com.android.internal.R.integer.config_navBarInteractionMode))
                 .thenReturn(NAV_BAR_MODE_2BUTTON);
 
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilityButtonGesturePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilityButtonGesturePreferenceControllerTest.java
index 3976056..83517c3 100644
--- a/tests/robotests/src/com/android/settings/accessibility/AccessibilityButtonGesturePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilityButtonGesturePreferenceControllerTest.java
@@ -30,6 +30,10 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.res.Resources;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
+import android.provider.Flags;
 import android.provider.Settings;
 
 import androidx.preference.ListPreference;
@@ -49,6 +53,8 @@
 public class AccessibilityButtonGesturePreferenceControllerTest {
 
     @Rule
+    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+    @Rule
     public final MockitoRule mockito = MockitoJUnit.rule();
 
     @Spy
@@ -67,6 +73,7 @@
     }
 
     @Test
+    @DisableFlags(Flags.FLAG_A11Y_STANDALONE_GESTURE_ENABLED)
     public void getAvailabilityStatus_navigationGestureEnabled_returnAvailable() {
         when(mResources.getInteger(com.android.internal.R.integer.config_navBarInteractionMode))
                 .thenReturn(NAV_BAR_MODE_GESTURAL);
@@ -75,6 +82,16 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_A11Y_STANDALONE_GESTURE_ENABLED)
+    public void
+            getAvailabilityStatus_navigationGestureEnabled_gestureFlag_conditionallyUnavailable() {
+        when(mResources.getInteger(com.android.internal.R.integer.config_navBarInteractionMode))
+                .thenReturn(NAV_BAR_MODE_GESTURAL);
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
+    }
+
+    @Test
     public void getAvailabilityStatus_navigationGestureDisabled_returnConditionallyUnavailable() {
         when(mResources.getInteger(com.android.internal.R.integer.config_navBarInteractionMode))
                 .thenReturn(NAV_BAR_MODE_2BUTTON);
diff --git a/tests/robotests/src/com/android/settings/accessibility/shortcuts/EditShortcutsPreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/shortcuts/EditShortcutsPreferenceFragmentTest.java
index b461cab..414fe63 100644
--- a/tests/robotests/src/com/android/settings/accessibility/shortcuts/EditShortcutsPreferenceFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/shortcuts/EditShortcutsPreferenceFragmentTest.java
@@ -18,6 +18,7 @@
 
 import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_COMPONENT_NAME;
 import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE;
 import static com.android.settings.accessibility.shortcuts.EditShortcutsPreferenceFragment.SHORTCUT_SETTINGS;
 
 import static com.google.android.setupcompat.util.WizardManagerHelper.EXTRA_IS_DEFERRED_SETUP;
@@ -36,6 +37,7 @@
 import android.content.Intent;
 import android.net.Uri;
 import android.os.Bundle;
+import android.platform.test.annotations.DisableFlags;
 import android.platform.test.annotations.EnableFlags;
 import android.platform.test.flag.junit.SetFlagsRule;
 import android.provider.Settings;
@@ -240,6 +242,7 @@
     }
 
     @Test
+    @DisableFlags(android.provider.Flags.FLAG_A11Y_STANDALONE_GESTURE_ENABLED)
     public void onSoftwareShortcutSettingChanged_softwareControllersUpdated() {
         mFragmentScenario = createFragScenario(/* isInSuw= */ false, TARGET);
         mFragmentScenario.moveToState(Lifecycle.State.CREATED);
@@ -256,6 +259,27 @@
     }
 
     @Test
+    @EnableFlags(android.provider.Flags.FLAG_A11Y_STANDALONE_GESTURE_ENABLED)
+    public void onSoftwareShortcutSettingsChanged_softwareControllersUpdated() {
+        mFragmentScenario = createFragScenario(/* isInSuw= */ false, TARGET);
+        mFragmentScenario.moveToState(Lifecycle.State.CREATED);
+
+        ShortcutUtils.optInValueToSettings(
+                mContext, ShortcutConstants.UserShortcutType.SOFTWARE, TARGET);
+        ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
+
+        mFragmentScenario.onFragment(fragment -> {
+            TwoStatePreference preference = fragment.findPreference(
+                    mContext.getString(R.string.accessibility_shortcut_fab_pref));
+            assertThat(preference.isChecked()).isTrue();
+            preference = fragment.findPreference(
+                    mContext.getString(R.string.accessibility_shortcut_gesture_pref));
+            assertThat(preference.isChecked()).isFalse();
+        });
+    }
+
+    @Test
+    @DisableFlags(android.provider.Flags.FLAG_A11Y_STANDALONE_GESTURE_ENABLED)
     public void onSoftwareShortcutModeChanged_softwareControllersUpdated() {
         mFragmentScenario = createFragScenario(/* isInSuw= */ false, TARGET);
         mFragmentScenario.moveToState(Lifecycle.State.CREATED);
@@ -309,6 +333,7 @@
     }
 
     @Test
+    @DisableFlags(android.provider.Flags.FLAG_A11Y_STANDALONE_GESTURE_ENABLED)
     public void fragmentResumed_enableTouchExploration_gestureShortcutOptionSummaryUpdated() {
         String expectedSummary = StringUtil.getIcuPluralsString(mContext, 3,
                 R.string.accessibility_shortcut_edit_dialog_summary_gesture)
@@ -330,6 +355,26 @@
     }
 
     @Test
+    @EnableFlags(android.provider.Flags.FLAG_A11Y_STANDALONE_GESTURE_ENABLED)
+    public void fragmentResumed_enableTouchExploration_gestureFlag_gestureSummaryUpdated() {
+        String expectedSummary = StringUtil.getIcuPluralsString(mContext, 3,
+                R.string.accessibility_shortcut_edit_dialog_summary_gesture);
+        mFragmentScenario = createFragScenario(/* isInSuw= */ false, TARGET);
+        mFragmentScenario.moveToState(Lifecycle.State.RESUMED);
+
+        ShadowAccessibilityManager am = shadowOf(
+                mContext.getSystemService(AccessibilityManager.class));
+        am.setTouchExplorationEnabled(true);
+
+        mFragmentScenario.onFragment(fragment -> {
+            Preference preference = fragment.findPreference(
+                    mContext.getString(R.string.accessibility_shortcut_gesture_pref));
+            assertThat(preference.getSummary().toString()).isEqualTo(expectedSummary);
+        });
+    }
+
+    @Test
+    @DisableFlags(android.provider.Flags.FLAG_A11Y_STANDALONE_GESTURE_ENABLED)
     public void fragmentPaused_enableTouchExploration_gestureShortcutOptionSummaryNotUpdated() {
         String expectedSummary = StringUtil.getIcuPluralsString(mContext, 2,
                 R.string.accessibility_shortcut_edit_dialog_summary_gesture)
@@ -351,6 +396,25 @@
     }
 
     @Test
+    @EnableFlags(android.provider.Flags.FLAG_A11Y_STANDALONE_GESTURE_ENABLED)
+    public void fragmentPaused_enableTouchExploration_gestureFlag_gestureSummaryNotUpdated() {
+        String expectedSummary = StringUtil.getIcuPluralsString(mContext, 2,
+                R.string.accessibility_shortcut_edit_dialog_summary_gesture);
+        mFragmentScenario = createFragScenario(/* isInSuw= */ false, TARGET);
+        mFragmentScenario.moveToState(Lifecycle.State.RESUMED).moveToState(Lifecycle.State.STARTED);
+
+        ShadowAccessibilityManager am = shadowOf(
+                mContext.getSystemService(AccessibilityManager.class));
+        am.setTouchExplorationEnabled(true);
+
+        mFragmentScenario.onFragment(fragment -> {
+            Preference preference = fragment.findPreference(
+                    mContext.getString(R.string.accessibility_shortcut_gesture_pref));
+            assertThat(preference.getSummary().toString()).isEqualTo(expectedSummary);
+        });
+    }
+
+    @Test
     @EnableFlags(Flags.FLAG_A11Y_QS_SHORTCUT)
     public void fragmentResumed_enableTouchExploration_qsShortcutOptionSummaryUpdated() {
         String expectedSummary = StringUtil.getIcuPluralsString(mContext, 2,
@@ -441,7 +505,7 @@
         assertThat(
                 PreferredShortcuts.retrieveUserShortcutType(
                         mContext, TARGET)
-        ).isEqualTo(ShortcutConstants.UserShortcutType.SOFTWARE);
+        ).isEqualTo(SOFTWARE);
         // Update the chosen shortcut type to Volume keys while the fragment is in the background
         ShortcutUtils.optInValueToSettings(
                 mContext, ShortcutConstants.UserShortcutType.HARDWARE, TARGET);
@@ -461,7 +525,7 @@
         assertThat(
                 PreferredShortcuts.retrieveUserShortcutType(
                         mContext, TARGET)
-        ).isEqualTo(ShortcutConstants.UserShortcutType.SOFTWARE);
+        ).isEqualTo(SOFTWARE);
 
         ShortcutUtils.optInValueToSettings(
                 mContext, ShortcutConstants.UserShortcutType.HARDWARE, TARGET);
diff --git a/tests/robotests/src/com/android/settings/accessibility/shortcuts/GestureShortcutOptionControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/shortcuts/GestureShortcutOptionControllerTest.java
index 1c9979f..a58cf07 100644
--- a/tests/robotests/src/com/android/settings/accessibility/shortcuts/GestureShortcutOptionControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/shortcuts/GestureShortcutOptionControllerTest.java
@@ -133,6 +133,7 @@
     }
 
     @Test
+    @DisableFlags(Flags.FLAG_A11Y_STANDALONE_GESTURE_ENABLED)
     public void getSummary_touchExplorationEnabled_notInSuw_verifySummary() {
         enableTouchExploration(true);
         mController.setInSetupWizard(false);
@@ -148,6 +149,19 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_A11Y_STANDALONE_GESTURE_ENABLED)
+    public void getSummary_touchExplorationEnabled_notInSuw_gestureFlag_verifySummary() {
+        enableTouchExploration(true);
+        mController.setInSetupWizard(false);
+        String expected = StringUtil.getIcuPluralsString(
+                mContext,
+                /* count= */ 3,
+                R.string.accessibility_shortcut_edit_dialog_summary_gesture);
+
+        assertThat(mController.getSummary().toString()).isEqualTo(expected);
+    }
+
+    @Test
     public void getSummary_touchExplorationEnabled_inSuw_verifySummary() {
         enableTouchExploration(true);
         mController.setInSetupWizard(true);
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/MainlineModuleVersionPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/MainlineModuleVersionPreferenceControllerTest.java
index 7cd6734..f6e4d2a 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/MainlineModuleVersionPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/MainlineModuleVersionPreferenceControllerTest.java
@@ -47,6 +47,7 @@
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
 
+// LINT.IfChange
 @RunWith(RobolectricTestRunner.class)
 public class MainlineModuleVersionPreferenceControllerTest {
 
@@ -222,3 +223,4 @@
         when(mPackageManager.getPackageInfo(eq(provider), anyInt())).thenReturn(info);
     }
 }
+// LINT.ThenChange(MainlineModuleVersionPreferenceTest.kt)
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/MainlineModuleVersionPreferenceTest.kt b/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/MainlineModuleVersionPreferenceTest.kt
new file mode 100644
index 0000000..8fc1a2b
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/MainlineModuleVersionPreferenceTest.kt
@@ -0,0 +1,185 @@
+/*
+ * 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.settings.deviceinfo.firmwareversion
+
+import android.content.ContextWrapper
+import android.content.Intent
+import android.content.pm.PackageInfo
+import android.content.pm.PackageManager
+import android.content.pm.ResolveInfo
+import android.content.res.Resources
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
+import android.platform.test.flag.junit.SetFlagsRule
+import androidx.preference.Preference
+import androidx.test.core.app.ApplicationProvider
+import com.android.settings.R
+import com.android.settings.deviceinfo.firmwareversion.MainlineModuleVersionPreference.Companion.MODULE_UPDATE_ACTION
+import com.android.settings.deviceinfo.firmwareversion.MainlineModuleVersionPreference.Companion.MODULE_UPDATE_ACTION_V2
+import com.android.settings.flags.Flags
+import com.google.common.truth.Truth.assertThat
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.any
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.ArgumentMatchers.eq
+import org.mockito.kotlin.KStubbing
+import org.mockito.kotlin.doAnswer
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.doThrow
+import org.mockito.kotlin.mock
+import org.robolectric.RobolectricTestRunner
+
+// LINT.IfChange
+@RunWith(RobolectricTestRunner::class)
+class MainlineModuleVersionPreferenceTest {
+    @get:Rule val setFlagsRule = SetFlagsRule()
+
+    private lateinit var mockPackageManager: PackageManager
+    private lateinit var mockResources: Resources
+
+    private val context =
+        object : ContextWrapper(ApplicationProvider.getApplicationContext()) {
+            override fun getPackageManager(): PackageManager = mockPackageManager
+
+            override fun getResources(): Resources = mockResources
+        }
+
+    private val mainlineModuleVersionPreference = MainlineModuleVersionPreference()
+
+    @Test
+    fun isAvailable_noMainlineModuleProvider_unavailable() {
+        createMocks("", null)
+        assertThat(mainlineModuleVersionPreference.isAvailable(context)).isFalse()
+    }
+
+    @Test
+    fun isAvailable_noMainlineModulePackageInfo_unavailable() {
+        createMocks("test.provider", PackageManager.NameNotFoundException())
+        assertThat(mainlineModuleVersionPreference.isAvailable(context)).isFalse()
+    }
+
+    @Test
+    fun isAvailable_hasMainlineModulePackageInfo_available() {
+        createMocks("test.provider", "test version 123")
+        assertThat(mainlineModuleVersionPreference.isAvailable(context)).isTrue()
+    }
+
+    @Test
+    fun getSummary_versionIsNull() {
+        createMocks("test.provider", PackageInfo())
+        assertThat(mainlineModuleVersionPreference.getSummary(context)).isNull()
+    }
+
+    @Test
+    fun getSummary_versionIsEmpty() {
+        createMocks("test.provider", "")
+        assertThat(mainlineModuleVersionPreference.getSummary(context)).isNull()
+    }
+
+    @Test
+    fun getSummary_versionIsNotDate() {
+        createMocks("test.provider", "a")
+        assertThat(mainlineModuleVersionPreference.getSummary(context)).isEqualTo("a")
+    }
+
+    @Test
+    fun getSummary_versionIsMonth() {
+        createMocks("test.provider", "2019-05")
+        assertThat(mainlineModuleVersionPreference.getSummary(context)).isEqualTo("May 1, 2019")
+    }
+
+    @Test
+    fun getSummary_versionIsDate() {
+        createMocks("test.provider", "2019-05-13")
+        assertThat(mainlineModuleVersionPreference.getSummary(context)).isEqualTo("May 13, 2019")
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_MAINLINE_MODULE_EXPLICIT_INTENT)
+    fun intentV2_preferenceShouldBeSelectable() {
+        intent_preferenceShouldBeSelectable(MODULE_UPDATE_ACTION_V2, MODULE_PACKAGE)
+    }
+
+    @Test
+    @DisableFlags(Flags.FLAG_MAINLINE_MODULE_EXPLICIT_INTENT)
+    fun intent_preferenceShouldBeSelectable() {
+        intent_preferenceShouldBeSelectable(MODULE_UPDATE_ACTION, null)
+    }
+
+    private fun intent_preferenceShouldBeSelectable(action: String, intentPackage: String?) {
+        createMocks("test.provider", "test version 123") {
+            on { resolveActivity(any(), anyInt()) } doAnswer
+                {
+                    when {
+                        (it.arguments[0] as Intent).action == action -> ResolveInfo()
+                        else -> null
+                    }
+                }
+        }
+
+        val preference = Preference(context)
+        mainlineModuleVersionPreference.bind(preference, mainlineModuleVersionPreference)
+
+        val intent = preference.intent!!
+        assertThat(intent.action).isEqualTo(action)
+        assertThat(preference.isSelectable).isTrue()
+        assertThat(intent.`package`).isEqualTo(intentPackage)
+    }
+
+    @Test
+    fun intent_null() {
+        createMocks("test.provider", "test version 123")
+
+        val preference = Preference(context)
+        mainlineModuleVersionPreference.bind(preference, mainlineModuleVersionPreference)
+
+        assertThat(preference.intent).isNull()
+        assertThat(preference.isSelectable).isFalse()
+    }
+
+    private fun createMocks(
+        pkg: String,
+        pkgInfo: Any?,
+        stubbing: KStubbing<PackageManager>.() -> Unit = {},
+    ) {
+        mockResources = mock {
+            on { getString(R.string.config_mainline_module_update_package) } doReturn MODULE_PACKAGE
+            on {
+                getString(com.android.internal.R.string.config_defaultModuleMetadataProvider)
+            } doReturn pkg
+        }
+
+        mockPackageManager = mock {
+            when (pkgInfo) {
+                is PackageInfo -> on { getPackageInfo(eq(pkg), anyInt()) } doReturn pkgInfo
+                is String ->
+                    on { getPackageInfo(eq(pkg), anyInt()) } doReturn
+                        PackageInfo().apply { versionName = pkgInfo }
+                is Exception -> on { getPackageInfo(eq(pkg), anyInt()) } doThrow pkgInfo
+                else -> {}
+            }
+            stubbing.invoke(this)
+        }
+    }
+
+    companion object {
+        const val MODULE_PACKAGE = "com.android.vending"
+    }
+}
+// LINT.ThenChange(MainlineModuleVersionPreferenceControllerTest.java)
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/SecurityPatchLevelPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/SecurityPatchLevelPreferenceControllerTest.java
index ccc91e6..8bafc23 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/SecurityPatchLevelPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/SecurityPatchLevelPreferenceControllerTest.java
@@ -46,6 +46,7 @@
 
 import java.util.Collections;
 
+// LINT.IfChange
 @RunWith(RobolectricTestRunner.class)
 public class SecurityPatchLevelPreferenceControllerTest {
 
@@ -108,3 +109,4 @@
         verify(mContext).startActivity(any());
     }
 }
+// LINT.ThenChange(SecurityPatchLevelPreferenceTest.kt)
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/SecurityPatchLevelPreferenceTest.kt b/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/SecurityPatchLevelPreferenceTest.kt
new file mode 100644
index 0000000..695c0b6
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/SecurityPatchLevelPreferenceTest.kt
@@ -0,0 +1,63 @@
+/*
+ * 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.settings.deviceinfo.firmwareversion
+
+import android.content.Context
+import android.os.Build
+import androidx.test.core.app.ApplicationProvider
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.robolectric.RobolectricTestRunner
+import org.robolectric.util.ReflectionHelpers
+
+// LINT.IfChange
+@RunWith(RobolectricTestRunner::class)
+class SecurityPatchLevelPreferenceTest {
+    private val context: Context = ApplicationProvider.getApplicationContext()
+
+    private val securityPatchLevelPreference = SecurityPatchLevelPreference()
+
+    @Test
+    fun isAvailable_noPatch_unavailable() {
+        setSecurityPatch("")
+        assertThat(securityPatchLevelPreference.isAvailable(context)).isFalse()
+    }
+
+    @Test
+    fun isAvailable_hasPatch_available() {
+        setSecurityPatch("foobar")
+        assertThat(securityPatchLevelPreference.isAvailable(context)).isTrue()
+    }
+
+    @Test
+    fun getSummary_patchIsDate() {
+        setSecurityPatch("2024-09-24")
+        assertThat(securityPatchLevelPreference.getSummary(context)).isEqualTo("September 24, 2024")
+    }
+
+    @Test
+    fun getSummary_patchIsNotDate() {
+        setSecurityPatch("foobar")
+        assertThat(securityPatchLevelPreference.getSummary(context)).isEqualTo("foobar")
+    }
+
+    private fun setSecurityPatch(patch: String) {
+        ReflectionHelpers.setStaticField(Build.VERSION::class.java, "SECURITY_PATCH", patch)
+    }
+}
+// LINT.ThenChange(SecurityPatchLevelPreferenceControllerTest.java)
diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenModeSettingsTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenModeSettingsTest.java
index 27c4ec4..22d6963 100644
--- a/tests/robotests/src/com/android/settings/notification/zen/ZenModeSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/notification/zen/ZenModeSettingsTest.java
@@ -98,13 +98,4 @@
         assertThat(mBuilder.getCallsSettingSummary(policy))
                 .isEqualTo("Starred contacts and repeat callers");
     }
-
-    @Test
-    public void searchProvider_shouldIndexDefaultXml() {
-        final List<SearchIndexableResource> sir = ZenModeSettings.SEARCH_INDEX_DATA_PROVIDER
-                .getXmlResourcesToIndex(mContext, true /* enabled */);
-
-        assertThat(sir).hasSize(1);
-        assertThat(sir.get(0).xmlResId).isEqualTo(R.xml.zen_mode_settings);
-    }
 }