DataConnectionTracker.java revision 3918e13b24d4e7ad410089eb615721ca026bec01
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 98 //***** Constants 99 100 /** Retry configuration: A doubling of retry times from 5secs to 30minutes */ 101 protected static final String DEFAULT_DATA_RETRY_CONFIG = "default_randomization=2000," 102 + "5000,10000,20000,40000,80000:5000,160000:5000," 103 + "320000:5000,640000:5000,1280000:5000,1800000:5000"; 104 105 /** Slow poll when attempting connection recovery. */ 106 protected static final int POLL_NETSTAT_SLOW_MILLIS = 5000; 107 /** Default ping deadline, in seconds. */ 108 protected static final int DEFAULT_PING_DEADLINE = 5; 109 /** Default max failure count before attempting to network re-registration. */ 110 protected static final int DEFAULT_MAX_PDP_RESET_FAIL = 3; 111 112 /** 113 * After detecting a potential connection problem, this is the max number 114 * of subsequent polls before attempting a radio reset. At this point, 115 * poll interval is 5 seconds (POLL_NETSTAT_SLOW_MILLIS), so set this to 116 * poll for about 2 more minutes. 117 */ 118 protected static final int NO_RECV_POLL_LIMIT = 24; 119 120 // 1 sec. default polling interval when screen is on. 121 protected static final int POLL_NETSTAT_MILLIS = 1000; 122 // 10 min. default polling interval when screen is off. 123 protected static final int POLL_NETSTAT_SCREEN_OFF_MILLIS = 1000*60*10; 124 // 2 min for round trip time 125 protected static final int POLL_LONGEST_RTT = 120 * 1000; 126 // 10 for packets without ack 127 protected static final int NUMBER_SENT_PACKETS_OF_HANG = 10; 128 // how long to wait before switching back to default APN 129 protected static final int RESTORE_DEFAULT_APN_DELAY = 1 * 60 * 1000; 130 // system property that can override the above value 131 protected static final String APN_RESTORE_DELAY_PROP_NAME = "android.telephony.apn-restore"; 132 // represents an invalid IP address 133 protected static final String NULL_IP = "0.0.0.0"; 134 135 136 // member variables 137 protected PhoneBase phone; 138 protected Activity activity = Activity.NONE; 139 protected State state = State.IDLE; 140 protected Handler mDataConnectionTracker = null; 141 142 143 protected INetStatService netstat; 144 protected long txPkts, rxPkts, sentSinceLastRecv; 145 protected int netStatPollPeriod; 146 protected int mNoRecvPollCount = 0; 147 protected boolean netStatPollEnabled = false; 148 149 // wifi connection status will be updated by sticky intent 150 protected boolean mIsWifiConnected = false; 151 152 /** Intent sent when the reconnect alarm fires. */ 153 protected PendingIntent mReconnectIntent = null; 154 155 /** CID of active data connection */ 156 protected int cidActive; 157 158 /** 159 * Default constructor 160 */ 161 protected DataConnectionTracker(PhoneBase phone) { 162 super(); 163 this.phone = phone; 164 } 165 166 public Activity getActivity() { 167 return activity; 168 } 169 170 public State getState() { 171 return state; 172 } 173 174 public String getStateInString() { 175 switch (state) { 176 case IDLE: return "IDLE"; 177 case INITING: return "INIT"; 178 case CONNECTING: return "CING"; 179 case SCANNING: return "SCAN"; 180 case CONNECTED: return "CNTD"; 181 case DISCONNECTING: return "DING"; 182 case FAILED: return "FAIL"; 183 default: return "ERRO"; 184 } 185 } 186 187 /** 188 * The data connection is expected to be setup while device 189 * 1. has Icc card 190 * 2. registered for data service 191 * 3. user doesn't explicitly disable data service 192 * 4. wifi is not on 193 * 194 * @return false while no data connection if all above requirements are met. 195 */ 196 public abstract boolean isDataConnectionAsDesired(); 197 198 //The data roaming setting is now located in the shared preferences. 199 // See if the requested preference value is the same as that stored in 200 // the shared values. If it is not, then update it. 201 public void setDataOnRoamingEnabled(boolean enabled) { 202 if (getDataOnRoamingEnabled() != enabled) { 203 Settings.Secure.putInt(phone.getContext().getContentResolver(), 204 Settings.Secure.DATA_ROAMING, enabled ? 1 : 0); 205 } 206 Message roamingMsg = phone.getServiceState().getRoaming() ? 207 obtainMessage(EVENT_ROAMING_ON) : obtainMessage(EVENT_ROAMING_OFF); 208 sendMessage(roamingMsg); 209 } 210 211 //Retrieve the data roaming setting from the shared preferences. 212 public boolean getDataOnRoamingEnabled() { 213 try { 214 return Settings.Secure.getInt(phone.getContext().getContentResolver(), 215 Settings.Secure.DATA_ROAMING) > 0; 216 } catch (SettingNotFoundException snfe) { 217 return false; 218 } 219 } 220 221 // abstract handler methods 222 protected abstract void onTrySetupData(String reason); 223 protected abstract void onRoamingOff(); 224 protected abstract void onRoamingOn(); 225 protected abstract void onRadioAvailable(); 226 protected abstract void onRadioOffOrNotAvailable(); 227 protected abstract void onDataSetupComplete(AsyncResult ar); 228 protected abstract void onDisconnectDone(AsyncResult ar); 229 protected abstract void onVoiceCallStarted(); 230 protected abstract void onVoiceCallEnded(); 231 protected abstract void onCleanUpConnection(boolean tearDown, String reason); 232 233 //***** Overridden from Handler 234 public void handleMessage (Message msg) { 235 switch (msg.what) { 236 237 case EVENT_TRY_SETUP_DATA: 238 String reason = null; 239 if (msg.obj instanceof String) { 240 reason = (String)msg.obj; 241 } 242 onTrySetupData(reason); 243 break; 244 245 case EVENT_ROAMING_OFF: 246 onRoamingOff(); 247 break; 248 249 case EVENT_ROAMING_ON: 250 onRoamingOn(); 251 break; 252 253 case EVENT_RADIO_AVAILABLE: 254 onRadioAvailable(); 255 break; 256 257 case EVENT_RADIO_OFF_OR_NOT_AVAILABLE: 258 onRadioOffOrNotAvailable(); 259 break; 260 261 case EVENT_DATA_SETUP_COMPLETE: 262 cidActive = msg.arg1; 263 onDataSetupComplete((AsyncResult) msg.obj); 264 break; 265 266 case EVENT_DISCONNECT_DONE: 267 onDisconnectDone((AsyncResult) msg.obj); 268 break; 269 270 case EVENT_VOICE_CALL_STARTED: 271 onVoiceCallStarted(); 272 break; 273 274 case EVENT_VOICE_CALL_ENDED: 275 onVoiceCallEnded(); 276 break; 277 278 case EVENT_CLEAN_UP_CONNECTION: 279 boolean tearDown = (msg.arg1 == 0) ? false : true; 280 onCleanUpConnection(tearDown, (String)msg.obj); 281 break; 282 283 default: 284 Log.e("DATA", "Unidentified event = " + msg.what); 285 break; 286 } 287 } 288 289 /** 290 * Report the current state of data connectivity (enabled or disabled) 291 * @return {@code false} if data connectivity has been explicitly disabled, 292 * {@code true} otherwise. 293 */ 294 public abstract boolean getDataEnabled(); 295 296 /** 297 * Report on whether data connectivity is enabled 298 * @return {@code false} if data connectivity has been explicitly disabled, 299 * {@code true} otherwise. 300 */ 301 public abstract boolean getAnyDataEnabled(); 302 303 /** 304 * Prevent mobile data connections from being established, 305 * or once again allow mobile data connections. If the state 306 * toggles, then either tear down or set up data, as 307 * appropriate to match the new state. 308 * @param enable indicates whether to enable ({@code true}) or disable ({@code false}) data 309 * @return {@code true} if the operation succeeded 310 */ 311 public abstract boolean setDataEnabled(boolean enable); 312 313 protected abstract void startNetStatPoll(); 314 315 protected abstract void stopNetStatPoll(); 316 317 protected abstract void restartRadio(); 318 319 protected abstract void log(String s); 320} 321