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.gsm; 18 19 import android.app.ProgressDialog; 20 import android.app.settings.SettingsEnums; 21 import android.content.Context; 22 import android.os.Bundle; 23 import android.os.Handler; 24 import android.os.Looper; 25 import android.os.PersistableBundle; 26 import android.os.SystemClock; 27 import android.provider.Settings; 28 import android.telephony.CarrierConfigManager; 29 import android.telephony.SubscriptionManager; 30 import android.telephony.TelephonyManager; 31 32 import androidx.annotation.VisibleForTesting; 33 import androidx.preference.Preference; 34 import androidx.preference.PreferenceScreen; 35 import androidx.preference.SwitchPreference; 36 37 import com.android.car.developeroptions.R; 38 import com.android.car.developeroptions.core.SubSettingLauncher; 39 import com.android.car.developeroptions.network.telephony.MobileNetworkUtils; 40 import com.android.car.developeroptions.network.telephony.NetworkSelectSettings; 41 import com.android.car.developeroptions.network.telephony.TelephonyTogglePreferenceController; 42 import com.android.settingslib.utils.ThreadUtils; 43 44 import java.util.ArrayList; 45 import java.util.List; 46 import java.util.concurrent.TimeUnit; 47 48 /** 49 * Preference controller for "Auto Select Network" 50 */ 51 public class AutoSelectPreferenceController extends TelephonyTogglePreferenceController { 52 private static final long MINIMUM_DIALOG_TIME_MILLIS = TimeUnit.SECONDS.toMillis(1); 53 54 private final Handler mUiHandler; 55 private int mSubId; 56 private TelephonyManager mTelephonyManager; 57 private boolean mOnlyAutoSelectInHome; 58 private List<OnNetworkSelectModeListener> mListeners; 59 @VisibleForTesting 60 ProgressDialog mProgressDialog; 61 @VisibleForTesting 62 SwitchPreference mSwitchPreference; 63 AutoSelectPreferenceController(Context context, String key)64 public AutoSelectPreferenceController(Context context, String key) { 65 super(context, key); 66 mTelephonyManager = context.getSystemService(TelephonyManager.class); 67 mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; 68 mListeners = new ArrayList<>(); 69 mUiHandler = new Handler(Looper.getMainLooper()); 70 } 71 72 @Override getAvailabilityStatus(int subId)73 public int getAvailabilityStatus(int subId) { 74 return MobileNetworkUtils.shouldDisplayNetworkSelectOptions(mContext, subId) 75 ? AVAILABLE 76 : CONDITIONALLY_UNAVAILABLE; 77 } 78 79 @Override displayPreference(PreferenceScreen screen)80 public void displayPreference(PreferenceScreen screen) { 81 super.displayPreference(screen); 82 mSwitchPreference = screen.findPreference(getPreferenceKey()); 83 } 84 85 @Override isChecked()86 public boolean isChecked() { 87 return mTelephonyManager.getNetworkSelectionMode() 88 == TelephonyManager.NETWORK_SELECTION_MODE_AUTO; 89 } 90 91 @Override updateState(Preference preference)92 public void updateState(Preference preference) { 93 super.updateState(preference); 94 95 preference.setSummary(null); 96 if (mTelephonyManager.getServiceState().getRoaming()) { 97 preference.setEnabled(true); 98 } else { 99 preference.setEnabled(!mOnlyAutoSelectInHome); 100 if (mOnlyAutoSelectInHome) { 101 preference.setSummary(mContext.getString( 102 R.string.manual_mode_disallowed_summary, 103 mTelephonyManager.getSimOperatorName())); 104 } 105 } 106 } 107 108 @Override setChecked(boolean isChecked)109 public boolean setChecked(boolean isChecked) { 110 if (isChecked) { 111 final long startMillis = SystemClock.elapsedRealtime(); 112 showAutoSelectProgressBar(); 113 mSwitchPreference.setEnabled(false); 114 ThreadUtils.postOnBackgroundThread(() -> { 115 // set network selection mode in background 116 mTelephonyManager.setNetworkSelectionModeAutomatic(); 117 final int mode = mTelephonyManager.getNetworkSelectionMode(); 118 119 //Update UI in UI thread 120 final long durationMillis = SystemClock.elapsedRealtime() - startMillis; 121 mUiHandler.postDelayed(() -> { 122 mSwitchPreference.setEnabled(true); 123 mSwitchPreference.setChecked( 124 mode == TelephonyManager.NETWORK_SELECTION_MODE_AUTO); 125 for (OnNetworkSelectModeListener lsn : mListeners) { 126 lsn.onNetworkSelectModeChanged(); 127 } 128 dismissProgressBar(); 129 }, 130 Math.max(MINIMUM_DIALOG_TIME_MILLIS - durationMillis, 0)); 131 }); 132 return false; 133 } else { 134 final Bundle bundle = new Bundle(); 135 bundle.putInt(Settings.EXTRA_SUB_ID, mSubId); 136 new SubSettingLauncher(mContext) 137 .setDestination(NetworkSelectSettings.class.getName()) 138 .setSourceMetricsCategory(SettingsEnums.MOBILE_NETWORK_SELECT) 139 .setTitleRes(R.string.choose_network_title) 140 .setArguments(bundle) 141 .launch(); 142 return false; 143 } 144 } 145 init(int subId)146 public AutoSelectPreferenceController init(int subId) { 147 mSubId = subId; 148 mTelephonyManager = TelephonyManager.from(mContext).createForSubscriptionId(mSubId); 149 final PersistableBundle carrierConfig = mContext.getSystemService( 150 CarrierConfigManager.class).getConfigForSubId(mSubId); 151 mOnlyAutoSelectInHome = carrierConfig != null 152 ? carrierConfig.getBoolean( 153 CarrierConfigManager.KEY_ONLY_AUTO_SELECT_IN_HOME_NETWORK_BOOL) 154 : false; 155 156 return this; 157 } 158 addListener(OnNetworkSelectModeListener lsn)159 public AutoSelectPreferenceController addListener(OnNetworkSelectModeListener lsn) { 160 mListeners.add(lsn); 161 162 return this; 163 } 164 showAutoSelectProgressBar()165 private void showAutoSelectProgressBar() { 166 if (mProgressDialog == null) { 167 mProgressDialog = new ProgressDialog(mContext); 168 mProgressDialog.setMessage( 169 mContext.getResources().getString(R.string.register_automatically)); 170 mProgressDialog.setCanceledOnTouchOutside(false); 171 mProgressDialog.setCancelable(false); 172 mProgressDialog.setIndeterminate(true); 173 } 174 mProgressDialog.show(); 175 } 176 dismissProgressBar()177 private void dismissProgressBar() { 178 if (mProgressDialog != null && mProgressDialog.isShowing()) { 179 mProgressDialog.dismiss(); 180 } 181 } 182 183 /** 184 * Callback when network select mode is changed 185 * 186 * @see TelephonyManager#getNetworkSelectionMode() 187 */ 188 public interface OnNetworkSelectModeListener { onNetworkSelectModeChanged()189 void onNetworkSelectModeChanged(); 190 } 191 }