1 /* 2 * Copyright (C) 2019 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.car.developeroptions.network.telephony; 18 19 import android.content.Context; 20 import android.os.Looper; 21 import android.os.PersistableBundle; 22 import android.telephony.CarrierConfigManager; 23 import android.telephony.PhoneStateListener; 24 import android.telephony.SubscriptionManager; 25 import android.telephony.TelephonyManager; 26 27 import androidx.annotation.VisibleForTesting; 28 import androidx.preference.Preference; 29 import androidx.preference.PreferenceScreen; 30 import androidx.preference.SwitchPreference; 31 32 import com.android.ims.ImsManager; 33 import com.android.car.developeroptions.R; 34 import com.android.settingslib.core.lifecycle.LifecycleObserver; 35 import com.android.settingslib.core.lifecycle.events.OnStart; 36 import com.android.settingslib.core.lifecycle.events.OnStop; 37 38 import java.util.ArrayList; 39 import java.util.List; 40 41 /** 42 * Preference controller for "Enhanced 4G LTE" 43 */ 44 public class Enhanced4gLtePreferenceController extends TelephonyTogglePreferenceController 45 implements LifecycleObserver, OnStart, OnStop { 46 47 private Preference mPreference; 48 private TelephonyManager mTelephonyManager; 49 private CarrierConfigManager mCarrierConfigManager; 50 private PersistableBundle mCarrierConfig; 51 @VisibleForTesting 52 ImsManager mImsManager; 53 private PhoneCallStateListener mPhoneStateListener; 54 private final List<On4gLteUpdateListener> m4gLteListeners; 55 private final CharSequence[] mVariantTitles; 56 private final CharSequence[] mVariantSumaries; 57 58 private final int VARIANT_TITLE_VOLTE = 0; 59 private final int VARIANT_TITLE_ADVANCED_CALL = 1; 60 private final int VARIANT_TITLE_4G_CALLING = 2; 61 Enhanced4gLtePreferenceController(Context context, String key)62 public Enhanced4gLtePreferenceController(Context context, String key) { 63 super(context, key); 64 mCarrierConfigManager = context.getSystemService(CarrierConfigManager.class); 65 m4gLteListeners = new ArrayList<>(); 66 mPhoneStateListener = new PhoneCallStateListener(Looper.getMainLooper()); 67 mVariantTitles = context.getResources() 68 .getTextArray(R.array.enhanced_4g_lte_mode_title_variant); 69 mVariantSumaries = context.getResources() 70 .getTextArray(R.array.enhanced_4g_lte_mode_sumary_variant); 71 } 72 73 @Override getAvailabilityStatus(int subId)74 public int getAvailabilityStatus(int subId) { 75 final PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(subId); 76 final boolean isVisible = subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID 77 && mImsManager != null && carrierConfig != null 78 && mImsManager.isVolteEnabledByPlatform() 79 && mImsManager.isVolteProvisionedOnDevice() 80 && MobileNetworkUtils.isImsServiceStateReady(mImsManager) 81 && !carrierConfig.getBoolean(CarrierConfigManager.KEY_HIDE_ENHANCED_4G_LTE_BOOL); 82 return isVisible 83 ? (is4gLtePrefEnabled() ? AVAILABLE : AVAILABLE_UNSEARCHABLE) 84 : CONDITIONALLY_UNAVAILABLE; 85 } 86 87 @Override displayPreference(PreferenceScreen screen)88 public void displayPreference(PreferenceScreen screen) { 89 super.displayPreference(screen); 90 mPreference = screen.findPreference(getPreferenceKey()); 91 } 92 93 @Override onStart()94 public void onStart() { 95 mPhoneStateListener.register(mSubId); 96 } 97 98 @Override onStop()99 public void onStop() { 100 mPhoneStateListener.unregister(); 101 } 102 103 @Override updateState(Preference preference)104 public void updateState(Preference preference) { 105 super.updateState(preference); 106 final SwitchPreference switchPreference = (SwitchPreference) preference; 107 final boolean show4GForLTE = mCarrierConfig.getBoolean( 108 CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL); 109 int variant4glteTitleIndex = mCarrierConfig.getInt( 110 CarrierConfigManager.KEY_ENHANCED_4G_LTE_TITLE_VARIANT_INT); 111 112 if (variant4glteTitleIndex != VARIANT_TITLE_ADVANCED_CALL) { 113 variant4glteTitleIndex = show4GForLTE ? VARIANT_TITLE_4G_CALLING : VARIANT_TITLE_VOLTE; 114 } 115 116 switchPreference.setTitle(mVariantTitles[variant4glteTitleIndex]); 117 switchPreference.setSummary(mVariantSumaries[variant4glteTitleIndex]); 118 switchPreference.setEnabled(is4gLtePrefEnabled()); 119 switchPreference.setChecked(mImsManager.isEnhanced4gLteModeSettingEnabledByUser() 120 && mImsManager.isNonTtyOrTtyOnVolteEnabled()); 121 } 122 123 @Override setChecked(boolean isChecked)124 public boolean setChecked(boolean isChecked) { 125 mImsManager.setEnhanced4gLteModeSetting(isChecked); 126 for (final On4gLteUpdateListener lsn : m4gLteListeners) { 127 lsn.on4gLteUpdated(); 128 } 129 return true; 130 } 131 132 @Override isChecked()133 public boolean isChecked() { 134 return mImsManager.isEnhanced4gLteModeSettingEnabledByUser(); 135 } 136 init(int subId)137 public Enhanced4gLtePreferenceController init(int subId) { 138 mSubId = subId; 139 mTelephonyManager = TelephonyManager.from(mContext).createForSubscriptionId(mSubId); 140 mCarrierConfig = mCarrierConfigManager.getConfigForSubId(mSubId); 141 if (mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 142 mImsManager = ImsManager.getInstance(mContext, SubscriptionManager.getPhoneId(mSubId)); 143 } 144 145 return this; 146 } 147 addListener(On4gLteUpdateListener lsn)148 public Enhanced4gLtePreferenceController addListener(On4gLteUpdateListener lsn) { 149 m4gLteListeners.add(lsn); 150 return this; 151 } 152 is4gLtePrefEnabled()153 private boolean is4gLtePrefEnabled() { 154 return mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID 155 && mTelephonyManager.getCallState(mSubId) == TelephonyManager.CALL_STATE_IDLE 156 && mImsManager != null 157 && mImsManager.isNonTtyOrTtyOnVolteEnabled() 158 && mCarrierConfig.getBoolean( 159 CarrierConfigManager.KEY_EDITABLE_ENHANCED_4G_LTE_BOOL); 160 } 161 162 private class PhoneCallStateListener extends PhoneStateListener { 163 PhoneCallStateListener(Looper looper)164 public PhoneCallStateListener(Looper looper) { 165 super(looper); 166 } 167 168 @Override onCallStateChanged(int state, String incomingNumber)169 public void onCallStateChanged(int state, String incomingNumber) { 170 updateState(mPreference); 171 } 172 register(int subId)173 public void register(int subId) { 174 mSubId = subId; 175 mTelephonyManager.listen(this, PhoneStateListener.LISTEN_CALL_STATE); 176 } 177 unregister()178 public void unregister() { 179 mTelephonyManager.listen(this, PhoneStateListener.LISTEN_NONE); 180 } 181 } 182 183 /** 184 * Update other preferences when 4gLte state is changed 185 */ 186 public interface On4gLteUpdateListener { on4gLteUpdated()187 void on4gLteUpdated(); 188 } 189 } 190