Merge "Make DataConnection asynchronous." into honeycomb-LTE
This commit is contained in:
@ -39,6 +39,7 @@ public class Protocol {
|
||||
public static final int BASE_WIFI = 0x00020000;
|
||||
public static final int BASE_DHCP = 0x00030000;
|
||||
public static final int BASE_DATA_CONNECTION = 0x00040000;
|
||||
public static final int BASE_DATA_CONNECTION_AC = 0x00041000;
|
||||
public static final int BASE_DATA_CONNECTION_TRACKER = 0x00050000;
|
||||
|
||||
//TODO: define all used protocols
|
||||
|
@ -51,6 +51,8 @@ public class ApnContext {
|
||||
|
||||
DataConnection mDataConnection;
|
||||
|
||||
DataConnectionAc mDataConnectionAc;
|
||||
|
||||
String mReason;
|
||||
|
||||
PendingIntent mReconnectIntent;
|
||||
@ -96,6 +98,17 @@ public class ApnContext {
|
||||
mDataConnection = dataConnection;
|
||||
}
|
||||
|
||||
|
||||
public synchronized DataConnectionAc getDataConnectionAc() {
|
||||
log("getDataConnectionAc dcac=" + mDataConnectionAc);
|
||||
return mDataConnectionAc;
|
||||
}
|
||||
|
||||
public synchronized void setDataConnectionAc(DataConnectionAc dcac) {
|
||||
log("setDataConnectionAc dcac=" + dcac);
|
||||
mDataConnectionAc = dcac;
|
||||
}
|
||||
|
||||
public synchronized ApnSetting getApnSetting() {
|
||||
return mApnSetting;
|
||||
}
|
||||
@ -206,6 +219,11 @@ public class ApnContext {
|
||||
return mDependencyMet.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "state=" + getState() + " apnType=" + mApnType;
|
||||
}
|
||||
|
||||
protected void log(String s) {
|
||||
Log.d(LOG_TAG, "[ApnContext] " + s);
|
||||
}
|
||||
|
@ -17,22 +17,24 @@
|
||||
package com.android.internal.telephony;
|
||||
|
||||
|
||||
import com.android.internal.util.AsyncChannel;
|
||||
import com.android.internal.util.Protocol;
|
||||
import com.android.internal.util.State;
|
||||
import com.android.internal.util.StateMachine;
|
||||
|
||||
import android.net.LinkAddress;
|
||||
import android.net.LinkCapabilities;
|
||||
import android.net.LinkProperties;
|
||||
import android.net.NetworkUtils;
|
||||
import android.net.ProxyProperties;
|
||||
import android.os.AsyncResult;
|
||||
import android.os.Bundle;
|
||||
import android.os.Message;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.os.SystemProperties;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.Inet4Address;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* {@hide}
|
||||
@ -60,6 +62,8 @@ public abstract class DataConnection extends StateMachine {
|
||||
|
||||
protected static Object mCountLock = new Object();
|
||||
protected static int mCount;
|
||||
protected AsyncChannel mAc;
|
||||
|
||||
|
||||
/**
|
||||
* Used internally for saving connecting parameters.
|
||||
@ -75,13 +79,6 @@ public abstract class DataConnection extends StateMachine {
|
||||
public Message onCompletedMsg;
|
||||
}
|
||||
|
||||
/**
|
||||
* An instance used for notification of blockingReset.
|
||||
* TODO: Remove when blockingReset is removed.
|
||||
*/
|
||||
class ResetSynchronouslyLock {
|
||||
}
|
||||
|
||||
/**
|
||||
* Used internally for saving disconnecting parameters.
|
||||
*/
|
||||
@ -90,15 +87,9 @@ public abstract class DataConnection extends StateMachine {
|
||||
this.reason = reason;
|
||||
this.onCompletedMsg = onCompletedMsg;
|
||||
}
|
||||
public DisconnectParams(ResetSynchronouslyLock lockObj) {
|
||||
this.reason = null;
|
||||
this.lockObj = lockObj;
|
||||
}
|
||||
|
||||
public int tag;
|
||||
public String reason;
|
||||
public Message onCompletedMsg;
|
||||
public ResetSynchronouslyLock lockObj;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -188,13 +179,13 @@ public abstract class DataConnection extends StateMachine {
|
||||
}
|
||||
|
||||
// ***** Event codes for driving the state machine
|
||||
protected static final int EVENT_RESET = 1;
|
||||
protected static final int EVENT_CONNECT = 2;
|
||||
protected static final int EVENT_SETUP_DATA_CONNECTION_DONE = 3;
|
||||
protected static final int EVENT_GET_LAST_FAIL_DONE = 4;
|
||||
protected static final int EVENT_DEACTIVATE_DONE = 5;
|
||||
protected static final int EVENT_DISCONNECT = 6;
|
||||
protected static final int EVENT_RIL_CONNECTED = 7;
|
||||
protected static final int BASE = Protocol.BASE_DATA_CONNECTION;
|
||||
protected static final int EVENT_CONNECT = BASE + 0;
|
||||
protected static final int EVENT_SETUP_DATA_CONNECTION_DONE = BASE + 1;
|
||||
protected static final int EVENT_GET_LAST_FAIL_DONE = BASE + 2;
|
||||
protected static final int EVENT_DEACTIVATE_DONE = BASE + 3;
|
||||
protected static final int EVENT_DISCONNECT = BASE + 4;
|
||||
protected static final int EVENT_RIL_CONNECTED = BASE + 5;
|
||||
|
||||
//***** Tag IDs for EventLog
|
||||
protected static final int EVENT_LOG_BAD_DNS_ADDRESS = 50100;
|
||||
@ -313,13 +304,8 @@ public abstract class DataConnection extends StateMachine {
|
||||
AsyncResult.forMessage(msg);
|
||||
msg.sendToTarget();
|
||||
}
|
||||
if (dp.lockObj != null) {
|
||||
synchronized(dp.lockObj) {
|
||||
dp.lockObj.notify();
|
||||
}
|
||||
}
|
||||
|
||||
clearSettings();
|
||||
if (DBG) log("NotifyDisconnectCompleted DisconnectParams=" + dp);
|
||||
}
|
||||
|
||||
protected int getRadioTechnology(int defaultRadioTechnology) {
|
||||
@ -408,6 +394,49 @@ public abstract class DataConnection extends StateMachine {
|
||||
return mRetryMgr.isRetryForever();
|
||||
}
|
||||
|
||||
private AtomicInteger mRefCount = new AtomicInteger(0);
|
||||
|
||||
/**
|
||||
* Set refCount.
|
||||
*
|
||||
* @param val is new refCount
|
||||
*/
|
||||
public void setRefCount(int val) {
|
||||
mRefCount.set(val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get refCount
|
||||
*
|
||||
* @return refCount
|
||||
*/
|
||||
public int getRefCount() {
|
||||
return mRefCount.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return decrement and return refCount
|
||||
*
|
||||
* TODO: Consider using the refCount for defining the
|
||||
* life time of a connection. When this goes zero the
|
||||
* DataConnection could tear itself down.
|
||||
*/
|
||||
public int decAndGetRefCount() {
|
||||
int v = mRefCount.decrementAndGet();
|
||||
if (v < 0) {
|
||||
log("BUG: decAndGetRefCount caused refCount to be < 0");
|
||||
mRefCount.set(0);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return increment and return refCount
|
||||
*/
|
||||
public int incAndGetRefCount() {
|
||||
return mRefCount.incrementAndGet();
|
||||
}
|
||||
|
||||
/*
|
||||
* **************************************************************************
|
||||
* End members owned by DataConnectionTracker
|
||||
@ -498,12 +527,74 @@ public abstract class DataConnection extends StateMachine {
|
||||
AsyncResult ar;
|
||||
|
||||
switch (msg.what) {
|
||||
case EVENT_RESET:
|
||||
if (DBG) log("DcDefaultState: msg.what=EVENT_RESET");
|
||||
clearSettings();
|
||||
if (msg.obj != null) {
|
||||
notifyDisconnectCompleted((DisconnectParams) msg.obj);
|
||||
case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION: {
|
||||
if (mAc != null) {
|
||||
log("Disconnecting to previous connection mAc=" + mAc);
|
||||
mAc.replyToMessage(msg, AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED,
|
||||
AsyncChannel.STATUS_FULL_CONNECTION_REFUSED_ALREADY_CONNECTED);
|
||||
} else {
|
||||
mAc = new AsyncChannel();
|
||||
mAc.connected(null, getHandler(), msg.replyTo);
|
||||
log("DcDefaultState: FULL_CONNECTION reply connected");
|
||||
mAc.replyToMessage(msg, AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED,
|
||||
AsyncChannel.STATUS_SUCCESSFUL, mId, "hi");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AsyncChannel.CMD_CHANNEL_DISCONNECT: {
|
||||
log("CMD_CHANNEL_DISCONNECT");
|
||||
mAc.disconnect();
|
||||
break;
|
||||
}
|
||||
case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
|
||||
log("CMD_CHANNEL_DISCONNECTED");
|
||||
mAc = null;
|
||||
break;
|
||||
}
|
||||
case DataConnectionAc.REQ_IS_INACTIVE: {
|
||||
boolean val = getCurrentState() == mInactiveState;
|
||||
log("REQ_IS_INACTIVE isInactive=" + val);
|
||||
mAc.replyToMessage(msg, DataConnectionAc.RSP_IS_INACTIVE, val ? 1 : 0);
|
||||
break;
|
||||
}
|
||||
case DataConnectionAc.REQ_GET_CID: {
|
||||
log("REQ_GET_CID cid=" + cid);
|
||||
mAc.replyToMessage(msg, DataConnectionAc.RSP_GET_CID, cid);
|
||||
break;
|
||||
}
|
||||
case DataConnectionAc.REQ_GET_APNSETTING: {
|
||||
log("REQ_GET_APNSETTING apnSetting=" + mApn);
|
||||
mAc.replyToMessage(msg, DataConnectionAc.RSP_GET_APNSETTING, mApn);
|
||||
break;
|
||||
}
|
||||
case DataConnectionAc.REQ_GET_LINK_PROPERTIES: {
|
||||
LinkProperties lp = new LinkProperties(mLinkProperties);
|
||||
log("REQ_GET_LINK_PROPERTIES linkProperties" + lp);
|
||||
mAc.replyToMessage(msg, DataConnectionAc.RSP_GET_LINK_PROPERTIES, lp);
|
||||
break;
|
||||
}
|
||||
case DataConnectionAc.REQ_SET_LINK_PROPERTIES_HTTP_PROXY: {
|
||||
ProxyProperties proxy = (ProxyProperties) msg.obj;
|
||||
log("REQ_SET_LINK_PROPERTIES_HTTP_PROXY proxy=" + proxy);
|
||||
mLinkProperties.setHttpProxy(proxy);
|
||||
mAc.replyToMessage(msg, DataConnectionAc.RSP_SET_LINK_PROPERTIES_HTTP_PROXY);
|
||||
break;
|
||||
}
|
||||
case DataConnectionAc.REQ_GET_LINK_CAPABILITIES: {
|
||||
LinkCapabilities lc = new LinkCapabilities(mCapabilities);
|
||||
log("REQ_GET_LINK_CAPABILITIES linkCapabilities" + lc);
|
||||
mAc.replyToMessage(msg, DataConnectionAc.RSP_GET_LINK_CAPABILITIES, lc);
|
||||
break;
|
||||
}
|
||||
case DataConnectionAc.REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE: {
|
||||
Bundle data = msg.getData();
|
||||
mLinkProperties = (LinkProperties) data.get("linkProperties");
|
||||
break;
|
||||
}
|
||||
case DataConnectionAc.REQ_RESET:
|
||||
if (DBG) log("DcDefaultState: msg.what=REQ_RESET");
|
||||
clearSettings();
|
||||
mAc.replyToMessage(msg, DataConnectionAc.RSP_RESET);
|
||||
transitionTo(mInactiveState);
|
||||
break;
|
||||
|
||||
@ -539,7 +630,7 @@ public abstract class DataConnection extends StateMachine {
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
return HANDLED;
|
||||
}
|
||||
}
|
||||
private DcDefaultState mDefaultState = new DcDefaultState();
|
||||
@ -597,14 +688,12 @@ public abstract class DataConnection extends StateMachine {
|
||||
boolean retVal;
|
||||
|
||||
switch (msg.what) {
|
||||
case EVENT_RESET:
|
||||
case DataConnectionAc.REQ_RESET:
|
||||
if (DBG) {
|
||||
log("DcInactiveState: msg.what=EVENT_RESET, ignore we're already reset");
|
||||
log("DcInactiveState: msg.what=RSP_RESET, ignore we're already reset");
|
||||
}
|
||||
if (msg.obj != null) {
|
||||
notifyDisconnectCompleted((DisconnectParams) msg.obj);
|
||||
}
|
||||
retVal = true;
|
||||
mAc.replyToMessage(msg, DataConnectionAc.RSP_RESET);
|
||||
retVal = HANDLED;
|
||||
break;
|
||||
|
||||
case EVENT_CONNECT:
|
||||
@ -613,12 +702,12 @@ public abstract class DataConnection extends StateMachine {
|
||||
cp.tag = mTag;
|
||||
onConnect(cp);
|
||||
transitionTo(mActivatingState);
|
||||
retVal = true;
|
||||
retVal = HANDLED;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (DBG) log("DcInactiveState nothandled msg.what=" + msg.what);
|
||||
retVal = false;
|
||||
retVal = NOT_HANDLED;
|
||||
break;
|
||||
}
|
||||
return retVal;
|
||||
@ -640,7 +729,7 @@ public abstract class DataConnection extends StateMachine {
|
||||
case EVENT_DISCONNECT:
|
||||
if (DBG) log("DcActivatingState deferring msg.what=EVENT_DISCONNECT");
|
||||
deferMessage(msg);
|
||||
retVal = true;
|
||||
retVal = HANDLED;
|
||||
break;
|
||||
|
||||
case EVENT_SETUP_DATA_CONNECTION_DONE:
|
||||
@ -685,7 +774,7 @@ public abstract class DataConnection extends StateMachine {
|
||||
default:
|
||||
throw new RuntimeException("Unknown SetupResult, should not happen");
|
||||
}
|
||||
retVal = true;
|
||||
retVal = HANDLED;
|
||||
break;
|
||||
|
||||
case EVENT_GET_LAST_FAIL_DONE:
|
||||
@ -710,12 +799,12 @@ public abstract class DataConnection extends StateMachine {
|
||||
}
|
||||
}
|
||||
|
||||
retVal = true;
|
||||
retVal = HANDLED;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (DBG) log("DcActivatingState not handled msg.what=" + msg.what);
|
||||
retVal = false;
|
||||
retVal = NOT_HANDLED;
|
||||
break;
|
||||
}
|
||||
return retVal;
|
||||
@ -768,12 +857,12 @@ public abstract class DataConnection extends StateMachine {
|
||||
dp.tag = mTag;
|
||||
tearDownData(dp);
|
||||
transitionTo(mDisconnectingState);
|
||||
retVal = true;
|
||||
retVal = HANDLED;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (DBG) log("DcActiveState nothandled msg.what=" + msg.what);
|
||||
retVal = false;
|
||||
retVal = NOT_HANDLED;
|
||||
break;
|
||||
}
|
||||
return retVal;
|
||||
@ -803,12 +892,12 @@ public abstract class DataConnection extends StateMachine {
|
||||
if (DBG) log("DcDisconnectState EVENT_DEACTIVATE_DONE stale dp.tag="
|
||||
+ dp.tag + " mTag=" + mTag);
|
||||
}
|
||||
retVal = true;
|
||||
retVal = HANDLED;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (DBG) log("DcDisconnectingState not handled msg.what=" + msg.what);
|
||||
retVal = false;
|
||||
retVal = NOT_HANDLED;
|
||||
break;
|
||||
}
|
||||
return retVal;
|
||||
@ -845,7 +934,7 @@ public abstract class DataConnection extends StateMachine {
|
||||
" stale dp.tag=" + cp.tag + ", mTag=" + mTag);
|
||||
}
|
||||
}
|
||||
retVal = true;
|
||||
retVal = HANDLED;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -853,7 +942,7 @@ public abstract class DataConnection extends StateMachine {
|
||||
log("DcDisconnectionErrorCreatingConnection not handled msg.what="
|
||||
+ msg.what);
|
||||
}
|
||||
retVal = false;
|
||||
retVal = NOT_HANDLED;
|
||||
break;
|
||||
}
|
||||
return retVal;
|
||||
@ -865,147 +954,26 @@ public abstract class DataConnection extends StateMachine {
|
||||
// ******* public interface
|
||||
|
||||
/**
|
||||
* Disconnect from the network.
|
||||
*
|
||||
* @param onCompletedMsg is sent with its msg.obj as an AsyncResult object.
|
||||
* With AsyncResult.userObj set to the original msg.obj.
|
||||
*/
|
||||
public void reset(Message onCompletedMsg) {
|
||||
sendMessage(obtainMessage(EVENT_RESET, new DisconnectParams(null, onCompletedMsg)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the connection and wait for it to complete.
|
||||
* TODO: Remove when all callers only need the asynchronous
|
||||
* reset defined above.
|
||||
*/
|
||||
public void resetSynchronously() {
|
||||
ResetSynchronouslyLock lockObj = new ResetSynchronouslyLock();
|
||||
synchronized(lockObj) {
|
||||
sendMessage(obtainMessage(EVENT_RESET, new DisconnectParams(lockObj)));
|
||||
try {
|
||||
lockObj.wait();
|
||||
} catch (InterruptedException e) {
|
||||
log("blockingReset: unexpected interrupted of wait()");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to the apn and return an AsyncResult in onCompletedMsg.
|
||||
* Bring up a connection to the apn and return an AsyncResult in onCompletedMsg.
|
||||
* Used for cellular networks that use Acesss Point Names (APN) such
|
||||
* as GSM networks.
|
||||
*
|
||||
* @param onCompletedMsg is sent with its msg.obj as an AsyncResult object.
|
||||
* With AsyncResult.userObj set to the original msg.obj,
|
||||
* AsyncResult.result = FailCause and AsyncResult.exception = Exception().
|
||||
* @param apn is the Access Point Name to connect to
|
||||
* @param apn is the Access Point Name to bring up a connection to
|
||||
*/
|
||||
public void connect(Message onCompletedMsg, ApnSetting apn) {
|
||||
public void bringUp(Message onCompletedMsg, ApnSetting apn) {
|
||||
sendMessage(obtainMessage(EVENT_CONNECT, new ConnectionParams(apn, onCompletedMsg)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to the apn and return an AsyncResult in onCompletedMsg.
|
||||
*
|
||||
* @param onCompletedMsg is sent with its msg.obj as an AsyncResult object.
|
||||
* With AsyncResult.userObj set to the original msg.obj,
|
||||
* AsyncResult.result = FailCause and AsyncResult.exception = Exception().
|
||||
*/
|
||||
public void connect(Message onCompletedMsg) {
|
||||
sendMessage(obtainMessage(EVENT_CONNECT, new ConnectionParams(null, onCompletedMsg)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect from the network.
|
||||
* Tear down the connection through the apn on the network.
|
||||
*
|
||||
* @param onCompletedMsg is sent with its msg.obj as an AsyncResult object.
|
||||
* With AsyncResult.userObj set to the original msg.obj.
|
||||
*/
|
||||
public void disconnect(String reason, Message onCompletedMsg) {
|
||||
public void tearDown(String reason, Message onCompletedMsg) {
|
||||
sendMessage(obtainMessage(EVENT_DISCONNECT, new DisconnectParams(reason, onCompletedMsg)));
|
||||
}
|
||||
|
||||
// ****** The following are used for debugging.
|
||||
|
||||
/**
|
||||
* TODO: This should be an asynchronous call and we wouldn't
|
||||
* have to use handle the notification in the DcInactiveState.enter.
|
||||
*
|
||||
* @return true if the state machine is in the inactive state.
|
||||
*/
|
||||
public boolean isInactive() {
|
||||
boolean retVal = getCurrentState() == mInactiveState;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: This should be an asynchronous call and we wouldn't
|
||||
* have to use handle the notification in the DcActiveState.enter.
|
||||
*
|
||||
* @return true if the state machine is in the active state.
|
||||
*/
|
||||
public boolean isActive() {
|
||||
boolean retVal = getCurrentState() == mActiveState;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the LinkProperties for the connection.
|
||||
*
|
||||
* @return a copy of the LinkProperties, is never null.
|
||||
*/
|
||||
public LinkProperties getLinkProperties() {
|
||||
return new LinkProperties(mLinkProperties);
|
||||
}
|
||||
|
||||
/**
|
||||
* A capability is an Integer/String pair, the capabilities
|
||||
* are defined in the class LinkSocket#Key.
|
||||
*
|
||||
* @return a copy of this connections capabilities, may be empty but never null.
|
||||
*/
|
||||
public LinkCapabilities getLinkCapabilities() {
|
||||
return new LinkCapabilities(mCapabilities);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the current state as a string.
|
||||
*/
|
||||
public String getStateAsString() {
|
||||
String retVal = getCurrentState().getName();
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the time of when this connection was created.
|
||||
*/
|
||||
public long getConnectionTime() {
|
||||
return createTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the time of the last failure.
|
||||
*/
|
||||
public long getLastFailTime() {
|
||||
return lastFailTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the last cause of failure.
|
||||
*/
|
||||
public FailCause getLastFailCause() {
|
||||
return lastFailCause;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the current ApnSetting
|
||||
*/
|
||||
public ApnSetting getApn() {
|
||||
return mApn;
|
||||
}
|
||||
|
||||
public int getCid() {
|
||||
return cid;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,288 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.internal.telephony;
|
||||
|
||||
import com.android.internal.util.AsyncChannel;
|
||||
import com.android.internal.util.Protocol;
|
||||
|
||||
import android.net.LinkCapabilities;
|
||||
import android.net.LinkProperties;
|
||||
import android.net.ProxyProperties;
|
||||
import android.os.Message;
|
||||
|
||||
/**
|
||||
* AsyncChannel to a DataConnection
|
||||
*/
|
||||
public class DataConnectionAc extends AsyncChannel {
|
||||
private static final boolean DBG = true;
|
||||
private String mLogTag;
|
||||
|
||||
public DataConnection dataConnection;
|
||||
|
||||
public static final int BASE = Protocol.BASE_DATA_CONNECTION_AC;
|
||||
|
||||
public static final int REQ_IS_INACTIVE = BASE + 0;
|
||||
public static final int RSP_IS_INACTIVE = BASE + 1;
|
||||
|
||||
public static final int REQ_GET_CID = BASE + 2;
|
||||
public static final int RSP_GET_CID = BASE + 3;
|
||||
|
||||
public static final int REQ_GET_APNSETTING = BASE + 4;
|
||||
public static final int RSP_GET_APNSETTING = BASE + 5;
|
||||
|
||||
public static final int REQ_GET_LINK_PROPERTIES = BASE + 6;
|
||||
public static final int RSP_GET_LINK_PROPERTIES = BASE + 7;
|
||||
|
||||
public static final int REQ_SET_LINK_PROPERTIES_HTTP_PROXY = BASE + 8;
|
||||
public static final int RSP_SET_LINK_PROPERTIES_HTTP_PROXY = BASE + 9;
|
||||
|
||||
public static final int REQ_GET_LINK_CAPABILITIES = BASE + 10;
|
||||
public static final int RSP_GET_LINK_CAPABILITIES = BASE + 11;
|
||||
|
||||
public static final int REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE = BASE + 12;
|
||||
public static final int RSP_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE = BASE + 13;
|
||||
|
||||
public static final int REQ_RESET = BASE + 14;
|
||||
public static final int RSP_RESET = BASE + 15;
|
||||
|
||||
public DataConnectionAc(DataConnection dc, String logTag) {
|
||||
dataConnection = dc;
|
||||
mLogTag = logTag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Request if the state machine is in the inactive state.
|
||||
* Response {@link #rspIsInactive}
|
||||
*/
|
||||
public void reqIsInactive() {
|
||||
sendMessage(REQ_IS_INACTIVE);
|
||||
if (DBG) log("reqIsInactive");
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate RSP_IS_INACTIVE.
|
||||
*
|
||||
* @return true if the state machine is in the inactive state.
|
||||
*/
|
||||
public boolean rspIsInactive(Message response) {
|
||||
boolean retVal = response.arg1 == 1;
|
||||
if (DBG) log("rspIsInactive=" + retVal);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the state machine is in the inactive state.
|
||||
*/
|
||||
public boolean isInactiveSync() {
|
||||
Message response = sendMessageSynchronously(REQ_IS_INACTIVE);
|
||||
if ((response != null) && (response.what == RSP_IS_INACTIVE)) {
|
||||
return rspIsInactive(response);
|
||||
} else {
|
||||
log("rspIsInactive error response=" + response);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Request the Connection ID.
|
||||
* Response {@link #rspCid}
|
||||
*/
|
||||
public void reqCid() {
|
||||
sendMessage(REQ_GET_CID);
|
||||
if (DBG) log("reqCid");
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate a RSP_GET_CID message and return the cid.
|
||||
*
|
||||
* @param response Message
|
||||
* @return connection id or -1 if an error
|
||||
*/
|
||||
public int rspCid(Message response) {
|
||||
int retVal = response.arg1;
|
||||
if (DBG) log("rspCid=" + retVal);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return connection id or -1 if an error
|
||||
*/
|
||||
public int getCidSync() {
|
||||
Message response = sendMessageSynchronously(REQ_GET_CID);
|
||||
if ((response != null) && (response.what == RSP_GET_CID)) {
|
||||
return rspCid(response);
|
||||
} else {
|
||||
log("rspCid error response=" + response);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Request the connections ApnSetting.
|
||||
* Response {@link #rspApnSetting}
|
||||
*/
|
||||
public void reqApnSetting() {
|
||||
sendMessage(REQ_GET_APNSETTING);
|
||||
if (DBG) log("reqApnSetting");
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate a RSP_APN_SETTING message and return the ApnSetting.
|
||||
*
|
||||
* @param response Message
|
||||
* @return ApnSetting, maybe null
|
||||
*/
|
||||
public ApnSetting rspApnSetting(Message response) {
|
||||
ApnSetting retVal = (ApnSetting) response.obj;
|
||||
if (DBG) log("rspApnSetting=" + retVal);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the connections ApnSetting.
|
||||
*
|
||||
* @return ApnSetting or null if an error
|
||||
*/
|
||||
public ApnSetting getApnSettingSync() {
|
||||
Message response = sendMessageSynchronously(REQ_GET_APNSETTING);
|
||||
if ((response != null) && (response.what == RSP_GET_APNSETTING)) {
|
||||
return rspApnSetting(response);
|
||||
} else {
|
||||
log("getApnSetting error response=" + response);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Request the connections LinkProperties.
|
||||
* Response {@link #rspLinkProperties}
|
||||
*/
|
||||
public void reqLinkProperties() {
|
||||
sendMessage(REQ_GET_LINK_PROPERTIES);
|
||||
if (DBG) log("reqLinkProperties");
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate RSP_GET_LINK_PROPERTIES
|
||||
*
|
||||
* @param response
|
||||
* @return LinkProperties, maybe null.
|
||||
*/
|
||||
public LinkProperties rspLinkProperties(Message response) {
|
||||
LinkProperties retVal = (LinkProperties) response.obj;
|
||||
if (DBG) log("rspLinkProperties=" + retVal);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the connections LinkProperties.
|
||||
*
|
||||
* @return LinkProperties or null if an error
|
||||
*/
|
||||
public LinkProperties getLinkPropertiesSync() {
|
||||
Message response = sendMessageSynchronously(REQ_GET_LINK_PROPERTIES);
|
||||
if ((response != null) && (response.what == RSP_GET_LINK_PROPERTIES)) {
|
||||
return rspLinkProperties(response);
|
||||
} else {
|
||||
log("getLinkProperties error response=" + response);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Request setting the connections LinkProperties.HttpProxy.
|
||||
* Response RSP_SET_LINK_PROPERTIES when complete.
|
||||
*/
|
||||
public void reqSetLinkPropertiesHttpProxy(ProxyProperties proxy) {
|
||||
sendMessage(REQ_SET_LINK_PROPERTIES_HTTP_PROXY, proxy);
|
||||
if (DBG) log("reqSetLinkPropertiesHttpProxy proxy=" + proxy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the connections LinkProperties.HttpProxy
|
||||
*/
|
||||
public void setLinkPropertiesHttpProxySync(ProxyProperties proxy) {
|
||||
Message response =
|
||||
sendMessageSynchronously(REQ_SET_LINK_PROPERTIES_HTTP_PROXY, proxy);
|
||||
if ((response != null) && (response.what == RSP_SET_LINK_PROPERTIES_HTTP_PROXY)) {
|
||||
if (DBG) log("setLinkPropertiesHttpPoxy ok");
|
||||
} else {
|
||||
log("setLinkPropertiesHttpPoxy error response=" + response);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Request the connections LinkCapabilities.
|
||||
* Response {@link #rspLinkCapabilities}
|
||||
*/
|
||||
public void reqLinkCapabilities() {
|
||||
sendMessage(REQ_GET_LINK_CAPABILITIES);
|
||||
if (DBG) log("reqLinkCapabilities");
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate RSP_GET_LINK_CAPABILITIES
|
||||
*
|
||||
* @param response
|
||||
* @return LinkCapabilites, maybe null.
|
||||
*/
|
||||
public LinkCapabilities rspLinkCapabilities(Message response) {
|
||||
LinkCapabilities retVal = (LinkCapabilities) response.obj;
|
||||
if (DBG) log("rspLinkCapabilities=" + retVal);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the connections LinkCapabilities.
|
||||
*
|
||||
* @return LinkCapabilities or null if an error
|
||||
*/
|
||||
public LinkCapabilities getLinkCapabilitiesSync() {
|
||||
Message response = sendMessageSynchronously(REQ_GET_LINK_CAPABILITIES);
|
||||
if ((response != null) && (response.what == RSP_GET_LINK_CAPABILITIES)) {
|
||||
return rspLinkCapabilities(response);
|
||||
} else {
|
||||
log("getLinkCapabilities error response=" + response);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Request the connections LinkCapabilities.
|
||||
* Response RSP_RESET when complete
|
||||
*/
|
||||
public void reqReset() {
|
||||
sendMessage(REQ_RESET);
|
||||
if (DBG) log("reqReset");
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the connection and wait for it to complete.
|
||||
*/
|
||||
public void resetSync() {
|
||||
Message response = sendMessageSynchronously(REQ_RESET);
|
||||
if ((response != null) && (response.what == RSP_RESET)) {
|
||||
if (DBG) log("restSync ok");
|
||||
} else {
|
||||
if (DBG) log("restSync error response=" + response);
|
||||
}
|
||||
}
|
||||
|
||||
private void log(String s) {
|
||||
android.util.Log.d(mLogTag, "DataConnectionAc " + s);
|
||||
}
|
||||
}
|
@ -22,7 +22,6 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
import android.net.IConnectivityManager;
|
||||
import android.net.LinkCapabilities;
|
||||
import android.net.LinkProperties;
|
||||
import android.net.NetworkInfo;
|
||||
@ -32,7 +31,6 @@ import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.os.Messenger;
|
||||
import android.os.ServiceManager;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.provider.Settings;
|
||||
import android.provider.Settings.SettingNotFoundException;
|
||||
@ -40,6 +38,8 @@ import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.util.AsyncChannel;
|
||||
import com.android.internal.util.Protocol;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@ -91,38 +91,39 @@ public abstract class DataConnectionTracker extends Handler {
|
||||
public static String EXTRA_MESSENGER = "EXTRA_MESSENGER";
|
||||
|
||||
/***** Event Codes *****/
|
||||
protected static final int EVENT_DATA_SETUP_COMPLETE = 1;
|
||||
protected static final int EVENT_RADIO_AVAILABLE = 3;
|
||||
protected static final int EVENT_RECORDS_LOADED = 4;
|
||||
protected static final int EVENT_TRY_SETUP_DATA = 5;
|
||||
protected static final int EVENT_DATA_STATE_CHANGED = 6;
|
||||
protected static final int EVENT_POLL_PDP = 7;
|
||||
protected static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 12;
|
||||
protected static final int EVENT_VOICE_CALL_STARTED = 14;
|
||||
protected static final int EVENT_VOICE_CALL_ENDED = 15;
|
||||
protected static final int EVENT_DATA_CONNECTION_DETACHED = 19;
|
||||
protected static final int EVENT_LINK_STATE_CHANGED = 20;
|
||||
protected static final int EVENT_ROAMING_ON = 21;
|
||||
protected static final int EVENT_ROAMING_OFF = 22;
|
||||
protected static final int EVENT_ENABLE_NEW_APN = 23;
|
||||
protected static final int EVENT_RESTORE_DEFAULT_APN = 24;
|
||||
protected static final int EVENT_DISCONNECT_DONE = 25;
|
||||
protected static final int EVENT_DATA_CONNECTION_ATTACHED = 26;
|
||||
protected static final int EVENT_START_NETSTAT_POLL = 27;
|
||||
protected static final int EVENT_START_RECOVERY = 28;
|
||||
protected static final int EVENT_APN_CHANGED = 29;
|
||||
protected static final int EVENT_CDMA_DATA_DETACHED = 30;
|
||||
protected static final int EVENT_NV_READY = 31;
|
||||
protected static final int EVENT_PS_RESTRICT_ENABLED = 32;
|
||||
protected static final int EVENT_PS_RESTRICT_DISABLED = 33;
|
||||
public static final int EVENT_CLEAN_UP_CONNECTION = 34;
|
||||
protected static final int EVENT_CDMA_OTA_PROVISION = 35;
|
||||
protected static final int EVENT_RESTART_RADIO = 36;
|
||||
protected static final int EVENT_SET_INTERNAL_DATA_ENABLE = 37;
|
||||
protected static final int EVENT_RESET_DONE = 38;
|
||||
public static final int CMD_SET_DATA_ENABLE = 39;
|
||||
public static final int EVENT_CLEAN_UP_ALL_CONNECTIONS = 40;
|
||||
public static final int CMD_SET_DEPENDENCY_MET = 41;
|
||||
protected static final int BASE = Protocol.BASE_DATA_CONNECTION_TRACKER;
|
||||
protected static final int EVENT_DATA_SETUP_COMPLETE = BASE + 0;
|
||||
protected static final int EVENT_RADIO_AVAILABLE = BASE + 1;
|
||||
protected static final int EVENT_RECORDS_LOADED = BASE + 2;
|
||||
protected static final int EVENT_TRY_SETUP_DATA = BASE + 3;
|
||||
protected static final int EVENT_DATA_STATE_CHANGED = BASE + 4;
|
||||
protected static final int EVENT_POLL_PDP = BASE + 5;
|
||||
protected static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = BASE + 6;
|
||||
protected static final int EVENT_VOICE_CALL_STARTED = BASE + 7;
|
||||
protected static final int EVENT_VOICE_CALL_ENDED = BASE + 8;
|
||||
protected static final int EVENT_DATA_CONNECTION_DETACHED = BASE + 9;
|
||||
protected static final int EVENT_LINK_STATE_CHANGED = BASE + 10;
|
||||
protected static final int EVENT_ROAMING_ON = BASE + 11;
|
||||
protected static final int EVENT_ROAMING_OFF = BASE + 12;
|
||||
protected static final int EVENT_ENABLE_NEW_APN = BASE + 13;
|
||||
protected static final int EVENT_RESTORE_DEFAULT_APN = BASE + 14;
|
||||
protected static final int EVENT_DISCONNECT_DONE = BASE + 15;
|
||||
protected static final int EVENT_DATA_CONNECTION_ATTACHED = BASE + 16;
|
||||
protected static final int EVENT_START_NETSTAT_POLL = BASE + 17;
|
||||
protected static final int EVENT_START_RECOVERY = BASE + 18;
|
||||
protected static final int EVENT_APN_CHANGED = BASE + 19;
|
||||
protected static final int EVENT_CDMA_DATA_DETACHED = BASE + 20;
|
||||
protected static final int EVENT_NV_READY = BASE + 21;
|
||||
protected static final int EVENT_PS_RESTRICT_ENABLED = BASE + 22;
|
||||
protected static final int EVENT_PS_RESTRICT_DISABLED = BASE + 23;
|
||||
public static final int EVENT_CLEAN_UP_CONNECTION = BASE + 24;
|
||||
protected static final int EVENT_CDMA_OTA_PROVISION = BASE + 25;
|
||||
protected static final int EVENT_RESTART_RADIO = BASE + 26;
|
||||
protected static final int EVENT_SET_INTERNAL_DATA_ENABLE = BASE + 27;
|
||||
protected static final int EVENT_RESET_DONE = BASE + 28;
|
||||
public static final int CMD_SET_DATA_ENABLE = BASE + 29;
|
||||
public static final int EVENT_CLEAN_UP_ALL_CONNECTIONS = BASE + 30;
|
||||
public static final int CMD_SET_DEPENDENCY_MET = BASE + 31;
|
||||
|
||||
/***** Constants *****/
|
||||
|
||||
@ -227,7 +228,7 @@ public abstract class DataConnectionTracker extends Handler {
|
||||
/** indication of our availability (preconditions to trysetupData are met) **/
|
||||
protected boolean mAvailability = false;
|
||||
|
||||
// When false we will not auto attach and manully attaching is required.
|
||||
// When false we will not auto attach and manually attaching is required.
|
||||
protected boolean mAutoAttachOnCreation = false;
|
||||
|
||||
// State of screen
|
||||
@ -235,12 +236,6 @@ public abstract class DataConnectionTracker extends Handler {
|
||||
// really a lower power mode")
|
||||
protected boolean mIsScreenOn = true;
|
||||
|
||||
/** The link properties (dns, gateway, ip, etc) */
|
||||
protected LinkProperties mLinkProperties = new LinkProperties();
|
||||
|
||||
/** The link capabilities */
|
||||
protected LinkCapabilities mLinkCapabilities = new LinkCapabilities();
|
||||
|
||||
/** Allows the generation of unique Id's for DataConnection objects */
|
||||
protected AtomicInteger mUniqueIdGenerator = new AtomicInteger(0);
|
||||
|
||||
@ -248,6 +243,10 @@ public abstract class DataConnectionTracker extends Handler {
|
||||
protected HashMap<Integer, DataConnection> mDataConnections =
|
||||
new HashMap<Integer, DataConnection>();
|
||||
|
||||
/** The data connection async channels */
|
||||
protected HashMap<Integer, DataConnectionAc> mDataConnectionAsyncChannels =
|
||||
new HashMap<Integer, DataConnectionAc>();
|
||||
|
||||
/** Convert an ApnType string to Id (TODO: Use "enumeration" instead of String for ApnType) */
|
||||
protected HashMap<String, Integer> mApnToDataConnectionId =
|
||||
new HashMap<String, Integer>();
|
||||
@ -267,7 +266,6 @@ public abstract class DataConnectionTracker extends Handler {
|
||||
/** Is packet service restricted by network */
|
||||
protected boolean mIsPsRestricted = false;
|
||||
|
||||
|
||||
/* Once disposed dont handle any messages */
|
||||
protected boolean mIsDisposed = false;
|
||||
|
||||
@ -351,6 +349,10 @@ public abstract class DataConnectionTracker extends Handler {
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
for (DataConnectionAc dcac : mDataConnectionAsyncChannels.values()) {
|
||||
dcac.disconnect();
|
||||
}
|
||||
mDataConnectionAsyncChannels.clear();
|
||||
mIsDisposed = true;
|
||||
mPhone.getContext().unregisterReceiver(this.mIntentReceiver);
|
||||
}
|
||||
@ -463,7 +465,13 @@ public abstract class DataConnectionTracker extends Handler {
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
switch (msg.what) {
|
||||
|
||||
case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
|
||||
log("DISCONNECTED_CONNECTED: msg=" + msg);
|
||||
DataConnectionAc dcac = (DataConnectionAc) msg.obj;
|
||||
mDataConnectionAsyncChannels.remove(dcac.dataConnection.getDataConnectionId());
|
||||
dcac.disconnected();
|
||||
break;
|
||||
}
|
||||
case EVENT_ENABLE_NEW_APN:
|
||||
onEnableApn(msg.arg1, msg.arg2);
|
||||
break;
|
||||
@ -528,19 +536,20 @@ public abstract class DataConnectionTracker extends Handler {
|
||||
break;
|
||||
}
|
||||
case EVENT_RESET_DONE: {
|
||||
if (DBG) log("EVENT_RESET_DONE");
|
||||
onResetDone((AsyncResult) msg.obj);
|
||||
break;
|
||||
}
|
||||
case CMD_SET_DATA_ENABLE: {
|
||||
log("CMD_SET_DATA_ENABLE msg=" + msg);
|
||||
boolean enabled = (msg.arg1 == ENABLED) ? true : false;
|
||||
if (DBG) log("CMD_SET_DATA_ENABLE enabled=" + enabled);
|
||||
onSetDataEnabled(enabled);
|
||||
break;
|
||||
}
|
||||
|
||||
case CMD_SET_DEPENDENCY_MET: {
|
||||
log("CMD_SET_DEPENDENCY_MET msg=" + msg);
|
||||
boolean met = (msg.arg1 == ENABLED) ? true : false;
|
||||
if (DBG) log("CMD_SET_DEPENDENCY_MET met=" + met);
|
||||
Bundle bundle = msg.getData();
|
||||
if (bundle != null) {
|
||||
String apnType = (String)bundle.get(APN_TYPE_KEY);
|
||||
@ -552,7 +561,7 @@ public abstract class DataConnectionTracker extends Handler {
|
||||
}
|
||||
|
||||
default:
|
||||
Log.e("DATA", "Unidentified event = " + msg.what);
|
||||
Log.e("DATA", "Unidentified event msg=" + msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -618,7 +627,8 @@ public abstract class DataConnectionTracker extends Handler {
|
||||
protected LinkProperties getLinkProperties(String apnType) {
|
||||
int id = apnTypeToId(apnType);
|
||||
if (isApnIdEnabled(id)) {
|
||||
return new LinkProperties(mLinkProperties);
|
||||
DataConnectionAc dcac = mDataConnectionAsyncChannels.get(id);
|
||||
return dcac.getLinkPropertiesSync();
|
||||
} else {
|
||||
return new LinkProperties();
|
||||
}
|
||||
@ -627,33 +637,13 @@ public abstract class DataConnectionTracker extends Handler {
|
||||
protected LinkCapabilities getLinkCapabilities(String apnType) {
|
||||
int id = apnTypeToId(apnType);
|
||||
if (isApnIdEnabled(id)) {
|
||||
return new LinkCapabilities(mLinkCapabilities);
|
||||
DataConnectionAc dcac = mDataConnectionAsyncChannels.get(id);
|
||||
return dcac.getLinkCapabilitiesSync();
|
||||
} else {
|
||||
return new LinkCapabilities();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the LinkProperties for the connection.
|
||||
*
|
||||
* @param connection
|
||||
* @return a copy of the LinkProperties, is never null.
|
||||
*/
|
||||
protected LinkProperties getLinkProperties(DataConnection connection) {
|
||||
return connection.getLinkProperties();
|
||||
}
|
||||
|
||||
/**
|
||||
* A capability is an Integer/String pair, the capabilities
|
||||
* are defined in the class LinkSocket#Key.
|
||||
*
|
||||
* @param connection
|
||||
* @return a copy of this connections capabilities, may be empty but never null.
|
||||
*/
|
||||
protected LinkCapabilities getLinkCapabilities(DataConnection connection) {
|
||||
return connection.getLinkCapabilities();
|
||||
}
|
||||
|
||||
// tell all active apns of the current condition
|
||||
protected void notifyDataConnection(String reason) {
|
||||
for (int id = 0; id < APN_NUM_TYPES; id++) {
|
||||
|
@ -20,7 +20,6 @@ import android.os.Message;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.telephony.DataConnection;
|
||||
import com.android.internal.telephony.DataConnection.FailCause;
|
||||
import com.android.internal.telephony.Phone;
|
||||
import com.android.internal.telephony.RILConstants;
|
||||
import com.android.internal.telephony.RetryManager;
|
||||
|
@ -37,10 +37,12 @@ import com.android.internal.telephony.CommandsInterface;
|
||||
import com.android.internal.telephony.DataCallState;
|
||||
import com.android.internal.telephony.DataConnection.FailCause;
|
||||
import com.android.internal.telephony.DataConnection;
|
||||
import com.android.internal.telephony.DataConnectionAc;
|
||||
import com.android.internal.telephony.DataConnectionTracker;
|
||||
import com.android.internal.telephony.EventLogTags;
|
||||
import com.android.internal.telephony.RetryManager;
|
||||
import com.android.internal.telephony.Phone;
|
||||
import com.android.internal.util.AsyncChannel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@ -297,14 +299,18 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
|
||||
boolean notificationDeferred = false;
|
||||
for (DataConnection conn : mDataConnections.values()) {
|
||||
if(conn != null) {
|
||||
DataConnectionAc dcac =
|
||||
mDataConnectionAsyncChannels.get(conn.getDataConnectionId());
|
||||
if (tearDown) {
|
||||
if (DBG) log("cleanUpConnection: teardown, call conn.disconnect");
|
||||
conn.disconnect(reason, obtainMessage(EVENT_DISCONNECT_DONE,
|
||||
conn.tearDown(reason, obtainMessage(EVENT_DISCONNECT_DONE,
|
||||
conn.getDataConnectionId(), 0, reason));
|
||||
notificationDeferred = true;
|
||||
} else {
|
||||
if (DBG) log("cleanUpConnection: !tearDown, call conn.resetSynchronously");
|
||||
conn.resetSynchronously();
|
||||
if (dcac != null) {
|
||||
dcac.resetSync();
|
||||
}
|
||||
notificationDeferred = false;
|
||||
}
|
||||
}
|
||||
@ -319,11 +325,13 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
|
||||
}
|
||||
|
||||
private CdmaDataConnection findFreeDataConnection() {
|
||||
for (DataConnection dc : mDataConnections.values()) {
|
||||
if (dc.isInactive()) {
|
||||
return (CdmaDataConnection) dc;
|
||||
for (DataConnectionAc dcac : mDataConnectionAsyncChannels.values()) {
|
||||
if (dcac.isInactiveSync()) {
|
||||
log("found free GsmDataConnection");
|
||||
return (CdmaDataConnection) dcac.dataConnection;
|
||||
}
|
||||
}
|
||||
log("NO free CdmaDataConnection");
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -349,12 +357,12 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
|
||||
}
|
||||
mActiveApn = new ApnSetting(apnId, "", "", "", "", "", "", "", "", "",
|
||||
"", 0, types, "IP", "IP");
|
||||
if (DBG) log("setupData: mActiveApn=" + mActiveApn);
|
||||
if (DBG) log("call conn.bringUp mActiveApn=" + mActiveApn);
|
||||
|
||||
Message msg = obtainMessage();
|
||||
msg.what = EVENT_DATA_SETUP_COMPLETE;
|
||||
msg.obj = reason;
|
||||
conn.connect(msg, mActiveApn);
|
||||
conn.bringUp(msg, mActiveApn);
|
||||
|
||||
setState(State.INITING);
|
||||
notifyDataConnection(reason);
|
||||
@ -653,11 +661,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
|
||||
}
|
||||
|
||||
if (ar.exception == null) {
|
||||
// TODO: We should clear LinkProperties/Capabilities when torn down or disconnected
|
||||
mLinkProperties = getLinkProperties(mPendingDataConnection);
|
||||
mLinkCapabilities = getLinkCapabilities(mPendingDataConnection);
|
||||
|
||||
// everything is setup
|
||||
// Everything is setup
|
||||
notifyDefaultData(reason);
|
||||
} else {
|
||||
FailCause cause = (FailCause) (ar.result);
|
||||
@ -767,6 +771,16 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
|
||||
int id = mUniqueIdGenerator.getAndIncrement();
|
||||
dataConn = CdmaDataConnection.makeDataConnection(mCdmaPhone, id, rm);
|
||||
mDataConnections.put(id, dataConn);
|
||||
DataConnectionAc dcac = new DataConnectionAc(dataConn, LOG_TAG);
|
||||
int status = dcac.fullyConnectSync(mPhone.getContext(), this, dataConn.getHandler());
|
||||
if (status == AsyncChannel.STATUS_SUCCESSFUL) {
|
||||
log("Fully connected");
|
||||
mDataConnectionAsyncChannels.put(dcac.dataConnection.getDataConnectionId(), dcac);
|
||||
} else {
|
||||
log("Could not connect to dcac.dataConnection=" + dcac.dataConnection +
|
||||
" status=" + status);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -897,6 +911,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
|
||||
|
||||
@Override
|
||||
public void handleMessage (Message msg) {
|
||||
if (DBG) log("CdmaDCT handleMessage msg=" + msg);
|
||||
|
||||
if (!mPhone.mIsTheCurrentActivePhone || mIsDisposed) {
|
||||
log("Ignore CDMA msgs since CDMA phone is inactive");
|
||||
|
@ -21,7 +21,6 @@ import android.util.Log;
|
||||
import android.util.Patterns;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.android.internal.telephony.ApnSetting;
|
||||
import com.android.internal.telephony.DataConnection;
|
||||
import com.android.internal.telephony.Phone;
|
||||
import com.android.internal.telephony.PhoneBase;
|
||||
|
@ -53,6 +53,7 @@ import com.android.internal.telephony.ApnContext;
|
||||
import com.android.internal.telephony.ApnSetting;
|
||||
import com.android.internal.telephony.DataCallState;
|
||||
import com.android.internal.telephony.DataConnection;
|
||||
import com.android.internal.telephony.DataConnectionAc;
|
||||
import com.android.internal.telephony.DataConnectionTracker;
|
||||
import com.android.internal.telephony.Phone;
|
||||
import com.android.internal.telephony.PhoneBase;
|
||||
@ -60,6 +61,7 @@ import com.android.internal.telephony.RetryManager;
|
||||
import com.android.internal.telephony.EventLogTags;
|
||||
import com.android.internal.telephony.DataConnection.FailCause;
|
||||
import com.android.internal.telephony.RILConstants;
|
||||
import com.android.internal.util.AsyncChannel;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
@ -119,7 +121,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
|
||||
@Override
|
||||
protected void onActionIntentReconnectAlarm(Intent intent) {
|
||||
log("GPRS reconnect alarm. Previous state was " + mState);
|
||||
if (DBG) log("GPRS reconnect alarm. Previous state was " + mState);
|
||||
|
||||
String reason = intent.getStringExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON);
|
||||
String type = intent.getStringExtra(INTENT_RECONNECT_ALARM_EXTRA_TYPE);
|
||||
@ -224,7 +226,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
boolean possible = (isDataAllowed()
|
||||
&& !(getAnyDataEnabled() && (getOverallState() == State.FAILED)));
|
||||
if (!possible && DBG && isDataAllowed()) {
|
||||
log("Data not possible. No coverage: dataState = " + getOverallState());
|
||||
if (DBG) log("Data not possible. No coverage: dataState = " + getOverallState());
|
||||
}
|
||||
return possible;
|
||||
}
|
||||
@ -319,10 +321,10 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
protected LinkProperties getLinkProperties(String apnType) {
|
||||
ApnContext apnContext = mApnContexts.get(apnType);
|
||||
if (apnContext != null) {
|
||||
DataConnection dataConnection = apnContext.getDataConnection();
|
||||
if (dataConnection != null) {
|
||||
if (DBG) log("get active pdp is not null, return link properites for " + apnType);
|
||||
return dataConnection.getLinkProperties();
|
||||
DataConnectionAc dcac = apnContext.getDataConnectionAc();
|
||||
if (dcac != null) {
|
||||
if (DBG) log("return link properites for " + apnType);
|
||||
return dcac.getLinkPropertiesSync();
|
||||
}
|
||||
}
|
||||
if (DBG) log("return new LinkProperties");
|
||||
@ -333,10 +335,10 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
protected LinkCapabilities getLinkCapabilities(String apnType) {
|
||||
ApnContext apnContext = mApnContexts.get(apnType);
|
||||
if (apnContext!=null) {
|
||||
DataConnection dataConnection = apnContext.getDataConnection();
|
||||
if (dataConnection != null) {
|
||||
DataConnectionAc dataConnectionAc = apnContext.getDataConnectionAc();
|
||||
if (dataConnectionAc != null) {
|
||||
if (DBG) log("get active pdp is not null, return link Capabilities for " + apnType);
|
||||
return dataConnection.getLinkCapabilities();
|
||||
return dataConnectionAc.getLinkCapabilitiesSync();
|
||||
}
|
||||
}
|
||||
if (DBG) log("return new LinkCapabilities");
|
||||
@ -424,6 +426,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
}
|
||||
|
||||
if (!isAnyEnabled) { // Nothing enabled. return IDLE.
|
||||
if (DBG) log( "overall state is IDLE");
|
||||
return State.IDLE;
|
||||
}
|
||||
|
||||
@ -450,34 +453,34 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
*/
|
||||
@Override
|
||||
public synchronized int enableApnType(String apnType) {
|
||||
if (DBG) log("calling enableApnType with type:" + apnType);
|
||||
|
||||
ApnContext apnContext = mApnContexts.get(apnType);
|
||||
if (apnContext == null || !isApnTypeAvailable(apnType)) {
|
||||
if (DBG) log("type not available");
|
||||
if (DBG) log("enableApnType: " + apnType + " is type not available");
|
||||
return Phone.APN_TYPE_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
// If already active, return
|
||||
log("enableApnType(" + apnType + ")" + ", mState(" + apnContext.getState() + ")");
|
||||
if (DBG) log("enableApnType: " + apnType + " mState(" + apnContext.getState() + ")");
|
||||
|
||||
if (apnContext.getState() == State.INITING) {
|
||||
if (DBG) log("return APN_REQUEST_STARTED");
|
||||
if (DBG) log("enableApnType: return APN_REQUEST_STARTED");
|
||||
return Phone.APN_REQUEST_STARTED;
|
||||
}
|
||||
else if (apnContext.getState() == State.CONNECTED) {
|
||||
if (DBG) log("return APN_ALREADY_ACTIVE");
|
||||
if (DBG) log("enableApnType: return APN_ALREADY_ACTIVE");
|
||||
return Phone.APN_ALREADY_ACTIVE;
|
||||
}
|
||||
else if (apnContext.getState() == State.DISCONNECTING) {
|
||||
if (DBG) log("requested APN while disconnecting");
|
||||
if (DBG) log("enableApnType: while disconnecting, return APN_REQUEST_STARTED");
|
||||
apnContext.setPendingAction(ApnContext.PENDING_ACTION_RECONNECT);
|
||||
return Phone.APN_REQUEST_STARTED;
|
||||
}
|
||||
|
||||
if (DBG) log("new apn request for type " + apnType + " is to be handled");
|
||||
setEnabled(apnTypeToId(apnType), true);
|
||||
if (DBG) log("return APN_REQUEST_STARTED");
|
||||
if (DBG) {
|
||||
log("enableApnType: new apn request for type " + apnType +
|
||||
" return APN_REQUEST_STARTED");
|
||||
}
|
||||
return Phone.APN_REQUEST_STARTED;
|
||||
}
|
||||
|
||||
@ -502,7 +505,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
|
||||
@Override
|
||||
public synchronized int disableApnType(String type) {
|
||||
if (DBG) log("calling disableApnType with type:" + type);
|
||||
if (DBG) log("disableApnType:" + type);
|
||||
ApnContext apnContext = mApnContexts.get(type);
|
||||
|
||||
if (apnContext != null) {
|
||||
@ -515,18 +518,19 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
apnContext.setReason(Phone.REASON_DATA_DISABLED);
|
||||
msg.obj = apnContext;
|
||||
sendMessage(msg);
|
||||
if (DBG) log("return APN_REQUEST_STARTED");
|
||||
if (DBG) log("diableApnType: return APN_REQUEST_STARTED");
|
||||
return Phone.APN_REQUEST_STARTED;
|
||||
} else {
|
||||
if (DBG) log("return APN_ALREADY_INACTIVE");
|
||||
if (DBG) log("disableApnType: return APN_ALREADY_INACTIVE");
|
||||
apnContext.setEnabled(false);
|
||||
apnContext.setDataConnection(null);
|
||||
return Phone.APN_ALREADY_INACTIVE;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (DBG)
|
||||
log("no apn context was found, return APN_REQUEST_FAILED");
|
||||
if (DBG) {
|
||||
log("disableApnType: no apn context was found, return APN_REQUEST_FAILED");
|
||||
}
|
||||
return Phone.APN_REQUEST_FAILED;
|
||||
}
|
||||
}
|
||||
@ -583,12 +587,15 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
* We presently believe it is unnecessary to tear down the PDP context
|
||||
* when GPRS detaches, but we should stop the network polling.
|
||||
*/
|
||||
if (DBG) log ("onDataConnectionDetached: stop polling and notify detached");
|
||||
stopNetStatPoll();
|
||||
notifyDataConnection(Phone.REASON_DATA_DETACHED);
|
||||
}
|
||||
|
||||
private void onDataConnectionAttached() {
|
||||
if (DBG) log("onDataConnectionAttached");
|
||||
if (getOverallState() == State.CONNECTED) {
|
||||
if (DBG) log("onDataConnectionAttached: start polling notify attached");
|
||||
startNetStatPoll();
|
||||
notifyDataConnection(Phone.REASON_DATA_ATTACHED);
|
||||
}
|
||||
@ -624,11 +631,40 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
}
|
||||
if (mIsPsRestricted) reason += " - mIsPsRestricted= true";
|
||||
if (!desiredPowerState) reason += " - desiredPowerState= false";
|
||||
log("Data not allowed due to" + reason);
|
||||
if (DBG) log("isDataAllowed: not allowed due to" + reason);
|
||||
}
|
||||
return allowed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Release the apnContext
|
||||
*
|
||||
* @param apnContext
|
||||
* @param tearDown
|
||||
* @return refCount
|
||||
*/
|
||||
private int releaseApnContext(ApnContext apnContext, boolean tearDown) {
|
||||
if (apnContext == null) {
|
||||
if (DBG) loge("releaseApnContext: apnContext null should not happen, ignore");
|
||||
return -1;
|
||||
}
|
||||
DataConnection dc = apnContext.getDataConnection();
|
||||
if (dc == null) {
|
||||
if (DBG) loge("releaseApnContext: apnContext dc == null should not happen, ignore");
|
||||
return -1;
|
||||
}
|
||||
int refCount = dc.decAndGetRefCount();
|
||||
if (DBG) log("releaseApnContext: dec refCount=" + refCount + " tearDown=" + tearDown);
|
||||
if (tearDown && (refCount == 0)) {
|
||||
if (DBG) log("releaseApnContext: tearing down");
|
||||
Message msg = obtainMessage(EVENT_DISCONNECT_DONE, apnContext);
|
||||
apnContext.getDataConnection().tearDown(apnContext.getReason(), msg);
|
||||
}
|
||||
apnContext.setDataConnection(null);
|
||||
apnContext.setDataConnectionAc(null);
|
||||
return refCount;
|
||||
}
|
||||
|
||||
private void setupDataOnReadyApns(String reason) {
|
||||
// Only check for default APN state
|
||||
for (ApnContext apnContext : mApnContexts.values()) {
|
||||
@ -651,9 +687,8 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
|
||||
private boolean trySetupData(String reason, String type) {
|
||||
if (DBG) {
|
||||
log("***trySetupData for type:" + type +
|
||||
" due to " + (reason == null ? "(unspecified)" : reason) +
|
||||
" isPsRestricted=" + mIsPsRestricted);
|
||||
log("trySetupData: " + type + " due to " + (reason == null ? "(unspecified)" : reason)
|
||||
+ " isPsRestricted=" + mIsPsRestricted);
|
||||
}
|
||||
|
||||
if (type == null) {
|
||||
@ -663,18 +698,16 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
ApnContext apnContext = mApnContexts.get(type);
|
||||
|
||||
if (apnContext == null ){
|
||||
if (DBG) log("new apn context for type:" + type);
|
||||
if (DBG) log("trySetupData new apn context for type:" + type);
|
||||
apnContext = new ApnContext(type, LOG_TAG);
|
||||
mApnContexts.put(type, apnContext);
|
||||
}
|
||||
apnContext.setReason(reason);
|
||||
|
||||
return trySetupData(apnContext);
|
||||
|
||||
}
|
||||
|
||||
private boolean trySetupData(ApnContext apnContext) {
|
||||
|
||||
if (DBG) {
|
||||
log("trySetupData for type:" + apnContext.getApnType() +
|
||||
" due to " + apnContext.getReason());
|
||||
@ -687,7 +720,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
apnContext.setState(State.CONNECTED);
|
||||
mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
|
||||
|
||||
log("(fix?) We're on the simulator; assuming data is connected");
|
||||
log("trySetupData: (fix?) We're on the simulator; assuming data is connected");
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -699,13 +732,15 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
if (apnContext.getState() == State.IDLE) {
|
||||
ArrayList<ApnSetting> waitingApns = buildWaitingApns(apnContext.getApnType());
|
||||
if (waitingApns.isEmpty()) {
|
||||
if (DBG) log("No APN found");
|
||||
if (DBG) log("trySetupData: No APN found");
|
||||
notifyNoData(GsmDataConnection.FailCause.MISSING_UNKNOWN_APN, apnContext);
|
||||
notifyOffApnsOfAvailability(apnContext.getReason(), false);
|
||||
return false;
|
||||
} else {
|
||||
apnContext.setWaitingApns(waitingApns);
|
||||
log ("Create from mAllApns : " + apnListToString(mAllApns));
|
||||
if (DBG) {
|
||||
log ("trySetupData: Create from mAllApns : " + apnListToString(mAllApns));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -735,7 +770,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
|
||||
for (ApnContext apnContext : mApnContexts.values()) {
|
||||
if (!apnContext.isReady()) {
|
||||
if (DBG) log("notify disconnected for type:" + apnContext.getApnType());
|
||||
if (DBG) log("notifyOffApnOfAvailability type:" + apnContext.getApnType());
|
||||
mPhone.notifyDataConnection(reason != null ? reason : apnContext.getReason(),
|
||||
apnContext.getApnType(),
|
||||
Phone.DataState.DISCONNECTED);
|
||||
@ -753,7 +788,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
* @param reason reason for the clean up.
|
||||
*/
|
||||
protected void cleanUpAllConnections(boolean tearDown, String reason) {
|
||||
if (DBG) log("Clean up all connections due to " + reason);
|
||||
if (DBG) log("cleanUpAllConnections: tearDown=" + tearDown + " reason=" + reason);
|
||||
|
||||
for (ApnContext apnContext : mApnContexts.values()) {
|
||||
apnContext.setReason(reason);
|
||||
@ -784,11 +819,13 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
private void cleanUpConnection(boolean tearDown, ApnContext apnContext) {
|
||||
|
||||
if (apnContext == null) {
|
||||
if (DBG) log("apn context is null");
|
||||
if (DBG) log("cleanUpConnection: apn context is null");
|
||||
return;
|
||||
}
|
||||
|
||||
if (DBG) log("Clean up connection due to " + apnContext.getReason());
|
||||
if (DBG) {
|
||||
log("cleanUpConnection: tearDown=" + tearDown + " reason=" + apnContext.getReason());
|
||||
}
|
||||
|
||||
// Clear the reconnect alarm, if set.
|
||||
if (apnContext.getReconnectIntent() != null) {
|
||||
@ -799,24 +836,26 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
}
|
||||
|
||||
if (apnContext.getState() == State.IDLE || apnContext.getState() == State.DISCONNECTING) {
|
||||
if (DBG) log("state is in " + apnContext.getState());
|
||||
if (DBG) log("cleanUpConnection: state= " + apnContext.getState());
|
||||
return;
|
||||
}
|
||||
|
||||
if (apnContext.getState() == State.FAILED) {
|
||||
if (DBG) log("state is in FAILED");
|
||||
if (DBG) log("cleanUpConnection: state is in FAILED");
|
||||
apnContext.setState(State.IDLE);
|
||||
return;
|
||||
}
|
||||
|
||||
DataConnection conn = apnContext.getDataConnection();
|
||||
if (conn != null) {
|
||||
DataConnectionAc dcac = mDataConnectionAsyncChannels.get(conn.getDataConnectionId());
|
||||
apnContext.setState(State.DISCONNECTING);
|
||||
if (tearDown) {
|
||||
Message msg = obtainMessage(EVENT_DISCONNECT_DONE, apnContext);
|
||||
conn.disconnect(apnContext.getReason(), msg);
|
||||
releaseApnContext(apnContext, tearDown);
|
||||
} else {
|
||||
conn.resetSynchronously();
|
||||
if (dcac != null) {
|
||||
dcac.resetSync();
|
||||
}
|
||||
apnContext.setState(State.IDLE);
|
||||
mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
|
||||
}
|
||||
@ -871,27 +910,31 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
}
|
||||
|
||||
private GsmDataConnection findFreeDataConnection() {
|
||||
for (DataConnection dc : mDataConnections.values()) {
|
||||
if (dc.isInactive()) {
|
||||
log("found free GsmDataConnection");
|
||||
return (GsmDataConnection) dc;
|
||||
for (DataConnectionAc dcac : mDataConnectionAsyncChannels.values()) {
|
||||
if (dcac.isInactiveSync()) {
|
||||
log("findFreeDataConnection: found free GsmDataConnection");
|
||||
return (GsmDataConnection) dcac.dataConnection;
|
||||
}
|
||||
}
|
||||
log("NO free GsmDataConnection");
|
||||
log("findFreeDataConnection: NO free GsmDataConnection");
|
||||
return null;
|
||||
}
|
||||
|
||||
protected GsmDataConnection findReadyDataConnection(ApnSetting apn) {
|
||||
if (DBG)
|
||||
log("findReadyDataConnection for apn string <" +
|
||||
log("findReadyDataConnection: apn string <" +
|
||||
(apn!=null?(apn.toString()):"null") +">");
|
||||
for (DataConnection conn : mDataConnections.values()) {
|
||||
GsmDataConnection dc = (GsmDataConnection) conn;
|
||||
if (DBG) log("dc apn string <" +
|
||||
(dc.getApn() != null ? (dc.getApn().toString()) : "null") + ">");
|
||||
if (dc.getApn() != null && apn != null
|
||||
&& dc.getApn().toString().equals(apn.toString())) {
|
||||
return dc;
|
||||
if (apn == null) {
|
||||
return null;
|
||||
}
|
||||
for (DataConnectionAc dcac : mDataConnectionAsyncChannels.values()) {
|
||||
ApnSetting apnSetting = dcac.getApnSettingSync();
|
||||
if (DBG) {
|
||||
log("findReadyDataConnection: dc apn string <" +
|
||||
(apnSetting != null ? (apnSetting.toString()) : "null") + ">");
|
||||
}
|
||||
if ((apnSetting != null) && TextUtils.equals(apnSetting.toString(), apn.toString())) {
|
||||
return (GsmDataConnection) dcac.dataConnection;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@ -899,7 +942,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
|
||||
|
||||
private boolean setupData(ApnContext apnContext) {
|
||||
if (DBG) log("enter setupData!");
|
||||
if (DBG) log("setupData: apnContext=" + apnContext);
|
||||
ApnSetting apn;
|
||||
GsmDataConnection dc;
|
||||
|
||||
@ -920,7 +963,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
}
|
||||
|
||||
if (dc == null) {
|
||||
dc = createDataConnection(apnContext);
|
||||
dc = createDataConnection(apnContext.getApnType());
|
||||
}
|
||||
|
||||
if (dc == null) {
|
||||
@ -928,17 +971,19 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
return false;
|
||||
}
|
||||
|
||||
apnContext.setApnSetting(apn);
|
||||
apnContext.setDataConnection(dc);
|
||||
dc.setProfileId( profileId );
|
||||
dc.setActiveApnType(apnContext.getApnType());
|
||||
int refCount = dc.incAndGetRefCount();
|
||||
if (DBG) log("setupData: init dc and apnContext refCount=" + refCount);
|
||||
DataConnectionAc dcac = mDataConnectionAsyncChannels.get(dc.getDataConnectionId());
|
||||
apnContext.setDataConnectionAc(mDataConnectionAsyncChannels.get(dc.getDataConnectionId()));
|
||||
apnContext.setApnSetting(apn);
|
||||
apnContext.setDataConnection(dc);
|
||||
|
||||
Message msg = obtainMessage();
|
||||
msg.what = EVENT_DATA_SETUP_COMPLETE;
|
||||
msg.obj = apnContext;
|
||||
|
||||
if (DBG) log("dc connect!");
|
||||
dc.connect(msg, apn);
|
||||
dc.bringUp(msg, apn);
|
||||
|
||||
apnContext.setState(State.INITING);
|
||||
mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
|
||||
@ -981,7 +1026,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
|
||||
// TODO: It'd be nice to only do this if the changed entrie(s)
|
||||
// match the current operator.
|
||||
if (DBG) log("onApnChanged createAllApnList and cleanUpAllConnections");
|
||||
if (DBG) log("onApnChanged: createAllApnList and cleanUpAllConnections");
|
||||
createAllApnList();
|
||||
cleanUpAllConnections(isConnected, Phone.REASON_APN_CHANGED);
|
||||
if (!isConnected) {
|
||||
@ -998,25 +1043,30 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
private void onDataStateChanged (AsyncResult ar) {
|
||||
ArrayList<DataCallState> dataCallStates;
|
||||
|
||||
if (DBG) log("onDataStateChanged(ar) E");
|
||||
dataCallStates = (ArrayList<DataCallState>)(ar.result);
|
||||
|
||||
if (ar.exception != null) {
|
||||
// This is probably "radio not available" or something
|
||||
// of that sort. If so, the whole connection is going
|
||||
// to come down soon anyway
|
||||
if (DBG) log("onDataStateChanged(ar): exception; likely radio not available, ignore");
|
||||
return;
|
||||
}
|
||||
|
||||
for (ApnContext apnContext : mApnContexts.values()) {
|
||||
onDataStateChanged(dataCallStates, apnContext);
|
||||
}
|
||||
if (DBG) log("onDataStateChanged(ar) X");
|
||||
}
|
||||
|
||||
private void onDataStateChanged (ArrayList<DataCallState> dataCallStates,
|
||||
ApnContext apnContext) {
|
||||
if (DBG) log("onDataStateChanged(dataCallState, apnContext): apnContext=" + apnContext);
|
||||
|
||||
if (apnContext == null) {
|
||||
// Should not happen
|
||||
if (DBG) log("onDataStateChanged(dataCallState, apnContext): ignore apnContext=null");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1027,28 +1077,37 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
// context is still listed with active = false, which
|
||||
// makes it hard to distinguish an activating context from
|
||||
// an activated-and-then deactivated one.
|
||||
if (!dataCallStatesHasCID(dataCallStates, apnContext.getDataConnection().getCid())) {
|
||||
DataConnectionAc dcac = apnContext.getDataConnectionAc();
|
||||
if (dcac == null) {
|
||||
if (DBG) log("onDataStateChanged(dataCallState, apnContext): dcac==null BAD NEWS");
|
||||
return;
|
||||
}
|
||||
int cid = dcac.getCidSync();
|
||||
if (!dataCallStatesHasCID(dataCallStates, cid)) {
|
||||
// It looks like the PDP context has deactivated.
|
||||
// Tear everything down and try to reconnect.
|
||||
|
||||
Log.i(LOG_TAG, "PDP connection has dropped. Reconnecting");
|
||||
|
||||
if (DBG) {
|
||||
log("onDataStateChanged(dataCallStates,apnContext) " +
|
||||
"PDP connection has dropped. Reconnecting");
|
||||
}
|
||||
// Add an event log when the network drops PDP
|
||||
int cid = getCellLocationId();
|
||||
EventLog.writeEvent(EventLogTags.PDP_NETWORK_DROP, cid,
|
||||
int cellLocationId = getCellLocationId();
|
||||
EventLog.writeEvent(EventLogTags.PDP_NETWORK_DROP, cellLocationId,
|
||||
TelephonyManager.getDefault().getNetworkType());
|
||||
|
||||
cleanUpConnection(true, apnContext);
|
||||
return;
|
||||
} else if (!dataCallStatesHasActiveCID(dataCallStates,
|
||||
apnContext.getDataConnection().getCid())) {
|
||||
apnContext.getDataConnectionAc().getCidSync())) {
|
||||
|
||||
Log.i(LOG_TAG, "PDP connection has dropped (active=false case). "
|
||||
+ " Reconnecting");
|
||||
if (DBG) {
|
||||
log("onDataStateChanged(dataCallStates,apnContext) " +
|
||||
"PDP connection has dropped (active=false case). Reconnecting");
|
||||
}
|
||||
|
||||
// Log the network drop on the event log.
|
||||
int cid = getCellLocationId();
|
||||
EventLog.writeEvent(EventLogTags.PDP_NETWORK_DROP, cid,
|
||||
int cellLocationId = getCellLocationId();
|
||||
EventLog.writeEvent(EventLogTags.PDP_NETWORK_DROP, cellLocationId,
|
||||
TelephonyManager.getDefault().getNetworkType());
|
||||
|
||||
cleanUpConnection(true, apnContext);
|
||||
@ -1057,9 +1116,10 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
}
|
||||
|
||||
private void notifyDefaultData(ApnContext apnContext) {
|
||||
if (DBG)
|
||||
log("notifyDefaultData for type: " + apnContext.getApnType()
|
||||
if (DBG) {
|
||||
log("notifyDefaultData: type=" + apnContext.getApnType()
|
||||
+ ", reason:" + apnContext.getReason());
|
||||
}
|
||||
apnContext.setState(State.CONNECTED);
|
||||
// setState(State.CONNECTED);
|
||||
mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
|
||||
@ -1091,21 +1151,25 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
if (mPdpResetCount < maxPdpReset) {
|
||||
mPdpResetCount++;
|
||||
EventLog.writeEvent(EventLogTags.PDP_RADIO_RESET, mSentSinceLastRecv);
|
||||
if (DBG) log("doRecovery() cleanup all connections mPdpResetCount < max");
|
||||
cleanUpAllConnections(true, Phone.REASON_PDP_RESET);
|
||||
} else {
|
||||
mPdpResetCount = 0;
|
||||
EventLog.writeEvent(EventLogTags.PDP_REREGISTER_NETWORK, mSentSinceLastRecv);
|
||||
if (DBG) log("doRecovery() re-register getting preferred network type");
|
||||
mPhone.getServiceStateTracker().reRegisterNetwork(null);
|
||||
}
|
||||
// TODO: Add increasingly drastic recovery steps, eg,
|
||||
// reset the radio, reset the device.
|
||||
} else {
|
||||
if (DBG) log("doRecovery(): ignore, we're not connected");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startNetStatPoll() {
|
||||
if (getOverallState() == State.CONNECTED && mNetStatPollEnabled == false) {
|
||||
log("[DataConnection] Start poll NetStat");
|
||||
if (DBG) log("startNetStatPoll");
|
||||
resetPollStats();
|
||||
mNetStatPollEnabled = true;
|
||||
mPollNetStat.run();
|
||||
@ -1116,12 +1180,12 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
protected void stopNetStatPoll() {
|
||||
mNetStatPollEnabled = false;
|
||||
removeCallbacks(mPollNetStat);
|
||||
log("[DataConnection] Stop poll NetStat");
|
||||
if (DBG) log("stopNetStatPoll");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void restartRadio() {
|
||||
log("************TURN OFF RADIO**************");
|
||||
if (DBG) log("restartRadio: ************TURN OFF RADIO**************");
|
||||
cleanUpAllConnections(true, Phone.REASON_RADIO_TURNED_OFF);
|
||||
mPhone.getServiceStateTracker().powerOffRadioSafely(this);
|
||||
/* Note: no need to call setRadioPower(true). Assuming the desired
|
||||
@ -1202,7 +1266,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
if (mNoRecvPollCount < noRecvPollLimit) {
|
||||
// It's possible the PDP context went down and we weren't notified.
|
||||
// Start polling the context list in an attempt to recover.
|
||||
if (DBG) log("no DATAIN in a while; polling PDP");
|
||||
if (DBG) log("Polling: no DATAIN in a while; polling PDP");
|
||||
mPhone.mCM.getDataCallList(obtainMessage(EVENT_DATA_STATE_CHANGED));
|
||||
|
||||
mNoRecvPollCount++;
|
||||
@ -1212,7 +1276,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
Settings.Secure.PDP_WATCHDOG_ERROR_POLL_INTERVAL_MS,
|
||||
POLL_NETSTAT_SLOW_MILLIS);
|
||||
} else {
|
||||
if (DBG) log("Sent " + String.valueOf(mSentSinceLastRecv) +
|
||||
if (DBG) log("Polling: Sent " + String.valueOf(mSentSinceLastRecv) +
|
||||
" pkts since last received start recovery process");
|
||||
stopNetStatPoll();
|
||||
sendMessage(obtainMessage(EVENT_START_RECOVERY));
|
||||
@ -1262,14 +1326,12 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
|
||||
private void reconnectAfterFail(FailCause lastFailCauseCode, ApnContext apnContext) {
|
||||
if (apnContext == null) {
|
||||
Log.d(LOG_TAG, "It is impossible");
|
||||
loge("reconnectAfterFail: apnContext == null, impossible");
|
||||
return;
|
||||
}
|
||||
if (apnContext.getState() == State.FAILED) {
|
||||
if (!apnContext.getDataConnection().isRetryNeeded()) {
|
||||
if (!apnContext.getApnType().equals(Phone.APN_TYPE_DEFAULT)){
|
||||
// if no more retries on a secondary APN attempt, tell the world and revert.
|
||||
apnContext.setDataConnection(null);
|
||||
if (!apnContext.getApnType().equals(Phone.APN_TYPE_DEFAULT)) {
|
||||
notifyDataConnection(Phone.REASON_APN_FAILED);
|
||||
return;
|
||||
}
|
||||
@ -1278,7 +1340,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
apnContext.getDataConnection().retryForeverUsingLastTimeout();
|
||||
} else {
|
||||
// Try to Re-register to the network.
|
||||
log("PDP activate failed, Reregistering to the network");
|
||||
if (DBG) log("reconnectAfterFail: activate failed, Reregistering to network");
|
||||
mReregisterOnReconnectFailure = true;
|
||||
mPhone.getServiceStateTracker().reRegisterNetwork(null);
|
||||
apnContext.getDataConnection().resetRetryCount();
|
||||
@ -1287,8 +1349,10 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
}
|
||||
|
||||
int nextReconnectDelay = apnContext.getDataConnection().getRetryTimer();
|
||||
log("PDP activate failed. Scheduling next attempt for "
|
||||
if (DBG) {
|
||||
log("reconnectAfterFail: activate failed. Scheduling next attempt for "
|
||||
+ (nextReconnectDelay / 1000) + "s");
|
||||
}
|
||||
|
||||
AlarmManager am =
|
||||
(AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
|
||||
@ -1305,8 +1369,10 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
apnContext.getDataConnection().increaseRetryCount();
|
||||
|
||||
if (!shouldPostNotification(lastFailCauseCode)) {
|
||||
Log.d(LOG_TAG, "NOT Posting GPRS Unavailable notification "
|
||||
if (DBG) {
|
||||
log("reconnectAfterFail: NOT Posting GPRS Unavailable notification "
|
||||
+ "-- likely transient error");
|
||||
}
|
||||
} else {
|
||||
notifyNoData(lastFailCauseCode, apnContext);
|
||||
}
|
||||
@ -1315,7 +1381,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
|
||||
private void notifyNoData(GsmDataConnection.FailCause lastFailCauseCode,
|
||||
ApnContext apnContext) {
|
||||
if (DBG) log( "notifyNoData for type:" + apnContext.getApnType());
|
||||
if (DBG) log( "notifyNoData: type=" + apnContext.getApnType());
|
||||
apnContext.setState(State.FAILED);
|
||||
if (lastFailCauseCode.isPermanentFail()
|
||||
&& (!apnContext.getApnType().equals(Phone.APN_TYPE_DEFAULT))) {
|
||||
@ -1327,7 +1393,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
if (DBG) log("onRecordsLoaded: createAllApnList");
|
||||
createAllApnList();
|
||||
if (mRadioAvailable) {
|
||||
if (DBG) log("onRecordsLoaded, notifying data availability");
|
||||
if (DBG) log("onRecordsLoaded: notifying data availability");
|
||||
notifyDataAvailability(null);
|
||||
}
|
||||
setupDataOnReadyApns(Phone.REASON_SIM_LOADED);
|
||||
@ -1337,7 +1403,8 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
protected void onSetDependencyMet(String apnType, boolean met) {
|
||||
ApnContext apnContext = mApnContexts.get(apnType);
|
||||
if (apnContext == null) {
|
||||
log("ApnContext not found in onSetDependencyMet(" + apnType + ", " + met + ")");
|
||||
loge("onSetDependencyMet: ApnContext not found in onSetDependencyMet(" +
|
||||
apnType + ", " + met + ")");
|
||||
return;
|
||||
}
|
||||
applyNewState(apnContext, apnContext.isEnabled(), met);
|
||||
@ -1373,12 +1440,15 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
}
|
||||
trySetup = true;
|
||||
} else {
|
||||
// TODO send notifications
|
||||
if (DBG) {
|
||||
log("Found existing connection for " + apnContext.getApnType() +
|
||||
": " + conn);
|
||||
}
|
||||
int refCount = conn.incAndGetRefCount();
|
||||
apnContext.setDataConnection(conn);
|
||||
apnContext.setDataConnectionAc(
|
||||
mDataConnectionAsyncChannels.get(conn.getDataConnectionId()));
|
||||
if (DBG) {
|
||||
log("applyNewState: Found existing connection for " +
|
||||
apnContext.getApnType() + " inc refCount=" + refCount +
|
||||
" conn=" + conn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1395,9 +1465,16 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
DataConnection conn = c.getDataConnection();
|
||||
if (conn != null) {
|
||||
ApnSetting apnSetting = c.getApnSetting();
|
||||
if (apnSetting != null && apnSetting.canHandleType(apnType)) return conn;
|
||||
if (apnSetting != null && apnSetting.canHandleType(apnType)) {
|
||||
if (DBG) {
|
||||
log("checkForConnectionForApnContext: apnContext=" + apnContext +
|
||||
" found conn=" + conn);
|
||||
}
|
||||
return conn;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (DBG) log("checkForConnectionForApnContext: apnContext=" + apnContext + " NO conn");
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -1405,43 +1482,47 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
protected void onEnableApn(int apnId, int enabled) {
|
||||
ApnContext apnContext = mApnContexts.get(apnIdToType(apnId));
|
||||
if (apnContext == null) {
|
||||
log("ApnContext not found in onEnableApn(" + apnId + ", " + enabled + ")");
|
||||
loge("onEnableApn(" + apnId + ", " + enabled + "): NO ApnContext");
|
||||
return;
|
||||
}
|
||||
// TODO change our retry manager to use the appropriate numbers for the new APN
|
||||
log("onEnableApn with ApnContext E");
|
||||
if (DBG) log("onEnableApn: apnContext=" + apnContext + " call applyNewState");
|
||||
applyNewState(apnContext, enabled == ENABLED, apnContext.getDependencyMet());
|
||||
}
|
||||
|
||||
@Override
|
||||
// TODO: We shouldnt need this.
|
||||
protected boolean onTrySetupData(String reason) {
|
||||
if (DBG) log("onTrySetupData: reason=" + reason);
|
||||
setupDataOnReadyApns(reason);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected boolean onTrySetupData(ApnContext apnContext) {
|
||||
if (DBG) log("onTrySetupData: apnContext=" + apnContext);
|
||||
return trySetupData(apnContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRoamingOff() {
|
||||
if (DBG) log("onRoamingOff");
|
||||
setupDataOnReadyApns(Phone.REASON_ROAMING_OFF);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRoamingOn() {
|
||||
if (getDataOnRoamingEnabled()) {
|
||||
if (DBG) log("onRoamingOn: setup data on roaming");
|
||||
setupDataOnReadyApns(Phone.REASON_ROAMING_ON);
|
||||
} else {
|
||||
if (DBG) log("Tear down data connection on roaming.");
|
||||
if (DBG) log("onRoamingOn: Tear down data connection on roaming.");
|
||||
cleanUpAllConnections(true, Phone.REASON_ROAMING_ON);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRadioAvailable() {
|
||||
|
||||
if (DBG) log("onRadioAvailable");
|
||||
mRadioAvailable = true;
|
||||
if (mPhone.getSimulatedRadioControl() != null) {
|
||||
// Assume data is connected on the simulator
|
||||
@ -1449,7 +1530,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
// setState(State.CONNECTED);
|
||||
notifyDataConnection(null);
|
||||
|
||||
log("We're on the simulator; assuming data is connected");
|
||||
log("onRadioAvailable: We're on the simulator; assuming data is connected");
|
||||
}
|
||||
|
||||
if (mPhone.mSIMRecords.getRecordsLoaded()) {
|
||||
@ -1477,7 +1558,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
// FIXME this can be improved
|
||||
log("We're on the simulator; assuming radio off is meaningless");
|
||||
} else {
|
||||
if (DBG) log("Radio is off and clean up all connection");
|
||||
if (DBG) log("onRadioOffOrNotAvailable: is off and clean up all connections");
|
||||
cleanUpAllConnections(false, Phone.REASON_RADIO_TURNED_OFF);
|
||||
}
|
||||
notifyDataAvailability(null);
|
||||
@ -1490,27 +1571,29 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
|
||||
if(ar.userObj instanceof ApnContext){
|
||||
apnContext = (ApnContext)ar.userObj;
|
||||
} else {
|
||||
throw new RuntimeException("onDataSetupComplete: No apnContext");
|
||||
}
|
||||
DataConnectionAc dcac = apnContext.getDataConnectionAc();
|
||||
if (dcac == null) {
|
||||
throw new RuntimeException("onDataSetupCompete: No dcac");
|
||||
}
|
||||
DataConnection dc = apnContext.getDataConnection();
|
||||
|
||||
if (ar.exception == null) {
|
||||
// Everything is setup
|
||||
// TODO: We should clear LinkProperties/Capabilities when torn down or disconnected
|
||||
if (DBG) {
|
||||
log(String.format("onDataSetupComplete: success apn=%s",
|
||||
apnContext.getWaitingApns().get(0).apn));
|
||||
apnContext.getWaitingApns().get(0).apn) + " refCount=" + dc.getRefCount());
|
||||
}
|
||||
mLinkProperties = getLinkProperties(apnContext.getApnType());
|
||||
mLinkCapabilities = getLinkCapabilities(apnContext.getApnType());
|
||||
|
||||
ApnSetting apn = apnContext.getApnSetting();
|
||||
if (apn.proxy != null && apn.proxy.length() != 0) {
|
||||
try {
|
||||
ProxyProperties proxy = new ProxyProperties(apn.proxy,
|
||||
Integer.parseInt(apn.port), null);
|
||||
mLinkProperties.setHttpProxy(proxy);
|
||||
dcac.setLinkPropertiesHttpProxySync(proxy);
|
||||
} catch (NumberFormatException e) {
|
||||
loge("NumberFormatException making ProxyProperties (" + apn.port +
|
||||
"): " + e);
|
||||
loge("onDataSetupComplete: NumberFormatException making ProxyProperties (" +
|
||||
apn.port + "): " + e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1518,7 +1601,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
if(TextUtils.equals(apnContext.getApnType(),Phone.APN_TYPE_DEFAULT)) {
|
||||
SystemProperties.set("gsm.defaultpdpcontext.active", "true");
|
||||
if (canSetPreferApn && mPreferredApn == null) {
|
||||
log("PREFERED APN is null");
|
||||
if (DBG) log("onDataSetupComplete: PREFERED APN is null");
|
||||
mPreferredApn = apnContext.getApnSetting();
|
||||
if (mPreferredApn != null) {
|
||||
setPreferredApn(mPreferredApn.id);
|
||||
@ -1528,15 +1611,13 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
SystemProperties.set("gsm.defaultpdpcontext.active", "false");
|
||||
}
|
||||
notifyDefaultData(apnContext);
|
||||
|
||||
// TODO: For simultaneous PDP support, we need to build another
|
||||
// trigger another TRY_SETUP_DATA for the next APN type. (Note
|
||||
// that the existing connection may service that type, in which
|
||||
// case we should try the next type, etc.
|
||||
// I dont believe for simultaneous PDP you need to trigger. Each
|
||||
// Connection should be independent and they can be setup simultaneously
|
||||
// So, dont have to wait till one is finished.
|
||||
} else {
|
||||
int refCount = releaseApnContext(apnContext, false);
|
||||
if (DBG) {
|
||||
log(String.format("onDataSetupComplete: error apn=%s",
|
||||
apnContext.getWaitingApns().get(0).apn) + " refCount=" + refCount);
|
||||
}
|
||||
|
||||
GsmDataConnection.FailCause cause;
|
||||
cause = (GsmDataConnection.FailCause) (ar.result);
|
||||
if (DBG) {
|
||||
@ -1573,7 +1654,6 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
log("onDataSetupComplete: All APN's had permanent failures, stop retrying");
|
||||
}
|
||||
apnContext.setState(State.FAILED);
|
||||
apnContext.setDataConnection(null);
|
||||
notifyDataConnection(Phone.REASON_APN_FAILED);
|
||||
} else {
|
||||
if (DBG) log("onDataSetupComplete: Not all permanent failures, retry");
|
||||
@ -1597,7 +1677,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
protected void onDisconnectDone(int connId, AsyncResult ar) {
|
||||
ApnContext apnContext = null;
|
||||
|
||||
if(DBG) log("EVENT_DISCONNECT_DONE connId=" + connId);
|
||||
if(DBG) log("onDisconnectDone: EVENT_DISCONNECT_DONE connId=" + connId);
|
||||
if (ar.userObj instanceof ApnContext) {
|
||||
apnContext = (ApnContext) ar.userObj;
|
||||
} else {
|
||||
@ -1610,9 +1690,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
|
||||
// Check if APN disabled.
|
||||
if (apnContext.getPendingAction() == ApnContext.PENDING_ACTION_APN_DISABLE) {
|
||||
apnContext.setEnabled(false);
|
||||
apnContext.setPendingAction(ApnContext.PENDING_ACTION_NONE);
|
||||
apnContext.setDataConnection(null);
|
||||
}
|
||||
mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
|
||||
|
||||
@ -1648,7 +1726,9 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
|
||||
@Override
|
||||
protected void onVoiceCallStarted() {
|
||||
if (DBG) log("onVoiceCallStarted");
|
||||
if (isConnected() && ! mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
|
||||
if (DBG) log("onVoiceCallStarted stop polling");
|
||||
stopNetStatPoll();
|
||||
notifyDataConnection(Phone.REASON_VOICE_CALL_STARTED);
|
||||
}
|
||||
@ -1656,6 +1736,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
|
||||
@Override
|
||||
protected void onVoiceCallEnded() {
|
||||
if (DBG) log("onVoiceCallEnded");
|
||||
if (isConnected()) {
|
||||
if (!mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
|
||||
startNetStatPoll();
|
||||
@ -1688,10 +1769,10 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
|
||||
@Override
|
||||
protected void notifyDataConnection(String reason) {
|
||||
if (DBG) log("notify all enabled connection for:" + reason);
|
||||
if (DBG) log("notifyDataConnection: reason=" + reason);
|
||||
for (ApnContext apnContext : mApnContexts.values()) {
|
||||
if (apnContext.isReady()) {
|
||||
if (DBG) log("notify for type:"+apnContext.getApnType());
|
||||
if (DBG) log("notifyDataConnection: type:"+apnContext.getApnType());
|
||||
mPhone.notifyDataConnection(reason != null ? reason : apnContext.getReason(),
|
||||
apnContext.getApnType());
|
||||
}
|
||||
@ -1738,17 +1819,16 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
}
|
||||
|
||||
/** Return the id for a new data connection */
|
||||
private GsmDataConnection createDataConnection(ApnContext apnContext) {
|
||||
String apnType = apnContext.getApnType();
|
||||
log("createDataConnection(" + apnType + ") E");
|
||||
private GsmDataConnection createDataConnection(String apnType) {
|
||||
if (DBG) log("createDataConnection(" + apnType + ") E");
|
||||
RetryManager rm = new RetryManager();
|
||||
|
||||
if (apnType.equals(Phone.APN_TYPE_DEFAULT)) {
|
||||
if (!rm.configure(SystemProperties.get("ro.gsm.data_retry_config"))) {
|
||||
if (!rm.configure(DEFAULT_DATA_RETRY_CONFIG)) {
|
||||
// Should never happen, log an error and default to a simple linear sequence.
|
||||
log("Could not configure using DEFAULT_DATA_RETRY_CONFIG="
|
||||
+ DEFAULT_DATA_RETRY_CONFIG);
|
||||
loge("createDataConnection: Could not configure using " +
|
||||
"DEFAULT_DATA_RETRY_CONFIG=" + DEFAULT_DATA_RETRY_CONFIG);
|
||||
rm.configure(20, 2000, 1000);
|
||||
}
|
||||
}
|
||||
@ -1756,8 +1836,8 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
if (!rm.configure(SystemProperties.get("ro.gsm.2nd_data_retry_config"))) {
|
||||
if (!rm.configure(SECONDARY_DATA_RETRY_CONFIG)) {
|
||||
// Should never happen, log an error and default to a simple sequence.
|
||||
log("Could note configure using SECONDARY_DATA_RETRY_CONFIG="
|
||||
+ SECONDARY_DATA_RETRY_CONFIG);
|
||||
loge("createDataConnection: Could note configure using " +
|
||||
"SECONDARY_DATA_RETRY_CONFIG=" + SECONDARY_DATA_RETRY_CONFIG);
|
||||
rm.configure("max_retries=3, 333, 333, 333");
|
||||
}
|
||||
}
|
||||
@ -1767,18 +1847,25 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
GsmDataConnection conn = GsmDataConnection.makeDataConnection(mPhone, id, rm);
|
||||
conn.resetRetryCount();
|
||||
mDataConnections.put(id, conn);
|
||||
apnContext.setDataConnection(conn);
|
||||
DataConnectionAc dcac = new DataConnectionAc(conn, LOG_TAG);
|
||||
int status = dcac.fullyConnectSync(mPhone.getContext(), this, conn.getHandler());
|
||||
if (status == AsyncChannel.STATUS_SUCCESSFUL) {
|
||||
mDataConnectionAsyncChannels.put(dcac.dataConnection.getDataConnectionId(), dcac);
|
||||
} else {
|
||||
loge("createDataConnection: Could not connect to dcac.mDc=" + dcac.dataConnection +
|
||||
" status=" + status);
|
||||
}
|
||||
|
||||
log("createDataConnection(" + apnType + ") X id=" + id);
|
||||
if (DBG) log("createDataConnection(" + apnType + ") X id=" + id);
|
||||
return conn;
|
||||
}
|
||||
|
||||
private void destroyDataConnections() {
|
||||
if(mDataConnections != null) {
|
||||
log("destroyDataConnectionList clear mDataConnectionList");
|
||||
if (DBG) log("destroyDataConnections: clear mDataConnectionList");
|
||||
mDataConnections.clear();
|
||||
} else {
|
||||
log("destroyDataConnectionList mDataConnecitonList is empty, ignore");
|
||||
if (DBG) log("destroyDataConnectionList mDataConnecitonList is empty, ignore");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1802,8 +1889,10 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
String operator = mPhone.mSIMRecords.getSIMOperatorNumeric();
|
||||
if (requestedApnType.equals(Phone.APN_TYPE_DEFAULT)) {
|
||||
if (canSetPreferApn && mPreferredApn != null) {
|
||||
log("Preferred APN:" + operator + ":"
|
||||
if (DBG) {
|
||||
log("buildWaitingApns: Preferred APN:" + operator + ":"
|
||||
+ mPreferredApn.numeric + ":" + mPreferredApn);
|
||||
}
|
||||
if (mPreferredApn.numeric.equals(operator)) {
|
||||
apnList.add(mPreferredApn);
|
||||
if (DBG) log("buildWaitingApns: X added preferred apnList=" + apnList);
|
||||
@ -1894,10 +1983,10 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
|
||||
@Override
|
||||
public void handleMessage (Message msg) {
|
||||
if (DBG) log("GSMDataConnTrack handleMessage "+msg);
|
||||
if (DBG) log("handleMessage msg=" + msg);
|
||||
|
||||
if (!mPhone.mIsTheCurrentActivePhone || mIsDisposed) {
|
||||
log("Ignore GSM msgs since GSM phone is inactive");
|
||||
loge("handleMessage: Ignore GSM msgs since GSM phone is inactive");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1941,7 +2030,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
* PDP context and notify us with PDP_CONTEXT_CHANGED.
|
||||
* But we should stop the network polling and prevent reset PDP.
|
||||
*/
|
||||
log("EVENT_PS_RESTRICT_ENABLED " + mIsPsRestricted);
|
||||
if (DBG) log("EVENT_PS_RESTRICT_ENABLED " + mIsPsRestricted);
|
||||
stopNetStatPoll();
|
||||
mIsPsRestricted = true;
|
||||
break;
|
||||
@ -1951,7 +2040,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
* When PS restrict is removed, we need setup PDP connection if
|
||||
* PDP connection is down.
|
||||
*/
|
||||
log("EVENT_PS_RESTRICT_DISABLED " + mIsPsRestricted);
|
||||
if (DBG) log("EVENT_PS_RESTRICT_DISABLED " + mIsPsRestricted);
|
||||
mIsPsRestricted = false;
|
||||
if (isConnected()) {
|
||||
startNetStatPoll();
|
||||
@ -1968,19 +2057,20 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
case EVENT_TRY_SETUP_DATA:
|
||||
if (msg.obj instanceof ApnContext) {
|
||||
onTrySetupData((ApnContext)msg.obj);
|
||||
} else if (msg.obj instanceof String) {
|
||||
onTrySetupData((String)msg.obj);
|
||||
} else {
|
||||
if (msg.obj instanceof String) {
|
||||
onTrySetupData((String)msg.obj);
|
||||
}
|
||||
loge("EVENT_TRY_SETUP request w/o apnContext or String");
|
||||
}
|
||||
break;
|
||||
|
||||
case EVENT_CLEAN_UP_CONNECTION:
|
||||
boolean tearDown = (msg.arg1 == 0) ? false : true;
|
||||
if (DBG) log("EVENT_CLEAN_UP_CONNECTION tearDown=" + tearDown);
|
||||
if (msg.obj instanceof ApnContext) {
|
||||
cleanUpConnection(tearDown, (ApnContext)msg.obj);
|
||||
} else {
|
||||
loge("[GsmDataConnectionTracker] connectpion cleanup request w/o apn context");
|
||||
loge("EVENT_CLEAN_UP_CONNECTION request w/o apn context");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
Reference in New Issue
Block a user