1 /* 2 * Copyright (C) 2020 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.network.telephony; 18 19 import android.content.Context; 20 import android.os.PersistableBundle; 21 import android.telephony.CarrierConfigManager; 22 import android.telephony.SubscriptionInfo; 23 import android.telephony.SubscriptionManager; 24 import android.telephony.ims.ImsException; 25 import android.telephony.ims.ImsManager; 26 import android.telephony.ims.ImsMmTelManager; 27 import android.util.Log; 28 29 import androidx.preference.Preference; 30 import androidx.preference.SwitchPreference; 31 32 import com.android.settings.R; 33 import com.android.settings.network.SubscriptionUtil; 34 import com.android.settings.network.ims.WifiCallingQueryImsState; 35 36 import java.util.List; 37 import java.util.Objects; 38 39 /** 40 * Preference controller for "Backup Calling" 41 **/ 42 public class BackupCallingPreferenceController extends TelephonyTogglePreferenceController { 43 44 private static final String LOG_TAG = "BackupCallingPrefCtrl"; 45 46 private Preference mPreference; 47 48 /** 49 * Class constructor of backup calling. 50 * 51 * @param context of settings 52 * @param key assigned within UI entry of XML file 53 **/ BackupCallingPreferenceController(Context context, String key)54 public BackupCallingPreferenceController(Context context, String key) { 55 super(context, key); 56 } 57 58 /** 59 * Initialization based on given subscription id. 60 * 61 * @param subId is the subscription id 62 * @return this instance after initialization 63 **/ init(int subId)64 public BackupCallingPreferenceController init(int subId) { 65 mSubId = subId; 66 return this; 67 } 68 69 @Override getAvailabilityStatus(int subId)70 public int getAvailabilityStatus(int subId) { 71 if (!hasBackupCallingFeature(subId)) { 72 return CONDITIONALLY_UNAVAILABLE; 73 } 74 List<SubscriptionInfo> subIdList = getActiveSubscriptionList(); 75 SubscriptionInfo subInfo = getSubscriptionInfoFromList(subIdList, subId); 76 if (subInfo == null) { // given subId is not actives 77 return CONDITIONALLY_UNAVAILABLE; 78 } 79 return (subIdList.size() > 1) ? AVAILABLE : CONDITIONALLY_UNAVAILABLE; 80 } 81 82 /** 83 * Implementation of abstract methods 84 **/ setChecked(boolean isChecked)85 public boolean setChecked(boolean isChecked) { 86 ImsMmTelManager imsMmTelMgr = getImsMmTelManager(mSubId); 87 if (imsMmTelMgr == null) { 88 return false; 89 } 90 try { 91 imsMmTelMgr.setCrossSimCallingEnabled(isChecked); 92 } catch (ImsException exception) { 93 Log.w(LOG_TAG, "fail to change cross SIM calling configuration: " + isChecked, 94 exception); 95 return false; 96 } 97 return true; 98 } 99 100 /** 101 * Implementation of abstract methods 102 **/ isChecked()103 public boolean isChecked() { 104 ImsMmTelManager imsMmTelMgr = getImsMmTelManager(mSubId); 105 if (imsMmTelMgr == null) { 106 return false; 107 } 108 try { 109 return imsMmTelMgr.isCrossSimCallingEnabled(); 110 } catch (ImsException exception) { 111 Log.w(LOG_TAG, "fail to get cross SIM calling configuration", exception); 112 } 113 return false; 114 } 115 116 @Override updateState(Preference preference)117 public void updateState(Preference preference) { 118 super.updateState(preference); 119 if ((preference == null) || (!(preference instanceof SwitchPreference))) { 120 return; 121 } 122 SubscriptionInfo subInfo = getSubscriptionInfoFromActiveList(mSubId); 123 124 mPreference = preference; 125 126 final SwitchPreference switchPreference = (SwitchPreference) preference; 127 switchPreference.setChecked((subInfo != null) ? isChecked() : false); 128 129 updateSummary(getLatestSummary(subInfo)); 130 } 131 getLatestSummary(SubscriptionInfo subInfo)132 private String getLatestSummary(SubscriptionInfo subInfo) { 133 return Objects.toString((subInfo == null) ? null 134 : SubscriptionUtil.getUniqueSubscriptionDisplayName(subInfo, mContext), ""); 135 } 136 updateSummary(String displayName)137 private void updateSummary(String displayName) { 138 Preference preference = mPreference; 139 if (preference == null) { 140 return; 141 } 142 String summary = displayName; 143 String finalText = String.format( 144 getResourcesForSubId().getString(R.string.backup_calling_setting_summary), 145 summary) 146 .toString(); 147 preference.setSummary(finalText); 148 } 149 hasBackupCallingFeature(int subscriptionId)150 private boolean hasBackupCallingFeature(int subscriptionId) { 151 return isCrossSimEnabledByPlatform(mContext, subscriptionId); 152 } 153 isCrossSimEnabledByPlatform(Context context, int subscriptionId)154 protected boolean isCrossSimEnabledByPlatform(Context context, int subscriptionId) { 155 // TODO : Change into API which created for accessing 156 // com.android.ims.ImsManager#isCrossSimEnabledByPlatform() 157 if ((new WifiCallingQueryImsState(context, subscriptionId)).isWifiCallingSupported()) { 158 PersistableBundle bundle = getCarrierConfigForSubId(subscriptionId); 159 return (bundle != null) && bundle.getBoolean( 160 CarrierConfigManager.KEY_CARRIER_CROSS_SIM_IMS_AVAILABLE_BOOL, 161 false /*default*/); 162 } 163 Log.d(LOG_TAG, "Not supported by framework. subId = " + subscriptionId); 164 return false; 165 } 166 getImsMmTelManager(int subId)167 private ImsMmTelManager getImsMmTelManager(int subId) { 168 if (!SubscriptionManager.isUsableSubscriptionId(subId)) { 169 return null; 170 } 171 ImsManager imsMgr = mContext.getSystemService(ImsManager.class); 172 return (imsMgr == null) ? null : imsMgr.getImsMmTelManager(subId); 173 } 174 getActiveSubscriptionList()175 private List<SubscriptionInfo> getActiveSubscriptionList() { 176 SubscriptionManager subscriptionManager = 177 mContext.getSystemService(SubscriptionManager.class); 178 return SubscriptionUtil.getActiveSubscriptions(subscriptionManager); 179 } 180 getSubscriptionInfoFromList( List<SubscriptionInfo> subInfoList, int subId)181 private SubscriptionInfo getSubscriptionInfoFromList( 182 List<SubscriptionInfo> subInfoList, int subId) { 183 for (SubscriptionInfo subInfo : subInfoList) { 184 if ((subInfo != null) && (subInfo.getSubscriptionId() == subId)) { 185 return subInfo; 186 } 187 } 188 return null; 189 } 190 getSubscriptionInfoFromActiveList(int subId)191 private SubscriptionInfo getSubscriptionInfoFromActiveList(int subId) { 192 if (!SubscriptionManager.isUsableSubscriptionId(subId)) { 193 return null; 194 } 195 return getSubscriptionInfoFromList(getActiveSubscriptionList(), subId); 196 } 197 } 198