blob: b071273c7257a8b95bfad668565d3c110820b92d [file] [log] [blame]
cretin45d4cea552016-04-25 11:00:04 -07001/*
2 * Copyright (C) 2016 The CyanogenMod Project
Christian Odercff63862020-11-09 17:14:42 +01003 * Copyright (C) 2017-2018,2020 The LineageOS Project
cretin45d4cea552016-04-25 11:00:04 -07004 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
Michael Bestasc83309e2018-02-03 17:42:13 +020018package org.lineageos.setupwizard;
cretin45d4cea552016-04-25 11:00:04 -070019
Michael Bestasc83309e2018-02-03 17:42:13 +020020import static org.lineageos.setupwizard.SetupWizardApp.LOGV;
cretin45d4cea552016-04-25 11:00:04 -070021
22import android.os.Bundle;
23import android.os.Handler;
24import android.telephony.ServiceState;
25import android.telephony.SignalStrength;
26import android.telephony.SubscriptionManager;
27import android.telephony.TelephonyManager;
28import android.text.TextUtils;
29import android.util.Log;
30import android.view.View;
cretin45d4cea552016-04-25 11:00:04 -070031import android.view.animation.AnimationUtils;
32import android.widget.ImageView;
33import android.widget.ProgressBar;
34import android.widget.Switch;
35import android.widget.TextView;
36
Michael Bestasc83309e2018-02-03 17:42:13 +020037import org.lineageos.setupwizard.util.NetworkMonitor;
38import org.lineageos.setupwizard.util.PhoneMonitor;
39import org.lineageos.setupwizard.util.SetupWizardUtils;
cretin45d4cea552016-04-25 11:00:04 -070040
41public class MobileDataActivity extends BaseSetupWizardActivity {
42
43 public static final String TAG = MobileDataActivity.class.getSimpleName();
44
45 private static final int DC_READY_TIMEOUT = 20 * 1000;
46
47 private ProgressBar mProgressBar;
48 private View mEnableDataRow;
49 private Switch mEnableMobileData;
50 private ImageView mSignalView;
51 private TextView mNameView;
52
53 private TelephonyManager mPhone;
54 private SignalStrength mSignalStrength;
55 private ServiceState mServiceState;
56 private PhoneMonitor mPhoneMonitor;
57 private NetworkMonitor mNetworkMonitor;
58
59 private boolean mIsAttached = false;
60
61 private final Handler mHandler = new Handler();
62
Michael W2236d292018-07-15 15:09:20 +020063 private final Runnable mRadioReadyRunnable = this::hideWaitForRadio;
cretin45d4cea552016-04-25 11:00:04 -070064
Michael W2236d292018-07-15 15:09:20 +020065 private final Runnable mDataConnectionReadyRunnable = this::onDataStateReady;
cretin45d4cea552016-04-25 11:00:04 -070066
67 private PhoneMonitor.SubscriptionStateListener mSubscriptionStateListener =
68 new PhoneMonitor.SubscriptionStateListener() {
69 @Override
70 public void onServiceStateChanged(int subId, ServiceState serviceState) {
71 if (LOGV) {
72 Log.v(TAG, "onServiceStateChanged{" +
73 "subId='" + subId + '\'' +
74 ", serviceState=" + serviceState.toString() +
75 '}');
76 }
77 if (SetupWizardUtils.isRadioReady(MobileDataActivity.this, serviceState)) {
78 hideWaitForRadio();
79 }
80 mServiceState = serviceState;
81 updateSignalStrength();
82 }
83
84 @Override
85 public void onDataConnectionStateChanged(int subId, int state, int networkType) {
86 if (LOGV) {
87 Log.v(TAG, "onDataConnectionStateChanged{" +
88 "subId='" + subId + '\'' +
89 ", state=" + state +
90 '}');
91 }
92 if (state == TelephonyManager.DATA_CONNECTED) {
93 onDataStateReady();
94 }
95 }
96
97 @Override
98 public void onDefaultDataSubscriptionChanged(int subId) {}
99
100 @Override
101 public void onDefaultDataSubscriptionChangeRequested(int currentSubId,
102 int newSubId) {}
103
104 @Override
105 public void onSignalStrengthsChanged(int subId, SignalStrength signalStrength) {
106 if (LOGV) {
107 Log.v(TAG, "onSignalStrengthsChanged{" +
108 "subId='" + subId + '\'' +
109 ", signalStrength=" + signalStrength.toString() +
110 '}');
111 }
112 mSignalStrength = signalStrength;
113 updateSignalStrength();
114 }
115
116 @Override
117 public void onSimStateChanged(int subId, int simState) {
118 if (LOGV) {
119 Log.v(TAG, "onSimStateChanged{" +
120 "subId='" + subId + '\'' +
121 ", simState=" + simState +
122 '}');
123 }
124 }
125 };
126
127 private View.OnClickListener mEnableDataClickListener = new View.OnClickListener() {
128 @Override
129 public void onClick(View view) {
130 boolean checked = !mEnableMobileData.isChecked();
131 SetupWizardUtils.setMobileDataEnabled(MobileDataActivity.this, checked);
132 mEnableMobileData.setChecked(checked);
133 if (checked && !mNetworkMonitor.isWifiConnected()) {
134 waitForData();
135 } else {
136 onDataStateReady();
137 }
138 }
139 };
140
141 @Override
142 protected void onCreate(Bundle savedInstanceState) {
143 super.onCreate(savedInstanceState);
144 mPhoneMonitor = PhoneMonitor.getInstance();
145 mNetworkMonitor = NetworkMonitor.getInstance();
146 setNextText(R.string.next);
147
148 mProgressBar = (ProgressBar) findViewById(R.id.progress);
149 mEnableDataRow = findViewById(R.id.data);
150 mEnableDataRow.setOnClickListener(mEnableDataClickListener);
151 mEnableMobileData = (Switch) findViewById(R.id.data_switch);
152 mSignalView = (ImageView) findViewById(R.id.signal);
153 mNameView = (TextView) findViewById(R.id.enable_data_title);
154 updateDataConnectionStatus();
155 updateSignalStrength();
156
157 }
158
159
160 @Override
161 public void onResume() {
162 super.onResume();
163 mIsAttached = true;
164 mPhone = getSystemService(TelephonyManager.class);
165 mPhoneMonitor.addListener(mSubscriptionStateListener);
166 updateDataConnectionStatus();
167 updateSignalStrength();
168 if (SetupWizardUtils.isRadioReady(this, null)) {
169 hideWaitForRadio();
170 } else {
171 mHandler.postDelayed(mRadioReadyRunnable, SetupWizardApp.RADIO_READY_TIMEOUT);
172 }
173 }
174
175 @Override
176 public void onPause() {
177 super.onPause();
178 mIsAttached = false;
179 mPhoneMonitor.removeListener(mSubscriptionStateListener);
180 }
181
cretin45d4cea552016-04-25 11:00:04 -0700182 private void hideWaitForRadio() {
183 if (mProgressBar.isShown()) {
184 mHandler.removeCallbacks(mRadioReadyRunnable);
185 // Something else, like data enablement, may have grabbed
186 // the "hold" status. Kill it only if "Next" is active
187 if (isNextAllowed()) {
188 mProgressBar.setVisibility(View.INVISIBLE);
189 }
190 }
191 }
192
193 private void waitForData() {
194 if (!mProgressBar.isShown()) {
195 mProgressBar.setVisibility(View.VISIBLE);
196 mProgressBar.startAnimation(
197 AnimationUtils.loadAnimation(this, R.anim.translucent_enter));
198 mEnableDataRow.setEnabled(false);
199 setNextAllowed(false);
200 mHandler.postDelayed(mDataConnectionReadyRunnable, DC_READY_TIMEOUT);
201 }
202 }
203
204 private void onDataStateReady() {
205 mHandler.removeCallbacks(mDataConnectionReadyRunnable);
206 if ((mProgressBar.isShown()) ||
207 !isNextAllowed()) {
208 mProgressBar.startAnimation(
209 AnimationUtils.loadAnimation(this, R.anim.translucent_exit));
210 mProgressBar.setVisibility(View.INVISIBLE);
211 mEnableDataRow.setEnabled(true);
212 setNextAllowed(true);
213 }
214 }
215
216 private void updateCarrierText() {
217 if (mIsAttached) {
Michael W2236d292018-07-15 15:09:20 +0200218 String name = mPhone.getSimOperatorName(getDefaultSubscriptionId());
cretin45d4cea552016-04-25 11:00:04 -0700219 if (TextUtils.isEmpty(name)) {
Michael W2236d292018-07-15 15:09:20 +0200220 name = mPhone.getNetworkOperatorName(getDefaultSubscriptionId());
cretin45d4cea552016-04-25 11:00:04 -0700221 }
222 if (TextUtils.isEmpty(name)) {
223 if (mServiceState != null && mServiceState.isEmergencyOnly()) {
224 name = getString(R.string.setup_mobile_data_emergency_only);
225 } else {
226 name = getString(R.string.setup_mobile_data_no_service);
227 }
228 }
229 mNameView.setText(name);
230 }
231 }
232
233 private void updateSignalStrength() {
234 if (mIsAttached) {
235 if (LOGV) {
236 Log.v(TAG, "updateSignalStrength{" +
237 "signalStrength='" + mSignalStrength + '\'' +
238 "signalStrengthLevel='" + ((mSignalStrength != null) ?
239 mSignalStrength.getLevel() : "null") + '\'' +
240 '}');
241 }
242 if (!hasService()) {
243 mSignalView.setImageResource(R.drawable.ic_signal_no_signal);
244 } else {
245 if (mSignalStrength != null) {
246 int resId;
247 switch (mSignalStrength.getLevel()) {
248 case 4:
249 resId = R.drawable.ic_signal_4;
250 break;
251 case 3:
252 resId = R.drawable.ic_signal_3;
253 break;
254 case 2:
255 resId = R.drawable.ic_signal_2;
256 break;
257 case 1:
258 resId = R.drawable.ic_signal_1;
259 break;
260 default:
261 resId = R.drawable.ic_signal_0;
262 break;
263 }
264 mSignalView.setImageResource(resId);
265 }
266 }
267 updateCarrierText();
268 }
269 }
270
271 private void updateDataConnectionStatus() {
272 mEnableMobileData.setChecked(SetupWizardUtils.isMobileDataEnabled(this));
273 }
274
275 private boolean hasService() {
276 boolean retVal;
277 if (mServiceState == null) {
278 mServiceState = TelephonyManager.from(this)
Michael W2236d292018-07-15 15:09:20 +0200279 .getServiceStateForSubscriber(getDefaultSubscriptionId());
cretin45d4cea552016-04-25 11:00:04 -0700280 }
281 if (mServiceState != null) {
282 // Consider the device to be in service if either voice or data service is available.
283 // Some SIM cards are marketed as data-only and do not support voice service, and on
284 // these SIM cards, we want to show signal bars for data service as well as the "no
285 // service" or "emergency calls only" text that indicates that voice is not available.
286 switch(mServiceState.getVoiceRegState()) {
287 case ServiceState.STATE_POWER_OFF:
288 retVal = false;
289 break;
290 case ServiceState.STATE_OUT_OF_SERVICE:
291 case ServiceState.STATE_EMERGENCY_ONLY:
292 retVal = mServiceState.getDataRegState() == ServiceState.STATE_IN_SERVICE;
293 break;
294 default:
295 retVal = true;
296 }
297 } else {
298 retVal = false;
299 }
300 return retVal;
301 }
302
303 @Override
304 protected int getLayoutResId() {
305 return R.layout.mobile_data_settings;
306 }
307
308 @Override
309 protected int getTitleResId() {
310 return R.string.setup_mobile_data;
311 }
312
313 @Override
314 protected int getIconResId() {
315 return R.drawable.ic_mobile_data;
316 }
317
Michael W2236d292018-07-15 15:09:20 +0200318 private int getDefaultSubscriptionId() {
319 return SubscriptionManager.getDefaultSubscriptionId();
320 }
cretin45d4cea552016-04-25 11:00:04 -0700321}