1 /* 2 * Copyright (C) 2006 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.internal.telephony; 18 19 import android.app.PendingIntent; 20 import android.content.BroadcastReceiver; 21 import android.content.ContentResolver; 22 import android.content.Context; 23 import android.content.Intent; 24 import android.content.IntentFilter; 25 import android.content.SharedPreferences; 26 import android.database.ContentObserver; 27 import android.net.LinkCapabilities; 28 import android.net.LinkProperties; 29 import android.net.NetworkInfo; 30 import android.net.TrafficStats; 31 import android.net.wifi.WifiManager; 32 import android.os.AsyncResult; 33 import android.os.Bundle; 34 import android.os.Handler; 35 import android.os.Message; 36 import android.os.Messenger; 37 import android.os.SystemClock; 38 import android.os.SystemProperties; 39 import android.preference.PreferenceManager; 40 import android.provider.Settings; 41 import android.provider.Settings.SettingNotFoundException; 42 import android.telephony.ServiceState; 43 import android.telephony.TelephonyManager; 44 import android.text.TextUtils; 45 import android.util.Log; 46 47 import com.android.internal.R; 48 import com.android.internal.telephony.DataConnection.FailCause; 49 import com.android.internal.util.AsyncChannel; 50 import com.android.internal.util.Protocol; 51 52 import java.io.FileDescriptor; 53 import java.io.PrintWriter; 54 import java.util.ArrayList; 55 import java.util.HashMap; 56 import java.util.Map.Entry; 57 import java.util.Set; 58 import java.util.concurrent.ConcurrentHashMap; 59 import java.util.concurrent.atomic.AtomicInteger; 60 61 /** 62 * {@hide} 63 */ 64 public abstract class DataConnectionTracker extends Handler { 65 protected static final boolean DBG = true; 66 protected static final boolean VDBG = false; 67 68 /** 69 * IDLE: ready to start data connection setup, default state 70 * INITING: state of issued setupDefaultPDP() but not finish yet 71 * CONNECTING: state of issued startPppd() but not finish yet 72 * SCANNING: data connection fails with one apn but other apns are available 73 * ready to start data connection on other apns (before INITING) 74 * CONNECTED: IP connection is setup 75 * DISCONNECTING: Connection.disconnect() has been called, but PDP 76 * context is not yet deactivated 77 * FAILED: data connection fail for all apns settings 78 * 79 * getDataConnectionState() maps State to DataState 80 * FAILED or IDLE : DISCONNECTED 81 * INITING or CONNECTING or SCANNING: CONNECTING 82 * CONNECTED : CONNECTED or DISCONNECTING 83 */ 84 public enum State { 85 IDLE, 86 INITING, 87 CONNECTING, 88 SCANNING, 89 CONNECTED, 90 DISCONNECTING, 91 FAILED 92 } 93 94 public enum Activity { 95 NONE, 96 DATAIN, 97 DATAOUT, 98 DATAINANDOUT, 99 DORMANT 100 } 101 102 public static String ACTION_DATA_CONNECTION_TRACKER_MESSENGER = 103 "com.android.internal.telephony"; 104 public static String EXTRA_MESSENGER = "EXTRA_MESSENGER"; 105 106 /***** Event Codes *****/ 107 protected static final int BASE = Protocol.BASE_DATA_CONNECTION_TRACKER; 108 protected static final int EVENT_DATA_SETUP_COMPLETE = BASE + 0; 109 protected static final int EVENT_RADIO_AVAILABLE = BASE + 1; 110 protected static final int EVENT_RECORDS_LOADED = BASE + 2; 111 protected static final int EVENT_TRY_SETUP_DATA = BASE + 3; 112 protected static final int EVENT_DATA_STATE_CHANGED = BASE + 4; 113 protected static final int EVENT_POLL_PDP = BASE + 5; 114 protected static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = BASE + 6; 115 protected static final int EVENT_VOICE_CALL_STARTED = BASE + 7; 116 protected static final int EVENT_VOICE_CALL_ENDED = BASE + 8; 117 protected static final int EVENT_DATA_CONNECTION_DETACHED = BASE + 9; 118 protected static final int EVENT_LINK_STATE_CHANGED = BASE + 10; 119 protected static final int EVENT_ROAMING_ON = BASE + 11; 120 protected static final int EVENT_ROAMING_OFF = BASE + 12; 121 protected static final int EVENT_ENABLE_NEW_APN = BASE + 13; 122 protected static final int EVENT_RESTORE_DEFAULT_APN = BASE + 14; 123 protected static final int EVENT_DISCONNECT_DONE = BASE + 15; 124 protected static final int EVENT_DATA_CONNECTION_ATTACHED = BASE + 16; 125 protected static final int EVENT_DATA_STALL_ALARM = BASE + 17; 126 protected static final int EVENT_DO_RECOVERY = BASE + 18; 127 protected static final int EVENT_APN_CHANGED = BASE + 19; 128 protected static final int EVENT_CDMA_DATA_DETACHED = BASE + 20; 129 protected static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = BASE + 21; 130 protected static final int EVENT_PS_RESTRICT_ENABLED = BASE + 22; 131 protected static final int EVENT_PS_RESTRICT_DISABLED = BASE + 23; 132 public static final int EVENT_CLEAN_UP_CONNECTION = BASE + 24; 133 protected static final int EVENT_CDMA_OTA_PROVISION = BASE + 25; 134 protected static final int EVENT_RESTART_RADIO = BASE + 26; 135 protected static final int EVENT_SET_INTERNAL_DATA_ENABLE = BASE + 27; 136 protected static final int EVENT_RESET_DONE = BASE + 28; 137 public static final int CMD_SET_USER_DATA_ENABLE = BASE + 29; 138 public static final int EVENT_CLEAN_UP_ALL_CONNECTIONS = BASE + 30; 139 public static final int CMD_SET_DEPENDENCY_MET = BASE + 31; 140 public static final int CMD_SET_POLICY_DATA_ENABLE = BASE + 32; 141 142 /***** Constants *****/ 143 144 protected static final int APN_INVALID_ID = -1; 145 protected static final int APN_DEFAULT_ID = 0; 146 protected static final int APN_MMS_ID = 1; 147 protected static final int APN_SUPL_ID = 2; 148 protected static final int APN_DUN_ID = 3; 149 protected static final int APN_HIPRI_ID = 4; 150 protected static final int APN_IMS_ID = 5; 151 protected static final int APN_FOTA_ID = 6; 152 protected static final int APN_CBS_ID = 7; 153 protected static final int APN_NUM_TYPES = 8; 154 155 public static final int DISABLED = 0; 156 public static final int ENABLED = 1; 157 158 public static final String APN_TYPE_KEY = "apnType"; 159 160 /** Delay between APN attempts. 161 Note the property override mechanism is there just for testing purpose only. */ 162 protected static final int APN_DELAY_MILLIS = 163 SystemProperties.getInt("persist.radio.apn_delay", 5000); 164 165 protected Object mDataEnabledLock = new Object(); 166 167 // responds to the setInternalDataEnabled call - used internally to turn off data 168 // for example during emergency calls 169 protected boolean mInternalDataEnabled = true; 170 171 // responds to public (user) API to enable/disable data use 172 // independent of mInternalDataEnabled and requests for APN access 173 // persisted 174 protected boolean mUserDataEnabled = true; 175 176 // TODO: move away from static state once 5587429 is fixed. 177 protected static boolean sPolicyDataEnabled = true; 178 179 private boolean[] dataEnabled = new boolean[APN_NUM_TYPES]; 180 181 private int enabledCount = 0; 182 183 /* Currently requested APN type (TODO: This should probably be a parameter not a member) */ 184 protected String mRequestedApnType = Phone.APN_TYPE_DEFAULT; 185 186 /** Retry configuration: A doubling of retry times from 5secs to 30minutes */ 187 protected static final String DEFAULT_DATA_RETRY_CONFIG = "default_randomization=2000," 188 + "5000,10000,20000,40000,80000:5000,160000:5000," 189 + "320000:5000,640000:5000,1280000:5000,1800000:5000"; 190 191 /** Retry configuration for secondary networks: 4 tries in 20 sec */ 192 protected static final String SECONDARY_DATA_RETRY_CONFIG = 193 "max_retries=3, 5000, 5000, 5000"; 194 195 /** Slow poll when attempting connection recovery. */ 196 protected static final int POLL_NETSTAT_SLOW_MILLIS = 5000; 197 /** Default max failure count before attempting to network re-registration. */ 198 protected static final int DEFAULT_MAX_PDP_RESET_FAIL = 3; 199 200 /** 201 * After detecting a potential connection problem, this is the max number 202 * of subsequent polls before attempting recovery. 203 */ 204 protected static final int NO_RECV_POLL_LIMIT = 24; 205 // 1 sec. default polling interval when screen is on. 206 protected static final int POLL_NETSTAT_MILLIS = 1000; 207 // 10 min. default polling interval when screen is off. 208 protected static final int POLL_NETSTAT_SCREEN_OFF_MILLIS = 1000*60*10; 209 // 2 min for round trip time 210 protected static final int POLL_LONGEST_RTT = 120 * 1000; 211 // Default sent packets without ack which triggers initial recovery steps 212 protected static final int NUMBER_SENT_PACKETS_OF_HANG = 10; 213 // how long to wait before switching back to default APN 214 protected static final int RESTORE_DEFAULT_APN_DELAY = 1 * 60 * 1000; 215 // system property that can override the above value 216 protected static final String APN_RESTORE_DELAY_PROP_NAME = "android.telephony.apn-restore"; 217 // represents an invalid IP address 218 protected static final String NULL_IP = "0.0.0.0"; 219 220 // Default for the data stall alarm while non-aggressive stall detection 221 protected static final int DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS_DEFAULT = 1000 * 60 * 6; 222 // Default for the data stall alarm for aggressive stall detection 223 protected static final int DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS_DEFAULT = 1000 * 60; 224 // If attempt is less than this value we're doing first level recovery 225 protected static final int DATA_STALL_NO_RECV_POLL_LIMIT = 1; 226 // Tag for tracking stale alarms 227 protected static final String DATA_STALL_ALARM_TAG_EXTRA = "data.stall.alram.tag"; 228 229 // TODO: See if we can remove INTENT_RECONNECT_ALARM 230 // having to have different values for GSM and 231 // CDMA. If so we can then remove the need for 232 // getActionIntentReconnectAlarm. 233 protected static final String INTENT_RECONNECT_ALARM_EXTRA_REASON = 234 "reconnect_alarm_extra_reason"; 235 236 // Used for debugging. Send the INTENT with an optional counter value with the number 237 // of times the setup is to fail before succeeding. If the counter isn't passed the 238 // setup will fail once. Example fail two times with FailCause.SIGNAL_LOST(-3) 239 // adb shell am broadcast \ 240 // -a com.android.internal.telephony.dataconnectiontracker.intent_set_fail_data_setup_counter \ 241 // --ei fail_data_setup_counter 3 --ei fail_data_setup_fail_cause -3 242 protected static final String INTENT_SET_FAIL_DATA_SETUP_COUNTER = 243 "com.android.internal.telephony.dataconnectiontracker.intent_set_fail_data_setup_counter"; 244 protected static final String FAIL_DATA_SETUP_COUNTER = "fail_data_setup_counter"; 245 protected int mFailDataSetupCounter = 0; 246 protected static final String FAIL_DATA_SETUP_FAIL_CAUSE = "fail_data_setup_fail_cause"; 247 protected FailCause mFailDataSetupFailCause = FailCause.ERROR_UNSPECIFIED; 248 249 protected static final String DEFALUT_DATA_ON_BOOT_PROP = "net.def_data_on_boot"; 250 251 // member variables 252 protected PhoneBase mPhone; 253 protected Activity mActivity = Activity.NONE; 254 protected State mState = State.IDLE; 255 protected Handler mDataConnectionTracker = null; 256 257 258 protected long mTxPkts; 259 protected long mRxPkts; 260 protected int mNetStatPollPeriod; 261 protected boolean mNetStatPollEnabled = false; 262 263 protected TxRxSum mDataStallTxRxSum = new TxRxSum(0, 0); 264 // Used to track stale data stall alarms. 265 protected int mDataStallAlarmTag = (int) SystemClock.elapsedRealtime(); 266 // The current data stall alarm intent 267 protected PendingIntent mDataStallAlarmIntent = null; 268 // Number of packets sent since the last received packet 269 protected long mSentSinceLastRecv; 270 // Controls when a simple recovery attempt it to be tried 271 protected int mNoRecvPollCount = 0; 272 273 // wifi connection status will be updated by sticky intent 274 protected boolean mIsWifiConnected = false; 275 276 /** Intent sent when the reconnect alarm fires. */ 277 protected PendingIntent mReconnectIntent = null; 278 279 /** CID of active data connection */ 280 protected int mCidActive; 281 282 // When false we will not auto attach and manually attaching is required. 283 protected boolean mAutoAttachOnCreation = false; 284 285 // State of screen 286 // (TODO: Reconsider tying directly to screen, maybe this is 287 // really a lower power mode") 288 protected boolean mIsScreenOn = true; 289 290 /** Allows the generation of unique Id's for DataConnection objects */ 291 protected AtomicInteger mUniqueIdGenerator = new AtomicInteger(0); 292 293 /** The data connections. */ 294 protected HashMap<Integer, DataConnection> mDataConnections = 295 new HashMap<Integer, DataConnection>(); 296 297 /** The data connection async channels */ 298 protected HashMap<Integer, DataConnectionAc> mDataConnectionAsyncChannels = 299 new HashMap<Integer, DataConnectionAc>(); 300 301 /** Convert an ApnType string to Id (TODO: Use "enumeration" instead of String for ApnType) */ 302 protected HashMap<String, Integer> mApnToDataConnectionId = 303 new HashMap<String, Integer>(); 304 305 /** Phone.APN_TYPE_* ===> ApnContext */ 306 protected ConcurrentHashMap<String, ApnContext> mApnContexts = 307 new ConcurrentHashMap<String, ApnContext>(); 308 309 /* Currently active APN */ 310 protected ApnSetting mActiveApn; 311 312 /** allApns holds all apns */ 313 protected ArrayList<ApnSetting> mAllApns = null; 314 315 /** preferred apn */ 316 protected ApnSetting mPreferredApn = null; 317 318 /** Is packet service restricted by network */ 319 protected boolean mIsPsRestricted = false; 320 321 /* Once disposed dont handle any messages */ 322 protected boolean mIsDisposed = false; 323 324 protected BroadcastReceiver mIntentReceiver = new BroadcastReceiver () 325 { 326 @Override 327 public void onReceive(Context context, Intent intent) 328 { 329 String action = intent.getAction(); 330 if (DBG) log("onReceive: action=" + action); 331 if (action.equals(Intent.ACTION_SCREEN_ON)) { 332 mIsScreenOn = true; 333 stopNetStatPoll(); 334 startNetStatPoll(); 335 restartDataStallAlarm(); 336 } else if (action.equals(Intent.ACTION_SCREEN_OFF)) { 337 mIsScreenOn = false; 338 stopNetStatPoll(); 339 startNetStatPoll(); 340 restartDataStallAlarm(); 341 } else if (action.startsWith(getActionIntentReconnectAlarm())) { 342 log("Reconnect alarm. Previous state was " + mState); 343 onActionIntentReconnectAlarm(intent); 344 } else if (action.equals(getActionIntentDataStallAlarm())) { 345 onActionIntentDataStallAlarm(intent); 346 } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) { 347 final android.net.NetworkInfo networkInfo = (NetworkInfo) 348 intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); 349 mIsWifiConnected = (networkInfo != null && networkInfo.isConnected()); 350 } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) { 351 final boolean enabled = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 352 WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_ENABLED; 353 354 if (!enabled) { 355 // when WiFi got disabled, the NETWORK_STATE_CHANGED_ACTION 356 // quit and won't report disconnected until next enabling. 357 mIsWifiConnected = false; 358 } 359 } else if (action.equals(INTENT_SET_FAIL_DATA_SETUP_COUNTER)) { 360 mFailDataSetupCounter = intent.getIntExtra(FAIL_DATA_SETUP_COUNTER, 1); 361 mFailDataSetupFailCause = FailCause.fromInt( 362 intent.getIntExtra(FAIL_DATA_SETUP_FAIL_CAUSE, 363 FailCause.ERROR_UNSPECIFIED.getErrorCode())); 364 if (DBG) log("set mFailDataSetupCounter=" + mFailDataSetupCounter + 365 " mFailDataSetupFailCause=" + mFailDataSetupFailCause); 366 } 367 } 368 }; 369 370 private final DataRoamingSettingObserver mDataRoamingSettingObserver; 371 372 private class DataRoamingSettingObserver extends ContentObserver { 373 public DataRoamingSettingObserver(Handler handler) { 374 super(handler); 375 } 376 377 public void register(Context context) { 378 final ContentResolver resolver = context.getContentResolver(); 379 resolver.registerContentObserver( 380 Settings.Secure.getUriFor(Settings.Secure.DATA_ROAMING), false, this); 381 } 382 383 public void unregister(Context context) { 384 final ContentResolver resolver = context.getContentResolver(); 385 resolver.unregisterContentObserver(this); 386 } 387 388 @Override 389 public void onChange(boolean selfChange) { 390 // already running on mPhone handler thread 391 handleDataOnRoamingChange(); 392 } 393 } 394 395 /** 396 * Maintian the sum of transmit and receive packets. 397 * 398 * The packet counts are initizlied and reset to -1 and 399 * remain -1 until they can be updated. 400 */ 401 public class TxRxSum { 402 public long txPkts; 403 public long rxPkts; 404 405 public TxRxSum() { 406 reset(); 407 } 408 409 public TxRxSum(long txPkts, long rxPkts) { 410 this.txPkts = txPkts; 411 this.rxPkts = rxPkts; 412 } 413 414 public TxRxSum(TxRxSum sum) { 415 txPkts = sum.txPkts; 416 rxPkts = sum.rxPkts; 417 } 418 419 public void reset() { 420 txPkts = -1; 421 rxPkts = -1; 422 } 423 424 public String toString() { 425 return "{txSum=" + txPkts + " rxSum=" + rxPkts + "}"; 426 } 427 428 public void updateTxRxSum() { 429 boolean txUpdated = false, rxUpdated = false; 430 long txSum = 0, rxSum = 0; 431 for (ApnContext apnContext : mApnContexts.values()) { 432 if (apnContext.getState() == State.CONNECTED) { 433 DataConnectionAc dcac = apnContext.getDataConnectionAc(); 434 if (dcac == null) continue; 435 436 LinkProperties linkProp = dcac.getLinkPropertiesSync(); 437 if (linkProp == null) continue; 438 439 String iface = linkProp.getInterfaceName(); 440 441 if (iface != null) { 442 long stats = TrafficStats.getTxPackets(iface); 443 if (stats > 0) { 444 txUpdated = true; 445 txSum += stats; 446 } 447 stats = TrafficStats.getRxPackets(iface); 448 if (stats > 0) { 449 rxUpdated = true; 450 rxSum += stats; 451 } 452 } 453 } 454 } 455 if (txUpdated) this.txPkts = txSum; 456 if (rxUpdated) this.rxPkts = rxSum; 457 } 458 } 459 460 protected boolean isDataSetupCompleteOk(AsyncResult ar) { 461 if (ar.exception != null) { 462 if (DBG) log("isDataSetupCompleteOk return false, ar.result=" + ar.result); 463 return false; 464 } 465 if (mFailDataSetupCounter <= 0) { 466 if (DBG) log("isDataSetupCompleteOk return true"); 467 return true; 468 } 469 ar.result = mFailDataSetupFailCause; 470 if (DBG) { 471 log("isDataSetupCompleteOk return false" + 472 " mFailDataSetupCounter=" + mFailDataSetupCounter + 473 " mFailDataSetupFailCause=" + mFailDataSetupFailCause); 474 } 475 mFailDataSetupCounter -= 1; 476 return false; 477 } 478 479 protected void onActionIntentReconnectAlarm(Intent intent) { 480 String reason = intent.getStringExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON); 481 if (mState == State.FAILED) { 482 Message msg = obtainMessage(EVENT_CLEAN_UP_CONNECTION); 483 msg.arg1 = 0; // tearDown is false 484 msg.arg2 = 0; 485 msg.obj = reason; 486 sendMessage(msg); 487 } 488 sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA)); 489 } 490 491 protected void onActionIntentDataStallAlarm(Intent intent) { 492 if (VDBG) log("onActionIntentDataStallAlarm: action=" + intent.getAction()); 493 Message msg = obtainMessage(EVENT_DATA_STALL_ALARM, intent.getAction()); 494 msg.arg1 = intent.getIntExtra(DATA_STALL_ALARM_TAG_EXTRA, 0); 495 sendMessage(msg); 496 } 497 498 /** 499 * Default constructor 500 */ 501 protected DataConnectionTracker(PhoneBase phone) { 502 super(); 503 if (DBG) log("DCT.constructor"); 504 mPhone = phone; 505 506 IntentFilter filter = new IntentFilter(); 507 filter.addAction(getActionIntentReconnectAlarm()); 508 filter.addAction(Intent.ACTION_SCREEN_ON); 509 filter.addAction(Intent.ACTION_SCREEN_OFF); 510 filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); 511 filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); 512 filter.addAction(INTENT_SET_FAIL_DATA_SETUP_COUNTER); 513 514 mUserDataEnabled = Settings.Secure.getInt( 515 mPhone.getContext().getContentResolver(), Settings.Secure.MOBILE_DATA, 1) == 1; 516 517 // TODO: Why is this registering the phone as the receiver of the intent 518 // and not its own handler? 519 mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone); 520 521 // This preference tells us 1) initial condition for "dataEnabled", 522 // and 2) whether the RIL will setup the baseband to auto-PS attach. 523 524 dataEnabled[APN_DEFAULT_ID] = SystemProperties.getBoolean(DEFALUT_DATA_ON_BOOT_PROP, 525 true); 526 if (dataEnabled[APN_DEFAULT_ID]) { 527 enabledCount++; 528 } 529 530 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mPhone.getContext()); 531 mAutoAttachOnCreation = sp.getBoolean(PhoneBase.DATA_DISABLED_ON_BOOT_KEY, false); 532 533 // watch for changes to Settings.Secure.DATA_ROAMING 534 mDataRoamingSettingObserver = new DataRoamingSettingObserver(mPhone); 535 mDataRoamingSettingObserver.register(mPhone.getContext()); 536 } 537 538 public void dispose() { 539 if (DBG) log("DCT.dispose"); 540 for (DataConnectionAc dcac : mDataConnectionAsyncChannels.values()) { 541 dcac.disconnect(); 542 } 543 mDataConnectionAsyncChannels.clear(); 544 mIsDisposed = true; 545 mPhone.getContext().unregisterReceiver(this.mIntentReceiver); 546 mDataRoamingSettingObserver.unregister(mPhone.getContext()); 547 } 548 549 protected void broadcastMessenger() { 550 Intent intent = new Intent(ACTION_DATA_CONNECTION_TRACKER_MESSENGER); 551 intent.putExtra(EXTRA_MESSENGER, new Messenger(this)); 552 mPhone.getContext().sendBroadcast(intent); 553 } 554 555 public Activity getActivity() { 556 return mActivity; 557 } 558 559 public boolean isApnTypeActive(String type) { 560 // TODO: support simultaneous with List instead 561 if (Phone.APN_TYPE_DUN.equals(type)) { 562 ApnSetting dunApn = fetchDunApn(); 563 if (dunApn != null) { 564 return ((mActiveApn != null) && (dunApn.toString().equals(mActiveApn.toString()))); 565 } 566 } 567 return mActiveApn != null && mActiveApn.canHandleType(type); 568 } 569 570 protected ApnSetting fetchDunApn() { 571 if (SystemProperties.getBoolean("net.tethering.noprovisioning", false)) { 572 log("fetchDunApn: net.tethering.noprovisioning=true ret: null"); 573 return null; 574 } 575 Context c = mPhone.getContext(); 576 String apnData = Settings.Secure.getString(c.getContentResolver(), 577 Settings.Secure.TETHER_DUN_APN); 578 ApnSetting dunSetting = ApnSetting.fromString(apnData); 579 if (dunSetting != null) { 580 if (VDBG) log("fetchDunApn: secure TETHER_DUN_APN dunSetting=" + dunSetting); 581 return dunSetting; 582 } 583 584 apnData = c.getResources().getString(R.string.config_tether_apndata); 585 dunSetting = ApnSetting.fromString(apnData); 586 if (VDBG) log("fetchDunApn: config_tether_apndata dunSetting=" + dunSetting); 587 return dunSetting; 588 } 589 590 public String[] getActiveApnTypes() { 591 String[] result; 592 if (mActiveApn != null) { 593 result = mActiveApn.types; 594 } else { 595 result = new String[1]; 596 result[0] = Phone.APN_TYPE_DEFAULT; 597 } 598 return result; 599 } 600 601 /** TODO: See if we can remove */ 602 public String getActiveApnString(String apnType) { 603 String result = null; 604 if (mActiveApn != null) { 605 result = mActiveApn.apn; 606 } 607 return result; 608 } 609 610 /** 611 * Modify {@link Settings.Secure#DATA_ROAMING} value. 612 */ 613 public void setDataOnRoamingEnabled(boolean enabled) { 614 if (getDataOnRoamingEnabled() != enabled) { 615 final ContentResolver resolver = mPhone.getContext().getContentResolver(); 616 Settings.Secure.putInt(resolver, Settings.Secure.DATA_ROAMING, enabled ? 1 : 0); 617 // will trigger handleDataOnRoamingChange() through observer 618 } 619 } 620 621 /** 622 * Return current {@link Settings.Secure#DATA_ROAMING} value. 623 */ 624 public boolean getDataOnRoamingEnabled() { 625 try { 626 final ContentResolver resolver = mPhone.getContext().getContentResolver(); 627 return Settings.Secure.getInt(resolver, Settings.Secure.DATA_ROAMING) != 0; 628 } catch (SettingNotFoundException snfe) { 629 return false; 630 } 631 } 632 633 private void handleDataOnRoamingChange() { 634 if (mPhone.getServiceState().getRoaming()) { 635 if (getDataOnRoamingEnabled()) { 636 resetAllRetryCounts(); 637 } 638 sendMessage(obtainMessage(EVENT_ROAMING_ON)); 639 } 640 } 641 642 // abstract methods 643 protected abstract String getActionIntentReconnectAlarm(); 644 protected abstract String getActionIntentDataStallAlarm(); 645 protected abstract void startNetStatPoll(); 646 protected abstract void stopNetStatPoll(); 647 protected abstract void restartDataStallAlarm(); 648 protected abstract void restartRadio(); 649 protected abstract void log(String s); 650 protected abstract void loge(String s); 651 protected abstract boolean isDataAllowed(); 652 protected abstract boolean isApnTypeAvailable(String type); 653 public abstract State getState(String apnType); 654 protected abstract void setState(State s); 655 protected abstract void gotoIdleAndNotifyDataConnection(String reason); 656 657 protected abstract boolean onTrySetupData(String reason); 658 protected abstract void onRoamingOff(); 659 protected abstract void onRoamingOn(); 660 protected abstract void onRadioAvailable(); 661 protected abstract void onRadioOffOrNotAvailable(); 662 protected abstract void onDataSetupComplete(AsyncResult ar); 663 protected abstract void onDisconnectDone(int connId, AsyncResult ar); 664 protected abstract void onVoiceCallStarted(); 665 protected abstract void onVoiceCallEnded(); 666 protected abstract void onCleanUpConnection(boolean tearDown, int apnId, String reason); 667 protected abstract void onCleanUpAllConnections(String cause); 668 protected abstract boolean isDataPossible(String apnType); 669 670 protected void onDataStallAlarm(int tag) { 671 loge("onDataStallAlarm: not impleted tag=" + tag); 672 } 673 674 @Override 675 public void handleMessage(Message msg) { 676 switch (msg.what) { 677 case AsyncChannel.CMD_CHANNEL_DISCONNECTED: { 678 log("DISCONNECTED_CONNECTED: msg=" + msg); 679 DataConnectionAc dcac = (DataConnectionAc) msg.obj; 680 mDataConnectionAsyncChannels.remove(dcac.dataConnection.getDataConnectionId()); 681 dcac.disconnected(); 682 break; 683 } 684 case EVENT_ENABLE_NEW_APN: 685 onEnableApn(msg.arg1, msg.arg2); 686 break; 687 688 case EVENT_TRY_SETUP_DATA: 689 String reason = null; 690 if (msg.obj instanceof String) { 691 reason = (String) msg.obj; 692 } 693 onTrySetupData(reason); 694 break; 695 696 case EVENT_DATA_STALL_ALARM: 697 onDataStallAlarm(msg.arg1); 698 break; 699 700 case EVENT_ROAMING_OFF: 701 if (getDataOnRoamingEnabled() == false) { 702 resetAllRetryCounts(); 703 } 704 onRoamingOff(); 705 break; 706 707 case EVENT_ROAMING_ON: 708 onRoamingOn(); 709 break; 710 711 case EVENT_RADIO_AVAILABLE: 712 onRadioAvailable(); 713 break; 714 715 case EVENT_RADIO_OFF_OR_NOT_AVAILABLE: 716 onRadioOffOrNotAvailable(); 717 break; 718 719 case EVENT_DATA_SETUP_COMPLETE: 720 mCidActive = msg.arg1; 721 onDataSetupComplete((AsyncResult) msg.obj); 722 break; 723 724 case EVENT_DISCONNECT_DONE: 725 log("DataConnectoinTracker.handleMessage: EVENT_DISCONNECT_DONE msg=" + msg); 726 onDisconnectDone(msg.arg1, (AsyncResult) msg.obj); 727 break; 728 729 case EVENT_VOICE_CALL_STARTED: 730 onVoiceCallStarted(); 731 break; 732 733 case EVENT_VOICE_CALL_ENDED: 734 onVoiceCallEnded(); 735 break; 736 737 case EVENT_CLEAN_UP_ALL_CONNECTIONS: { 738 onCleanUpAllConnections((String) msg.obj); 739 break; 740 } 741 case EVENT_CLEAN_UP_CONNECTION: { 742 boolean tearDown = (msg.arg1 == 0) ? false : true; 743 onCleanUpConnection(tearDown, msg.arg2, (String) msg.obj); 744 break; 745 } 746 case EVENT_SET_INTERNAL_DATA_ENABLE: { 747 boolean enabled = (msg.arg1 == ENABLED) ? true : false; 748 onSetInternalDataEnabled(enabled); 749 break; 750 } 751 case EVENT_RESET_DONE: { 752 if (DBG) log("EVENT_RESET_DONE"); 753 onResetDone((AsyncResult) msg.obj); 754 break; 755 } 756 case CMD_SET_USER_DATA_ENABLE: { 757 final boolean enabled = (msg.arg1 == ENABLED) ? true : false; 758 if (DBG) log("CMD_SET_USER_DATA_ENABLE enabled=" + enabled); 759 onSetUserDataEnabled(enabled); 760 break; 761 } 762 case CMD_SET_DEPENDENCY_MET: { 763 boolean met = (msg.arg1 == ENABLED) ? true : false; 764 if (DBG) log("CMD_SET_DEPENDENCY_MET met=" + met); 765 Bundle bundle = msg.getData(); 766 if (bundle != null) { 767 String apnType = (String)bundle.get(APN_TYPE_KEY); 768 if (apnType != null) { 769 onSetDependencyMet(apnType, met); 770 } 771 } 772 break; 773 } 774 case CMD_SET_POLICY_DATA_ENABLE: { 775 final boolean enabled = (msg.arg1 == ENABLED) ? true : false; 776 onSetPolicyDataEnabled(enabled); 777 break; 778 } 779 default: 780 Log.e("DATA", "Unidentified event msg=" + msg); 781 break; 782 } 783 } 784 785 /** 786 * Report on whether data connectivity is enabled 787 * 788 * @return {@code false} if data connectivity has been explicitly disabled, 789 * {@code true} otherwise. 790 */ 791 public boolean getAnyDataEnabled() { 792 final boolean result; 793 synchronized (mDataEnabledLock) { 794 result = (mInternalDataEnabled && mUserDataEnabled && sPolicyDataEnabled 795 && (enabledCount != 0)); 796 } 797 if (!result && DBG) log("getAnyDataEnabled " + result); 798 return result; 799 } 800 801 protected boolean isEmergency() { 802 final boolean result; 803 synchronized (mDataEnabledLock) { 804 result = mPhone.isInEcm() || mPhone.isInEmergencyCall(); 805 } 806 log("isEmergency: result=" + result); 807 return result; 808 } 809 810 protected int apnTypeToId(String type) { 811 if (TextUtils.equals(type, Phone.APN_TYPE_DEFAULT)) { 812 return APN_DEFAULT_ID; 813 } else if (TextUtils.equals(type, Phone.APN_TYPE_MMS)) { 814 return APN_MMS_ID; 815 } else if (TextUtils.equals(type, Phone.APN_TYPE_SUPL)) { 816 return APN_SUPL_ID; 817 } else if (TextUtils.equals(type, Phone.APN_TYPE_DUN)) { 818 return APN_DUN_ID; 819 } else if (TextUtils.equals(type, Phone.APN_TYPE_HIPRI)) { 820 return APN_HIPRI_ID; 821 } else if (TextUtils.equals(type, Phone.APN_TYPE_IMS)) { 822 return APN_IMS_ID; 823 } else if (TextUtils.equals(type, Phone.APN_TYPE_FOTA)) { 824 return APN_FOTA_ID; 825 } else if (TextUtils.equals(type, Phone.APN_TYPE_CBS)) { 826 return APN_CBS_ID; 827 } else { 828 return APN_INVALID_ID; 829 } 830 } 831 832 protected String apnIdToType(int id) { 833 switch (id) { 834 case APN_DEFAULT_ID: 835 return Phone.APN_TYPE_DEFAULT; 836 case APN_MMS_ID: 837 return Phone.APN_TYPE_MMS; 838 case APN_SUPL_ID: 839 return Phone.APN_TYPE_SUPL; 840 case APN_DUN_ID: 841 return Phone.APN_TYPE_DUN; 842 case APN_HIPRI_ID: 843 return Phone.APN_TYPE_HIPRI; 844 case APN_IMS_ID: 845 return Phone.APN_TYPE_IMS; 846 case APN_FOTA_ID: 847 return Phone.APN_TYPE_FOTA; 848 case APN_CBS_ID: 849 return Phone.APN_TYPE_CBS; 850 default: 851 log("Unknown id (" + id + ") in apnIdToType"); 852 return Phone.APN_TYPE_DEFAULT; 853 } 854 } 855 856 protected LinkProperties getLinkProperties(String apnType) { 857 int id = apnTypeToId(apnType); 858 859 if (isApnIdEnabled(id)) { 860 // TODO - remove this cdma-only hack and support multiple DCs. 861 DataConnectionAc dcac = mDataConnectionAsyncChannels.get(0); 862 return dcac.getLinkPropertiesSync(); 863 } else { 864 return new LinkProperties(); 865 } 866 } 867 868 protected LinkCapabilities getLinkCapabilities(String apnType) { 869 int id = apnTypeToId(apnType); 870 if (isApnIdEnabled(id)) { 871 // TODO - remove this cdma-only hack and support multiple DCs. 872 DataConnectionAc dcac = mDataConnectionAsyncChannels.get(0); 873 return dcac.getLinkCapabilitiesSync(); 874 } else { 875 return new LinkCapabilities(); 876 } 877 } 878 879 // tell all active apns of the current condition 880 protected void notifyDataConnection(String reason) { 881 for (int id = 0; id < APN_NUM_TYPES; id++) { 882 if (dataEnabled[id]) { 883 mPhone.notifyDataConnection(reason, apnIdToType(id)); 884 } 885 } 886 notifyOffApnsOfAvailability(reason); 887 } 888 889 // a new APN has gone active and needs to send events to catch up with the 890 // current condition 891 private void notifyApnIdUpToCurrent(String reason, int apnId) { 892 switch (mState) { 893 case IDLE: 894 case INITING: 895 break; 896 case CONNECTING: 897 case SCANNING: 898 mPhone.notifyDataConnection(reason, apnIdToType(apnId), Phone.DataState.CONNECTING); 899 break; 900 case CONNECTED: 901 case DISCONNECTING: 902 mPhone.notifyDataConnection(reason, apnIdToType(apnId), Phone.DataState.CONNECTING); 903 mPhone.notifyDataConnection(reason, apnIdToType(apnId), Phone.DataState.CONNECTED); 904 break; 905 } 906 } 907 908 // since we normally don't send info to a disconnected APN, we need to do this specially 909 private void notifyApnIdDisconnected(String reason, int apnId) { 910 mPhone.notifyDataConnection(reason, apnIdToType(apnId), Phone.DataState.DISCONNECTED); 911 } 912 913 // disabled apn's still need avail/unavail notificiations - send them out 914 protected void notifyOffApnsOfAvailability(String reason) { 915 if (DBG) log("notifyOffApnsOfAvailability - reason= " + reason); 916 for (int id = 0; id < APN_NUM_TYPES; id++) { 917 if (!isApnIdEnabled(id)) { 918 notifyApnIdDisconnected(reason, id); 919 } 920 } 921 } 922 923 public boolean isApnTypeEnabled(String apnType) { 924 if (apnType == null) { 925 return false; 926 } else { 927 return isApnIdEnabled(apnTypeToId(apnType)); 928 } 929 } 930 931 protected synchronized boolean isApnIdEnabled(int id) { 932 if (id != APN_INVALID_ID) { 933 return dataEnabled[id]; 934 } 935 return false; 936 } 937 938 /** 939 * Ensure that we are connected to an APN of the specified type. 940 * 941 * @param type the APN type (currently the only valid values are 942 * {@link Phone#APN_TYPE_MMS} and {@link Phone#APN_TYPE_SUPL}) 943 * @return Success is indicated by {@code Phone.APN_ALREADY_ACTIVE} or 944 * {@code Phone.APN_REQUEST_STARTED}. In the latter case, a 945 * broadcast will be sent by the ConnectivityManager when a 946 * connection to the APN has been established. 947 */ 948 public synchronized int enableApnType(String type) { 949 int id = apnTypeToId(type); 950 if (id == APN_INVALID_ID) { 951 return Phone.APN_REQUEST_FAILED; 952 } 953 954 if (DBG) { 955 log("enableApnType(" + type + "), isApnTypeActive = " + isApnTypeActive(type) 956 + ", isApnIdEnabled =" + isApnIdEnabled(id) + " and state = " + mState); 957 } 958 959 if (!isApnTypeAvailable(type)) { 960 if (DBG) log("type not available"); 961 return Phone.APN_TYPE_NOT_AVAILABLE; 962 } 963 964 if (isApnIdEnabled(id)) { 965 return Phone.APN_ALREADY_ACTIVE; 966 } else { 967 setEnabled(id, true); 968 } 969 return Phone.APN_REQUEST_STARTED; 970 } 971 972 /** 973 * The APN of the specified type is no longer needed. Ensure that if use of 974 * the default APN has not been explicitly disabled, we are connected to the 975 * default APN. 976 * 977 * @param type the APN type. The only valid values are currently 978 * {@link Phone#APN_TYPE_MMS} and {@link Phone#APN_TYPE_SUPL}. 979 * @return Success is indicated by {@code Phone.APN_ALREADY_ACTIVE} or 980 * {@code Phone.APN_REQUEST_STARTED}. In the latter case, a 981 * broadcast will be sent by the ConnectivityManager when a 982 * connection to the APN has been disconnected. A {@code 983 * Phone.APN_REQUEST_FAILED} is returned if the type parameter is 984 * invalid or if the apn wasn't enabled. 985 */ 986 public synchronized int disableApnType(String type) { 987 if (DBG) log("disableApnType(" + type + ")"); 988 int id = apnTypeToId(type); 989 if (id == APN_INVALID_ID) { 990 return Phone.APN_REQUEST_FAILED; 991 } 992 if (isApnIdEnabled(id)) { 993 setEnabled(id, false); 994 if (isApnTypeActive(Phone.APN_TYPE_DEFAULT)) { 995 if (dataEnabled[APN_DEFAULT_ID]) { 996 return Phone.APN_ALREADY_ACTIVE; 997 } else { 998 return Phone.APN_REQUEST_STARTED; 999 } 1000 } else { 1001 return Phone.APN_REQUEST_STARTED; 1002 } 1003 } else { 1004 return Phone.APN_REQUEST_FAILED; 1005 } 1006 } 1007 1008 protected void setEnabled(int id, boolean enable) { 1009 if (DBG) { 1010 log("setEnabled(" + id + ", " + enable + ") with old state = " + dataEnabled[id] 1011 + " and enabledCount = " + enabledCount); 1012 } 1013 Message msg = obtainMessage(EVENT_ENABLE_NEW_APN); 1014 msg.arg1 = id; 1015 msg.arg2 = (enable ? ENABLED : DISABLED); 1016 sendMessage(msg); 1017 } 1018 1019 protected void onEnableApn(int apnId, int enabled) { 1020 if (DBG) { 1021 log("EVENT_APN_ENABLE_REQUEST apnId=" + apnId + ", apnType=" + apnIdToType(apnId) + 1022 ", enabled=" + enabled + ", dataEnabled = " + dataEnabled[apnId] + 1023 ", enabledCount = " + enabledCount + ", isApnTypeActive = " + 1024 isApnTypeActive(apnIdToType(apnId))); 1025 } 1026 if (enabled == ENABLED) { 1027 synchronized (this) { 1028 if (!dataEnabled[apnId]) { 1029 dataEnabled[apnId] = true; 1030 enabledCount++; 1031 } 1032 } 1033 String type = apnIdToType(apnId); 1034 if (!isApnTypeActive(type)) { 1035 mRequestedApnType = type; 1036 onEnableNewApn(); 1037 } else { 1038 notifyApnIdUpToCurrent(Phone.REASON_APN_SWITCHED, apnId); 1039 } 1040 } else { 1041 // disable 1042 boolean didDisable = false; 1043 synchronized (this) { 1044 if (dataEnabled[apnId]) { 1045 dataEnabled[apnId] = false; 1046 enabledCount--; 1047 didDisable = true; 1048 } 1049 } 1050 if (didDisable) { 1051 if ((enabledCount == 0) || (apnId == APN_DUN_ID)) { 1052 mRequestedApnType = Phone.APN_TYPE_DEFAULT; 1053 onCleanUpConnection(true, apnId, Phone.REASON_DATA_DISABLED); 1054 } 1055 1056 // send the disconnect msg manually, since the normal route wont send 1057 // it (it's not enabled) 1058 notifyApnIdDisconnected(Phone.REASON_DATA_DISABLED, apnId); 1059 if (dataEnabled[APN_DEFAULT_ID] == true 1060 && !isApnTypeActive(Phone.APN_TYPE_DEFAULT)) { 1061 // TODO - this is an ugly way to restore the default conn - should be done 1062 // by a real contention manager and policy that disconnects the lower pri 1063 // stuff as enable requests come in and pops them back on as we disable back 1064 // down to the lower pri stuff 1065 mRequestedApnType = Phone.APN_TYPE_DEFAULT; 1066 onEnableNewApn(); 1067 } 1068 } 1069 } 1070 } 1071 1072 /** 1073 * Called when we switch APNs. 1074 * 1075 * mRequestedApnType is set prior to call 1076 * To be overridden. 1077 */ 1078 protected void onEnableNewApn() { 1079 } 1080 1081 /** 1082 * Called when EVENT_RESET_DONE is received so goto 1083 * IDLE state and send notifications to those interested. 1084 * 1085 * TODO - currently unused. Needs to be hooked into DataConnection cleanup 1086 * TODO - needs to pass some notion of which connection is reset.. 1087 */ 1088 protected void onResetDone(AsyncResult ar) { 1089 if (DBG) log("EVENT_RESET_DONE"); 1090 String reason = null; 1091 if (ar.userObj instanceof String) { 1092 reason = (String) ar.userObj; 1093 } 1094 gotoIdleAndNotifyDataConnection(reason); 1095 } 1096 1097 /** 1098 * Prevent mobile data connections from being established, or once again 1099 * allow mobile data connections. If the state toggles, then either tear 1100 * down or set up data, as appropriate to match the new state. 1101 * 1102 * @param enable indicates whether to enable ({@code true}) or disable ( 1103 * {@code false}) data 1104 * @return {@code true} if the operation succeeded 1105 */ 1106 public boolean setInternalDataEnabled(boolean enable) { 1107 if (DBG) 1108 log("setInternalDataEnabled(" + enable + ")"); 1109 1110 Message msg = obtainMessage(EVENT_SET_INTERNAL_DATA_ENABLE); 1111 msg.arg1 = (enable ? ENABLED : DISABLED); 1112 sendMessage(msg); 1113 return true; 1114 } 1115 1116 protected void onSetInternalDataEnabled(boolean enabled) { 1117 synchronized (mDataEnabledLock) { 1118 mInternalDataEnabled = enabled; 1119 if (enabled) { 1120 log("onSetInternalDataEnabled: changed to enabled, try to setup data call"); 1121 resetAllRetryCounts(); 1122 onTrySetupData(Phone.REASON_DATA_ENABLED); 1123 } else { 1124 log("onSetInternalDataEnabled: changed to disabled, cleanUpAllConnections"); 1125 cleanUpAllConnections(null); 1126 } 1127 } 1128 } 1129 1130 public void cleanUpAllConnections(String cause) { 1131 Message msg = obtainMessage(EVENT_CLEAN_UP_ALL_CONNECTIONS); 1132 msg.obj = cause; 1133 sendMessage(msg); 1134 } 1135 1136 public abstract boolean isDisconnected(); 1137 1138 protected void onSetUserDataEnabled(boolean enabled) { 1139 synchronized (mDataEnabledLock) { 1140 final boolean prevEnabled = getAnyDataEnabled(); 1141 if (mUserDataEnabled != enabled) { 1142 mUserDataEnabled = enabled; 1143 Settings.Secure.putInt(mPhone.getContext().getContentResolver(), 1144 Settings.Secure.MOBILE_DATA, enabled ? 1 : 0); 1145 if (getDataOnRoamingEnabled() == false && 1146 mPhone.getServiceState().getRoaming() == true) { 1147 if (enabled) { 1148 notifyOffApnsOfAvailability(Phone.REASON_ROAMING_ON); 1149 } else { 1150 notifyOffApnsOfAvailability(Phone.REASON_DATA_DISABLED); 1151 } 1152 } 1153 if (prevEnabled != getAnyDataEnabled()) { 1154 if (!prevEnabled) { 1155 resetAllRetryCounts(); 1156 onTrySetupData(Phone.REASON_DATA_ENABLED); 1157 } else { 1158 onCleanUpAllConnections(Phone.REASON_DATA_DISABLED); 1159 } 1160 } 1161 } 1162 } 1163 } 1164 1165 protected void onSetDependencyMet(String apnType, boolean met) { 1166 } 1167 1168 protected void onSetPolicyDataEnabled(boolean enabled) { 1169 synchronized (mDataEnabledLock) { 1170 final boolean prevEnabled = getAnyDataEnabled(); 1171 if (sPolicyDataEnabled != enabled) { 1172 sPolicyDataEnabled = enabled; 1173 if (prevEnabled != getAnyDataEnabled()) { 1174 if (!prevEnabled) { 1175 resetAllRetryCounts(); 1176 onTrySetupData(Phone.REASON_DATA_ENABLED); 1177 } else { 1178 onCleanUpAllConnections(Phone.REASON_DATA_DISABLED); 1179 } 1180 } 1181 } 1182 } 1183 } 1184 1185 protected String getReryConfig(boolean forDefault) { 1186 int nt = mPhone.getServiceState().getNetworkType(); 1187 1188 if ((nt == TelephonyManager.NETWORK_TYPE_CDMA) || 1189 (nt == TelephonyManager.NETWORK_TYPE_1xRTT) || 1190 (nt == TelephonyManager.NETWORK_TYPE_EVDO_0) || 1191 (nt == TelephonyManager.NETWORK_TYPE_EVDO_A) || 1192 (nt == TelephonyManager.NETWORK_TYPE_EVDO_B) || 1193 (nt == TelephonyManager.NETWORK_TYPE_EHRPD)) { 1194 // CDMA variant 1195 return SystemProperties.get("ro.cdma.data_retry_config"); 1196 } else { 1197 // Use GSM varient for all others. 1198 if (forDefault) { 1199 return SystemProperties.get("ro.gsm.data_retry_config"); 1200 } else { 1201 return SystemProperties.get("ro.gsm.2nd_data_retry_config"); 1202 } 1203 } 1204 } 1205 1206 protected void resetAllRetryCounts() { 1207 for (ApnContext ac : mApnContexts.values()) { 1208 ac.setRetryCount(0); 1209 } 1210 for (DataConnection dc : mDataConnections.values()) { 1211 dc.resetRetryCount(); 1212 } 1213 } 1214 1215 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1216 pw.println("DataConnectionTracker:"); 1217 pw.println(" mInternalDataEnabled=" + mInternalDataEnabled); 1218 pw.println(" mUserDataEnabled=" + mUserDataEnabled); 1219 pw.println(" sPolicyDataEnabed=" + sPolicyDataEnabled); 1220 pw.println(" dataEnabled:"); 1221 for(int i=0; i < dataEnabled.length; i++) { 1222 pw.printf(" dataEnabled[%d]=%b\n", i, dataEnabled[i]); 1223 } 1224 pw.flush(); 1225 pw.println(" enabledCount=" + enabledCount); 1226 pw.println(" mRequestedApnType=" + mRequestedApnType); 1227 pw.println(" mPhone=" + mPhone.getPhoneName()); 1228 pw.println(" mActivity=" + mActivity); 1229 pw.println(" mState=" + mState); 1230 pw.println(" mTxPkts=" + mTxPkts); 1231 pw.println(" mRxPkts=" + mRxPkts); 1232 pw.println(" mNetStatPollPeriod=" + mNetStatPollPeriod); 1233 pw.println(" mNetStatPollEnabled=" + mNetStatPollEnabled); 1234 pw.println(" mDataStallTxRxSum=" + mDataStallTxRxSum); 1235 pw.println(" mDataStallAlarmTag=" + mDataStallAlarmTag); 1236 pw.println(" mSentSinceLastRecv=" + mSentSinceLastRecv); 1237 pw.println(" mNoRecvPollCount=" + mNoRecvPollCount); 1238 pw.println(" mIsWifiConnected=" + mIsWifiConnected); 1239 pw.println(" mReconnectIntent=" + mReconnectIntent); 1240 pw.println(" mCidActive=" + mCidActive); 1241 pw.println(" mAutoAttachOnCreation=" + mAutoAttachOnCreation); 1242 pw.println(" mIsScreenOn=" + mIsScreenOn); 1243 pw.println(" mUniqueIdGenerator=" + mUniqueIdGenerator); 1244 pw.flush(); 1245 pw.println(" ***************************************"); 1246 Set<Entry<Integer, DataConnection> > mDcSet = mDataConnections.entrySet(); 1247 pw.println(" mDataConnections: count=" + mDcSet.size()); 1248 for (Entry<Integer, DataConnection> entry : mDcSet) { 1249 pw.printf(" *** mDataConnection[%d] \n", entry.getKey()); 1250 entry.getValue().dump(fd, pw, args); 1251 } 1252 pw.println(" ***************************************"); 1253 pw.flush(); 1254 Set<Entry<String, Integer>> mApnToDcIdSet = mApnToDataConnectionId.entrySet(); 1255 pw.println(" mApnToDataConnectonId size=" + mApnToDcIdSet.size()); 1256 for (Entry<String, Integer> entry : mApnToDcIdSet) { 1257 pw.printf(" mApnToDataConnectonId[%s]=%d\n", entry.getKey(), entry.getValue()); 1258 } 1259 pw.println(" ***************************************"); 1260 pw.flush(); 1261 if (mApnContexts != null) { 1262 Set<Entry<String, ApnContext>> mApnContextsSet = mApnContexts.entrySet(); 1263 pw.println(" mApnContexts size=" + mApnContextsSet.size()); 1264 for (Entry<String, ApnContext> entry : mApnContextsSet) { 1265 entry.getValue().dump(fd, pw, args); 1266 } 1267 pw.println(" ***************************************"); 1268 } else { 1269 pw.println(" mApnContexts=null"); 1270 } 1271 pw.flush(); 1272 pw.println(" mActiveApn=" + mActiveApn); 1273 if (mAllApns != null) { 1274 pw.println(" mAllApns size=" + mAllApns.size()); 1275 for (int i=0; i < mAllApns.size(); i++) { 1276 pw.printf(" mAllApns[%d]: %s\n", i, mAllApns.get(i)); 1277 } 1278 pw.flush(); 1279 } else { 1280 pw.println(" mAllApns=null"); 1281 } 1282 pw.println(" mPreferredApn=" + mPreferredApn); 1283 pw.println(" mIsPsRestricted=" + mIsPsRestricted); 1284 pw.println(" mIsDisposed=" + mIsDisposed); 1285 pw.println(" mIntentReceiver=" + mIntentReceiver); 1286 pw.println(" mDataRoamingSettingObserver=" + mDataRoamingSettingObserver); 1287 pw.flush(); 1288 } 1289 } 1290