blob: cb7bf18cedc881837617201e99b717d4767918a6 [file] [log] [blame]
cretin45d4cea552016-04-25 11:00:04 -07001/*
2 * Copyright (C) 2016 The CyanogenMod Project
3 * Copyright (C) 2017 The LineageOS Project
4 *
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
18package com.cyanogenmod.setupwizard;
19
20import static com.cyanogenmod.setupwizard.SetupWizardApp.LOGV;
21
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;
31import android.view.ViewGroup;
32import android.view.animation.AnimationUtils;
33import android.widget.ImageView;
34import android.widget.ProgressBar;
35import android.widget.Switch;
36import android.widget.TextView;
37
38import com.cyanogenmod.setupwizard.util.NetworkMonitor;
39import com.cyanogenmod.setupwizard.util.PhoneMonitor;
40import com.cyanogenmod.setupwizard.util.SetupWizardUtils;
41
42public class MobileDataActivity extends BaseSetupWizardActivity {
43
44 public static final String TAG = MobileDataActivity.class.getSimpleName();
45
46 private static final int DC_READY_TIMEOUT = 20 * 1000;
47
48 private ProgressBar mProgressBar;
49 private View mEnableDataRow;
50 private Switch mEnableMobileData;
51 private ImageView mSignalView;
52 private TextView mNameView;
53
54 private TelephonyManager mPhone;
55 private SignalStrength mSignalStrength;
56 private ServiceState mServiceState;
57 private PhoneMonitor mPhoneMonitor;
58 private NetworkMonitor mNetworkMonitor;
59
60 private boolean mIsAttached = false;
61
62 private final Handler mHandler = new Handler();
63
64 private final Runnable mRadioReadyRunnable = new Runnable() {
65 @Override
66 public void run() {
67 hideWaitForRadio();
68 }
69 };
70
71 private final Runnable mDataConnectionReadyRunnable = new Runnable() {
72 @Override
73 public void run() {
74 onDataStateReady();
75 }
76 };
77
78 private PhoneMonitor.SubscriptionStateListener mSubscriptionStateListener =
79 new PhoneMonitor.SubscriptionStateListener() {
80 @Override
81 public void onServiceStateChanged(int subId, ServiceState serviceState) {
82 if (LOGV) {
83 Log.v(TAG, "onServiceStateChanged{" +
84 "subId='" + subId + '\'' +
85 ", serviceState=" + serviceState.toString() +
86 '}');
87 }
88 if (SetupWizardUtils.isRadioReady(MobileDataActivity.this, serviceState)) {
89 hideWaitForRadio();
90 }
91 mServiceState = serviceState;
92 updateSignalStrength();
93 }
94
95 @Override
96 public void onDataConnectionStateChanged(int subId, int state, int networkType) {
97 if (LOGV) {
98 Log.v(TAG, "onDataConnectionStateChanged{" +
99 "subId='" + subId + '\'' +
100 ", state=" + state +
101 '}');
102 }
103 if (state == TelephonyManager.DATA_CONNECTED) {
104 onDataStateReady();
105 }
106 }
107
108 @Override
109 public void onDefaultDataSubscriptionChanged(int subId) {}
110
111 @Override
112 public void onDefaultDataSubscriptionChangeRequested(int currentSubId,
113 int newSubId) {}
114
115 @Override
116 public void onSignalStrengthsChanged(int subId, SignalStrength signalStrength) {
117 if (LOGV) {
118 Log.v(TAG, "onSignalStrengthsChanged{" +
119 "subId='" + subId + '\'' +
120 ", signalStrength=" + signalStrength.toString() +
121 '}');
122 }
123 mSignalStrength = signalStrength;
124 updateSignalStrength();
125 }
126
127 @Override
128 public void onSimStateChanged(int subId, int simState) {
129 if (LOGV) {
130 Log.v(TAG, "onSimStateChanged{" +
131 "subId='" + subId + '\'' +
132 ", simState=" + simState +
133 '}');
134 }
135 }
136 };
137
138 private View.OnClickListener mEnableDataClickListener = new View.OnClickListener() {
139 @Override
140 public void onClick(View view) {
141 boolean checked = !mEnableMobileData.isChecked();
142 SetupWizardUtils.setMobileDataEnabled(MobileDataActivity.this, checked);
143 mEnableMobileData.setChecked(checked);
144 if (checked && !mNetworkMonitor.isWifiConnected()) {
145 waitForData();
146 } else {
147 onDataStateReady();
148 }
149 }
150 };
151
152 @Override
153 protected void onCreate(Bundle savedInstanceState) {
154 super.onCreate(savedInstanceState);
155 mPhoneMonitor = PhoneMonitor.getInstance();
156 mNetworkMonitor = NetworkMonitor.getInstance();
157 setNextText(R.string.next);
158
159 mProgressBar = (ProgressBar) findViewById(R.id.progress);
160 mEnableDataRow = findViewById(R.id.data);
161 mEnableDataRow.setOnClickListener(mEnableDataClickListener);
162 mEnableMobileData = (Switch) findViewById(R.id.data_switch);
163 mSignalView = (ImageView) findViewById(R.id.signal);
164 mNameView = (TextView) findViewById(R.id.enable_data_title);
165 updateDataConnectionStatus();
166 updateSignalStrength();
167
168 }
169
170
171 @Override
172 public void onResume() {
173 super.onResume();
174 mIsAttached = true;
175 mPhone = getSystemService(TelephonyManager.class);
176 mPhoneMonitor.addListener(mSubscriptionStateListener);
177 updateDataConnectionStatus();
178 updateSignalStrength();
179 if (SetupWizardUtils.isRadioReady(this, null)) {
180 hideWaitForRadio();
181 } else {
182 mHandler.postDelayed(mRadioReadyRunnable, SetupWizardApp.RADIO_READY_TIMEOUT);
183 }
184 }
185
186 @Override
187 public void onPause() {
188 super.onPause();
189 mIsAttached = false;
190 mPhoneMonitor.removeListener(mSubscriptionStateListener);
191 }
192
193 @Override
194 protected int getTransition() {
195 return TRANSITION_ID_SLIDE;
196 }
197
198 private void hideWaitForRadio() {
199 if (mProgressBar.isShown()) {
200 mHandler.removeCallbacks(mRadioReadyRunnable);
201 // Something else, like data enablement, may have grabbed
202 // the "hold" status. Kill it only if "Next" is active
203 if (isNextAllowed()) {
204 mProgressBar.setVisibility(View.INVISIBLE);
205 }
206 }
207 }
208
209 private void waitForData() {
210 if (!mProgressBar.isShown()) {
211 mProgressBar.setVisibility(View.VISIBLE);
212 mProgressBar.startAnimation(
213 AnimationUtils.loadAnimation(this, R.anim.translucent_enter));
214 mEnableDataRow.setEnabled(false);
215 setNextAllowed(false);
216 mHandler.postDelayed(mDataConnectionReadyRunnable, DC_READY_TIMEOUT);
217 }
218 }
219
220 private void onDataStateReady() {
221 mHandler.removeCallbacks(mDataConnectionReadyRunnable);
222 if ((mProgressBar.isShown()) ||
223 !isNextAllowed()) {
224 mProgressBar.startAnimation(
225 AnimationUtils.loadAnimation(this, R.anim.translucent_exit));
226 mProgressBar.setVisibility(View.INVISIBLE);
227 mEnableDataRow.setEnabled(true);
228 setNextAllowed(true);
229 }
230 }
231
232 private void updateCarrierText() {
233 if (mIsAttached) {
234 String name = mPhone.getSimOperatorName(SubscriptionManager.getDefaultSubscriptionId());
235 if (TextUtils.isEmpty(name)) {
236 name = mPhone.getNetworkOperatorName(SubscriptionManager.getDefaultSubscriptionId());
237 }
238 if (TextUtils.isEmpty(name)) {
239 if (mServiceState != null && mServiceState.isEmergencyOnly()) {
240 name = getString(R.string.setup_mobile_data_emergency_only);
241 } else {
242 name = getString(R.string.setup_mobile_data_no_service);
243 }
244 }
245 mNameView.setText(name);
246 }
247 }
248
249 private void updateSignalStrength() {
250 if (mIsAttached) {
251 if (LOGV) {
252 Log.v(TAG, "updateSignalStrength{" +
253 "signalStrength='" + mSignalStrength + '\'' +
254 "signalStrengthLevel='" + ((mSignalStrength != null) ?
255 mSignalStrength.getLevel() : "null") + '\'' +
256 '}');
257 }
258 if (!hasService()) {
259 mSignalView.setImageResource(R.drawable.ic_signal_no_signal);
260 } else {
261 if (mSignalStrength != null) {
262 int resId;
263 switch (mSignalStrength.getLevel()) {
264 case 4:
265 resId = R.drawable.ic_signal_4;
266 break;
267 case 3:
268 resId = R.drawable.ic_signal_3;
269 break;
270 case 2:
271 resId = R.drawable.ic_signal_2;
272 break;
273 case 1:
274 resId = R.drawable.ic_signal_1;
275 break;
276 default:
277 resId = R.drawable.ic_signal_0;
278 break;
279 }
280 mSignalView.setImageResource(resId);
281 }
282 }
283 updateCarrierText();
284 }
285 }
286
287 private void updateDataConnectionStatus() {
288 mEnableMobileData.setChecked(SetupWizardUtils.isMobileDataEnabled(this));
289 }
290
291 private boolean hasService() {
292 boolean retVal;
293 if (mServiceState == null) {
294 mServiceState = TelephonyManager.from(this)
295 .getServiceStateForSubscriber(SubscriptionManager.getDefaultSubscriptionId());
296 }
297 if (mServiceState != null) {
298 // Consider the device to be in service if either voice or data service is available.
299 // Some SIM cards are marketed as data-only and do not support voice service, and on
300 // these SIM cards, we want to show signal bars for data service as well as the "no
301 // service" or "emergency calls only" text that indicates that voice is not available.
302 switch(mServiceState.getVoiceRegState()) {
303 case ServiceState.STATE_POWER_OFF:
304 retVal = false;
305 break;
306 case ServiceState.STATE_OUT_OF_SERVICE:
307 case ServiceState.STATE_EMERGENCY_ONLY:
308 retVal = mServiceState.getDataRegState() == ServiceState.STATE_IN_SERVICE;
309 break;
310 default:
311 retVal = true;
312 }
313 } else {
314 retVal = false;
315 }
316 return retVal;
317 }
318
319 @Override
320 protected int getLayoutResId() {
321 return R.layout.mobile_data_settings;
322 }
323
324 @Override
325 protected int getTitleResId() {
326 return R.string.setup_mobile_data;
327 }
328
329 @Override
330 protected int getIconResId() {
331 return R.drawable.ic_mobile_data;
332 }
333
334}