• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.gsm;
18 
19 import static androidx.lifecycle.Lifecycle.Event.ON_START;
20 import static androidx.lifecycle.Lifecycle.Event.ON_STOP;
21 
22 import android.app.ProgressDialog;
23 import android.app.settings.SettingsEnums;
24 import android.content.Context;
25 import android.os.Bundle;
26 import android.os.Handler;
27 import android.os.HandlerExecutor;
28 import android.os.Looper;
29 import android.os.PersistableBundle;
30 import android.os.SystemClock;
31 import android.provider.Settings;
32 import android.telephony.CarrierConfigManager;
33 import android.telephony.ServiceState;
34 import android.telephony.SubscriptionManager;
35 import android.telephony.TelephonyManager;
36 
37 import androidx.annotation.VisibleForTesting;
38 import androidx.lifecycle.Lifecycle;
39 import androidx.lifecycle.LifecycleObserver;
40 import androidx.lifecycle.OnLifecycleEvent;
41 import androidx.preference.Preference;
42 import androidx.preference.PreferenceScreen;
43 import androidx.preference.SwitchPreference;
44 
45 import com.android.settings.R;
46 import com.android.settings.core.SubSettingLauncher;
47 import com.android.settings.network.AllowedNetworkTypesListener;
48 import com.android.settings.network.telephony.MobileNetworkUtils;
49 import com.android.settings.network.telephony.NetworkSelectSettings;
50 import com.android.settings.network.telephony.TelephonyTogglePreferenceController;
51 import com.android.settingslib.utils.ThreadUtils;
52 
53 import java.util.ArrayList;
54 import java.util.List;
55 import java.util.concurrent.Future;
56 import java.util.concurrent.TimeUnit;
57 
58 /**
59  * Preference controller for "Auto Select Network"
60  */
61 public class AutoSelectPreferenceController extends TelephonyTogglePreferenceController
62         implements LifecycleObserver{
63     private static final long MINIMUM_DIALOG_TIME_MILLIS = TimeUnit.SECONDS.toMillis(1);
64 
65     private final Handler mUiHandler;
66     private PreferenceScreen mPreferenceScreen;
67     private AllowedNetworkTypesListener mAllowedNetworkTypesListener;
68     private TelephonyManager mTelephonyManager;
69     private boolean mOnlyAutoSelectInHome;
70     private List<OnNetworkSelectModeListener> mListeners;
71     @VisibleForTesting
72     ProgressDialog mProgressDialog;
73     @VisibleForTesting
74     SwitchPreference mSwitchPreference;
75 
AutoSelectPreferenceController(Context context, String key)76     public AutoSelectPreferenceController(Context context, String key) {
77         super(context, key);
78         mTelephonyManager = context.getSystemService(TelephonyManager.class);
79         mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
80         mListeners = new ArrayList<>();
81         mUiHandler = new Handler(Looper.getMainLooper());
82         mAllowedNetworkTypesListener = new AllowedNetworkTypesListener(
83                 new HandlerExecutor(mUiHandler));
84         mAllowedNetworkTypesListener.setAllowedNetworkTypesListener(
85                 () -> updatePreference());
86     }
87 
updatePreference()88     private void updatePreference() {
89         if (mPreferenceScreen != null) {
90             displayPreference(mPreferenceScreen);
91         }
92         if (mSwitchPreference != null) {
93             updateState(mSwitchPreference);
94         }
95     }
96 
97     @OnLifecycleEvent(ON_START)
onStart()98     public void onStart() {
99         mAllowedNetworkTypesListener.register(mContext, mSubId);
100     }
101 
102     @OnLifecycleEvent(ON_STOP)
onStop()103     public void onStop() {
104         mAllowedNetworkTypesListener.unregister(mContext, mSubId);
105     }
106 
107     @Override
getAvailabilityStatus(int subId)108     public int getAvailabilityStatus(int subId) {
109         return MobileNetworkUtils.shouldDisplayNetworkSelectOptions(mContext, subId)
110                 ? AVAILABLE
111                 : CONDITIONALLY_UNAVAILABLE;
112     }
113 
114     @Override
displayPreference(PreferenceScreen screen)115     public void displayPreference(PreferenceScreen screen) {
116         super.displayPreference(screen);
117         mPreferenceScreen = screen;
118         mSwitchPreference = screen.findPreference(getPreferenceKey());
119     }
120 
121     @Override
isChecked()122     public boolean isChecked() {
123         return mTelephonyManager.getNetworkSelectionMode()
124                 == TelephonyManager.NETWORK_SELECTION_MODE_AUTO;
125     }
126 
127     @Override
updateState(Preference preference)128     public void updateState(Preference preference) {
129         super.updateState(preference);
130 
131         preference.setSummary(null);
132         final ServiceState serviceState = mTelephonyManager.getServiceState();
133         if (serviceState == null) {
134             preference.setEnabled(false);
135             return;
136         }
137 
138         if (serviceState.getRoaming()) {
139             preference.setEnabled(true);
140         } else {
141             preference.setEnabled(!mOnlyAutoSelectInHome);
142             if (mOnlyAutoSelectInHome) {
143                 preference.setSummary(mContext.getString(
144                         R.string.manual_mode_disallowed_summary,
145                         mTelephonyManager.getSimOperatorName()));
146             }
147         }
148     }
149 
150     @Override
setChecked(boolean isChecked)151     public boolean setChecked(boolean isChecked) {
152         if (isChecked) {
153             setAutomaticSelectionMode();
154             return false;
155         } else {
156             final Bundle bundle = new Bundle();
157             bundle.putInt(Settings.EXTRA_SUB_ID, mSubId);
158             new SubSettingLauncher(mContext)
159                     .setDestination(NetworkSelectSettings.class.getName())
160                     .setSourceMetricsCategory(SettingsEnums.MOBILE_NETWORK_SELECT)
161                     .setTitleRes(R.string.choose_network_title)
162                     .setArguments(bundle)
163                     .launch();
164             return false;
165         }
166     }
167 
168     @VisibleForTesting
setAutomaticSelectionMode()169     Future setAutomaticSelectionMode() {
170         final long startMillis = SystemClock.elapsedRealtime();
171         showAutoSelectProgressBar();
172         mSwitchPreference.setEnabled(false);
173         return ThreadUtils.postOnBackgroundThread(() -> {
174             // set network selection mode in background
175             mTelephonyManager.setNetworkSelectionModeAutomatic();
176             final int mode = mTelephonyManager.getNetworkSelectionMode();
177 
178             //Update UI in UI thread
179             final long durationMillis = SystemClock.elapsedRealtime() - startMillis;
180             mUiHandler.postDelayed(() -> {
181                 mSwitchPreference.setEnabled(true);
182                 mSwitchPreference.setChecked(
183                         mode == TelephonyManager.NETWORK_SELECTION_MODE_AUTO);
184                 for (OnNetworkSelectModeListener lsn : mListeners) {
185                     lsn.onNetworkSelectModeChanged();
186                 }
187                 dismissProgressBar();
188             }, Math.max(MINIMUM_DIALOG_TIME_MILLIS - durationMillis, 0));
189         });
190     }
191 
init(Lifecycle lifecycle, int subId)192     public AutoSelectPreferenceController init(Lifecycle lifecycle, int subId) {
193         mSubId = subId;
194         mTelephonyManager = mContext.getSystemService(TelephonyManager.class)
195                 .createForSubscriptionId(mSubId);
196         final PersistableBundle carrierConfig = mContext.getSystemService(
197                 CarrierConfigManager.class).getConfigForSubId(mSubId);
198         mOnlyAutoSelectInHome = carrierConfig != null
199                 ? carrierConfig.getBoolean(
200                 CarrierConfigManager.KEY_ONLY_AUTO_SELECT_IN_HOME_NETWORK_BOOL)
201                 : false;
202 
203         lifecycle.addObserver(this);
204         return this;
205     }
206 
addListener(OnNetworkSelectModeListener lsn)207     public AutoSelectPreferenceController addListener(OnNetworkSelectModeListener lsn) {
208         mListeners.add(lsn);
209 
210         return this;
211     }
212 
showAutoSelectProgressBar()213     private void showAutoSelectProgressBar() {
214         if (mProgressDialog == null) {
215             mProgressDialog = new ProgressDialog(mContext);
216             mProgressDialog.setMessage(
217                     mContext.getResources().getString(R.string.register_automatically));
218             mProgressDialog.setCanceledOnTouchOutside(false);
219             mProgressDialog.setCancelable(false);
220             mProgressDialog.setIndeterminate(true);
221         }
222         mProgressDialog.show();
223     }
224 
dismissProgressBar()225     private void dismissProgressBar() {
226         if (mProgressDialog != null && mProgressDialog.isShowing()) {
227             try {
228                 mProgressDialog.dismiss();
229             } catch (IllegalArgumentException e) {
230                 // Ignore exception since the dialog will be gone anyway.
231             }
232         }
233     }
234 
235     /**
236      * Callback when network select mode is changed
237      *
238      * @see TelephonyManager#getNetworkSelectionMode()
239      */
240     public interface OnNetworkSelectModeListener {
onNetworkSelectModeChanged()241         void onNetworkSelectModeChanged();
242     }
243 }
244