Loading src/java/com/android/internal/telephony/data/DataNetwork.java +27 −14 Original line number Diff line number Diff line Loading @@ -1842,6 +1842,31 @@ public class DataNetwork extends StateMachine { || !oldImmutableCapabilities.containsAll(newImmutableCapabilities); } /** * In some rare cases we need to re-create the network agent, for example, underlying network * IP changed, or when we unfortunately need to remove/add a immutable network capability. */ private void recreateNetworkAgent() { if (isConnecting() || isDisconnected() || isDisconnecting()) { loge("Incorrect state for re-creating the network agent."); return; } // Abandon the network agent because we are going to create a new one. mNetworkAgent.abandon(); // Create a new network agent and register with connectivity service. Note that the agent // will always be registered with NOT_SUSPENDED capability. mNetworkAgent = createNetworkAgent(); mNetworkAgent.markConnected(); // Because network agent is always created with NOT_SUSPENDED, we need to update // the suspended if it's was in suspended state. if (mSuspended) { log("recreateNetworkAgent: The network is in suspended state. Update the network" + " capability again. nc=" + mNetworkCapabilities); mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities); } } /** * Update the network capabilities. */ Loading Loading @@ -2040,13 +2065,8 @@ public class DataNetwork extends StateMachine { logl("updateNetworkCapabilities: Immutable capabilities changed. Re-create the " + "network agent. Attempted to change from " + mNetworkCapabilities + " to " + nc); // Abandon the network agent because we are going to create a new one. mNetworkAgent.abandon(); // Update the capabilities first so the new network agent would be created with the // new capabilities. mNetworkCapabilities = nc; mNetworkAgent = createNetworkAgent(); mNetworkAgent.markConnected(); recreateNetworkAgent(); } else { // Now we need to inform connectivity service and data network controller // about the capabilities changed. Loading Loading @@ -2341,14 +2361,7 @@ public class DataNetwork extends StateMachine { + linkProperties); mLinkProperties = linkProperties; // Abandon the network agent because we are going to create a new one. mNetworkAgent.abandon(); // Update the link properties first so the new network agent would be created with // the new link properties. mLinkProperties = linkProperties; mNetworkAgent = createNetworkAgent(); mNetworkAgent.markConnected(); recreateNetworkAgent(); } else { mLinkProperties = linkProperties; log("sendLinkProperties " + mLinkProperties); Loading src/java/com/android/internal/telephony/data/TelephonyNetworkAgent.java +11 −2 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.annotation.Nullable; import android.net.KeepalivePacketData; import android.net.NetworkAgent; import android.net.NetworkAgentConfig; import android.net.NetworkCapabilities; import android.net.NetworkProvider; import android.net.NetworkScore; import android.net.QosFilter; Loading Loading @@ -153,7 +154,13 @@ public class TelephonyNetworkAgent extends NetworkAgent implements NotifyQosSess @NonNull NetworkAgentConfig config, @NonNull NetworkProvider provider, @NonNull TelephonyNetworkAgentCallback callback) { super(phone.getContext(), looper, "TelephonyNetworkAgent", dataNetwork.getNetworkCapabilities(), dataNetwork.getLinkProperties(), score, // Connectivity service does not allow an agent created in suspended state. // Always create the network agent with NOT_SUSPENDED and immediately update the // suspended state afterwards. new NetworkCapabilities.Builder(dataNetwork.getNetworkCapabilities()) .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED) .build(), dataNetwork.getLinkProperties(), score, config, provider); register(); mDataNetwork = dataNetwork; Loading @@ -164,7 +171,9 @@ public class TelephonyNetworkAgent extends NetworkAgent implements NotifyQosSess mLogTag = "TNA-" + mId; log("TelephonyNetworkAgent created, nc=" + dataNetwork.getNetworkCapabilities() + ", score=" + score); + new NetworkCapabilities.Builder(dataNetwork.getNetworkCapabilities()) .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED) .build() + ", score=" + score); } /** Loading tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkTest.java +100 −0 Original line number Diff line number Diff line Loading @@ -469,6 +469,106 @@ public class DataNetworkTest extends TelephonyTest { verify(mDataNetworkCallback).onConnected(eq(mDataNetworkUT)); } @Test public void testCreateDataNetworkWhenOos() throws Exception { DataSpecificRegistrationInfo dsri = new DataSpecificRegistrationInfo(8, false, true, true, new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_SUPPORTED, LteVopsSupportInfo.LTE_STATUS_SUPPORTED)); // Out of service serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE, NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING, dsri); NetworkRequestList networkRequestList = new NetworkRequestList(); networkRequestList.add(new TelephonyNetworkRequest(new NetworkRequest.Builder() .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) .build(), mPhone)); setSuccessfulSetupDataResponse(mMockedWwanDataServiceManager, 123); mDataNetworkUT = new DataNetwork(mPhone, Looper.myLooper(), mDataServiceManagers, mInternetDataProfile, networkRequestList, AccessNetworkConstants.TRANSPORT_TYPE_WWAN, DataAllowedReason.NORMAL, mDataNetworkCallback); replaceInstance(DataNetwork.class, "mDataCallSessionStats", mDataNetworkUT, mDataCallSessionStats); processAllMessages(); ArgumentCaptor<NetworkCapabilities> networkCapabilitiesCaptor = ArgumentCaptor.forClass(NetworkCapabilities.class); verify(mConnectivityManager).registerNetworkAgent(any(), any(NetworkInfo.class), any(LinkProperties.class), networkCapabilitiesCaptor.capture(), any(), any(), anyInt()); // Make sure the initial network capability has NOT_SUSPENDED assertThat(networkCapabilitiesCaptor.getValue().hasCapability( NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED)).isTrue(); // The final network should not have NOT_SUSPENDED because the device is OOS. assertThat(mDataNetworkUT.getNetworkCapabilities().hasCapability( NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED)).isFalse(); } @Test public void testRecreateAgentWhenOos() throws Exception { testCreateDataNetwork(); DataSpecificRegistrationInfo dsri = new DataSpecificRegistrationInfo(8, false, true, true, new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_SUPPORTED, LteVopsSupportInfo.LTE_STATUS_SUPPORTED)); // Out of service serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE, NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING, dsri); DataCallResponse response = new DataCallResponse.Builder() .setCause(0) .setRetryDurationMillis(-1L) .setId(123) .setLinkStatus(2) .setProtocolType(ApnSetting.PROTOCOL_IPV4V6) .setInterfaceName("ifname") .setAddresses(Arrays.asList( new LinkAddress(InetAddresses.parseNumericAddress(IPV4_ADDRESS1), 32), new LinkAddress(IPV6_ADDRESS + "/64"))) .setDnsAddresses(Arrays.asList(InetAddresses.parseNumericAddress("10.0.2.3"), InetAddresses.parseNumericAddress("fd00:976a::9"))) .setGatewayAddresses(Arrays.asList( InetAddresses.parseNumericAddress("10.0.2.15"), InetAddresses.parseNumericAddress("fe80::2"))) .setPcscfAddresses(Arrays.asList( InetAddresses.parseNumericAddress("fd00:976a:c305:1d::8"), InetAddresses.parseNumericAddress("fd00:976a:c202:1d::7"), InetAddresses.parseNumericAddress("fd00:976a:c305:1d::5"))) .setMtuV4(1234) .setMtuV6(5678) .setPduSessionId(1) .setQosBearerSessions(new ArrayList<>()) .setTrafficDescriptors(Collections.emptyList()) .build(); // IP changes mDataNetworkUT.obtainMessage(8/*EVENT_DATA_STATE_CHANGED*/, new AsyncResult(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, List.of(response), null)).sendToTarget(); processAllMessages(); ArgumentCaptor<NetworkCapabilities> networkCapabilitiesCaptor = ArgumentCaptor.forClass(NetworkCapabilities.class); // Agent re-created, so register should be called twice. verify(mConnectivityManager, times(2)).registerNetworkAgent(any(), any(NetworkInfo.class), any(LinkProperties.class), networkCapabilitiesCaptor.capture(), any(), any(), anyInt()); // Make sure the 2nd network agent was created with NOT_SUSPENDED. assertThat(networkCapabilitiesCaptor.getValue().hasCapability( NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED)).isTrue(); // The final network should not have NOT_SUSPENDED because the device is OOS. assertThat(mDataNetworkUT.getNetworkCapabilities().hasCapability( NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED)).isFalse(); } @Test public void testRilCrash() throws Exception { NetworkRequestList networkRequestList = new NetworkRequestList(); Loading Loading
src/java/com/android/internal/telephony/data/DataNetwork.java +27 −14 Original line number Diff line number Diff line Loading @@ -1842,6 +1842,31 @@ public class DataNetwork extends StateMachine { || !oldImmutableCapabilities.containsAll(newImmutableCapabilities); } /** * In some rare cases we need to re-create the network agent, for example, underlying network * IP changed, or when we unfortunately need to remove/add a immutable network capability. */ private void recreateNetworkAgent() { if (isConnecting() || isDisconnected() || isDisconnecting()) { loge("Incorrect state for re-creating the network agent."); return; } // Abandon the network agent because we are going to create a new one. mNetworkAgent.abandon(); // Create a new network agent and register with connectivity service. Note that the agent // will always be registered with NOT_SUSPENDED capability. mNetworkAgent = createNetworkAgent(); mNetworkAgent.markConnected(); // Because network agent is always created with NOT_SUSPENDED, we need to update // the suspended if it's was in suspended state. if (mSuspended) { log("recreateNetworkAgent: The network is in suspended state. Update the network" + " capability again. nc=" + mNetworkCapabilities); mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities); } } /** * Update the network capabilities. */ Loading Loading @@ -2040,13 +2065,8 @@ public class DataNetwork extends StateMachine { logl("updateNetworkCapabilities: Immutable capabilities changed. Re-create the " + "network agent. Attempted to change from " + mNetworkCapabilities + " to " + nc); // Abandon the network agent because we are going to create a new one. mNetworkAgent.abandon(); // Update the capabilities first so the new network agent would be created with the // new capabilities. mNetworkCapabilities = nc; mNetworkAgent = createNetworkAgent(); mNetworkAgent.markConnected(); recreateNetworkAgent(); } else { // Now we need to inform connectivity service and data network controller // about the capabilities changed. Loading Loading @@ -2341,14 +2361,7 @@ public class DataNetwork extends StateMachine { + linkProperties); mLinkProperties = linkProperties; // Abandon the network agent because we are going to create a new one. mNetworkAgent.abandon(); // Update the link properties first so the new network agent would be created with // the new link properties. mLinkProperties = linkProperties; mNetworkAgent = createNetworkAgent(); mNetworkAgent.markConnected(); recreateNetworkAgent(); } else { mLinkProperties = linkProperties; log("sendLinkProperties " + mLinkProperties); Loading
src/java/com/android/internal/telephony/data/TelephonyNetworkAgent.java +11 −2 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.annotation.Nullable; import android.net.KeepalivePacketData; import android.net.NetworkAgent; import android.net.NetworkAgentConfig; import android.net.NetworkCapabilities; import android.net.NetworkProvider; import android.net.NetworkScore; import android.net.QosFilter; Loading Loading @@ -153,7 +154,13 @@ public class TelephonyNetworkAgent extends NetworkAgent implements NotifyQosSess @NonNull NetworkAgentConfig config, @NonNull NetworkProvider provider, @NonNull TelephonyNetworkAgentCallback callback) { super(phone.getContext(), looper, "TelephonyNetworkAgent", dataNetwork.getNetworkCapabilities(), dataNetwork.getLinkProperties(), score, // Connectivity service does not allow an agent created in suspended state. // Always create the network agent with NOT_SUSPENDED and immediately update the // suspended state afterwards. new NetworkCapabilities.Builder(dataNetwork.getNetworkCapabilities()) .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED) .build(), dataNetwork.getLinkProperties(), score, config, provider); register(); mDataNetwork = dataNetwork; Loading @@ -164,7 +171,9 @@ public class TelephonyNetworkAgent extends NetworkAgent implements NotifyQosSess mLogTag = "TNA-" + mId; log("TelephonyNetworkAgent created, nc=" + dataNetwork.getNetworkCapabilities() + ", score=" + score); + new NetworkCapabilities.Builder(dataNetwork.getNetworkCapabilities()) .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED) .build() + ", score=" + score); } /** Loading
tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkTest.java +100 −0 Original line number Diff line number Diff line Loading @@ -469,6 +469,106 @@ public class DataNetworkTest extends TelephonyTest { verify(mDataNetworkCallback).onConnected(eq(mDataNetworkUT)); } @Test public void testCreateDataNetworkWhenOos() throws Exception { DataSpecificRegistrationInfo dsri = new DataSpecificRegistrationInfo(8, false, true, true, new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_SUPPORTED, LteVopsSupportInfo.LTE_STATUS_SUPPORTED)); // Out of service serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE, NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING, dsri); NetworkRequestList networkRequestList = new NetworkRequestList(); networkRequestList.add(new TelephonyNetworkRequest(new NetworkRequest.Builder() .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) .build(), mPhone)); setSuccessfulSetupDataResponse(mMockedWwanDataServiceManager, 123); mDataNetworkUT = new DataNetwork(mPhone, Looper.myLooper(), mDataServiceManagers, mInternetDataProfile, networkRequestList, AccessNetworkConstants.TRANSPORT_TYPE_WWAN, DataAllowedReason.NORMAL, mDataNetworkCallback); replaceInstance(DataNetwork.class, "mDataCallSessionStats", mDataNetworkUT, mDataCallSessionStats); processAllMessages(); ArgumentCaptor<NetworkCapabilities> networkCapabilitiesCaptor = ArgumentCaptor.forClass(NetworkCapabilities.class); verify(mConnectivityManager).registerNetworkAgent(any(), any(NetworkInfo.class), any(LinkProperties.class), networkCapabilitiesCaptor.capture(), any(), any(), anyInt()); // Make sure the initial network capability has NOT_SUSPENDED assertThat(networkCapabilitiesCaptor.getValue().hasCapability( NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED)).isTrue(); // The final network should not have NOT_SUSPENDED because the device is OOS. assertThat(mDataNetworkUT.getNetworkCapabilities().hasCapability( NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED)).isFalse(); } @Test public void testRecreateAgentWhenOos() throws Exception { testCreateDataNetwork(); DataSpecificRegistrationInfo dsri = new DataSpecificRegistrationInfo(8, false, true, true, new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_SUPPORTED, LteVopsSupportInfo.LTE_STATUS_SUPPORTED)); // Out of service serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE, NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING, dsri); DataCallResponse response = new DataCallResponse.Builder() .setCause(0) .setRetryDurationMillis(-1L) .setId(123) .setLinkStatus(2) .setProtocolType(ApnSetting.PROTOCOL_IPV4V6) .setInterfaceName("ifname") .setAddresses(Arrays.asList( new LinkAddress(InetAddresses.parseNumericAddress(IPV4_ADDRESS1), 32), new LinkAddress(IPV6_ADDRESS + "/64"))) .setDnsAddresses(Arrays.asList(InetAddresses.parseNumericAddress("10.0.2.3"), InetAddresses.parseNumericAddress("fd00:976a::9"))) .setGatewayAddresses(Arrays.asList( InetAddresses.parseNumericAddress("10.0.2.15"), InetAddresses.parseNumericAddress("fe80::2"))) .setPcscfAddresses(Arrays.asList( InetAddresses.parseNumericAddress("fd00:976a:c305:1d::8"), InetAddresses.parseNumericAddress("fd00:976a:c202:1d::7"), InetAddresses.parseNumericAddress("fd00:976a:c305:1d::5"))) .setMtuV4(1234) .setMtuV6(5678) .setPduSessionId(1) .setQosBearerSessions(new ArrayList<>()) .setTrafficDescriptors(Collections.emptyList()) .build(); // IP changes mDataNetworkUT.obtainMessage(8/*EVENT_DATA_STATE_CHANGED*/, new AsyncResult(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, List.of(response), null)).sendToTarget(); processAllMessages(); ArgumentCaptor<NetworkCapabilities> networkCapabilitiesCaptor = ArgumentCaptor.forClass(NetworkCapabilities.class); // Agent re-created, so register should be called twice. verify(mConnectivityManager, times(2)).registerNetworkAgent(any(), any(NetworkInfo.class), any(LinkProperties.class), networkCapabilitiesCaptor.capture(), any(), any(), anyInt()); // Make sure the 2nd network agent was created with NOT_SUSPENDED. assertThat(networkCapabilitiesCaptor.getValue().hasCapability( NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED)).isTrue(); // The final network should not have NOT_SUSPENDED because the device is OOS. assertThat(mDataNetworkUT.getNetworkCapabilities().hasCapability( NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED)).isFalse(); } @Test public void testRilCrash() throws Exception { NetworkRequestList networkRequestList = new NetworkRequestList(); Loading