blob: 3c3d8ec675b4db2d3179a9a3a015e37f15248ebd [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2008 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
17package android.net;
18
19import android.content.BroadcastReceiver;
20import android.content.Context;
21import android.content.Intent;
22import android.content.IntentFilter;
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -070023import android.net.NetworkInfo.DetailedState;
Robert Greenwaltd55a6b42011-03-25 13:09:25 -070024import android.os.Bundle;
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -070025import android.os.Handler;
Wink Savillee7982682010-12-07 10:31:02 -080026import android.os.Looper;
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -070027import android.os.Message;
Wink Savillee7982682010-12-07 10:31:02 -080028import android.os.Messenger;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029import android.os.RemoteException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030import android.os.ServiceManager;
Vinit Deshapnde1f12cb52013-08-21 13:09:01 -070031import android.telephony.PhoneStateListener;
32import android.telephony.SignalStrength;
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -070033import android.telephony.TelephonyManager;
34import android.text.TextUtils;
35import android.util.Slog;
Wink Savillee7982682010-12-07 10:31:02 -080036
Wink Savillea639b312012-07-10 12:37:54 -070037import com.android.internal.telephony.DctConstants;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080038import com.android.internal.telephony.ITelephony;
Wink Savillea639b312012-07-10 12:37:54 -070039import com.android.internal.telephony.PhoneConstants;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040import com.android.internal.telephony.TelephonyIntents;
Wink Savillee7982682010-12-07 10:31:02 -080041import com.android.internal.util.AsyncChannel;
42
Jeff Sharkey47eb1022011-08-25 17:48:52 -070043import java.io.CharArrayWriter;
44import java.io.PrintWriter;
Wink Savilled747cbc2013-08-07 16:22:47 -070045import java.util.concurrent.atomic.AtomicBoolean;
Jeff Sharkey47eb1022011-08-25 17:48:52 -070046
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047/**
48 * Track the state of mobile data connectivity. This is done by
49 * receiving broadcast intents from the Phone process whenever
50 * the state of data connectivity changes.
51 *
52 * {@hide}
53 */
Vinit Deshapnde1f12cb52013-08-21 13:09:01 -070054public class MobileDataStateTracker extends BaseNetworkStateTracker {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080055
56 private static final String TAG = "MobileDataStateTracker";
Wink Saville5e56bc52013-07-29 15:00:57 -070057 private static final boolean DBG = true;
Wink Saville1aef7fc2013-07-31 15:49:04 -070058 private static final boolean VDBG = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080059
Wink Savillea639b312012-07-10 12:37:54 -070060 private PhoneConstants.DataState mMobileDataState;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061 private ITelephony mPhoneService;
Robert Greenwalt42acef32009-08-12 16:08:25 -070062
63 private String mApnType;
Irfan Sheriffd649c122010-06-09 15:39:36 -070064 private NetworkInfo mNetworkInfo;
65 private boolean mTeardownRequested = false;
66 private Handler mTarget;
67 private Context mContext;
Robert Greenwalt37e65eb2010-08-30 10:56:47 -070068 private LinkProperties mLinkProperties;
Wink Savillef61101f2010-09-16 16:36:42 -070069 private LinkCapabilities mLinkCapabilities;
Irfan Sheriffd649c122010-06-09 15:39:36 -070070 private boolean mPrivateDnsRouteSet = false;
Irfan Sheriffd649c122010-06-09 15:39:36 -070071 private boolean mDefaultRouteSet = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080072
Jeff Sharkey47eb1022011-08-25 17:48:52 -070073 // NOTE: these are only kept for debugging output; actual values are
74 // maintained in DataConnectionTracker.
75 protected boolean mUserDataEnabled = true;
76 protected boolean mPolicyDataEnabled = true;
77
Wink Savillee7982682010-12-07 10:31:02 -080078 private Handler mHandler;
79 private AsyncChannel mDataConnectionTrackerAc;
Wink Savillee7982682010-12-07 10:31:02 -080080
Wink Savilled747cbc2013-08-07 16:22:47 -070081 private AtomicBoolean mIsCaptivePortal = new AtomicBoolean(false);
82
Vinit Deshapnde1f12cb52013-08-21 13:09:01 -070083 private SignalStrength mSignalStrength;
84
85 private SamplingDataTracker mSamplingDataTracker = new SamplingDataTracker();
86
Vinit Deshapnde6a2d3252013-09-04 14:11:24 -070087 private static final int UNKNOWN = LinkQualityInfo.UNKNOWN_INT;
88
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089 /**
90 * Create a new MobileDataStateTracker
Robert Greenwalt42acef32009-08-12 16:08:25 -070091 * @param netType the ConnectivityManager network type
Robert Greenwalt42acef32009-08-12 16:08:25 -070092 * @param tag the name of this network
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093 */
Wink Savillec7a98342010-08-13 16:11:42 -070094 public MobileDataStateTracker(int netType, String tag) {
Irfan Sheriffd649c122010-06-09 15:39:36 -070095 mNetworkInfo = new NetworkInfo(netType,
Robert Greenwalt42acef32009-08-12 16:08:25 -070096 TelephonyManager.getDefault().getNetworkType(), tag,
97 TelephonyManager.getDefault().getNetworkTypeName());
Robert Greenwalt5154ae762009-10-30 14:17:42 -070098 mApnType = networkTypeToApnType(netType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080099 }
100
101 /**
Wink Savillec7a98342010-08-13 16:11:42 -0700102 * Begin monitoring data connectivity.
103 *
104 * @param context is the current Android context
105 * @param target is the Hander to which to return the events.
106 */
107 public void startMonitoring(Context context, Handler target) {
108 mTarget = target;
109 mContext = context;
110
Robert Greenwalt5a8921f2011-07-29 16:33:16 -0700111 mHandler = new MdstHandler(target.getLooper(), this);
Wink Savillee7982682010-12-07 10:31:02 -0800112
Wink Saville30bf6542010-09-03 10:28:57 -0700113 IntentFilter filter = new IntentFilter();
114 filter.addAction(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
Wink Saville948282b2013-08-29 08:55:16 -0700115 filter.addAction(TelephonyIntents.ACTION_DATA_CONNECTION_CONNECTED_TO_PROVISIONING_APN);
Wink Savillec7a98342010-08-13 16:11:42 -0700116 filter.addAction(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED);
Wink Savillec7a98342010-08-13 16:11:42 -0700117
118 mContext.registerReceiver(new MobileDataStateReceiver(), filter);
Wink Savillea639b312012-07-10 12:37:54 -0700119 mMobileDataState = PhoneConstants.DataState.DISCONNECTED;
Vinit Deshapnde1f12cb52013-08-21 13:09:01 -0700120
121 TelephonyManager tm = (TelephonyManager)mContext.getSystemService(
122 Context.TELEPHONY_SERVICE);
123 tm.listen(mPhoneStateListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
Wink Savillec7a98342010-08-13 16:11:42 -0700124 }
125
Vinit Deshapnde1f12cb52013-08-21 13:09:01 -0700126 private final PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
127 @Override
128 public void onSignalStrengthsChanged(SignalStrength signalStrength) {
129 mSignalStrength = signalStrength;
130 }
131 };
132
Wink Savillee7982682010-12-07 10:31:02 -0800133 static class MdstHandler extends Handler {
134 private MobileDataStateTracker mMdst;
135
136 MdstHandler(Looper looper, MobileDataStateTracker mdst) {
137 super(looper);
138 mMdst = mdst;
139 }
140
141 @Override
142 public void handleMessage(Message msg) {
143 switch (msg.what) {
144 case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
145 if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
Robert Greenwalt58d4c592011-08-02 17:18:41 -0700146 if (VDBG) {
Wink Savillee7982682010-12-07 10:31:02 -0800147 mMdst.log("MdstHandler connected");
148 }
149 mMdst.mDataConnectionTrackerAc = (AsyncChannel) msg.obj;
150 } else {
Robert Greenwalt58d4c592011-08-02 17:18:41 -0700151 if (VDBG) {
Wink Savillee7982682010-12-07 10:31:02 -0800152 mMdst.log("MdstHandler %s NOT connected error=" + msg.arg1);
153 }
154 }
155 break;
156 case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
Robert Greenwalt58d4c592011-08-02 17:18:41 -0700157 if (VDBG) mMdst.log("Disconnected from DataStateTracker");
Wink Savillee7982682010-12-07 10:31:02 -0800158 mMdst.mDataConnectionTrackerAc = null;
159 break;
160 default: {
Robert Greenwalt58d4c592011-08-02 17:18:41 -0700161 if (VDBG) mMdst.log("Ignorning unknown message=" + msg);
Wink Savillee7982682010-12-07 10:31:02 -0800162 break;
163 }
164 }
165 }
166 }
167
Irfan Sheriffd649c122010-06-09 15:39:36 -0700168 public boolean isPrivateDnsRouteSet() {
169 return mPrivateDnsRouteSet;
170 }
171
172 public void privateDnsRouteSet(boolean enabled) {
173 mPrivateDnsRouteSet = enabled;
174 }
175
176 public NetworkInfo getNetworkInfo() {
177 return mNetworkInfo;
178 }
179
Irfan Sheriffd649c122010-06-09 15:39:36 -0700180 public boolean isDefaultRouteSet() {
181 return mDefaultRouteSet;
182 }
183
184 public void defaultRouteSet(boolean enabled) {
185 mDefaultRouteSet = enabled;
186 }
187
188 /**
189 * This is not implemented.
190 */
191 public void releaseWakeLock() {
192 }
193
Wink Saville948282b2013-08-29 08:55:16 -0700194 private void updateLinkProperitesAndCapatilities(Intent intent) {
195 mLinkProperties = intent.getParcelableExtra(
196 PhoneConstants.DATA_LINK_PROPERTIES_KEY);
197 if (mLinkProperties == null) {
198 loge("CONNECTED event did not supply link properties.");
199 mLinkProperties = new LinkProperties();
200 }
sy.yun9d9b74a2013-09-02 05:24:09 +0900201 mLinkProperties.setMtu(mContext.getResources().getInteger(
202 com.android.internal.R.integer.config_mobile_mtu));
Wink Saville948282b2013-08-29 08:55:16 -0700203 mLinkCapabilities = intent.getParcelableExtra(
204 PhoneConstants.DATA_LINK_CAPABILITIES_KEY);
205 if (mLinkCapabilities == null) {
206 loge("CONNECTED event did not supply link capabilities.");
207 mLinkCapabilities = new LinkCapabilities();
208 }
209 }
210
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800211 private class MobileDataStateReceiver extends BroadcastReceiver {
Wink Saville26f5a382010-11-24 16:44:29 -0800212 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800213 public void onReceive(Context context, Intent intent) {
Robert Greenwalt153b4372010-07-23 12:32:12 -0700214 if (intent.getAction().equals(TelephonyIntents.
Wink Saville948282b2013-08-29 08:55:16 -0700215 ACTION_DATA_CONNECTION_CONNECTED_TO_PROVISIONING_APN)) {
216 String apnName = intent.getStringExtra(PhoneConstants.DATA_APN_KEY);
217 String apnType = intent.getStringExtra(PhoneConstants.DATA_APN_TYPE_KEY);
218 if (!TextUtils.equals(mApnType, apnType)) {
219 return;
220 }
221 if (DBG) {
222 log("Broadcast received: " + intent.getAction() + " apnType=" + apnType
223 + " apnName=" + apnName);
224 }
225
226 // Make us in the connecting state until we make a new TYPE_MOBILE_PROVISIONING
227 mMobileDataState = PhoneConstants.DataState.CONNECTING;
228 updateLinkProperitesAndCapatilities(intent);
Wink Saville67c38212013-09-05 12:02:25 -0700229 mNetworkInfo.setIsConnectedToProvisioningNetwork(true);
230
231 // Change state to SUSPENDED so setDetailedState
232 // sends EVENT_STATE_CHANGED to connectivityService
233 setDetailedState(DetailedState.SUSPENDED, "", apnName);
Wink Saville948282b2013-08-29 08:55:16 -0700234 } else if (intent.getAction().equals(TelephonyIntents.
Robert Greenwalt153b4372010-07-23 12:32:12 -0700235 ACTION_ANY_DATA_CONNECTION_STATE_CHANGED)) {
Wink Savillea639b312012-07-10 12:37:54 -0700236 String apnType = intent.getStringExtra(PhoneConstants.DATA_APN_TYPE_KEY);
Wink Savilleed9c02b2010-12-03 12:01:38 -0800237 if (VDBG) {
238 log(String.format("Broadcast received: ACTION_ANY_DATA_CONNECTION_STATE_CHANGED"
239 + "mApnType=%s %s received apnType=%s", mApnType,
240 TextUtils.equals(apnType, mApnType) ? "==" : "!=", apnType));
241 }
Robert Greenwalt153b4372010-07-23 12:32:12 -0700242 if (!TextUtils.equals(apnType, mApnType)) {
243 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800244 }
Wink Saville1e4f4612013-09-21 09:01:19 -0700245 // Assume this isn't a provisioning network.
246 mNetworkInfo.setIsConnectedToProvisioningNetwork(false);
Wink Saville948282b2013-08-29 08:55:16 -0700247 if (DBG) {
248 log("Broadcast received: " + intent.getAction() + " apnType=" + apnType);
249 }
Robert Greenwaltd14e1762012-08-20 11:15:39 -0700250
251 int oldSubtype = mNetworkInfo.getSubtype();
252 int newSubType = TelephonyManager.getDefault().getNetworkType();
253 String subTypeName = TelephonyManager.getDefault().getNetworkTypeName();
254 mNetworkInfo.setSubtype(newSubType, subTypeName);
255 if (newSubType != oldSubtype && mNetworkInfo.isConnected()) {
256 Message msg = mTarget.obtainMessage(EVENT_NETWORK_SUBTYPE_CHANGED,
257 oldSubtype, 0, mNetworkInfo);
258 msg.sendToTarget();
259 }
260
Wink Savillea639b312012-07-10 12:37:54 -0700261 PhoneConstants.DataState state = Enum.valueOf(PhoneConstants.DataState.class,
262 intent.getStringExtra(PhoneConstants.STATE_KEY));
263 String reason = intent.getStringExtra(PhoneConstants.STATE_CHANGE_REASON_KEY);
264 String apnName = intent.getStringExtra(PhoneConstants.DATA_APN_KEY);
265 mNetworkInfo.setRoaming(intent.getBooleanExtra(
266 PhoneConstants.DATA_NETWORK_ROAMING_KEY, false));
Robert Greenwalt12e24ae2011-10-17 22:10:03 -0700267 if (VDBG) {
268 log(mApnType + " setting isAvailable to " +
Wink Savillea639b312012-07-10 12:37:54 -0700269 intent.getBooleanExtra(PhoneConstants.NETWORK_UNAVAILABLE_KEY,false));
Robert Greenwalt12e24ae2011-10-17 22:10:03 -0700270 }
Wink Savillea639b312012-07-10 12:37:54 -0700271 mNetworkInfo.setIsAvailable(!intent.getBooleanExtra(
272 PhoneConstants.NETWORK_UNAVAILABLE_KEY, false));
Robert Greenwalt153b4372010-07-23 12:32:12 -0700273
Wink Savilleed9c02b2010-12-03 12:01:38 -0800274 if (DBG) {
Wink Savillee7982682010-12-07 10:31:02 -0800275 log("Received state=" + state + ", old=" + mMobileDataState +
Wink Savilleed9c02b2010-12-03 12:01:38 -0800276 ", reason=" + (reason == null ? "(unspecified)" : reason));
277 }
Robert Greenwalt153b4372010-07-23 12:32:12 -0700278 if (mMobileDataState != state) {
279 mMobileDataState = state;
280 switch (state) {
281 case DISCONNECTED:
282 if(isTeardownRequested()) {
283 setTeardownRequested(false);
284 }
285
286 setDetailedState(DetailedState.DISCONNECTED, reason, apnName);
Robert Greenwalt153b4372010-07-23 12:32:12 -0700287 // can't do this here - ConnectivityService needs it to clear stuff
288 // it's ok though - just leave it to be refreshed next time
289 // we connect.
Wink Savilleed9c02b2010-12-03 12:01:38 -0800290 //if (DBG) log("clearing mInterfaceName for "+ mApnType +
Robert Greenwalt153b4372010-07-23 12:32:12 -0700291 // " as it DISCONNECTED");
292 //mInterfaceName = null;
Robert Greenwalt153b4372010-07-23 12:32:12 -0700293 break;
294 case CONNECTING:
295 setDetailedState(DetailedState.CONNECTING, reason, apnName);
296 break;
297 case SUSPENDED:
298 setDetailedState(DetailedState.SUSPENDED, reason, apnName);
299 break;
300 case CONNECTED:
Wink Saville948282b2013-08-29 08:55:16 -0700301 updateLinkProperitesAndCapatilities(intent);
Robert Greenwalt153b4372010-07-23 12:32:12 -0700302 setDetailedState(DetailedState.CONNECTED, reason, apnName);
303 break;
304 }
Vinit Deshapnde1f12cb52013-08-21 13:09:01 -0700305
306 if (VDBG) {
307 Slog.d(TAG, "TelephonyMgr.DataConnectionStateChanged");
308 if (mNetworkInfo != null) {
Jake Hamby8f9b33e2014-01-15 13:08:03 -0800309 Slog.d(TAG, "NetworkInfo = " + mNetworkInfo);
310 Slog.d(TAG, "subType = " + mNetworkInfo.getSubtype());
Vinit Deshapnde1f12cb52013-08-21 13:09:01 -0700311 Slog.d(TAG, "subType = " + mNetworkInfo.getSubtypeName());
312 }
313 if (mLinkProperties != null) {
Jake Hamby8f9b33e2014-01-15 13:08:03 -0800314 Slog.d(TAG, "LinkProperties = " + mLinkProperties);
Vinit Deshapnde1f12cb52013-08-21 13:09:01 -0700315 } else {
316 Slog.d(TAG, "LinkProperties = " );
317 }
318
319 if (mLinkCapabilities != null) {
Jake Hamby8f9b33e2014-01-15 13:08:03 -0800320 Slog.d(TAG, "LinkCapabilities = " + mLinkCapabilities);
Vinit Deshapnde1f12cb52013-08-21 13:09:01 -0700321 } else {
322 Slog.d(TAG, "LinkCapabilities = " );
323 }
324 }
325
326
327 /* lets not sample traffic data across state changes */
328 mSamplingDataTracker.resetSamplingData();
Kazuhiro Ondo01758e82011-04-30 20:10:57 -0500329 } else {
330 // There was no state change. Check if LinkProperties has been updated.
Wink Savillea639b312012-07-10 12:37:54 -0700331 if (TextUtils.equals(reason, PhoneConstants.REASON_LINK_PROPERTIES_CHANGED)) {
332 mLinkProperties = intent.getParcelableExtra(
333 PhoneConstants.DATA_LINK_PROPERTIES_KEY);
Kazuhiro Ondo01758e82011-04-30 20:10:57 -0500334 if (mLinkProperties == null) {
Robert Greenwalt58d4c592011-08-02 17:18:41 -0700335 loge("No link property in LINK_PROPERTIES change event.");
Kazuhiro Ondo01758e82011-04-30 20:10:57 -0500336 mLinkProperties = new LinkProperties();
337 }
338 // Just update reason field in this NetworkInfo
339 mNetworkInfo.setDetailedState(mNetworkInfo.getDetailedState(), reason,
340 mNetworkInfo.getExtraInfo());
341 Message msg = mTarget.obtainMessage(EVENT_CONFIGURATION_CHANGED,
342 mNetworkInfo);
343 msg.sendToTarget();
344 }
Robert Greenwalt153b4372010-07-23 12:32:12 -0700345 }
346 } else if (intent.getAction().
347 equals(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED)) {
Wink Savillea639b312012-07-10 12:37:54 -0700348 String apnType = intent.getStringExtra(PhoneConstants.DATA_APN_TYPE_KEY);
Robert Greenwalt153b4372010-07-23 12:32:12 -0700349 if (!TextUtils.equals(apnType, mApnType)) {
Wink Savilleed9c02b2010-12-03 12:01:38 -0800350 if (DBG) {
351 log(String.format(
352 "Broadcast received: ACTION_ANY_DATA_CONNECTION_FAILED ignore, " +
353 "mApnType=%s != received apnType=%s", mApnType, apnType));
354 }
Robert Greenwalt153b4372010-07-23 12:32:12 -0700355 return;
356 }
Wink Saville1e4f4612013-09-21 09:01:19 -0700357 // Assume this isn't a provisioning network.
358 mNetworkInfo.setIsConnectedToProvisioningNetwork(false);
Wink Savillea639b312012-07-10 12:37:54 -0700359 String reason = intent.getStringExtra(PhoneConstants.FAILURE_REASON_KEY);
360 String apnName = intent.getStringExtra(PhoneConstants.DATA_APN_KEY);
Wink Savilleed9c02b2010-12-03 12:01:38 -0800361 if (DBG) {
Wink Saville948282b2013-08-29 08:55:16 -0700362 log("Broadcast received: " + intent.getAction() +
363 " reason=" + reason == null ? "null" : reason);
Wink Savilleed9c02b2010-12-03 12:01:38 -0800364 }
Robert Greenwalt153b4372010-07-23 12:32:12 -0700365 setDetailedState(DetailedState.FAILED, reason, apnName);
Wink Saville26f5a382010-11-24 16:44:29 -0800366 } else {
Wink Savilleed9c02b2010-12-03 12:01:38 -0800367 if (DBG) log("Broadcast received: ignore " + intent.getAction());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800368 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800369 }
370 }
371
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800372 private void getPhoneService(boolean forceRefresh) {
373 if ((mPhoneService == null) || forceRefresh) {
374 mPhoneService = ITelephony.Stub.asInterface(ServiceManager.getService("phone"));
375 }
376 }
377
378 /**
379 * Report whether data connectivity is possible.
380 */
381 public boolean isAvailable() {
Robert Greenwaltcff25ff2010-08-30 15:39:36 -0700382 return mNetworkInfo.isAvailable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800383 }
384
385 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800386 * Return the system properties name associated with the tcp buffer sizes
387 * for this network.
388 */
389 public String getTcpBufferSizesPropName() {
Wink Saville767a6622009-04-02 01:37:02 -0700390 String networkTypeStr = "unknown";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800391 TelephonyManager tm = new TelephonyManager(mContext);
Wink Saville767a6622009-04-02 01:37:02 -0700392 //TODO We have to edit the parameter for getNetworkType regarding CDMA
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800393 switch(tm.getNetworkType()) {
Wink Saville767a6622009-04-02 01:37:02 -0700394 case TelephonyManager.NETWORK_TYPE_GPRS:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800395 networkTypeStr = "gprs";
396 break;
Wink Saville767a6622009-04-02 01:37:02 -0700397 case TelephonyManager.NETWORK_TYPE_EDGE:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800398 networkTypeStr = "edge";
399 break;
Wink Saville767a6622009-04-02 01:37:02 -0700400 case TelephonyManager.NETWORK_TYPE_UMTS:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800401 networkTypeStr = "umts";
402 break;
Li Zheebe66342009-08-14 19:22:16 +0800403 case TelephonyManager.NETWORK_TYPE_HSDPA:
404 networkTypeStr = "hsdpa";
405 break;
406 case TelephonyManager.NETWORK_TYPE_HSUPA:
407 networkTypeStr = "hsupa";
408 break;
409 case TelephonyManager.NETWORK_TYPE_HSPA:
410 networkTypeStr = "hspa";
411 break;
Naveen Kalla897b3112012-03-31 10:09:49 -0700412 case TelephonyManager.NETWORK_TYPE_HSPAP:
413 networkTypeStr = "hspap";
414 break;
Wink Saville767a6622009-04-02 01:37:02 -0700415 case TelephonyManager.NETWORK_TYPE_CDMA:
416 networkTypeStr = "cdma";
417 break;
Li Zheebe66342009-08-14 19:22:16 +0800418 case TelephonyManager.NETWORK_TYPE_1xRTT:
419 networkTypeStr = "1xrtt";
420 break;
Wink Saville767a6622009-04-02 01:37:02 -0700421 case TelephonyManager.NETWORK_TYPE_EVDO_0:
422 networkTypeStr = "evdo";
423 break;
424 case TelephonyManager.NETWORK_TYPE_EVDO_A:
425 networkTypeStr = "evdo";
426 break;
Naveen Kalla0a5174a2010-04-21 14:48:03 -0700427 case TelephonyManager.NETWORK_TYPE_EVDO_B:
428 networkTypeStr = "evdo";
429 break;
Robert Greenwalt962a9902010-11-02 11:10:25 -0700430 case TelephonyManager.NETWORK_TYPE_IDEN:
431 networkTypeStr = "iden";
432 break;
433 case TelephonyManager.NETWORK_TYPE_LTE:
434 networkTypeStr = "lte";
435 break;
436 case TelephonyManager.NETWORK_TYPE_EHRPD:
437 networkTypeStr = "ehrpd";
438 break;
439 default:
Wink Savilleed9c02b2010-12-03 12:01:38 -0800440 loge("unknown network type: " + tm.getNetworkType());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800441 }
442 return "net.tcp.buffersize." + networkTypeStr;
443 }
444
445 /**
446 * Tear down mobile data connectivity, i.e., disable the ability to create
447 * mobile data connections.
Robert Greenwalt02648a42010-05-18 10:52:51 -0700448 * TODO - make async and return nothing?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800449 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800450 public boolean teardown() {
Robert Greenwalt25a5d3d2009-08-13 15:59:51 -0700451 setTeardownRequested(true);
Wink Savillea639b312012-07-10 12:37:54 -0700452 return (setEnableApn(mApnType, false) != PhoneConstants.APN_REQUEST_FAILED);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800453 }
454
Wink Savilledce52cd2013-08-16 17:17:28 -0700455 /**
456 * @return true if this is ready to operate
457 */
458 public boolean isReady() {
459 return mDataConnectionTrackerAc != null;
460 }
461
Irfan Sheriffda6da092012-08-16 12:49:23 -0700462 @Override
Wink Savilled747cbc2013-08-07 16:22:47 -0700463 public void captivePortalCheckCompleted(boolean isCaptivePortal) {
464 if (mIsCaptivePortal.getAndSet(isCaptivePortal) != isCaptivePortal) {
465 // Captive portal change enable/disable failing fast
466 setEnableFailFastMobileData(
467 isCaptivePortal ? DctConstants.ENABLED : DctConstants.DISABLED);
468 }
469 }
470
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800471 /**
Irfan Sheriffd649c122010-06-09 15:39:36 -0700472 * Record the detailed state of a network, and if it is a
473 * change from the previous state, send a notification to
474 * any listeners.
Jeff Smitha45746e2012-07-19 14:19:24 -0500475 * @param state the new {@code DetailedState}
Irfan Sheriffd649c122010-06-09 15:39:36 -0700476 * @param reason a {@code String} indicating a reason for the state change,
477 * if one was supplied. May be {@code null}.
478 * @param extraInfo optional {@code String} providing extra information about the state change
479 */
Wink Savilleed9c02b2010-12-03 12:01:38 -0800480 private void setDetailedState(NetworkInfo.DetailedState state, String reason,
481 String extraInfo) {
482 if (DBG) log("setDetailed state, old ="
Irfan Sheriffd649c122010-06-09 15:39:36 -0700483 + mNetworkInfo.getDetailedState() + " and new state=" + state);
484 if (state != mNetworkInfo.getDetailedState()) {
485 boolean wasConnecting = (mNetworkInfo.getState() == NetworkInfo.State.CONNECTING);
486 String lastReason = mNetworkInfo.getReason();
487 /*
488 * If a reason was supplied when the CONNECTING state was entered, and no
489 * reason was supplied for entering the CONNECTED state, then retain the
490 * reason that was supplied when going to CONNECTING.
491 */
492 if (wasConnecting && state == NetworkInfo.DetailedState.CONNECTED && reason == null
493 && lastReason != null)
494 reason = lastReason;
495 mNetworkInfo.setDetailedState(state, reason, extraInfo);
Robert Greenwalt6aecb982011-09-09 12:38:12 -0700496 Message msg = mTarget.obtainMessage(EVENT_STATE_CHANGED, new NetworkInfo(mNetworkInfo));
Irfan Sheriffd649c122010-06-09 15:39:36 -0700497 msg.sendToTarget();
498 }
499 }
500
Irfan Sheriffd649c122010-06-09 15:39:36 -0700501 public void setTeardownRequested(boolean isRequested) {
502 mTeardownRequested = isRequested;
503 }
504
505 public boolean isTeardownRequested() {
506 return mTeardownRequested;
507 }
508
509 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800510 * Re-enable mobile data connectivity after a {@link #teardown()}.
Robert Greenwalt02648a42010-05-18 10:52:51 -0700511 * TODO - make async and always get a notification?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800512 */
513 public boolean reconnect() {
Robert Greenwalt02648a42010-05-18 10:52:51 -0700514 boolean retValue = false; //connected or expect to be?
Robert Greenwalt25a5d3d2009-08-13 15:59:51 -0700515 setTeardownRequested(false);
Robert Greenwaltc85675d2009-08-17 19:27:14 -0700516 switch (setEnableApn(mApnType, true)) {
Wink Savillea639b312012-07-10 12:37:54 -0700517 case PhoneConstants.APN_ALREADY_ACTIVE:
Robert Greenwalta64bf832009-08-19 20:19:33 -0700518 // need to set self to CONNECTING so the below message is handled.
Robert Greenwalt02648a42010-05-18 10:52:51 -0700519 retValue = true;
Robert Greenwaltc85675d2009-08-17 19:27:14 -0700520 break;
Wink Savillea639b312012-07-10 12:37:54 -0700521 case PhoneConstants.APN_REQUEST_STARTED:
Wink Saville9d7d6282011-03-12 14:52:01 -0800522 // set IDLE here , avoid the following second FAILED not sent out
523 mNetworkInfo.setDetailedState(DetailedState.IDLE, null, null);
Robert Greenwalt02648a42010-05-18 10:52:51 -0700524 retValue = true;
Robert Greenwaltc85675d2009-08-17 19:27:14 -0700525 break;
Wink Savillea639b312012-07-10 12:37:54 -0700526 case PhoneConstants.APN_REQUEST_FAILED:
527 case PhoneConstants.APN_TYPE_NOT_AVAILABLE:
Robert Greenwaltc85675d2009-08-17 19:27:14 -0700528 break;
529 default:
Wink Savilleed9c02b2010-12-03 12:01:38 -0800530 loge("Error in reconnect - unexpected response.");
Robert Greenwaltc85675d2009-08-17 19:27:14 -0700531 break;
532 }
Robert Greenwalt02648a42010-05-18 10:52:51 -0700533 return retValue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800534 }
535
536 /**
537 * Turn on or off the mobile radio. No connectivity will be possible while the
538 * radio is off. The operation is a no-op if the radio is already in the desired state.
539 * @param turnOn {@code true} if the radio should be turned on, {@code false} if
540 */
541 public boolean setRadio(boolean turnOn) {
542 getPhoneService(false);
543 /*
544 * If the phone process has crashed in the past, we'll get a
545 * RemoteException and need to re-reference the service.
546 */
547 for (int retry = 0; retry < 2; retry++) {
548 if (mPhoneService == null) {
Robert Greenwalt58d4c592011-08-02 17:18:41 -0700549 loge("Ignoring mobile radio request because could not acquire PhoneService");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800550 break;
551 }
Wink Saville767a6622009-04-02 01:37:02 -0700552
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800553 try {
554 return mPhoneService.setRadio(turnOn);
555 } catch (RemoteException e) {
556 if (retry == 0) getPhoneService(true);
557 }
558 }
559
Robert Greenwalt58d4c592011-08-02 17:18:41 -0700560 loge("Could not set radio power to " + (turnOn ? "on" : "off"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800561 return false;
562 }
563
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -0700564 @Override
565 public void setUserDataEnable(boolean enabled) {
566 if (DBG) log("setUserDataEnable: E enabled=" + enabled);
567 final AsyncChannel channel = mDataConnectionTrackerAc;
568 if (channel != null) {
Wink Savillea639b312012-07-10 12:37:54 -0700569 channel.sendMessage(DctConstants.CMD_SET_USER_DATA_ENABLE,
570 enabled ? DctConstants.ENABLED : DctConstants.DISABLED);
Jeff Sharkey47eb1022011-08-25 17:48:52 -0700571 mUserDataEnabled = enabled;
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -0700572 }
573 if (VDBG) log("setUserDataEnable: X enabled=" + enabled);
574 }
575
576 @Override
577 public void setPolicyDataEnable(boolean enabled) {
578 if (DBG) log("setPolicyDataEnable(enabled=" + enabled + ")");
579 final AsyncChannel channel = mDataConnectionTrackerAc;
580 if (channel != null) {
Wink Savillea639b312012-07-10 12:37:54 -0700581 channel.sendMessage(DctConstants.CMD_SET_POLICY_DATA_ENABLE,
582 enabled ? DctConstants.ENABLED : DctConstants.DISABLED);
Jeff Sharkey47eb1022011-08-25 17:48:52 -0700583 mPolicyDataEnabled = enabled;
Wink Savillee7982682010-12-07 10:31:02 -0800584 }
585 }
586
Robert Greenwaltd55a6b42011-03-25 13:09:25 -0700587 /**
Wink Savilleab9321d2013-06-29 21:10:57 -0700588 * Eanble/disable FailFast
589 *
590 * @param enabled is DctConstants.ENABLED/DISABLED
591 */
592 public void setEnableFailFastMobileData(int enabled) {
593 if (DBG) log("setEnableFailFastMobileData(enabled=" + enabled + ")");
594 final AsyncChannel channel = mDataConnectionTrackerAc;
595 if (channel != null) {
596 channel.sendMessage(DctConstants.CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA, enabled);
597 }
598 }
599
600 /**
Robert Greenwaltd55a6b42011-03-25 13:09:25 -0700601 * carrier dependency is met/unmet
602 * @param met
603 */
604 public void setDependencyMet(boolean met) {
Wink Savillea639b312012-07-10 12:37:54 -0700605 Bundle bundle = Bundle.forPair(DctConstants.APN_TYPE_KEY, mApnType);
Robert Greenwaltd55a6b42011-03-25 13:09:25 -0700606 try {
Robert Greenwalt58d4c592011-08-02 17:18:41 -0700607 if (DBG) log("setDependencyMet: E met=" + met);
Robert Greenwaltd55a6b42011-03-25 13:09:25 -0700608 Message msg = Message.obtain();
Wink Savillea639b312012-07-10 12:37:54 -0700609 msg.what = DctConstants.CMD_SET_DEPENDENCY_MET;
610 msg.arg1 = (met ? DctConstants.ENABLED : DctConstants.DISABLED);
Robert Greenwaltd55a6b42011-03-25 13:09:25 -0700611 msg.setData(bundle);
612 mDataConnectionTrackerAc.sendMessage(msg);
Robert Greenwalt58d4c592011-08-02 17:18:41 -0700613 if (VDBG) log("setDependencyMet: X met=" + met);
Robert Greenwaltd55a6b42011-03-25 13:09:25 -0700614 } catch (NullPointerException e) {
Robert Greenwalt58d4c592011-08-02 17:18:41 -0700615 loge("setDependencyMet: X mAc was null" + e);
Robert Greenwaltd55a6b42011-03-25 13:09:25 -0700616 }
617 }
618
Wink Saville948282b2013-08-29 08:55:16 -0700619 /**
620 * Inform DCT mobile provisioning has started, it ends when provisioning completes.
621 */
622 public void enableMobileProvisioning(String url) {
623 if (DBG) log("enableMobileProvisioning(url=" + url + ")");
624 final AsyncChannel channel = mDataConnectionTrackerAc;
625 if (channel != null) {
626 Message msg = Message.obtain();
627 msg.what = DctConstants.CMD_ENABLE_MOBILE_PROVISIONING;
628 msg.setData(Bundle.forPair(DctConstants.PROVISIONING_URL_KEY, url));
629 channel.sendMessage(msg);
630 }
631 }
632
633 /**
634 * Return if this network is the provisioning network. Valid only if connected.
635 * @param met
636 */
637 public boolean isProvisioningNetwork() {
638 boolean retVal;
639 try {
640 Message msg = Message.obtain();
641 msg.what = DctConstants.CMD_IS_PROVISIONING_APN;
642 msg.setData(Bundle.forPair(DctConstants.APN_TYPE_KEY, mApnType));
643 Message result = mDataConnectionTrackerAc.sendMessageSynchronously(msg);
644 retVal = result.arg1 == DctConstants.ENABLED;
645 } catch (NullPointerException e) {
646 loge("isProvisioningNetwork: X " + e);
647 retVal = false;
648 }
649 if (DBG) log("isProvisioningNetwork: retVal=" + retVal);
650 return retVal;
651 }
652
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800653 @Override
Lorenzo Colitti69edd642013-03-07 11:01:12 -0800654 public void addStackedLink(LinkProperties link) {
655 mLinkProperties.addStackedLink(link);
656 }
657
658 @Override
659 public void removeStackedLink(LinkProperties link) {
660 mLinkProperties.removeStackedLink(link);
661 }
662
663 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800664 public String toString() {
Jeff Sharkey47eb1022011-08-25 17:48:52 -0700665 final CharArrayWriter writer = new CharArrayWriter();
666 final PrintWriter pw = new PrintWriter(writer);
667 pw.print("Mobile data state: "); pw.println(mMobileDataState);
668 pw.print("Data enabled: user="); pw.print(mUserDataEnabled);
669 pw.print(", policy="); pw.println(mPolicyDataEnabled);
670 return writer.toString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800671 }
672
Vinit Deshapnde1f12cb52013-08-21 13:09:01 -0700673 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800674 * Internal method supporting the ENABLE_MMS feature.
675 * @param apnType the type of APN to be enabled or disabled (e.g., mms)
676 * @param enable {@code true} to enable the specified APN type,
677 * {@code false} to disable it.
678 * @return an integer value representing the outcome of the request.
679 */
680 private int setEnableApn(String apnType, boolean enable) {
681 getPhoneService(false);
682 /*
683 * If the phone process has crashed in the past, we'll get a
684 * RemoteException and need to re-reference the service.
685 */
686 for (int retry = 0; retry < 2; retry++) {
687 if (mPhoneService == null) {
Robert Greenwalt58d4c592011-08-02 17:18:41 -0700688 loge("Ignoring feature request because could not acquire PhoneService");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800689 break;
690 }
691
692 try {
693 if (enable) {
694 return mPhoneService.enableApnType(apnType);
695 } else {
696 return mPhoneService.disableApnType(apnType);
697 }
698 } catch (RemoteException e) {
699 if (retry == 0) getPhoneService(true);
700 }
701 }
702
Robert Greenwalt58d4c592011-08-02 17:18:41 -0700703 loge("Could not " + (enable ? "enable" : "disable") + " APN type \"" + apnType + "\"");
Wink Savillea639b312012-07-10 12:37:54 -0700704 return PhoneConstants.APN_REQUEST_FAILED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800705 }
Robert Greenwalt5154ae762009-10-30 14:17:42 -0700706
707 public static String networkTypeToApnType(int netType) {
708 switch(netType) {
709 case ConnectivityManager.TYPE_MOBILE:
Wink Savillea639b312012-07-10 12:37:54 -0700710 return PhoneConstants.APN_TYPE_DEFAULT; // TODO - use just one of these
Robert Greenwalt5154ae762009-10-30 14:17:42 -0700711 case ConnectivityManager.TYPE_MOBILE_MMS:
Wink Savillea639b312012-07-10 12:37:54 -0700712 return PhoneConstants.APN_TYPE_MMS;
Robert Greenwalt5154ae762009-10-30 14:17:42 -0700713 case ConnectivityManager.TYPE_MOBILE_SUPL:
Wink Savillea639b312012-07-10 12:37:54 -0700714 return PhoneConstants.APN_TYPE_SUPL;
Robert Greenwalt5154ae762009-10-30 14:17:42 -0700715 case ConnectivityManager.TYPE_MOBILE_DUN:
Wink Savillea639b312012-07-10 12:37:54 -0700716 return PhoneConstants.APN_TYPE_DUN;
Robert Greenwalt5154ae762009-10-30 14:17:42 -0700717 case ConnectivityManager.TYPE_MOBILE_HIPRI:
Wink Savillea639b312012-07-10 12:37:54 -0700718 return PhoneConstants.APN_TYPE_HIPRI;
Wink Saville9d7d6282011-03-12 14:52:01 -0800719 case ConnectivityManager.TYPE_MOBILE_FOTA:
Wink Savillea639b312012-07-10 12:37:54 -0700720 return PhoneConstants.APN_TYPE_FOTA;
Wink Saville9d7d6282011-03-12 14:52:01 -0800721 case ConnectivityManager.TYPE_MOBILE_IMS:
Wink Savillea639b312012-07-10 12:37:54 -0700722 return PhoneConstants.APN_TYPE_IMS;
Wink Saville9d7d6282011-03-12 14:52:01 -0800723 case ConnectivityManager.TYPE_MOBILE_CBS:
Wink Savillea639b312012-07-10 12:37:54 -0700724 return PhoneConstants.APN_TYPE_CBS;
Wink Saville5e56bc52013-07-29 15:00:57 -0700725 case ConnectivityManager.TYPE_MOBILE_IA:
726 return PhoneConstants.APN_TYPE_IA;
Robert Greenwalt5154ae762009-10-30 14:17:42 -0700727 default:
Wink Savillee7982682010-12-07 10:31:02 -0800728 sloge("Error mapping networkType " + netType + " to apnType.");
Robert Greenwalt5154ae762009-10-30 14:17:42 -0700729 return null;
730 }
731 }
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700732
Vinit Deshapnde1f12cb52013-08-21 13:09:01 -0700733
Wink Savillef61101f2010-09-16 16:36:42 -0700734 /**
735 * @see android.net.NetworkStateTracker#getLinkProperties()
736 */
Vinit Deshapnde1f12cb52013-08-21 13:09:01 -0700737 @Override
Robert Greenwalt37e65eb2010-08-30 10:56:47 -0700738 public LinkProperties getLinkProperties() {
739 return new LinkProperties(mLinkProperties);
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700740 }
Wink Savillef61101f2010-09-16 16:36:42 -0700741
742 /**
743 * @see android.net.NetworkStateTracker#getLinkCapabilities()
744 */
Vinit Deshapnde1f12cb52013-08-21 13:09:01 -0700745 @Override
Wink Savillef61101f2010-09-16 16:36:42 -0700746 public LinkCapabilities getLinkCapabilities() {
747 return new LinkCapabilities(mLinkCapabilities);
748 }
Wink Savilleed9c02b2010-12-03 12:01:38 -0800749
Robert Greenwalt665e1ae2012-08-21 19:27:00 -0700750 public void supplyMessenger(Messenger messenger) {
751 if (VDBG) log(mApnType + " got supplyMessenger");
752 AsyncChannel ac = new AsyncChannel();
753 ac.connect(mContext, MobileDataStateTracker.this.mHandler, messenger);
754 }
755
Wink Savillee7982682010-12-07 10:31:02 -0800756 private void log(String s) {
757 Slog.d(TAG, mApnType + ": " + s);
Wink Savilleed9c02b2010-12-03 12:01:38 -0800758 }
759
Wink Savillee7982682010-12-07 10:31:02 -0800760 private void loge(String s) {
761 Slog.e(TAG, mApnType + ": " + s);
762 }
763
764 static private void sloge(String s) {
Wink Savilleed9c02b2010-12-03 12:01:38 -0800765 Slog.e(TAG, s);
766 }
Vinit Deshapnde1f12cb52013-08-21 13:09:01 -0700767
768 @Override
Vinit Deshapnde6a2d3252013-09-04 14:11:24 -0700769 public LinkQualityInfo getLinkQualityInfo() {
Vinit Deshapnde1f12cb52013-08-21 13:09:01 -0700770 if (mNetworkInfo == null || mNetworkInfo.getType() == ConnectivityManager.TYPE_NONE) {
771 // no data available yet; just return
772 return null;
773 }
774
Vinit Deshapnde6a2d3252013-09-04 14:11:24 -0700775 MobileLinkQualityInfo li = new MobileLinkQualityInfo();
Vinit Deshapnde1f12cb52013-08-21 13:09:01 -0700776
Vinit Deshapnde6a2d3252013-09-04 14:11:24 -0700777 li.setNetworkType(mNetworkInfo.getType());
Vinit Deshapnde1f12cb52013-08-21 13:09:01 -0700778
Vinit Deshapnde6a2d3252013-09-04 14:11:24 -0700779 mSamplingDataTracker.setCommonLinkQualityInfoFields(li);
Vinit Deshapnde1f12cb52013-08-21 13:09:01 -0700780
781 if (mNetworkInfo.getSubtype() != TelephonyManager.NETWORK_TYPE_UNKNOWN) {
Vinit Deshapnde6a2d3252013-09-04 14:11:24 -0700782 li.setMobileNetworkType(mNetworkInfo.getSubtype());
Vinit Deshapnde1f12cb52013-08-21 13:09:01 -0700783
784 NetworkDataEntry entry = getNetworkDataEntry(mNetworkInfo.getSubtype());
785 if (entry != null) {
Vinit Deshapnde6a2d3252013-09-04 14:11:24 -0700786 li.setTheoreticalRxBandwidth(entry.downloadBandwidth);
787 li.setTheoreticalRxBandwidth(entry.uploadBandwidth);
788 li.setTheoreticalLatency(entry.latency);
Vinit Deshapnde1f12cb52013-08-21 13:09:01 -0700789 }
790
791 if (mSignalStrength != null) {
Vinit Deshapnde6a2d3252013-09-04 14:11:24 -0700792 li.setNormalizedSignalStrength(getNormalizedSignalStrength(
793 li.getMobileNetworkType(), mSignalStrength));
Vinit Deshapnde1f12cb52013-08-21 13:09:01 -0700794 }
795 }
796
797 SignalStrength ss = mSignalStrength;
798 if (ss != null) {
799
Vinit Deshapnde6a2d3252013-09-04 14:11:24 -0700800 li.setRssi(ss.getGsmSignalStrength());
801 li.setGsmErrorRate(ss.getGsmBitErrorRate());
802 li.setCdmaDbm(ss.getCdmaDbm());
803 li.setCdmaEcio(ss.getCdmaEcio());
804 li.setEvdoDbm(ss.getEvdoDbm());
805 li.setEvdoEcio(ss.getEvdoEcio());
806 li.setEvdoSnr(ss.getEvdoSnr());
807 li.setLteSignalStrength(ss.getLteSignalStrength());
808 li.setLteRsrp(ss.getLteRsrp());
809 li.setLteRsrq(ss.getLteRsrq());
810 li.setLteRssnr(ss.getLteRssnr());
811 li.setLteCqi(ss.getLteCqi());
Vinit Deshapnde1f12cb52013-08-21 13:09:01 -0700812 }
813
814 if (VDBG) {
Vinit Deshapnde6a2d3252013-09-04 14:11:24 -0700815 Slog.d(TAG, "Returning LinkQualityInfo with"
816 + " MobileNetworkType = " + String.valueOf(li.getMobileNetworkType())
817 + " Theoretical Rx BW = " + String.valueOf(li.getTheoreticalRxBandwidth())
818 + " gsm Signal Strength = " + String.valueOf(li.getRssi())
819 + " cdma Signal Strength = " + String.valueOf(li.getCdmaDbm())
820 + " evdo Signal Strength = " + String.valueOf(li.getEvdoDbm())
821 + " Lte Signal Strength = " + String.valueOf(li.getLteSignalStrength()));
Vinit Deshapnde1f12cb52013-08-21 13:09:01 -0700822 }
823
824 return li;
825 }
826
827 static class NetworkDataEntry {
828 public int networkType;
829 public int downloadBandwidth; // in kbps
830 public int uploadBandwidth; // in kbps
831 public int latency; // in millisecond
832
833 NetworkDataEntry(int i1, int i2, int i3, int i4) {
834 networkType = i1;
835 downloadBandwidth = i2;
836 uploadBandwidth = i3;
837 latency = i4;
838 }
839 }
840
841 private static NetworkDataEntry [] mTheoreticalBWTable = new NetworkDataEntry[] {
Vinit Deshapnde6a2d3252013-09-04 14:11:24 -0700842 new NetworkDataEntry(TelephonyManager.NETWORK_TYPE_EDGE, 237, 118, UNKNOWN),
843 new NetworkDataEntry(TelephonyManager.NETWORK_TYPE_GPRS, 48, 40, UNKNOWN),
844 new NetworkDataEntry(TelephonyManager.NETWORK_TYPE_UMTS, 384, 64, UNKNOWN),
845 new NetworkDataEntry(TelephonyManager.NETWORK_TYPE_HSDPA, 14400, UNKNOWN, UNKNOWN),
846 new NetworkDataEntry(TelephonyManager.NETWORK_TYPE_HSUPA, 14400, 5760, UNKNOWN),
847 new NetworkDataEntry(TelephonyManager.NETWORK_TYPE_HSPA, 14400, 5760, UNKNOWN),
848 new NetworkDataEntry(TelephonyManager.NETWORK_TYPE_HSPAP, 21000, 5760, UNKNOWN),
849 new NetworkDataEntry(TelephonyManager.NETWORK_TYPE_CDMA, UNKNOWN, UNKNOWN, UNKNOWN),
850 new NetworkDataEntry(TelephonyManager.NETWORK_TYPE_1xRTT, UNKNOWN, UNKNOWN, UNKNOWN),
851 new NetworkDataEntry(TelephonyManager.NETWORK_TYPE_EVDO_0, 2468, 153, UNKNOWN),
852 new NetworkDataEntry(TelephonyManager.NETWORK_TYPE_EVDO_A, 3072, 1800, UNKNOWN),
853 new NetworkDataEntry(TelephonyManager.NETWORK_TYPE_EVDO_B, 14700, 1800, UNKNOWN),
854 new NetworkDataEntry(TelephonyManager.NETWORK_TYPE_IDEN, UNKNOWN, UNKNOWN, UNKNOWN),
855 new NetworkDataEntry(TelephonyManager.NETWORK_TYPE_LTE, 100000, 50000, UNKNOWN),
856 new NetworkDataEntry(TelephonyManager.NETWORK_TYPE_EHRPD, UNKNOWN, UNKNOWN, UNKNOWN),
Vinit Deshapnde1f12cb52013-08-21 13:09:01 -0700857 };
858
859 private static NetworkDataEntry getNetworkDataEntry(int networkType) {
860 for (NetworkDataEntry entry : mTheoreticalBWTable) {
861 if (entry.networkType == networkType) {
862 return entry;
863 }
864 }
865
866 Slog.e(TAG, "Could not find Theoretical BW entry for " + String.valueOf(networkType));
867 return null;
868 }
869
870 private static int getNormalizedSignalStrength(int networkType, SignalStrength ss) {
871
872 int level;
873
874 switch(networkType) {
875 case TelephonyManager.NETWORK_TYPE_EDGE:
876 case TelephonyManager.NETWORK_TYPE_GPRS:
877 case TelephonyManager.NETWORK_TYPE_UMTS:
878 case TelephonyManager.NETWORK_TYPE_HSDPA:
879 case TelephonyManager.NETWORK_TYPE_HSUPA:
880 case TelephonyManager.NETWORK_TYPE_HSPA:
881 case TelephonyManager.NETWORK_TYPE_HSPAP:
882 level = ss.getGsmLevel();
883 break;
884 case TelephonyManager.NETWORK_TYPE_CDMA:
885 case TelephonyManager.NETWORK_TYPE_1xRTT:
886 level = ss.getCdmaLevel();
887 break;
888 case TelephonyManager.NETWORK_TYPE_EVDO_0:
889 case TelephonyManager.NETWORK_TYPE_EVDO_A:
890 case TelephonyManager.NETWORK_TYPE_EVDO_B:
891 level = ss.getEvdoLevel();
892 break;
893 case TelephonyManager.NETWORK_TYPE_LTE:
894 level = ss.getLteLevel();
895 break;
896 case TelephonyManager.NETWORK_TYPE_IDEN:
897 case TelephonyManager.NETWORK_TYPE_EHRPD:
898 default:
Vinit Deshapnde6a2d3252013-09-04 14:11:24 -0700899 return UNKNOWN;
Vinit Deshapnde1f12cb52013-08-21 13:09:01 -0700900 }
901
Vinit Deshapnde6a2d3252013-09-04 14:11:24 -0700902 return (level * LinkQualityInfo.NORMALIZED_SIGNAL_STRENGTH_RANGE) /
Vinit Deshapnde1f12cb52013-08-21 13:09:01 -0700903 SignalStrength.NUM_SIGNAL_STRENGTH_BINS;
904 }
905
906 @Override
907 public void startSampling(SamplingDataTracker.SamplingSnapshot s) {
908 mSamplingDataTracker.startSampling(s);
909 }
910
911 @Override
912 public void stopSampling(SamplingDataTracker.SamplingSnapshot s) {
913 mSamplingDataTracker.stopSampling(s);
914 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800915}