Loading src/java/com/android/internal/telephony/dataconnection/AccessNetworksManager.java +1 −0 Original line number Diff line number Diff line Loading @@ -106,6 +106,7 @@ public class AccessNetworksManager { */ public static class QualifiedNetworks { public final @ApnType int apnType; // The qualified netowrks in preferred order. Each network is a AccessNetworkType. public final int[] qualifiedNetworks; public QualifiedNetworks(@ApnType int apnType, int[] qualifiedNetworks) { this.apnType = apnType; Loading src/java/com/android/internal/telephony/dataconnection/ApnContext.java +11 −13 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.net.ConnectivityManager; import android.net.NetworkCapabilities; import android.net.NetworkConfig; import android.net.NetworkRequest; import android.os.Message; import android.telephony.Rlog; import android.telephony.data.ApnSetting; import android.telephony.data.ApnSetting.ApnType; Loading Loading @@ -413,15 +414,13 @@ public class ApnContext { } } public void requestNetwork(NetworkRequest networkRequest, @RequestNetworkType int type, LocalLog log) { public void requestNetwork(NetworkRequest networkRequest, @RequestNetworkType int type, Message onCompleteMsg, LocalLog log) { synchronized (mRefCountLock) { if (mLocalLogs.contains(log) || mNetworkRequests.contains(networkRequest)) { log.log("ApnContext.requestNetwork has duplicate add - " + mNetworkRequests.size()); } else { mLocalLogs.add(log); mNetworkRequests.add(networkRequest); mDcTracker.enableApn(ApnSetting.getApnTypesBitmaskFromString(mApnType), type); mDcTracker.enableApn(ApnSetting.getApnTypesBitmaskFromString(mApnType), type, onCompleteMsg); if (mDataConnection != null) { // New network request added. Should re-evaluate properties of // the data connection. For example, the score may change. Loading @@ -429,7 +428,6 @@ public class ApnContext { } } } } public void releaseNetwork(NetworkRequest networkRequest, @ReleaseNetworkType int type, LocalLog log) { Loading src/java/com/android/internal/telephony/dataconnection/DcTracker.java +77 −17 Original line number Diff line number Diff line Loading @@ -111,6 +111,7 @@ import java.util.ArrayList; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.PriorityQueue; import java.util.Set; Loading Loading @@ -180,6 +181,12 @@ public class DcTracker extends Handler { */ public static final int RELEASE_TYPE_HANDOVER = 3; /** The extras for request network completion message */ static final String DATA_COMPLETE_MSG_EXTRA_NETWORK_REQUEST = "extra_network_request"; static final String DATA_COMPLETE_MSG_EXTRA_TRANSPORT_TYPE = "extra_transport_type"; static final String DATA_COMPLETE_MSG_EXTRA_REQUEST_TYPE = "extra_request_type"; static final String DATA_COMPLETE_MSG_EXTRA_SUCCESS = "extra_success"; private final String mLogTag; public AtomicBoolean isCleanupRequired = new AtomicBoolean(false); Loading Loading @@ -628,6 +635,13 @@ public class DcTracker extends Handler { private DataStallRecoveryHandler mDsRecoveryHandler; /** * Request network completion message map. Key is the APN type, value is the list of completion * messages to be sent. Using a list because there might be multiple network requests for * the same APN type. */ private final Map<Integer, List<Message>> mRequestNetworkCompletionMsgs = new HashMap<>(); //***** Constructor public DcTracker(Phone phone, int transportType) { super(); Loading Loading @@ -853,13 +867,13 @@ public class DcTracker extends Handler { } public void requestNetwork(NetworkRequest networkRequest, @RequestNetworkType int type, LocalLog log) { Message onCompleteMsg, LocalLog log) { final int apnType = ApnContext.getApnTypeFromNetworkRequest(networkRequest); final ApnContext apnContext = mApnContextsByType.get(apnType); log.log("DcTracker.requestNetwork for " + networkRequest + " found " + apnContext + ", type=" + requestTypeToString(type)); if (apnContext != null) { apnContext.requestNetwork(networkRequest, type, log); apnContext.requestNetwork(networkRequest, type, onCompleteMsg, log); } } Loading Loading @@ -2269,20 +2283,44 @@ public class DcTracker extends Handler { return null; } public void enableApn(@ApnSetting.ApnType int apnType, @RequestNetworkType int requestType) { sendMessage(obtainMessage(DctConstants.EVENT_ENABLE_APN, apnType, requestType)); private void addRequestNetworkCompleteMsg(Message onCompleteMsg, @ApnSetting.ApnType int apnType) { if (onCompleteMsg != null) { List<Message> messageList = mRequestNetworkCompletionMsgs.get(apnType); if (messageList == null) messageList = new ArrayList<>(); messageList.add(onCompleteMsg); mRequestNetworkCompletionMsgs.put(apnType, messageList); } } private void sendRequestNetworkCompleteMsg(Message message, boolean success, int transport, @RequestNetworkType int requestType) { if (message == null) return; Bundle b = message.getData(); b.putBoolean(DATA_COMPLETE_MSG_EXTRA_SUCCESS, success); b.putInt(DATA_COMPLETE_MSG_EXTRA_REQUEST_TYPE, requestType); b.putInt(DATA_COMPLETE_MSG_EXTRA_TRANSPORT_TYPE, transport); message.sendToTarget(); } private void onEnableApn(@ApnSetting.ApnType int apnType, @RequestNetworkType int requestType) { public void enableApn(@ApnSetting.ApnType int apnType, @RequestNetworkType int requestType, Message onCompleteMsg) { sendMessage(obtainMessage(DctConstants.EVENT_ENABLE_APN, apnType, requestType, onCompleteMsg)); } private void onEnableApn(@ApnSetting.ApnType int apnType, @RequestNetworkType int requestType, Message onCompleteMsg) { ApnContext apnContext = mApnContextsByType.get(apnType); if (apnContext == null) { loge("onEnableApn(" + apnType + "): NO ApnContext"); sendRequestNetworkCompleteMsg(onCompleteMsg, false, mTransportType, requestType); return; } boolean trySetup = false; String str = "onEnableApn: apnType=" + ApnSetting.getApnTypeString(apnType) + ", request type=" + requestType; + ", request type=" + requestTypeToString(requestType); if (DBG) log(str); apnContext.requestLog(str); Loading @@ -2292,6 +2330,7 @@ public class DcTracker extends Handler { str = "onEnableApn: dependency is not met."; if (DBG) log(str); apnContext.requestLog(str); sendRequestNetworkCompleteMsg(onCompleteMsg, false, mTransportType, requestType); return; } Loading @@ -2299,11 +2338,22 @@ public class DcTracker extends Handler { DctConstants.State state = apnContext.getState(); switch(state) { case CONNECTING: if (DBG) log("onEnableApn: 'CONNECTING' so return"); apnContext.requestLog("onEnableApn state=CONNECTING, so return"); addRequestNetworkCompleteMsg(onCompleteMsg, apnType); return; case CONNECTED: if (DBG) log("onEnableApn: 'CONNECTED' so return"); apnContext.requestLog("onEnableApn state=CONNECTED, so return"); sendRequestNetworkCompleteMsg(onCompleteMsg, true, mTransportType, requestType); return; case DISCONNECTING: // We're "READY" and active so just return if (DBG) log("onEnableApn: 'ready' so return"); apnContext.requestLog("onEnableApn state=" + state + ", so return"); if (DBG) log("onEnableApn: 'DISCONNECTING' so return"); apnContext.requestLog("onEnableApn state=DISCONNECTING, so return"); sendRequestNetworkCompleteMsg(onCompleteMsg, false, mTransportType, requestType); return; case IDLE: // fall through: this is unexpected but if it happens cleanup and try setup Loading @@ -2311,7 +2361,6 @@ public class DcTracker extends Handler { case RETRYING: // We're "READY" but not active so disconnect (cleanup = true) and // connect (trySetup = true) to be sure we retry the connection. trySetup = true; apnContext.setReason(Phone.REASON_DATA_ENABLED); break; } Loading @@ -2324,12 +2373,14 @@ public class DcTracker extends Handler { if (apnContext.getState() == DctConstants.State.FAILED) { apnContext.setState(DctConstants.State.IDLE); } trySetup = true; } apnContext.setEnabled(true); if (trySetup) { apnContext.resetErrorCodeRetries(); trySetupData(apnContext, requestType); if (trySetupData(apnContext, requestType)) { addRequestNetworkCompleteMsg(onCompleteMsg, apnType); } else { sendRequestNetworkCompleteMsg(onCompleteMsg, false, mTransportType, requestType); } } Loading @@ -2347,7 +2398,7 @@ public class DcTracker extends Handler { boolean cleanup = false; String str = "onDisableApn: apnType=" + ApnSetting.getApnTypeString(apnType) + ", release type=" + releaseType; + ", release type=" + releaseTypeToString(releaseType); if (DBG) log(str); apnContext.requestLog(str); Loading Loading @@ -2672,6 +2723,15 @@ public class DcTracker extends Handler { */ private void onDataSetupComplete(ApnContext apnContext, boolean success, int cause, @RequestNetworkType int requestType) { int apnType = ApnSetting.getApnTypesBitmaskFromString(apnContext.getApnType()); List<Message> messageList = mRequestNetworkCompletionMsgs.get(apnType); if (messageList != null) { for (Message msg : messageList) { sendRequestNetworkCompleteMsg(msg, success, mTransportType, requestType); } messageList.clear(); } if (success) { DataConnection dataConnection = apnContext.getDataConnection(); Loading Loading @@ -3512,7 +3572,7 @@ public class DcTracker extends Handler { break; case DctConstants.EVENT_ENABLE_APN: onEnableApn(msg.arg1, msg.arg2); onEnableApn(msg.arg1, msg.arg2, (Message) msg.obj); break; case DctConstants.EVENT_DISABLE_APN: Loading src/java/com/android/internal/telephony/dataconnection/TelephonyNetworkFactory.java +130 −41 Original line number Diff line number Diff line Loading @@ -22,10 +22,15 @@ import android.net.NetworkCapabilities; import android.net.NetworkFactory; import android.net.NetworkRequest; import android.net.StringNetworkSpecifier; import android.os.AsyncResult; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.telephony.AccessNetworkConstants.TransportType; import android.telephony.Rlog; import android.telephony.data.ApnSetting; import android.telephony.data.ApnSetting.ApnType; import android.util.LocalLog; import com.android.internal.telephony.Phone; Loading @@ -33,6 +38,8 @@ import com.android.internal.telephony.PhoneSwitcher; import com.android.internal.telephony.SubscriptionController; import com.android.internal.telephony.SubscriptionMonitor; import com.android.internal.telephony.dataconnection.DcTracker.ReleaseNetworkType; import com.android.internal.telephony.dataconnection.DcTracker.RequestNetworkType; import com.android.internal.telephony.dataconnection.TransportManager.HandoverParams; import com.android.internal.util.IndentingPrintWriter; import java.io.FileDescriptor; Loading @@ -55,8 +62,9 @@ public class TelephonyNetworkFactory extends NetworkFactory { private final SubscriptionMonitor mSubscriptionMonitor; private final LocalLog mLocalLog = new LocalLog(REQUEST_LOG_SIZE); // Key: network request. Value: whether it's applied to DcTracker. private final Map<NetworkRequest, Boolean> mNetworkRequests = new HashMap<>(); // Key: network request. Value: the transport of DcTracker it applies to, // TransportType.INVALID if not applied. private final Map<NetworkRequest, Integer> mNetworkRequests = new HashMap<>(); private final Phone mPhone; Loading @@ -71,6 +79,8 @@ public class TelephonyNetworkFactory extends NetworkFactory { private static final int EVENT_SUBSCRIPTION_CHANGED = 2; private static final int EVENT_NETWORK_REQUEST = 3; private static final int EVENT_NETWORK_RELEASE = 4; private static final int EVENT_DATA_HANDOVER_NEEDED = 5; private static final int EVENT_DATA_HANDOVER_COMPLETED = 6; public TelephonyNetworkFactory(SubscriptionMonitor subscriptionMonitor, Looper looper, Phone phone) { Loading @@ -91,6 +101,8 @@ public class TelephonyNetworkFactory extends NetworkFactory { mPhoneSwitcher.registerForActivePhoneSwitch(mInternalHandler, EVENT_ACTIVE_PHONE_SWITCH, null); mTransportManager.registerForHandoverNeededEvent(mInternalHandler, EVENT_DATA_HANDOVER_NEEDED); mSubscriptionId = INVALID_SUBSCRIPTION_ID; mSubscriptionMonitor.registerForSubscriptionChanged(mPhone.getPhoneId(), mInternalHandler, Loading Loading @@ -148,6 +160,26 @@ public class TelephonyNetworkFactory extends NetworkFactory { onReleaseNetworkFor(msg); break; } case EVENT_DATA_HANDOVER_NEEDED: { AsyncResult ar = (AsyncResult) msg.obj; HandoverParams handoverParams = (HandoverParams) ar.result; onDataHandoverNeeded(handoverParams.apnType, handoverParams.targetTransport); break; } case EVENT_DATA_HANDOVER_COMPLETED: { Bundle bundle = msg.getData(); int requestType = bundle.getInt(DcTracker.DATA_COMPLETE_MSG_EXTRA_REQUEST_TYPE); if (requestType == DcTracker.REQUEST_TYPE_HANDOVER) { NetworkRequest nr = bundle.getParcelable( DcTracker.DATA_COMPLETE_MSG_EXTRA_NETWORK_REQUEST); boolean success = bundle.getBoolean( DcTracker.DATA_COMPLETE_MSG_EXTRA_SUCCESS); int transport = bundle.getInt( DcTracker.DATA_COMPLETE_MSG_EXTRA_TRANSPORT_TYPE); onDataHandoverSetupCompleted(nr, success, transport); } break; } } } } Loading @@ -157,38 +189,24 @@ public class TelephonyNetworkFactory extends NetworkFactory { return mTransportManager.getCurrentTransport(apnType); } private void requestNetworkInternal(NetworkRequest networkRequest) { int transportType = getTransportTypeFromNetworkRequest(networkRequest); if (mPhone.getDcTracker(transportType) != null) { // TODO: Handover logic will be added later. For now always normal request. mPhone.getDcTracker(transportType).requestNetwork(networkRequest, DcTracker.REQUEST_TYPE_NORMAL, mLocalLog); private void requestNetworkInternal(NetworkRequest networkRequest, @RequestNetworkType int requestType, int transport, Message onCompleteMsg) { if (mPhone.getDcTracker(transport) != null) { mPhone.getDcTracker(transport).requestNetwork(networkRequest, requestType, onCompleteMsg, mLocalLog); } } private void releaseNetworkInternal(NetworkRequest networkRequest, @ReleaseNetworkType int releaseType) { int transportType = getTransportTypeFromNetworkRequest(networkRequest); if (mPhone.getDcTracker(transportType) != null) { // TODO: Handover logic will be added later. For now always normal or detach request. mPhone.getDcTracker(transportType).releaseNetwork(networkRequest, releaseType, @ReleaseNetworkType int releaseType, int transport) { if (mPhone.getDcTracker(transport) != null) { mPhone.getDcTracker(transport).releaseNetwork(networkRequest, releaseType, mLocalLog); } } private void applyRequestsOnActivePhoneSwitch(NetworkRequest networkRequest, int action) { if (action == ACTION_NO_OP) return; String logStr = "onActivePhoneSwitch: " + ((action == ACTION_REQUEST) ? "Requesting" : "Releasing") + " network request " + networkRequest; mLocalLog.log(logStr); if (action == ACTION_REQUEST) { requestNetworkInternal(networkRequest); } else if (action == ACTION_RELEASE) { releaseNetworkInternal(networkRequest, DcTracker.RELEASE_TYPE_DETACH); } } private static int getAction(boolean wasActive, boolean isActive) { if (!wasActive && isActive) { return ACTION_REQUEST; Loading @@ -201,15 +219,30 @@ public class TelephonyNetworkFactory extends NetworkFactory { // apply or revoke requests if our active-ness changes private void onActivePhoneSwitch() { for (HashMap.Entry<NetworkRequest, Boolean> entry : mNetworkRequests.entrySet()) { for (HashMap.Entry<NetworkRequest, Integer> entry : mNetworkRequests.entrySet()) { NetworkRequest networkRequest = entry.getKey(); boolean applied = entry.getValue(); boolean applied = entry.getValue() != TransportType.INVALID; boolean shouldApply = mPhoneSwitcher.shouldApplyNetworkRequest( networkRequest, mPhone.getPhoneId()); applyRequestsOnActivePhoneSwitch(networkRequest, getAction(applied, shouldApply)); mNetworkRequests.put(networkRequest, shouldApply); int action = getAction(applied, shouldApply); if (action == ACTION_NO_OP) continue; String logStr = "onActivePhoneSwitch: " + ((action == ACTION_REQUEST) ? "Requesting" : "Releasing") + " network request " + networkRequest; mLocalLog.log(logStr); int transportType = getTransportTypeFromNetworkRequest(networkRequest); if (action == ACTION_REQUEST) { requestNetworkInternal(networkRequest, DcTracker.REQUEST_TYPE_NORMAL, getTransportTypeFromNetworkRequest(networkRequest), null); } else if (action == ACTION_RELEASE) { int transport = getTransportTypeFromNetworkRequest(networkRequest); releaseNetworkInternal(networkRequest, DcTracker.RELEASE_TYPE_DETACH, transport); } mNetworkRequests.put(networkRequest, shouldApply ? transportType : TransportType.INVALID); } } Loading Loading @@ -237,14 +270,16 @@ public class TelephonyNetworkFactory extends NetworkFactory { boolean shouldApply = mPhoneSwitcher.shouldApplyNetworkRequest( networkRequest, mPhone.getPhoneId()); mNetworkRequests.put(networkRequest, shouldApply); mNetworkRequests.put(networkRequest, shouldApply ? getTransportTypeFromNetworkRequest(networkRequest) : TransportType.INVALID); String s = "onNeedNetworkFor " + networkRequest + " shouldApply " + shouldApply; log(s); mLocalLog.log(s); if (shouldApply) { requestNetworkInternal(networkRequest); requestNetworkInternal(networkRequest, DcTracker.REQUEST_TYPE_NORMAL, getTransportTypeFromNetworkRequest(networkRequest), null); } } Loading @@ -257,7 +292,7 @@ public class TelephonyNetworkFactory extends NetworkFactory { private void onReleaseNetworkFor(Message msg) { NetworkRequest networkRequest = (NetworkRequest)msg.obj; boolean applied = mNetworkRequests.get(networkRequest); boolean applied = mNetworkRequests.get(networkRequest) != TransportType.INVALID; mNetworkRequests.remove(networkRequest); Loading @@ -266,7 +301,60 @@ public class TelephonyNetworkFactory extends NetworkFactory { mLocalLog.log(s); if (applied) { releaseNetworkInternal(networkRequest, DcTracker.RELEASE_TYPE_NORMAL); int transport = getTransportTypeFromNetworkRequest(networkRequest); releaseNetworkInternal(networkRequest, DcTracker.RELEASE_TYPE_NORMAL, transport); } } private void onDataHandoverNeeded(@ApnType int apnType, int targetTransport) { log("onDataHandoverNeeded: apnType=" + ApnSetting.getApnTypeString(apnType) + ", target transport=" + TransportType.toString(targetTransport)); if (mTransportManager.getCurrentTransport(apnType) == targetTransport) { log("apnType " + ApnSetting.getApnTypeString(apnType) + " is already on " + TransportType.toString(targetTransport)); return; } for (HashMap.Entry<NetworkRequest, Integer> entry : mNetworkRequests.entrySet()) { NetworkRequest networkRequest = entry.getKey(); int currentTransport = entry.getValue(); boolean applied = currentTransport != TransportType.INVALID; if (ApnContext.getApnTypeFromNetworkRequest(networkRequest) == apnType && applied && currentTransport != targetTransport) { Message onCompleteMsg = mInternalHandler.obtainMessage( EVENT_DATA_HANDOVER_COMPLETED); onCompleteMsg.getData().putParcelable( DcTracker.DATA_COMPLETE_MSG_EXTRA_NETWORK_REQUEST, networkRequest); requestNetworkInternal(networkRequest, DcTracker.REQUEST_TYPE_HANDOVER, targetTransport, onCompleteMsg); } } } private void onDataHandoverSetupCompleted(NetworkRequest networkRequest, boolean success, int targetTransport) { log("onDataHandoverSetupCompleted: " + networkRequest + ", success=" + success + ", targetTransport=" + TransportType.toString(targetTransport)); // At this point, handover setup has been completed on the target transport. If succeeded, // we can release the data connection on the original transport. If failed, then we also // need to remove the network request from the targeting transport. if (success) { // Handover setup succeeded on targeting transport. Now we can release the network // request on the original transport. int originTransport = (targetTransport == TransportType.WWAN) ? TransportType.WLAN : TransportType.WWAN; int apnType = ApnContext.getApnTypeFromNetworkRequest(networkRequest); releaseNetworkInternal(networkRequest, DcTracker.RELEASE_TYPE_HANDOVER, originTransport); mNetworkRequests.put(networkRequest, targetTransport); // Switch the current transport to the new one. mTransportManager.setCurrentTransport(apnType, targetTransport); } else { // If handover failed, we need to remove the request on the targeting transport. releaseNetworkInternal(networkRequest, DcTracker.RELEASE_TYPE_NORMAL, targetTransport); } } Loading @@ -278,10 +366,11 @@ public class TelephonyNetworkFactory extends NetworkFactory { final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " "); pw.println("Network Requests:"); pw.increaseIndent(); for (HashMap.Entry<NetworkRequest, Boolean> entry : mNetworkRequests.entrySet()) { for (HashMap.Entry<NetworkRequest, Integer> entry : mNetworkRequests.entrySet()) { NetworkRequest nr = entry.getKey(); boolean applied = entry.getValue(); pw.println((applied ? "Applied: " : "Not applied: ") + nr); int transport = entry.getValue(); pw.println(nr + (transport != TransportType.INVALID ? (" applied on " + transport) : " not applied")); } mLocalLog.dump(fd, pw, args); pw.decreaseIndent(); Loading src/java/com/android/internal/telephony/dataconnection/TransportManager.java +121 −15 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
src/java/com/android/internal/telephony/dataconnection/AccessNetworksManager.java +1 −0 Original line number Diff line number Diff line Loading @@ -106,6 +106,7 @@ public class AccessNetworksManager { */ public static class QualifiedNetworks { public final @ApnType int apnType; // The qualified netowrks in preferred order. Each network is a AccessNetworkType. public final int[] qualifiedNetworks; public QualifiedNetworks(@ApnType int apnType, int[] qualifiedNetworks) { this.apnType = apnType; Loading
src/java/com/android/internal/telephony/dataconnection/ApnContext.java +11 −13 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.net.ConnectivityManager; import android.net.NetworkCapabilities; import android.net.NetworkConfig; import android.net.NetworkRequest; import android.os.Message; import android.telephony.Rlog; import android.telephony.data.ApnSetting; import android.telephony.data.ApnSetting.ApnType; Loading Loading @@ -413,15 +414,13 @@ public class ApnContext { } } public void requestNetwork(NetworkRequest networkRequest, @RequestNetworkType int type, LocalLog log) { public void requestNetwork(NetworkRequest networkRequest, @RequestNetworkType int type, Message onCompleteMsg, LocalLog log) { synchronized (mRefCountLock) { if (mLocalLogs.contains(log) || mNetworkRequests.contains(networkRequest)) { log.log("ApnContext.requestNetwork has duplicate add - " + mNetworkRequests.size()); } else { mLocalLogs.add(log); mNetworkRequests.add(networkRequest); mDcTracker.enableApn(ApnSetting.getApnTypesBitmaskFromString(mApnType), type); mDcTracker.enableApn(ApnSetting.getApnTypesBitmaskFromString(mApnType), type, onCompleteMsg); if (mDataConnection != null) { // New network request added. Should re-evaluate properties of // the data connection. For example, the score may change. Loading @@ -429,7 +428,6 @@ public class ApnContext { } } } } public void releaseNetwork(NetworkRequest networkRequest, @ReleaseNetworkType int type, LocalLog log) { Loading
src/java/com/android/internal/telephony/dataconnection/DcTracker.java +77 −17 Original line number Diff line number Diff line Loading @@ -111,6 +111,7 @@ import java.util.ArrayList; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.PriorityQueue; import java.util.Set; Loading Loading @@ -180,6 +181,12 @@ public class DcTracker extends Handler { */ public static final int RELEASE_TYPE_HANDOVER = 3; /** The extras for request network completion message */ static final String DATA_COMPLETE_MSG_EXTRA_NETWORK_REQUEST = "extra_network_request"; static final String DATA_COMPLETE_MSG_EXTRA_TRANSPORT_TYPE = "extra_transport_type"; static final String DATA_COMPLETE_MSG_EXTRA_REQUEST_TYPE = "extra_request_type"; static final String DATA_COMPLETE_MSG_EXTRA_SUCCESS = "extra_success"; private final String mLogTag; public AtomicBoolean isCleanupRequired = new AtomicBoolean(false); Loading Loading @@ -628,6 +635,13 @@ public class DcTracker extends Handler { private DataStallRecoveryHandler mDsRecoveryHandler; /** * Request network completion message map. Key is the APN type, value is the list of completion * messages to be sent. Using a list because there might be multiple network requests for * the same APN type. */ private final Map<Integer, List<Message>> mRequestNetworkCompletionMsgs = new HashMap<>(); //***** Constructor public DcTracker(Phone phone, int transportType) { super(); Loading Loading @@ -853,13 +867,13 @@ public class DcTracker extends Handler { } public void requestNetwork(NetworkRequest networkRequest, @RequestNetworkType int type, LocalLog log) { Message onCompleteMsg, LocalLog log) { final int apnType = ApnContext.getApnTypeFromNetworkRequest(networkRequest); final ApnContext apnContext = mApnContextsByType.get(apnType); log.log("DcTracker.requestNetwork for " + networkRequest + " found " + apnContext + ", type=" + requestTypeToString(type)); if (apnContext != null) { apnContext.requestNetwork(networkRequest, type, log); apnContext.requestNetwork(networkRequest, type, onCompleteMsg, log); } } Loading Loading @@ -2269,20 +2283,44 @@ public class DcTracker extends Handler { return null; } public void enableApn(@ApnSetting.ApnType int apnType, @RequestNetworkType int requestType) { sendMessage(obtainMessage(DctConstants.EVENT_ENABLE_APN, apnType, requestType)); private void addRequestNetworkCompleteMsg(Message onCompleteMsg, @ApnSetting.ApnType int apnType) { if (onCompleteMsg != null) { List<Message> messageList = mRequestNetworkCompletionMsgs.get(apnType); if (messageList == null) messageList = new ArrayList<>(); messageList.add(onCompleteMsg); mRequestNetworkCompletionMsgs.put(apnType, messageList); } } private void sendRequestNetworkCompleteMsg(Message message, boolean success, int transport, @RequestNetworkType int requestType) { if (message == null) return; Bundle b = message.getData(); b.putBoolean(DATA_COMPLETE_MSG_EXTRA_SUCCESS, success); b.putInt(DATA_COMPLETE_MSG_EXTRA_REQUEST_TYPE, requestType); b.putInt(DATA_COMPLETE_MSG_EXTRA_TRANSPORT_TYPE, transport); message.sendToTarget(); } private void onEnableApn(@ApnSetting.ApnType int apnType, @RequestNetworkType int requestType) { public void enableApn(@ApnSetting.ApnType int apnType, @RequestNetworkType int requestType, Message onCompleteMsg) { sendMessage(obtainMessage(DctConstants.EVENT_ENABLE_APN, apnType, requestType, onCompleteMsg)); } private void onEnableApn(@ApnSetting.ApnType int apnType, @RequestNetworkType int requestType, Message onCompleteMsg) { ApnContext apnContext = mApnContextsByType.get(apnType); if (apnContext == null) { loge("onEnableApn(" + apnType + "): NO ApnContext"); sendRequestNetworkCompleteMsg(onCompleteMsg, false, mTransportType, requestType); return; } boolean trySetup = false; String str = "onEnableApn: apnType=" + ApnSetting.getApnTypeString(apnType) + ", request type=" + requestType; + ", request type=" + requestTypeToString(requestType); if (DBG) log(str); apnContext.requestLog(str); Loading @@ -2292,6 +2330,7 @@ public class DcTracker extends Handler { str = "onEnableApn: dependency is not met."; if (DBG) log(str); apnContext.requestLog(str); sendRequestNetworkCompleteMsg(onCompleteMsg, false, mTransportType, requestType); return; } Loading @@ -2299,11 +2338,22 @@ public class DcTracker extends Handler { DctConstants.State state = apnContext.getState(); switch(state) { case CONNECTING: if (DBG) log("onEnableApn: 'CONNECTING' so return"); apnContext.requestLog("onEnableApn state=CONNECTING, so return"); addRequestNetworkCompleteMsg(onCompleteMsg, apnType); return; case CONNECTED: if (DBG) log("onEnableApn: 'CONNECTED' so return"); apnContext.requestLog("onEnableApn state=CONNECTED, so return"); sendRequestNetworkCompleteMsg(onCompleteMsg, true, mTransportType, requestType); return; case DISCONNECTING: // We're "READY" and active so just return if (DBG) log("onEnableApn: 'ready' so return"); apnContext.requestLog("onEnableApn state=" + state + ", so return"); if (DBG) log("onEnableApn: 'DISCONNECTING' so return"); apnContext.requestLog("onEnableApn state=DISCONNECTING, so return"); sendRequestNetworkCompleteMsg(onCompleteMsg, false, mTransportType, requestType); return; case IDLE: // fall through: this is unexpected but if it happens cleanup and try setup Loading @@ -2311,7 +2361,6 @@ public class DcTracker extends Handler { case RETRYING: // We're "READY" but not active so disconnect (cleanup = true) and // connect (trySetup = true) to be sure we retry the connection. trySetup = true; apnContext.setReason(Phone.REASON_DATA_ENABLED); break; } Loading @@ -2324,12 +2373,14 @@ public class DcTracker extends Handler { if (apnContext.getState() == DctConstants.State.FAILED) { apnContext.setState(DctConstants.State.IDLE); } trySetup = true; } apnContext.setEnabled(true); if (trySetup) { apnContext.resetErrorCodeRetries(); trySetupData(apnContext, requestType); if (trySetupData(apnContext, requestType)) { addRequestNetworkCompleteMsg(onCompleteMsg, apnType); } else { sendRequestNetworkCompleteMsg(onCompleteMsg, false, mTransportType, requestType); } } Loading @@ -2347,7 +2398,7 @@ public class DcTracker extends Handler { boolean cleanup = false; String str = "onDisableApn: apnType=" + ApnSetting.getApnTypeString(apnType) + ", release type=" + releaseType; + ", release type=" + releaseTypeToString(releaseType); if (DBG) log(str); apnContext.requestLog(str); Loading Loading @@ -2672,6 +2723,15 @@ public class DcTracker extends Handler { */ private void onDataSetupComplete(ApnContext apnContext, boolean success, int cause, @RequestNetworkType int requestType) { int apnType = ApnSetting.getApnTypesBitmaskFromString(apnContext.getApnType()); List<Message> messageList = mRequestNetworkCompletionMsgs.get(apnType); if (messageList != null) { for (Message msg : messageList) { sendRequestNetworkCompleteMsg(msg, success, mTransportType, requestType); } messageList.clear(); } if (success) { DataConnection dataConnection = apnContext.getDataConnection(); Loading Loading @@ -3512,7 +3572,7 @@ public class DcTracker extends Handler { break; case DctConstants.EVENT_ENABLE_APN: onEnableApn(msg.arg1, msg.arg2); onEnableApn(msg.arg1, msg.arg2, (Message) msg.obj); break; case DctConstants.EVENT_DISABLE_APN: Loading
src/java/com/android/internal/telephony/dataconnection/TelephonyNetworkFactory.java +130 −41 Original line number Diff line number Diff line Loading @@ -22,10 +22,15 @@ import android.net.NetworkCapabilities; import android.net.NetworkFactory; import android.net.NetworkRequest; import android.net.StringNetworkSpecifier; import android.os.AsyncResult; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.telephony.AccessNetworkConstants.TransportType; import android.telephony.Rlog; import android.telephony.data.ApnSetting; import android.telephony.data.ApnSetting.ApnType; import android.util.LocalLog; import com.android.internal.telephony.Phone; Loading @@ -33,6 +38,8 @@ import com.android.internal.telephony.PhoneSwitcher; import com.android.internal.telephony.SubscriptionController; import com.android.internal.telephony.SubscriptionMonitor; import com.android.internal.telephony.dataconnection.DcTracker.ReleaseNetworkType; import com.android.internal.telephony.dataconnection.DcTracker.RequestNetworkType; import com.android.internal.telephony.dataconnection.TransportManager.HandoverParams; import com.android.internal.util.IndentingPrintWriter; import java.io.FileDescriptor; Loading @@ -55,8 +62,9 @@ public class TelephonyNetworkFactory extends NetworkFactory { private final SubscriptionMonitor mSubscriptionMonitor; private final LocalLog mLocalLog = new LocalLog(REQUEST_LOG_SIZE); // Key: network request. Value: whether it's applied to DcTracker. private final Map<NetworkRequest, Boolean> mNetworkRequests = new HashMap<>(); // Key: network request. Value: the transport of DcTracker it applies to, // TransportType.INVALID if not applied. private final Map<NetworkRequest, Integer> mNetworkRequests = new HashMap<>(); private final Phone mPhone; Loading @@ -71,6 +79,8 @@ public class TelephonyNetworkFactory extends NetworkFactory { private static final int EVENT_SUBSCRIPTION_CHANGED = 2; private static final int EVENT_NETWORK_REQUEST = 3; private static final int EVENT_NETWORK_RELEASE = 4; private static final int EVENT_DATA_HANDOVER_NEEDED = 5; private static final int EVENT_DATA_HANDOVER_COMPLETED = 6; public TelephonyNetworkFactory(SubscriptionMonitor subscriptionMonitor, Looper looper, Phone phone) { Loading @@ -91,6 +101,8 @@ public class TelephonyNetworkFactory extends NetworkFactory { mPhoneSwitcher.registerForActivePhoneSwitch(mInternalHandler, EVENT_ACTIVE_PHONE_SWITCH, null); mTransportManager.registerForHandoverNeededEvent(mInternalHandler, EVENT_DATA_HANDOVER_NEEDED); mSubscriptionId = INVALID_SUBSCRIPTION_ID; mSubscriptionMonitor.registerForSubscriptionChanged(mPhone.getPhoneId(), mInternalHandler, Loading Loading @@ -148,6 +160,26 @@ public class TelephonyNetworkFactory extends NetworkFactory { onReleaseNetworkFor(msg); break; } case EVENT_DATA_HANDOVER_NEEDED: { AsyncResult ar = (AsyncResult) msg.obj; HandoverParams handoverParams = (HandoverParams) ar.result; onDataHandoverNeeded(handoverParams.apnType, handoverParams.targetTransport); break; } case EVENT_DATA_HANDOVER_COMPLETED: { Bundle bundle = msg.getData(); int requestType = bundle.getInt(DcTracker.DATA_COMPLETE_MSG_EXTRA_REQUEST_TYPE); if (requestType == DcTracker.REQUEST_TYPE_HANDOVER) { NetworkRequest nr = bundle.getParcelable( DcTracker.DATA_COMPLETE_MSG_EXTRA_NETWORK_REQUEST); boolean success = bundle.getBoolean( DcTracker.DATA_COMPLETE_MSG_EXTRA_SUCCESS); int transport = bundle.getInt( DcTracker.DATA_COMPLETE_MSG_EXTRA_TRANSPORT_TYPE); onDataHandoverSetupCompleted(nr, success, transport); } break; } } } } Loading @@ -157,38 +189,24 @@ public class TelephonyNetworkFactory extends NetworkFactory { return mTransportManager.getCurrentTransport(apnType); } private void requestNetworkInternal(NetworkRequest networkRequest) { int transportType = getTransportTypeFromNetworkRequest(networkRequest); if (mPhone.getDcTracker(transportType) != null) { // TODO: Handover logic will be added later. For now always normal request. mPhone.getDcTracker(transportType).requestNetwork(networkRequest, DcTracker.REQUEST_TYPE_NORMAL, mLocalLog); private void requestNetworkInternal(NetworkRequest networkRequest, @RequestNetworkType int requestType, int transport, Message onCompleteMsg) { if (mPhone.getDcTracker(transport) != null) { mPhone.getDcTracker(transport).requestNetwork(networkRequest, requestType, onCompleteMsg, mLocalLog); } } private void releaseNetworkInternal(NetworkRequest networkRequest, @ReleaseNetworkType int releaseType) { int transportType = getTransportTypeFromNetworkRequest(networkRequest); if (mPhone.getDcTracker(transportType) != null) { // TODO: Handover logic will be added later. For now always normal or detach request. mPhone.getDcTracker(transportType).releaseNetwork(networkRequest, releaseType, @ReleaseNetworkType int releaseType, int transport) { if (mPhone.getDcTracker(transport) != null) { mPhone.getDcTracker(transport).releaseNetwork(networkRequest, releaseType, mLocalLog); } } private void applyRequestsOnActivePhoneSwitch(NetworkRequest networkRequest, int action) { if (action == ACTION_NO_OP) return; String logStr = "onActivePhoneSwitch: " + ((action == ACTION_REQUEST) ? "Requesting" : "Releasing") + " network request " + networkRequest; mLocalLog.log(logStr); if (action == ACTION_REQUEST) { requestNetworkInternal(networkRequest); } else if (action == ACTION_RELEASE) { releaseNetworkInternal(networkRequest, DcTracker.RELEASE_TYPE_DETACH); } } private static int getAction(boolean wasActive, boolean isActive) { if (!wasActive && isActive) { return ACTION_REQUEST; Loading @@ -201,15 +219,30 @@ public class TelephonyNetworkFactory extends NetworkFactory { // apply or revoke requests if our active-ness changes private void onActivePhoneSwitch() { for (HashMap.Entry<NetworkRequest, Boolean> entry : mNetworkRequests.entrySet()) { for (HashMap.Entry<NetworkRequest, Integer> entry : mNetworkRequests.entrySet()) { NetworkRequest networkRequest = entry.getKey(); boolean applied = entry.getValue(); boolean applied = entry.getValue() != TransportType.INVALID; boolean shouldApply = mPhoneSwitcher.shouldApplyNetworkRequest( networkRequest, mPhone.getPhoneId()); applyRequestsOnActivePhoneSwitch(networkRequest, getAction(applied, shouldApply)); mNetworkRequests.put(networkRequest, shouldApply); int action = getAction(applied, shouldApply); if (action == ACTION_NO_OP) continue; String logStr = "onActivePhoneSwitch: " + ((action == ACTION_REQUEST) ? "Requesting" : "Releasing") + " network request " + networkRequest; mLocalLog.log(logStr); int transportType = getTransportTypeFromNetworkRequest(networkRequest); if (action == ACTION_REQUEST) { requestNetworkInternal(networkRequest, DcTracker.REQUEST_TYPE_NORMAL, getTransportTypeFromNetworkRequest(networkRequest), null); } else if (action == ACTION_RELEASE) { int transport = getTransportTypeFromNetworkRequest(networkRequest); releaseNetworkInternal(networkRequest, DcTracker.RELEASE_TYPE_DETACH, transport); } mNetworkRequests.put(networkRequest, shouldApply ? transportType : TransportType.INVALID); } } Loading Loading @@ -237,14 +270,16 @@ public class TelephonyNetworkFactory extends NetworkFactory { boolean shouldApply = mPhoneSwitcher.shouldApplyNetworkRequest( networkRequest, mPhone.getPhoneId()); mNetworkRequests.put(networkRequest, shouldApply); mNetworkRequests.put(networkRequest, shouldApply ? getTransportTypeFromNetworkRequest(networkRequest) : TransportType.INVALID); String s = "onNeedNetworkFor " + networkRequest + " shouldApply " + shouldApply; log(s); mLocalLog.log(s); if (shouldApply) { requestNetworkInternal(networkRequest); requestNetworkInternal(networkRequest, DcTracker.REQUEST_TYPE_NORMAL, getTransportTypeFromNetworkRequest(networkRequest), null); } } Loading @@ -257,7 +292,7 @@ public class TelephonyNetworkFactory extends NetworkFactory { private void onReleaseNetworkFor(Message msg) { NetworkRequest networkRequest = (NetworkRequest)msg.obj; boolean applied = mNetworkRequests.get(networkRequest); boolean applied = mNetworkRequests.get(networkRequest) != TransportType.INVALID; mNetworkRequests.remove(networkRequest); Loading @@ -266,7 +301,60 @@ public class TelephonyNetworkFactory extends NetworkFactory { mLocalLog.log(s); if (applied) { releaseNetworkInternal(networkRequest, DcTracker.RELEASE_TYPE_NORMAL); int transport = getTransportTypeFromNetworkRequest(networkRequest); releaseNetworkInternal(networkRequest, DcTracker.RELEASE_TYPE_NORMAL, transport); } } private void onDataHandoverNeeded(@ApnType int apnType, int targetTransport) { log("onDataHandoverNeeded: apnType=" + ApnSetting.getApnTypeString(apnType) + ", target transport=" + TransportType.toString(targetTransport)); if (mTransportManager.getCurrentTransport(apnType) == targetTransport) { log("apnType " + ApnSetting.getApnTypeString(apnType) + " is already on " + TransportType.toString(targetTransport)); return; } for (HashMap.Entry<NetworkRequest, Integer> entry : mNetworkRequests.entrySet()) { NetworkRequest networkRequest = entry.getKey(); int currentTransport = entry.getValue(); boolean applied = currentTransport != TransportType.INVALID; if (ApnContext.getApnTypeFromNetworkRequest(networkRequest) == apnType && applied && currentTransport != targetTransport) { Message onCompleteMsg = mInternalHandler.obtainMessage( EVENT_DATA_HANDOVER_COMPLETED); onCompleteMsg.getData().putParcelable( DcTracker.DATA_COMPLETE_MSG_EXTRA_NETWORK_REQUEST, networkRequest); requestNetworkInternal(networkRequest, DcTracker.REQUEST_TYPE_HANDOVER, targetTransport, onCompleteMsg); } } } private void onDataHandoverSetupCompleted(NetworkRequest networkRequest, boolean success, int targetTransport) { log("onDataHandoverSetupCompleted: " + networkRequest + ", success=" + success + ", targetTransport=" + TransportType.toString(targetTransport)); // At this point, handover setup has been completed on the target transport. If succeeded, // we can release the data connection on the original transport. If failed, then we also // need to remove the network request from the targeting transport. if (success) { // Handover setup succeeded on targeting transport. Now we can release the network // request on the original transport. int originTransport = (targetTransport == TransportType.WWAN) ? TransportType.WLAN : TransportType.WWAN; int apnType = ApnContext.getApnTypeFromNetworkRequest(networkRequest); releaseNetworkInternal(networkRequest, DcTracker.RELEASE_TYPE_HANDOVER, originTransport); mNetworkRequests.put(networkRequest, targetTransport); // Switch the current transport to the new one. mTransportManager.setCurrentTransport(apnType, targetTransport); } else { // If handover failed, we need to remove the request on the targeting transport. releaseNetworkInternal(networkRequest, DcTracker.RELEASE_TYPE_NORMAL, targetTransport); } } Loading @@ -278,10 +366,11 @@ public class TelephonyNetworkFactory extends NetworkFactory { final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " "); pw.println("Network Requests:"); pw.increaseIndent(); for (HashMap.Entry<NetworkRequest, Boolean> entry : mNetworkRequests.entrySet()) { for (HashMap.Entry<NetworkRequest, Integer> entry : mNetworkRequests.entrySet()) { NetworkRequest nr = entry.getKey(); boolean applied = entry.getValue(); pw.println((applied ? "Applied: " : "Not applied: ") + nr); int transport = entry.getValue(); pw.println(nr + (transport != TransportType.INVALID ? (" applied on " + transport) : " not applied")); } mLocalLog.dump(fd, pw, args); pw.decreaseIndent(); Loading
src/java/com/android/internal/telephony/dataconnection/TransportManager.java +121 −15 File changed.Preview size limit exceeded, changes collapsed. Show changes