DataConnectionTracker.java revision ad4d9e5bebb5a9ba01c1459d941019887f4a7d6d
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 17package com.android.internal.telephony; 18 19import android.app.PendingIntent; 20import android.os.AsyncResult; 21import android.os.Handler; 22import android.os.INetStatService; 23import android.os.Message; 24import android.os.RemoteException; 25import android.provider.Settings; 26import android.provider.Settings.SettingNotFoundException; 27import android.util.Log; 28 29/** 30 * {@hide} 31 * 32 */ 33public abstract class DataConnectionTracker extends Handler { 34 private static final boolean DBG = true; 35 36 /** 37 * IDLE: ready to start data connection setup, default state 38 * INITING: state of issued setupDefaultPDP() but not finish yet 39 * CONNECTING: state of issued startPppd() but not finish yet 40 * SCANNING: data connection fails with one apn but other apns are available 41 * ready to start data connection on other apns (before INITING) 42 * CONNECTED: IP connection is setup 43 * DISCONNECTING: Connection.disconnect() has been called, but PDP 44 * context is not yet deactivated 45 * FAILED: data connection fail for all apns settings 46 * 47 * getDataConnectionState() maps State to DataState 48 * FAILED or IDLE : DISCONNECTED 49 * INITING or CONNECTING or SCANNING: CONNECTING 50 * CONNECTED : CONNECTED or DISCONNECTING 51 */ 52 public enum State { 53 IDLE, 54 INITING, 55 CONNECTING, 56 SCANNING, 57 CONNECTED, 58 DISCONNECTING, 59 FAILED 60 } 61 62 public enum Activity { 63 NONE, 64 DATAIN, 65 DATAOUT, 66 DATAINANDOUT, 67 DORMANT 68 } 69 70 //***** Event Codes 71 protected static final int EVENT_DATA_SETUP_COMPLETE = 1; 72 protected static final int EVENT_RADIO_AVAILABLE = 3; 73 protected static final int EVENT_RECORDS_LOADED = 4; 74 protected static final int EVENT_TRY_SETUP_DATA = 5; 75 protected static final int EVENT_DATA_STATE_CHANGED = 6; 76 protected static final int EVENT_POLL_PDP = 7; 77 protected static final int EVENT_GET_PDP_LIST_COMPLETE = 11; 78 protected static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 12; 79 protected static final int EVENT_VOICE_CALL_STARTED = 14; 80 protected static final int EVENT_VOICE_CALL_ENDED = 15; 81 protected static final int EVENT_GPRS_DETACHED = 19; 82 protected static final int EVENT_LINK_STATE_CHANGED = 20; 83 protected static final int EVENT_ROAMING_ON = 21; 84 protected static final int EVENT_ROAMING_OFF = 22; 85 protected static final int EVENT_ENABLE_NEW_APN = 23; 86 protected static final int EVENT_RESTORE_DEFAULT_APN = 24; 87 protected static final int EVENT_DISCONNECT_DONE = 25; 88 protected static final int EVENT_GPRS_ATTACHED = 26; 89 protected static final int EVENT_START_NETSTAT_POLL = 27; 90 protected static final int EVENT_START_RECOVERY = 28; 91 protected static final int EVENT_APN_CHANGED = 29; 92 protected static final int EVENT_CDMA_DATA_DETACHED = 30; 93 protected static final int EVENT_NV_READY = 31; 94 protected static final int EVENT_PS_RESTRICT_ENABLED = 32; 95 protected static final int EVENT_PS_RESTRICT_DISABLED = 33; 96 public static final int EVENT_CLEAN_UP_CONNECTION = 34; 97 protected static final int EVENT_CDMA_OTA_PROVISION = 35; 98 99 //***** Constants 100 101 /** Retry configuration: A doubling of retry times from 5secs to 30minutes */ 102 protected static final String DEFAULT_DATA_RETRY_CONFIG = "default_randomization=2000," 103 + "5000,10000,20000,40000,80000:5000,160000:5000," 104 + "320000:5000,640000:5000,1280000:5000,1800000:5000"; 105 106 /** Slow poll when attempting connection recovery. */ 107 protected static final int POLL_NETSTAT_SLOW_MILLIS = 5000; 108 /** Default ping deadline, in seconds. */ 109 protected static final int DEFAULT_PING_DEADLINE = 5; 110 /** Default max failure count before attempting to network re-registration. */ 111 protected static final int DEFAULT_MAX_PDP_RESET_FAIL = 3; 112 113 /** 114 * After detecting a potential connection problem, this is the max number 115 * of subsequent polls before attempting a radio reset. At this point, 116 * poll interval is 5 seconds (POLL_NETSTAT_SLOW_MILLIS), so set this to 117 * poll for about 2 more minutes. 118 */ 119 protected static final int NO_RECV_POLL_LIMIT = 24; 120 121 // 1 sec. default polling interval when screen is on. 122 protected static final int POLL_NETSTAT_MILLIS = 1000; 123 // 10 min. default polling interval when screen is off. 124 protected static final int POLL_NETSTAT_SCREEN_OFF_MILLIS = 1000*60*10; 125 // 2 min for round trip time 126 protected static final int POLL_LONGEST_RTT = 120 * 1000; 127 // 10 for packets without ack 128 protected static final int NUMBER_SENT_PACKETS_OF_HANG = 10; 129 // how long to wait before switching back to default APN 130 protected static final int RESTORE_DEFAULT_APN_DELAY = 1 * 60 * 1000; 131 // system property that can override the above value 132 protected static final String APN_RESTORE_DELAY_PROP_NAME = "android.telephony.apn-restore"; 133 // represents an invalid IP address 134 protected static final String NULL_IP = "0.0.0.0"; 135 136 137 // member variables 138 protected PhoneBase phone; 139 protected Activity activity = Activity.NONE; 140 protected State state = State.IDLE; 141 protected Handler mDataConnectionTracker = null; 142 143 144 protected INetStatService netstat; 145 protected long txPkts, rxPkts, sentSinceLastRecv; 146 protected int netStatPollPeriod; 147 protected int mNoRecvPollCount = 0; 148 protected boolean netStatPollEnabled = false; 149 150 /** Manage the behavior of data retry after failure */ 151 protected final RetryManager mRetryMgr = new RetryManager(); 152 153 // wifi connection status will be updated by sticky intent 154 protected boolean mIsWifiConnected = false; 155 156 /** Intent sent when the reconnect alarm fires. */ 157 protected PendingIntent mReconnectIntent = null; 158 159 /** CID of active data connection */ 160 protected int cidActive; 161 162 /** 163 * Default constructor 164 */ 165 protected DataConnectionTracker(PhoneBase phone) { 166 super(); 167 this.phone = phone; 168 } 169 170 public Activity getActivity() { 171 return activity; 172 } 173 174 public State getState() { 175 return state; 176 } 177 178 public String getStateInString() { 179 switch (state) { 180 case IDLE: return "IDLE"; 181 case INITING: return "INIT"; 182 case CONNECTING: return "CING"; 183 case SCANNING: return "SCAN"; 184 case CONNECTED: return "CNTD"; 185 case DISCONNECTING: return "DING"; 186 case FAILED: return "FAIL"; 187 default: return "ERRO"; 188 } 189 } 190 191 /** 192 * The data connection is expected to be setup while device 193 * 1. has Icc card 194 * 2. registered for data service 195 * 3. user doesn't explicitly disable data service 196 * 4. wifi is not on 197 * 198 * @return false while no data connection if all above requirements are met. 199 */ 200 public abstract boolean isDataConnectionAsDesired(); 201 202 //The data roaming setting is now located in the shared preferences. 203 // See if the requested preference value is the same as that stored in 204 // the shared values. If it is not, then update it. 205 public void setDataOnRoamingEnabled(boolean enabled) { 206 if (getDataOnRoamingEnabled() != enabled) { 207 Settings.Secure.putInt(phone.getContext().getContentResolver(), 208 Settings.Secure.DATA_ROAMING, enabled ? 1 : 0); 209 if (phone.getServiceState().getRoaming()) { 210 if (enabled) { 211 mRetryMgr.resetRetryCount(); 212 } 213 sendMessage(obtainMessage(EVENT_ROAMING_ON)); 214 } 215 } 216 } 217 218 //Retrieve the data roaming setting from the shared preferences. 219 public boolean getDataOnRoamingEnabled() { 220 try { 221 return Settings.Secure.getInt(phone.getContext().getContentResolver(), 222 Settings.Secure.DATA_ROAMING) > 0; 223 } catch (SettingNotFoundException snfe) { 224 return false; 225 } 226 } 227 228 // abstract handler methods 229 protected abstract void onTrySetupData(String reason); 230 protected abstract void onRoamingOff(); 231 protected abstract void onRoamingOn(); 232 protected abstract void onRadioAvailable(); 233 protected abstract void onRadioOffOrNotAvailable(); 234 protected abstract void onDataSetupComplete(AsyncResult ar); 235 protected abstract void onDisconnectDone(AsyncResult ar); 236 protected abstract void onVoiceCallStarted(); 237 protected abstract void onVoiceCallEnded(); 238 protected abstract void onCleanUpConnection(boolean tearDown, String reason); 239 240 //***** Overridden from Handler 241 public void handleMessage (Message msg) { 242 switch (msg.what) { 243 244 case EVENT_TRY_SETUP_DATA: 245 String reason = null; 246 if (msg.obj instanceof String) { 247 reason = (String)msg.obj; 248 } 249 onTrySetupData(reason); 250 break; 251 252 case EVENT_ROAMING_OFF: 253 if (getDataOnRoamingEnabled() == false) { 254 mRetryMgr.resetRetryCount(); 255 } 256 onRoamingOff(); 257 break; 258 259 case EVENT_ROAMING_ON: 260 onRoamingOn(); 261 break; 262 263 case EVENT_RADIO_AVAILABLE: 264 onRadioAvailable(); 265 break; 266 267 case EVENT_RADIO_OFF_OR_NOT_AVAILABLE: 268 onRadioOffOrNotAvailable(); 269 break; 270 271 case EVENT_DATA_SETUP_COMPLETE: 272 cidActive = msg.arg1; 273 onDataSetupComplete((AsyncResult) msg.obj); 274 break; 275 276 case EVENT_DISCONNECT_DONE: 277 onDisconnectDone((AsyncResult) msg.obj); 278 break; 279 280 case EVENT_VOICE_CALL_STARTED: 281 onVoiceCallStarted(); 282 break; 283 284 case EVENT_VOICE_CALL_ENDED: 285 onVoiceCallEnded(); 286 break; 287 288 case EVENT_CLEAN_UP_CONNECTION: 289 boolean tearDown = (msg.arg1 == 0) ? false : true; 290 onCleanUpConnection(tearDown, (String)msg.obj); 291 break; 292 293 default: 294 Log.e("DATA", "Unidentified event = " + msg.what); 295 break; 296 } 297 } 298 299 /** 300 * Report the current state of data connectivity (enabled or disabled) 301 * @return {@code false} if data connectivity has been explicitly disabled, 302 * {@code true} otherwise. 303 */ 304 public abstract boolean getDataEnabled(); 305 306 /** 307 * Report on whether data connectivity is enabled 308 * @return {@code false} if data connectivity has been explicitly disabled, 309 * {@code true} otherwise. 310 */ 311 public abstract boolean getAnyDataEnabled(); 312 313 /** 314 * Prevent mobile data connections from being established, 315 * or once again allow mobile data connections. If the state 316 * toggles, then either tear down or set up data, as 317 * appropriate to match the new state. 318 * @param enable indicates whether to enable ({@code true}) or disable ({@code false}) data 319 * @return {@code true} if the operation succeeded 320 */ 321 public abstract boolean setDataEnabled(boolean enable); 322 323 protected abstract void startNetStatPoll(); 324 325 protected abstract void stopNetStatPoll(); 326 327 protected abstract void restartRadio(); 328 329 protected abstract void log(String s); 330} 331