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                 .setPackage(mDialerPackage);
66         Log.d(TAG, "init controller");
67     }
68 
69     @Override
getAvailabilityStatus()70     public int getAvailabilityStatus() {
71         final List<ResolveInfo> resolved =
72                 mPackageManager.queryIntentActivities(mRTTIntent, 0 /* flags */);
73         return resolved != null && !resolved.isEmpty() && isRttSettingSupported()
74                 ? AVAILABLE
75                 : UNSUPPORTED_ON_DEVICE;
76     }
77 
78     @Override
displayPreference(PreferenceScreen screen)79     public void displayPreference(PreferenceScreen screen) {
80         super.displayPreference(screen);
81         final Preference pref = screen.findPreference(getPreferenceKey());
82         pref.setIntent(mRTTIntent);
83     }
84 
85     @Override
getSummary()86     public CharSequence getSummary() {
87         final int option = Settings.Secure.getInt(mContext.getContentResolver(),
88                 DIALER_RTT_CONFIGURATION, 0 /* Invalid value */);
89         Log.d(TAG, "DIALER_RTT_CONFIGURATION value =  " + option);
90         return mModes[option];
91     }
92 
93     @VisibleForTesting
isRttSettingSupported()94     boolean isRttSettingSupported() {
95         Log.d(TAG, "isRttSettingSupported [start]");
96         if (!isDefaultDialerSupportedRTT(mContext)) {
97             Log.d(TAG, "Dialer doesn't support RTT.");
98             return false;
99         }
100         // At least one PhoneAccount must have both isRttSupported and
101         // ignore_rtt_mode_setting_bool being true
102         for (PhoneAccountHandle phoneAccountHandle :
103                 TelecomUtil.getCallCapablePhoneAccounts(mContext)) {
104             final int subId =
105                     TelecomUtil.getSubIdForPhoneAccountHandle(mContext, phoneAccountHandle);
106             Log.d(TAG, "subscription id for the device: " + subId);
107 
108             final boolean isRttCallingSupported = isRttSupportedByTelecom(phoneAccountHandle);
109             Log.d(TAG, "rtt calling supported by telecom:: " + isRttCallingSupported);
110 
111             if (isRttCallingSupported) {
112                 PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(subId);
113                 // If IGNORE_RTT_MODE_SETTING_BOOL=true, RTT visibility is not supported because
114                 // this means we must use the legacy Telecom setting, which does not support RTT
115                 // visibility.
116                 if (carrierConfig != null
117                         && getBooleanCarrierConfig(
118                         CarrierConfigManager.KEY_IGNORE_RTT_MODE_SETTING_BOOL)) {
119                     Log.d(TAG, "RTT visibility setting is supported.");
120                     return true;
121                 }
122                 Log.d(TAG, "IGNORE_RTT_MODE_SETTING_BOOL is false.");
123             }
124         }
125         Log.d(TAG, "isRttSettingSupported [Not support]");
126         return false;
127     }
128 
isRttSupportedByTelecom(PhoneAccountHandle phoneAccountHandle)129     private boolean isRttSupportedByTelecom(PhoneAccountHandle phoneAccountHandle) {
130         PhoneAccount phoneAccount =
131                 TelecomUtil.getTelecomManager(mContext).getPhoneAccount(phoneAccountHandle);
132         if (phoneAccount != null && phoneAccount.hasCapabilities(PhoneAccount.CAPABILITY_RTT)) {
133             Log.d(TAG, "Phone account has RTT capability.");
134             return true;
135         }
136         return false;
137     }
138 
139     /**
140      * Gets the boolean config from carrier config manager.
141      *
142      * @param key config key defined in CarrierConfigManager.
143      * @return boolean value of corresponding key.
144      */
getBooleanCarrierConfig(String key)145     private boolean getBooleanCarrierConfig(String key) {
146         if (mCarrierConfigManager == null) {
147             // Return static default defined in CarrierConfigManager.
148             return CarrierConfigManager.getDefaultConfig().getBoolean(key);
149         }
150 
151         // If an invalid subId is used, this bundle will contain default values.
152         final int subId = SubscriptionManager.getDefaultVoiceSubscriptionId();
153         final PersistableBundle bundle = mCarrierConfigManager.getConfigForSubId(subId);
154 
155         return bundle != null
156                 ? bundle.getBoolean(key)
157                 : CarrierConfigManager.getDefaultConfig().getBoolean(key);
158     }
159 
160     /** Returns whether is a correct default dialer which supports RTT. */
isDefaultDialerSupportedRTT(Context context)161     private static boolean isDefaultDialerSupportedRTT(Context context) {
162         return TextUtils.equals(
163                 context.getString(R.string.config_rtt_setting_package_name),
164                 TelecomUtil.getTelecomManager(context).getDefaultDialerPackage());
165     }
166 }
167