diff --git a/framework/src/android/net/NetworkInfo.java b/framework/src/android/net/NetworkInfo.java index b7ec519d2c..7aa984709b 100644 --- a/framework/src/android/net/NetworkInfo.java +++ b/framework/src/android/net/NetworkInfo.java @@ -333,6 +333,24 @@ public class NetworkInfo implements Parcelable { } } + /** + * Indicates whether this network is suspended. + * @deprecated Apps should instead use the + * {@link android.net.ConnectivityManager.NetworkCallback} API to + * learn about connectivity changes. See + * {@link ConnectivityManager#registerDefaultNetworkCallback} and + * {@link ConnectivityManager#registerNetworkCallback}. These will + * give a more accurate picture of the connectivity state of + * the device and let apps react more easily and quickly to changes. + * @hide + */ + @Deprecated + public boolean isSuspended() { + synchronized (this) { + return mState == State.SUSPENDED; + } + } + /** * Indicates whether network connectivity is possible. A network is unavailable * when a persistent or semi-persistent condition prevents the possibility diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java index b17af9978d..c667d72d90 100755 --- a/service/src/com/android/server/ConnectivityService.java +++ b/service/src/com/android/server/ConnectivityService.java @@ -4546,7 +4546,7 @@ public class ConnectivityService extends IConnectivityManager.Stub // because they lost all their requests or because their score isn't good) // then they would disconnect organically, report their new state and then // disconnect the channel. - if (nai.networkInfo.isConnected()) { + if (nai.networkInfo.isConnected() || nai.networkInfo.isSuspended()) { nai.networkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, null, null); } diff --git a/tests/unit/java/com/android/server/ConnectivityServiceTest.java b/tests/unit/java/com/android/server/ConnectivityServiceTest.java index 31f3124e54..e6ffecd51d 100755 --- a/tests/unit/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/unit/java/com/android/server/ConnectivityServiceTest.java @@ -17987,4 +17987,33 @@ public class ConnectivityServiceTest { verify(mDeps).destroyLiveTcpSockets(eq(UidRange.toIntRanges(ranges)), eq(exemptUids)); } + + @Test + public void testDisconnectSuspendedNetworkStopClatd() throws Exception { + final TestNetworkCallback networkCallback = new TestNetworkCallback(); + final NetworkRequest networkRequest = new NetworkRequest.Builder() + .addCapability(NET_CAPABILITY_DUN) + .build(); + mCm.requestNetwork(networkRequest, networkCallback); + + final IpPrefix nat64Prefix = new IpPrefix(InetAddress.getByName("64:ff9b::"), 96); + NetworkCapabilities nc = new NetworkCapabilities().addCapability(NET_CAPABILITY_DUN); + final LinkProperties lp = new LinkProperties(); + lp.setInterfaceName(MOBILE_IFNAME); + lp.addLinkAddress(new LinkAddress("2001:db8:1::1/64")); + lp.setNat64Prefix(nat64Prefix); + mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, lp, nc); + mCellAgent.connect(true /* validated */, false /* hasInternet */, + false /* privateDnsProbeSent */); + + verifyClatdStart(null /* inOrder */, MOBILE_IFNAME, mCellAgent.getNetwork().netId, + nat64Prefix.toString()); + + mCellAgent.suspend(); + mCm.unregisterNetworkCallback(networkCallback); + mCellAgent.expectDisconnected(); + waitForIdle(); + + verifyClatdStop(null /* inOrder */, MOBILE_IFNAME); + } }