Snap for 12406339 from 658459de9ba9f3150ec88c58d0efd1701ab3a493 to 24Q4-release

Change-Id: I01b270ceb3f0850e5043a7401701c117a8766843
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/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/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 1d46cae..39535cb 100644
--- a/tests/robotests/src/com/android/settings/accessibility/shortcuts/GestureShortcutOptionControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/shortcuts/GestureShortcutOptionControllerTest.java
@@ -119,6 +119,7 @@
     }
 
     @Test
+    @DisableFlags(Flags.FLAG_A11Y_STANDALONE_GESTURE_ENABLED)
     public void getSummary_touchExplorationEnabled_notInSuw_verifySummary() {
         enableTouchExploration(true);
         mController.setInSetupWizard(false);
@@ -134,6 +135,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);