diff options
9 files changed, 778 insertions, 410 deletions
diff --git a/core/java/com/android/internal/util/Protocol.java b/core/java/com/android/internal/util/Protocol.java index b35f615..2e7ec58 100644 --- a/core/java/com/android/internal/util/Protocol.java +++ b/core/java/com/android/internal/util/Protocol.java @@ -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 diff --git a/telephony/java/com/android/internal/telephony/ApnContext.java b/telephony/java/com/android/internal/telephony/ApnContext.java index 3f1ca9e..010d61d 100644 --- a/telephony/java/com/android/internal/telephony/ApnContext.java +++ b/telephony/java/com/android/internal/telephony/ApnContext.java @@ -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); } diff --git a/telephony/java/com/android/internal/telephony/DataConnection.java b/telephony/java/com/android/internal/telephony/DataConnection.java index 791fbfd..6a5b82c 100644 --- a/telephony/java/com/android/internal/telephony/DataConnection.java +++ b/telephony/java/com/android/internal/telephony/DataConnection.java @@ -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. @@ -76,13 +80,6 @@ public abstract class DataConnection extends StateMachine { } /** - * An instance used for notification of blockingReset. - * TODO: Remove when blockingReset is removed. - */ - class ResetSynchronouslyLock { - } - - /** * Used internally for saving disconnecting parameters. */ protected static class DisconnectParams { @@ -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; - } } diff --git a/telephony/java/com/android/internal/telephony/DataConnectionAc.java b/telephony/java/com/android/internal/telephony/DataConnectionAc.java new file mode 100644 index 0000000..a9796dd --- /dev/null +++ b/telephony/java/com/android/internal/telephony/DataConnectionAc.java @@ -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); + } +} diff --git a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java index 01ac95f..ad4e796 100644 --- a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java +++ b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java @@ -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++) { diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java index e299d4a..d55f346 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java @@ -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; diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java index dc85017..4b185a0 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java @@ -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"); diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java index 545ad8a..9695344 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java @@ -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; diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java index 8e675fc..a1b4376 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java @@ -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 + int refCount = conn.incAndGetRefCount(); + apnContext.setDataConnection(conn); + apnContext.setDataConnectionAc( + mDataConnectionAsyncChannels.get(conn.getDataConnectionId())); if (DBG) { - log("Found existing connection for " + apnContext.getApnType() + - ": " + conn); + log("applyNewState: Found existing connection for " + + apnContext.getApnType() + " inc refCount=" + refCount + + " conn=" + conn); } - apnContext.setDataConnection(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: |