1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.settings.accessibility;
18 
19 import android.content.Context;
20 import android.content.Intent;
21 import android.content.pm.PackageManager;
22 import android.content.pm.ResolveInfo;
23 import android.os.PersistableBundle;
24 import android.provider.Settings;
25 import android.telecom.PhoneAccount;
26 import android.telecom.PhoneAccountHandle;
27 import android.telephony.CarrierConfigManager;
28 import android.telephony.SubscriptionManager;
29 import android.text.TextUtils;
30 import android.util.Log;
31 
32 import androidx.annotation.VisibleForTesting;
33 import androidx.preference.Preference;
34 import androidx.preference.PreferenceScreen;
35 
36 import com.android.settings.R;
37 import com.android.settings.accessibility.rtt.TelecomUtil;
38 import com.android.settings.core.BasePreferenceController;
39 
40 import java.util.List;
41 
42 /** A controller to control the status for RTT setting in Accessibility screen. */
43 public class RTTSettingPreferenceController extends BasePreferenceController {
44 
45     private static final String TAG = "RTTSettingsCtr";
46 
47     private static final String DIALER_RTT_CONFIGURATION = "dialer_rtt_configuration";
48     private final Context mContext;
49     private final PackageManager mPackageManager;
50     private final CarrierConfigManager mCarrierConfigManager;
51     private final CharSequence[] mModes;
52     private final String mDialerPackage;
53 
54     @VisibleForTesting
55     Intent mRTTIntent;
56 
RTTSettingPreferenceController(Context context, String preferenceKey)57     public RTTSettingPreferenceController(Context context, String preferenceKey) {
58         super(context, preferenceKey);
59         mContext = context;
60         mModes = mContext.getResources().getTextArray(R.array.rtt_setting_mode);
61         mDialerPackage = mContext.getString(R.string.config_rtt_setting_package_name);
62         mPackageManager = mContext.getPackageManager();
63         mCarrierConfigManager = mContext.getSystemService(CarrierConfigManager.class);
64         mRTTIntent = new Intent(context.getString(R.string.config_rtt_setting_intent_action));
65         Log.d(TAG, "init controller");
66     }
67 
68     @Override
getAvailabilityStatus()69     public int getAvailabilityStatus() {
70         final List<ResolveInfo> resolved =
71                 mPackageManager.queryIntentActivities(mRTTIntent, 0 /* flags */);
72         return resolved != null && !resolved.isEmpty() && isRttSettingSupported()
73                 ? AVAILABLE
74                 : UNSUPPORTED_ON_DEVICE;
75     }
76 
77     @Override
displayPreference(PreferenceScreen screen)78     public void displayPreference(PreferenceScreen screen) {
79         super.displayPreference(screen);
80         final Preference pref = screen.findPreference(getPreferenceKey());
81         pref.setIntent(mRTTIntent);
82     }
83 
84     @Override
getSummary()85     public CharSequence getSummary() {
86         final int option = Settings.Secure.getInt(mContext.getContentResolver(),
87                 DIALER_RTT_CONFIGURATION, 0 /* Invalid value */);
88         Log.d(TAG, "DIALER_RTT_CONFIGURATION value =  " + option);
89         return mModes[option];
90     }
91 
92     @VisibleForTesting
isRttSettingSupported()93     boolean isRttSettingSupported() {
94         Log.d(TAG, "isRttSettingSupported [start]");
95         if (!isDefaultDialerSupportedRTT(mContext)) {
96             Log.d(TAG, "Dialer doesn't support RTT.");
97             return false;
98         }
99         // At least one PhoneAccount must have both isRttSupported and
100         // ignore_rtt_mode_setting_bool being true
101         for (PhoneAccountHandle phoneAccountHandle :
102                 TelecomUtil.getCallCapablePhoneAccounts(mContext)) {
103             final int subId =
104                     TelecomUtil.getSubIdForPhoneAccountHandle(mContext, phoneAccountHandle);
105             Log.d(TAG, "subscription id for the device: " + subId);
106 
107             final boolean isRttCallingSupported = isRttSupportedByTelecom(phoneAccountHandle);
108             Log.d(TAG, "rtt calling supported by telecom:: " + isRttCallingSupported);
109 
110             if (isRttCallingSupported) {
111                 PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(subId);
112                 // If IGNORE_RTT_MODE_SETTING_BOOL=true, RTT visibility is not supported because
113                 // this means we must use the legacy Telecom setting, which does not support RTT
114                 // visibility.
115                 if (carrierConfig != null
116                         && getBooleanCarrierConfig(
117                         CarrierConfigManager.KEY_IGNORE_RTT_MODE_SETTING_BOOL)) {
118                     Log.d(TAG, "RTT visibility setting is supported.");
119                     return true;
120                 }
121                 Log.d(TAG, "IGNORE_RTT_MODE_SETTING_BOOL is false.");
122             }
123         }
124         Log.d(TAG, "isRttSettingSupported [Not support]");
125         return false;
126     }
127 
isRttSupportedByTelecom(PhoneAccountHandle phoneAccountHandle)128     private boolean isRttSupportedByTelecom(PhoneAccountHandle phoneAccountHandle) {
129         PhoneAccount phoneAccount =
130                 TelecomUtil.getTelecomManager(mContext).getPhoneAccount(phoneAccountHandle);
131         if (phoneAccount != null && phoneAccount.hasCapabilities(PhoneAccount.CAPABILITY_RTT)) {
132             Log.d(TAG, "Phone account has RTT capability.");
133             return true;
134         }
135         return false;
136     }
137 
138     /**
139      * Gets the boolean config from carrier config manager.
140      *
141      * @param key config key defined in CarrierConfigManager.
142      * @return boolean value of corresponding key.
143      */
getBooleanCarrierConfig(String key)144     private boolean getBooleanCarrierConfig(String key) {
145         if (mCarrierConfigManager == null) {
146             // Return static default defined in CarrierConfigManager.
147             return CarrierConfigManager.getDefaultConfig().getBoolean(key);
148         }
149 
150         // If an invalid subId is used, this bundle will contain default values.
151         final int subId = SubscriptionManager.getDefaultVoiceSubscriptionId();
152         final PersistableBundle bundle = mCarrierConfigManager.getConfigForSubId(subId);
153 
154         return bundle != null
155                 ? bundle.getBoolean(key)
156                 : CarrierConfigManager.getDefaultConfig().getBoolean(key);
157     }
158 
159     /** Returns whether is a correct default dialer which supports RTT. */
isDefaultDialerSupportedRTT(Context context)160     private static boolean isDefaultDialerSupportedRTT(Context context) {
161         return TextUtils.equals(
162                 context.getString(R.string.config_rtt_setting_package_name),
163                 TelecomUtil.getTelecomManager(context).getDefaultDialerPackage());
164     }
165 }
166