Merge "Add a RTT setting in A11y screen" into qt-qpr1-dev
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index ef75d03..194e8fb 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -1419,4 +1419,16 @@
         <item>@string/enhanced_4g_lte_mode_summary_4g_calling</item>
     </string-array>
 
+    <!--String arrays for showing the rtt settings options -->
+    <string-array name="rtt_setting_mode">
+        <!-- 0: Invalid value -->
+        <item></item>
+        <!-- 1:  Not visible -->
+        <item>@string/rtt_settings_no_visible</item>
+        <!-- 2:  Visible during call -->
+        <item>@string/rtt_settings_visible_during_call</item>
+        <!-- 3:  Always visible -->
+        <item>@string/rtt_settings_always_visible</item>
+    </string-array>
+
 </resources>
diff --git a/res/values/config.xml b/res/values/config.xml
index a39533e..b3eceb3 100755
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -420,4 +420,8 @@
 
     <!-- RTT setting intent action -->
     <string name="config_rtt_setting_intent_action" translatable="false"></string>
+
+    <!-- Package name of dialer supports RTT setting-->
+    <string name="config_rtt_setting_package_name" translatable="false"></string>
+
 </resources>
diff --git a/res/xml/accessibility_settings.xml b/res/xml/accessibility_settings.xml
index d9c61b5..3e27117 100644
--- a/res/xml/accessibility_settings.xml
+++ b/res/xml/accessibility_settings.xml
@@ -145,6 +145,12 @@
             android:title="@string/accessibility_hearingaid_title"/>
 
         <Preference
+            android:key="rtt_setting"
+            android:summary="@string/summary_placeholder"
+            android:title="@string/rtt_settings_title"
+            settings:controller="com.android.settings.accessibility.RTTSettingPreferenceController"/>
+
+        <Preference
                 android:fragment="com.android.settings.accessibility.CaptionPropertiesFragment"
                 android:key="captioning_preference_screen"
                 android:title="@string/accessibility_captioning_title" />
diff --git a/src/com/android/settings/accessibility/AccessibilitySettings.java b/src/com/android/settings/accessibility/AccessibilitySettings.java
index cb98892..3d1e946 100644
--- a/src/com/android/settings/accessibility/AccessibilitySettings.java
+++ b/src/com/android/settings/accessibility/AccessibilitySettings.java
@@ -121,6 +121,7 @@
             "accessibility_shortcut_preference";
     private static final String HEARING_AID_PREFERENCE =
             "hearing_aid_preference";
+    private static final String RTT_SETTINGS_SCREEN = "rtt_setting";
     private static final String CAPTIONING_PREFERENCE_SCREEN =
             "captioning_preference_screen";
     private static final String DISPLAY_MAGNIFICATION_PREFERENCE_SCREEN =
@@ -240,6 +241,7 @@
     private Preference mAccessibilityShortcutPreferenceScreen;
     private Preference mDisplayDaltonizerPreferenceScreen;
     private Preference mHearingAidPreference;
+    private Preference mRTTPreference;
     private Preference mVibrationPreferenceScreen;
     private Preference mLiveCaptionPreference;
     private SwitchPreference mToggleInversionPreference;
@@ -248,6 +250,7 @@
     private SwitchPreference mDarkUIModePreference;
     private DarkUIPreferenceController mDarkUIPreferenceController;
     private LiveCaptionPreferenceController mLiveCaptionPreferenceController;
+    private RTTSettingPreferenceController mRTTSettingPreferenceController;
 
     private int mLongPressTimeoutDefault;
 
@@ -309,6 +312,9 @@
 
         mLiveCaptionPreferenceController = new LiveCaptionPreferenceController(context,
                 LIVE_CAPTION_PREFERENCE_KEY);
+        mRTTSettingPreferenceController =
+                new RTTSettingPreferenceController(context, RTT_SETTINGS_SCREEN);
+
     }
 
     @Override
@@ -503,6 +509,11 @@
         mHearingAidPreference = findPreference(HEARING_AID_PREFERENCE);
         mHearingAidPreferenceController.displayPreference(getPreferenceScreen());
 
+        // RTT Setting
+        mRTTPreference = findPreference(RTT_SETTINGS_SCREEN);
+        mRTTSettingPreferenceController.displayPreference(getPreferenceScreen());
+
+
         // Captioning.
         mCaptioningPreferenceScreen = findPreference(CAPTIONING_PREFERENCE_SCREEN);
 
@@ -787,6 +798,8 @@
 
         mHearingAidPreferenceController.updateState(mHearingAidPreference);
 
+        mRTTSettingPreferenceController.updateState(mRTTPreference);
+
         mLiveCaptionPreferenceController.updateState(mLiveCaptionPreference);
 
         updateFeatureSummary(Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED,
diff --git a/src/com/android/settings/accessibility/RTTSettingPreferenceController.java b/src/com/android/settings/accessibility/RTTSettingPreferenceController.java
new file mode 100644
index 0000000..d455fc1
--- /dev/null
+++ b/src/com/android/settings/accessibility/RTTSettingPreferenceController.java
@@ -0,0 +1,87 @@
+/*
+ * 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.settings.accessibility;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.provider.Settings;
+import android.telecom.TelecomManager;
+import android.text.TextUtils;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
+
+import java.util.List;
+
+/** A controller to control the status for RTT setting in Accessibility screen.*/
+public class RTTSettingPreferenceController extends BasePreferenceController {
+
+    private static final String DIALER_RTT_CONFIGURATION = "dialer_rtt_configuration";
+
+    private final Context mContext;
+    private final PackageManager mPackageManager;
+    private final TelecomManager mTelecomManager;
+    private final CharSequence[] mModes;
+    private final String mDialerPackage;
+
+    @VisibleForTesting
+    Intent mRTTIntent;
+
+    public RTTSettingPreferenceController(Context context, String preferenceKey) {
+        super(context, preferenceKey);
+        mContext = context;
+        mModes = mContext.getResources().getTextArray(R.array.rtt_setting_mode);
+        mDialerPackage = mContext.getString(R.string.config_rtt_setting_package_name);
+        mPackageManager = context.getPackageManager();
+        mTelecomManager = context.getSystemService(TelecomManager.class);
+        mRTTIntent = new Intent(context.getString(R.string.config_rtt_setting_intent_action));
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        final List<ResolveInfo> resolved =
+                mPackageManager.queryIntentActivities(mRTTIntent, 0 /* flags */);
+        return resolved != null && !resolved.isEmpty() && isDialerSupportRTTSetting()
+                ? AVAILABLE
+                : UNSUPPORTED_ON_DEVICE;
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        final Preference pref = screen.findPreference(getPreferenceKey());
+        pref.setIntent(mRTTIntent);
+    }
+
+    @Override
+    public CharSequence getSummary() {
+        final int option = Settings.Secure.getInt(mContext.getContentResolver(),
+                DIALER_RTT_CONFIGURATION, 1 /* not visible */);
+        return mModes[option];
+    }
+
+    @VisibleForTesting
+    boolean isDialerSupportRTTSetting() {
+        return TextUtils.equals(mTelecomManager.getDefaultDialerPackage(), mDialerPackage);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/accessibility/RTTSettingPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/RTTSettingPreferenceControllerTest.java
new file mode 100644
index 0000000..6f3f77d
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/RTTSettingPreferenceControllerTest.java
@@ -0,0 +1,91 @@
+/*
+ * 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.settings.accessibility;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.robolectric.Shadows.shadowOf;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ResolveInfo;
+
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.testutils.ResolveInfoBuilder;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadows.ShadowPackageManager;
+
+@RunWith(RobolectricTestRunner.class)
+public class RTTSettingPreferenceControllerTest {
+
+    private Context mContext;
+    private ShadowPackageManager mShadowPackageManager;
+    private RTTSettingPreferenceController mController;
+
+    @Before
+    public void setUp() {
+        mContext = RuntimeEnvironment.application;
+        mShadowPackageManager = shadowOf(mContext.getPackageManager());
+        mController = spy(new RTTSettingPreferenceController(mContext, "rtt_setting"));
+        mController.mRTTIntent = new Intent("com.android.test.action.example");
+    }
+
+    @Test
+    public void getAvailabilityStatus_defaultDialerIsExpected_intentCanBeHandled_returnAVAILABLE() {
+        // Default dialer is expected.
+        doReturn(true).when(mController).isDialerSupportRTTSetting();
+        // Intent can be handled.
+        final ResolveInfo info = new ResolveInfoBuilder("pkg")
+                .setActivity("pkg", "class").build();
+        final Intent intent = new Intent("com.android.test.action.example");
+        mShadowPackageManager.addResolveInfoForIntent(intent, info);
+
+        assertThat(mController.getAvailabilityStatus())
+                .isEqualTo(BasePreferenceController.AVAILABLE);
+    }
+
+    @Test
+    public void getAvailabilityStatus_intentCanNotBeHandled_shouldReturnUNSUPPORTED_ON_DEVICE() {
+        // Default dialer is expected.
+        doReturn(true).when(mController).isDialerSupportRTTSetting();
+        // Intent can not be handled.
+
+        assertThat(mController.getAvailabilityStatus())
+                .isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE);
+    }
+
+    @Test
+    public void getAvailabilityStatus_defaultDialerIsNotExpected_returnUNSUPPORTED_ON_DEVICE() {
+        // Default dialer is not expected.
+        doReturn(false).when(mController).isDialerSupportRTTSetting();
+        // Intent can be handled.
+        final ResolveInfo info = new ResolveInfoBuilder("pkg")
+                .setActivity("pkg", "class").build();
+        final Intent intent = new Intent("com.android.test.action.example");
+        mShadowPackageManager.addResolveInfoForIntent(intent, info);
+
+        assertThat(mController.getAvailabilityStatus())
+                .isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/testutils/ResolveInfoBuilder.java b/tests/robotests/src/com/android/settings/testutils/ResolveInfoBuilder.java
new file mode 100644
index 0000000..5eaf2a4
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/testutils/ResolveInfoBuilder.java
@@ -0,0 +1,71 @@
+/*
+ * 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.settings.testutils;
+
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.ProviderInfo;
+import android.content.pm.ResolveInfo;
+
+import com.google.common.base.Preconditions;
+
+/**
+ * Helper for building {@link ResolveInfo}s to be used in Robolectric tests.
+ *
+ * <p>The resulting {@link PackageInfo}s should typically be added to {@link
+ * org.robolectric.shadows.ShadowPackageManager#addResolveInfoForIntent(Intent, ResolveInfo)}.
+ */
+public final class ResolveInfoBuilder {
+
+    private final String mPackageName;
+    private ActivityInfo mActivityInfo;
+    private ProviderInfo mProviderInfo;
+
+    public ResolveInfoBuilder(String packageName) {
+        this.mPackageName = Preconditions.checkNotNull(packageName);
+    }
+
+    public ResolveInfoBuilder setActivity(String packageName, String className) {
+        mActivityInfo = new ActivityInfo();
+        mActivityInfo.packageName = packageName;
+        mActivityInfo.name = className;
+        return this;
+    }
+
+    public ResolveInfoBuilder setProvider(
+            String packageName, String className, String authority, boolean isSystemApp) {
+        mProviderInfo = new ProviderInfo();
+        mProviderInfo.authority = authority;
+        mProviderInfo.applicationInfo = new ApplicationInfo();
+        if (isSystemApp) {
+            mProviderInfo.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
+        }
+        mProviderInfo.packageName = mPackageName;
+        mProviderInfo.applicationInfo.packageName  = mPackageName;
+        mProviderInfo.name = className;
+        return this;
+    }
+
+    public ResolveInfo build() {
+        ResolveInfo info = new ResolveInfo();
+        info.activityInfo = mActivityInfo;
+        info.resolvePackageName = mPackageName;
+        info.providerInfo = mProviderInfo;
+        return info;
+    }
+}