1 /* 2 * Copyright (C) 2018 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 static androidx.lifecycle.Lifecycle.Event.ON_START; 20 import static androidx.lifecycle.Lifecycle.Event.ON_STOP; 21 22 import android.content.Context; 23 import android.telephony.SubscriptionManager; 24 import android.telephony.TelephonyManager; 25 import android.text.TextUtils; 26 import android.util.Log; 27 28 import androidx.annotation.VisibleForTesting; 29 import androidx.fragment.app.FragmentManager; 30 import androidx.lifecycle.LifecycleObserver; 31 import androidx.lifecycle.LifecycleOwner; 32 import androidx.lifecycle.OnLifecycleEvent; 33 import androidx.preference.Preference; 34 import androidx.preference.PreferenceScreen; 35 import androidx.preference.TwoStatePreference; 36 37 import com.android.settings.R; 38 import com.android.settings.flags.Flags; 39 import com.android.settings.network.MobileNetworkRepository; 40 import com.android.settings.wifi.WifiPickerTrackerHelper; 41 import com.android.settingslib.core.lifecycle.Lifecycle; 42 import com.android.settingslib.mobile.dataservice.MobileNetworkInfoEntity; 43 import com.android.settingslib.mobile.dataservice.SubscriptionInfoEntity; 44 45 import java.util.ArrayList; 46 import java.util.List; 47 48 /** 49 * Preference controller for "Mobile data" 50 */ 51 public class MobileDataPreferenceController extends TelephonyTogglePreferenceController 52 implements LifecycleObserver, MobileNetworkRepository.MobileNetworkCallback { 53 54 private static final String DIALOG_TAG = "MobileDataDialog"; 55 56 private TwoStatePreference mPreference; 57 private TelephonyManager mTelephonyManager; 58 private SubscriptionManager mSubscriptionManager; 59 private FragmentManager mFragmentManager; 60 @VisibleForTesting 61 int mDialogType; 62 @VisibleForTesting 63 boolean mNeedDialog; 64 65 private WifiPickerTrackerHelper mWifiPickerTrackerHelper; 66 protected MobileNetworkRepository mMobileNetworkRepository; 67 protected LifecycleOwner mLifecycleOwner; 68 private List<SubscriptionInfoEntity> mSubscriptionInfoEntityList = new ArrayList<>(); 69 private List<MobileNetworkInfoEntity> mMobileNetworkInfoEntityList = new ArrayList<>(); 70 private int mDefaultSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; 71 SubscriptionInfoEntity mSubscriptionInfoEntity; 72 MobileNetworkInfoEntity mMobileNetworkInfoEntity; 73 MobileDataPreferenceController(Context context, String key, Lifecycle lifecycle, LifecycleOwner lifecycleOwner, int subId)74 public MobileDataPreferenceController(Context context, String key, Lifecycle lifecycle, 75 LifecycleOwner lifecycleOwner, int subId) { 76 this(context, key); 77 mSubId = subId; 78 mLifecycleOwner = lifecycleOwner; 79 if (lifecycle != null) { 80 lifecycle.addObserver(this); 81 } 82 } 83 MobileDataPreferenceController(Context context, String key)84 public MobileDataPreferenceController(Context context, String key) { 85 super(context, key); 86 mSubscriptionManager = context.getSystemService(SubscriptionManager.class); 87 mMobileNetworkRepository = MobileNetworkRepository.getInstance(context); 88 } 89 90 @Override getAvailabilityStatus(int subId)91 public int getAvailabilityStatus(int subId) { 92 if (Flags.isDualSimOnboardingEnabled()) { 93 return CONDITIONALLY_UNAVAILABLE; 94 } 95 return subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID 96 ? AVAILABLE 97 : AVAILABLE_UNSEARCHABLE; 98 } 99 100 @Override displayPreference(PreferenceScreen screen)101 public void displayPreference(PreferenceScreen screen) { 102 super.displayPreference(screen); 103 mPreference = screen.findPreference(getPreferenceKey()); 104 } 105 106 @OnLifecycleEvent(ON_START) onStart()107 public void onStart() { 108 mMobileNetworkRepository.addRegister(mLifecycleOwner, this, mSubId); 109 mMobileNetworkRepository.updateEntity(); 110 } 111 112 @OnLifecycleEvent(ON_STOP) onStop()113 public void onStop() { 114 mMobileNetworkRepository.removeRegister(this); 115 } 116 117 @Override handlePreferenceTreeClick(Preference preference)118 public boolean handlePreferenceTreeClick(Preference preference) { 119 if (TextUtils.equals(preference.getKey(), getPreferenceKey())) { 120 if (mNeedDialog) { 121 showDialog(mDialogType); 122 } 123 return true; 124 } 125 126 return false; 127 } 128 129 @Override setChecked(boolean isChecked)130 public boolean setChecked(boolean isChecked) { 131 mNeedDialog = isDialogNeeded(); 132 133 if (!mNeedDialog) { 134 // Update data directly if we don't need dialog 135 Log.d(DIALOG_TAG, "setMobileDataEnabled: " + isChecked); 136 MobileNetworkUtils.setMobileDataEnabled(mContext, mSubId, isChecked, false); 137 if (mWifiPickerTrackerHelper != null 138 && !mWifiPickerTrackerHelper.isCarrierNetworkProvisionEnabled(mSubId)) { 139 mWifiPickerTrackerHelper.setCarrierNetworkEnabled(isChecked); 140 } 141 return true; 142 } 143 144 return false; 145 } 146 147 @Override isChecked()148 public boolean isChecked() { 149 return mMobileNetworkInfoEntity == null ? false 150 : mMobileNetworkInfoEntity.isMobileDataEnabled; 151 } 152 153 @Override updateState(Preference preference)154 public void updateState(Preference preference) { 155 super.updateState(preference); 156 mPreference = (TwoStatePreference) preference; 157 update(); 158 } 159 update()160 private void update() { 161 162 if (mSubscriptionInfoEntity == null || mPreference == null) { 163 return; 164 } 165 166 mPreference.setChecked(isChecked()); 167 if (mSubscriptionInfoEntity.isOpportunistic) { 168 mPreference.setEnabled(false); 169 mPreference.setSummary(R.string.mobile_data_settings_summary_auto_switch); 170 } else { 171 mPreference.setEnabled(true); 172 mPreference.setSummary(R.string.mobile_data_settings_summary); 173 } 174 if (!mSubscriptionInfoEntity.isValidSubscription) { 175 mPreference.setSelectable(false); 176 mPreference.setSummary(R.string.mobile_data_settings_summary_unavailable); 177 } else { 178 mPreference.setSelectable(true); 179 } 180 } 181 init(FragmentManager fragmentManager, int subId, SubscriptionInfoEntity subInfoEntity, MobileNetworkInfoEntity networkInfoEntity)182 public void init(FragmentManager fragmentManager, int subId, 183 SubscriptionInfoEntity subInfoEntity, MobileNetworkInfoEntity networkInfoEntity) { 184 mFragmentManager = fragmentManager; 185 mSubId = subId; 186 mTelephonyManager = null; 187 mTelephonyManager = getTelephonyManager(); 188 mSubscriptionInfoEntity = subInfoEntity; 189 mMobileNetworkInfoEntity = networkInfoEntity; 190 } 191 getTelephonyManager()192 private TelephonyManager getTelephonyManager() { 193 if (mTelephonyManager != null) { 194 return mTelephonyManager; 195 } 196 TelephonyManager telMgr = 197 mContext.getSystemService(TelephonyManager.class); 198 if (mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 199 telMgr = telMgr.createForSubscriptionId(mSubId); 200 } 201 mTelephonyManager = telMgr; 202 return telMgr; 203 } 204 setWifiPickerTrackerHelper(WifiPickerTrackerHelper helper)205 public void setWifiPickerTrackerHelper(WifiPickerTrackerHelper helper) { 206 mWifiPickerTrackerHelper = helper; 207 } 208 209 @VisibleForTesting isDialogNeeded()210 boolean isDialogNeeded() { 211 final boolean enableData = !isChecked(); 212 mTelephonyManager = getTelephonyManager(); 213 final boolean isMultiSim = (mTelephonyManager.getActiveModemCount() > 1); 214 final boolean needToDisableOthers = mDefaultSubId != mSubId; 215 216 if (enableData && isMultiSim && needToDisableOthers) { 217 mDialogType = MobileDataDialogFragment.TYPE_MULTI_SIM_DIALOG; 218 return true; 219 } 220 return false; 221 } 222 showDialog(int type)223 private void showDialog(int type) { 224 final MobileDataDialogFragment dialogFragment = MobileDataDialogFragment.newInstance(type, 225 mSubId); 226 dialogFragment.show(mFragmentManager, DIALOG_TAG); 227 } 228 229 @VisibleForTesting setSubscriptionInfoEntity(SubscriptionInfoEntity subscriptionInfoEntity)230 public void setSubscriptionInfoEntity(SubscriptionInfoEntity subscriptionInfoEntity) { 231 mSubscriptionInfoEntity = subscriptionInfoEntity; 232 } 233 234 @VisibleForTesting setMobileNetworkInfoEntity(MobileNetworkInfoEntity mobileNetworkInfoEntity)235 public void setMobileNetworkInfoEntity(MobileNetworkInfoEntity mobileNetworkInfoEntity) { 236 mMobileNetworkInfoEntity = mobileNetworkInfoEntity; 237 } 238 239 @Override onActiveSubInfoChanged(List<SubscriptionInfoEntity> subInfoEntityList)240 public void onActiveSubInfoChanged(List<SubscriptionInfoEntity> subInfoEntityList) { 241 mSubscriptionInfoEntityList = subInfoEntityList; 242 mSubscriptionInfoEntityList.forEach(entity -> { 243 if (entity.getSubId() == mSubId) { 244 mSubscriptionInfoEntity = entity; 245 if (entity.getSubId() == SubscriptionManager.getDefaultDataSubscriptionId()) { 246 mDefaultSubId = entity.getSubId(); 247 } 248 } 249 }); 250 251 update(); 252 refreshSummary(mPreference); 253 } 254 255 256 @Override onAllMobileNetworkInfoChanged( List<MobileNetworkInfoEntity> mobileNetworkInfoEntityList)257 public void onAllMobileNetworkInfoChanged( 258 List<MobileNetworkInfoEntity> mobileNetworkInfoEntityList) { 259 mMobileNetworkInfoEntityList = mobileNetworkInfoEntityList; 260 mMobileNetworkInfoEntityList.forEach(entity -> { 261 if (Integer.parseInt(entity.subId) == mSubId) { 262 mMobileNetworkInfoEntity = entity; 263 update(); 264 refreshSummary(mPreference); 265 return; 266 } 267 }); 268 } 269 } 270