diff options
7 files changed, 150 insertions, 41 deletions
diff --git a/api/current.txt b/api/current.txt index 4762095a6617..cd29286aacc6 100644 --- a/api/current.txt +++ b/api/current.txt @@ -25716,7 +25716,7 @@ package android.net {      field public static final deprecated java.lang.String ACTION_BACKGROUND_DATA_SETTING_CHANGED = "android.net.conn.BACKGROUND_DATA_SETTING_CHANGED";      field public static final java.lang.String ACTION_CAPTIVE_PORTAL_SIGN_IN = "android.net.conn.CAPTIVE_PORTAL";      field public static final java.lang.String ACTION_RESTRICT_BACKGROUND_CHANGED = "android.net.conn.RESTRICT_BACKGROUND_CHANGED"; -    field public static final java.lang.String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE"; +    field public static final deprecated java.lang.String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";      field public static final deprecated int DEFAULT_NETWORK_PREFERENCE = 1; // 0x1      field public static final java.lang.String EXTRA_CAPTIVE_PORTAL = "android.net.extra.CAPTIVE_PORTAL";      field public static final java.lang.String EXTRA_CAPTIVE_PORTAL_URL = "android.net.extra.CAPTIVE_PORTAL_URL"; @@ -25992,6 +25992,7 @@ package android.net {      field public static final int NET_CAPABILITY_CBS = 5; // 0x5      field public static final int NET_CAPABILITY_DUN = 2; // 0x2      field public static final int NET_CAPABILITY_EIMS = 10; // 0xa +    field public static final int NET_CAPABILITY_FOREGROUND = 19; // 0x13      field public static final int NET_CAPABILITY_FOTA = 3; // 0x3      field public static final int NET_CAPABILITY_IA = 7; // 0x7      field public static final int NET_CAPABILITY_IMS = 4; // 0x4 @@ -26000,6 +26001,7 @@ package android.net {      field public static final int NET_CAPABILITY_NOT_METERED = 11; // 0xb      field public static final int NET_CAPABILITY_NOT_RESTRICTED = 13; // 0xd      field public static final int NET_CAPABILITY_NOT_ROAMING = 18; // 0x12 +    field public static final int NET_CAPABILITY_NOT_SUSPENDED = 21; // 0x15      field public static final int NET_CAPABILITY_NOT_VPN = 15; // 0xf      field public static final int NET_CAPABILITY_RCS = 8; // 0x8      field public static final int NET_CAPABILITY_SUPL = 1; // 0x1 diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 11d338d05c68..2e701329dbfc 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -112,8 +112,14 @@ public class ConnectivityManager {       * <p/>       * For a disconnect event, the boolean extra EXTRA_NO_CONNECTIVITY       * is set to {@code true} if there are no connected networks at all. +     * +     * @deprecated apps should use the more versatile {@link #requestNetwork}, +     *             {@link #registerNetworkCallback} or {@link #registerDefaultNetworkCallback} +     *             functions instead for faster and more detailed updates about the network +     *             changes they care about.       */      @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) +    @Deprecated      public static final String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";      /** @@ -2685,6 +2691,32 @@ public class ConnectivityManager {           * satisfying the request changes.           *           * @param network The {@link Network} of the satisfying network. +         * @param networkCapabilities The {@link NetworkCapabilities} of the satisfying network. +         * @param linkProperties The {@link LinkProperties} of the satisfying network. +         * @hide +         */ +        public void onAvailable(Network network, NetworkCapabilities networkCapabilities, +                LinkProperties linkProperties) { +            // Internally only this method is called when a new network is available, and +            // it calls the callback in the same way and order that older versions used +            // to call so as not to change the behavior. +            onAvailable(network); +            if (!networkCapabilities.hasCapability( +                    NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED)) { +                onNetworkSuspended(network); +            } +            onCapabilitiesChanged(network, networkCapabilities); +            onLinkPropertiesChanged(network, linkProperties); +        } + +        /** +         * Called when the framework connects and has declared a new network ready for use. +         * This callback may be called more than once if the {@link Network} that is +         * satisfying the request changes. This will always immediately be followed by a +         * call to {@link #onCapabilitiesChanged(Network, NetworkCapabilities)} then by a +         * call to {@link #onLinkPropertiesChanged(Network, LinkProperties)}. +         * +         * @param network The {@link Network} of the satisfying network.           */          public void onAvailable(Network network) {} @@ -2727,7 +2759,8 @@ public class ConnectivityManager {           * changes capabilities but still satisfies the stated need.           *           * @param network The {@link Network} whose capabilities have changed. -         * @param networkCapabilities The new {@link android.net.NetworkCapabilities} for this network. +         * @param networkCapabilities The new {@link android.net.NetworkCapabilities} for this +         *                            network.           */          public void onCapabilitiesChanged(Network network,                  NetworkCapabilities networkCapabilities) {} @@ -2743,7 +2776,7 @@ public class ConnectivityManager {          /**           * Called when the network the framework connected to for this request -         * goes into {@link NetworkInfo.DetailedState.SUSPENDED}. +         * goes into {@link NetworkInfo.State#SUSPENDED}.           * This generally means that while the TCP connections are still live,           * temporarily network data fails to transfer.  Specifically this is used           * on cellular networks to mask temporary outages when driving through @@ -2754,9 +2787,8 @@ public class ConnectivityManager {          /**           * Called when the network the framework connected to for this request -         * returns from a {@link NetworkInfo.DetailedState.SUSPENDED} state. -         * This should always be preceeded by a matching {@code onNetworkSuspended} -         * call. +         * returns from a {@link NetworkInfo.State#SUSPENDED} state. This should always be +         * preceded by a matching {@link NetworkCallback#onNetworkSuspended} call.           * @hide           */          public void onNetworkResumed(Network network) {} @@ -2865,7 +2897,9 @@ public class ConnectivityManager {                      break;                  }                  case CALLBACK_AVAILABLE: { -                    callback.onAvailable(network); +                    NetworkCapabilities cap = getObject(message, NetworkCapabilities.class); +                    LinkProperties lp = getObject(message, LinkProperties.class); +                    callback.onAvailable(network, cap, lp);                      break;                  }                  case CALLBACK_LOSING: { diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java index e81ed9a21c4f..bc4d9555c9e7 100644 --- a/core/java/android/net/NetworkCapabilities.java +++ b/core/java/android/net/NetworkCapabilities.java @@ -116,6 +116,7 @@ public final class NetworkCapabilities implements Parcelable {              NET_CAPABILITY_NOT_ROAMING,              NET_CAPABILITY_FOREGROUND,              NET_CAPABILITY_NOT_CONGESTED, +            NET_CAPABILITY_NOT_SUSPENDED,      })      public @interface NetCapability { } @@ -239,7 +240,6 @@ public final class NetworkCapabilities implements Parcelable {      /**       * Indicates that this network is available for use by apps, and not a network that is being       * kept up in the background to facilitate fast network switching. -     * @hide       */      public static final int NET_CAPABILITY_FOREGROUND = 19; @@ -252,8 +252,20 @@ public final class NetworkCapabilities implements Parcelable {       */      public static final int NET_CAPABILITY_NOT_CONGESTED = 20; +    /** +     * Indicates that this network is not currently suspended. +     * <p> +     * When a network is suspended, the network's IP addresses and any connections +     * established on the network remain valid, but the network is temporarily unable +     * to transfer data. This can happen, for example, if a cellular network experiences +     * a temporary loss of signal, such as when driving through a tunnel, etc. +     * A network with this capability is not suspended, so is expected to be able to +     * transfer data. +     */ +    public static final int NET_CAPABILITY_NOT_SUSPENDED = 21; +      private static final int MIN_NET_CAPABILITY = NET_CAPABILITY_MMS; -    private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_NOT_CONGESTED; +    private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_NOT_SUSPENDED;      /**       * Network capabilities that are expected to be mutable, i.e., can change while a particular @@ -262,12 +274,13 @@ public final class NetworkCapabilities implements Parcelable {      private static final long MUTABLE_CAPABILITIES =              // TRUSTED can change when user explicitly connects to an untrusted network in Settings.              // http://b/18206275 -            (1 << NET_CAPABILITY_TRUSTED) | -            (1 << NET_CAPABILITY_VALIDATED) | -            (1 << NET_CAPABILITY_CAPTIVE_PORTAL) | -            (1 << NET_CAPABILITY_NOT_ROAMING) | -            (1 << NET_CAPABILITY_FOREGROUND) | -            (1 << NET_CAPABILITY_NOT_CONGESTED); +            (1 << NET_CAPABILITY_TRUSTED) +            | (1 << NET_CAPABILITY_VALIDATED) +            | (1 << NET_CAPABILITY_CAPTIVE_PORTAL) +            | (1 << NET_CAPABILITY_NOT_ROAMING) +            | (1 << NET_CAPABILITY_FOREGROUND) +            | (1 << NET_CAPABILITY_NOT_CONGESTED) +            | (1 << NET_CAPABILITY_NOT_SUSPENDED);      /**       * Network capabilities that are not allowed in NetworkRequests. This exists because the @@ -1276,6 +1289,7 @@ public final class NetworkCapabilities implements Parcelable {              case NET_CAPABILITY_NOT_ROAMING:    return "NOT_ROAMING";              case NET_CAPABILITY_FOREGROUND:     return "FOREGROUND";              case NET_CAPABILITY_NOT_CONGESTED:  return "NOT_CONGESTED"; +            case NET_CAPABILITY_NOT_SUSPENDED:  return "NOT_SUSPENDED";              default:                            return Integer.toString(capability);          }      } diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index bff5c10d4e82..fd2ef18d624a 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -30,6 +30,7 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;  import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;  import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;  import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING; +import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED;  import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;  import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;  import static android.net.NetworkCapabilities.TRANSPORT_VPN; @@ -1260,11 +1261,7 @@ public class ConnectivityService extends IConnectivityManager.Stub                          for (Network network : networks) {                              nai = getNetworkAgentInfoForNetwork(network);                              nc = getNetworkCapabilitiesInternal(nai); -                            // nc is a copy of the capabilities in nai, so it's fine to mutate it -                            // TODO : don't remove the UIDs when communicating with processes -                            // that have the NETWORK_SETTINGS permission.                              if (nc != null) { -                                nc.setSingleUid(userId);                                  result.put(network, nc);                              }                          } @@ -1332,7 +1329,9 @@ public class ConnectivityService extends IConnectivityManager.Stub          if (nai != null) {              synchronized (nai) {                  if (nai.networkCapabilities != null) { -                    return new NetworkCapabilities(nai.networkCapabilities); +                    // TODO : don't remove the UIDs when communicating with processes +                    // that have the NETWORK_SETTINGS permission. +                    return networkCapabilitiesWithoutUids(nai.networkCapabilities);                  }              }          } @@ -1345,6 +1344,10 @@ public class ConnectivityService extends IConnectivityManager.Stub          return getNetworkCapabilitiesInternal(getNetworkAgentInfoForNetwork(network));      } +    private NetworkCapabilities networkCapabilitiesWithoutUids(NetworkCapabilities nc) { +        return new NetworkCapabilities(nc).setUids(null); +    } +      @Override      public NetworkState[] getAllNetworkState() {          // Require internal since we're handing out IMSI details @@ -1354,6 +1357,10 @@ public class ConnectivityService extends IConnectivityManager.Stub          for (Network network : getAllNetworks()) {              final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);              if (nai != null) { +                // TODO (b/73321673) : NetworkState contains a copy of the +                // NetworkCapabilities, which may contain UIDs of apps to which the +                // network applies. Should the UIDs be cleared so as not to leak or +                // interfere ?                  result.add(nai.getNetworkState());              }          } @@ -4497,10 +4504,12 @@ public class ConnectivityService extends IConnectivityManager.Stub          lp.ensureDirectlyConnectedRoutes();          // TODO: Instead of passing mDefaultRequest, provide an API to determine whether a Network          // satisfies mDefaultRequest. +        final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);          final NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(), -                new Network(reserveNetId()), new NetworkInfo(networkInfo), lp, -                new NetworkCapabilities(networkCapabilities), currentScore, +                new Network(reserveNetId()), new NetworkInfo(networkInfo), lp, nc, currentScore,                  mContext, mTrackerHandler, new NetworkMisc(networkMisc), mDefaultRequest, this); +        // Make sure the network capabilities reflect what the agent info says. +        nai.networkCapabilities = mixInCapabilities(nai, nc);          synchronized (this) {              nai.networkMonitor.systemReady = mSystemReady;          } @@ -4729,6 +4738,11 @@ public class ConnectivityService extends IConnectivityManager.Stub          } else {              newNc.addCapability(NET_CAPABILITY_FOREGROUND);          } +        if (nai.isSuspended()) { +            newNc.removeCapability(NET_CAPABILITY_NOT_SUSPENDED); +        } else { +            newNc.addCapability(NET_CAPABILITY_NOT_SUSPENDED); +        }          return newNc;      } @@ -4909,7 +4923,7 @@ public class ConnectivityService extends IConnectivityManager.Stub          releasePendingNetworkRequestWithDelay(pendingIntent);      } -    private static void callCallbackForRequest(NetworkRequestInfo nri, +    private void callCallbackForRequest(NetworkRequestInfo nri,              NetworkAgentInfo networkAgent, int notificationType, int arg1) {          if (nri.messenger == null) {              return;  // Default request has no msgr @@ -4922,16 +4936,19 @@ public class ConnectivityService extends IConnectivityManager.Stub              putParcelable(bundle, networkAgent.network);          }          switch (notificationType) { +            case ConnectivityManager.CALLBACK_AVAILABLE: { +                putParcelable(bundle, new NetworkCapabilities(networkAgent.networkCapabilities)); +                putParcelable(bundle, new LinkProperties(networkAgent.linkProperties)); +                break; +            }              case ConnectivityManager.CALLBACK_LOSING: {                  msg.arg1 = arg1;                  break;              }              case ConnectivityManager.CALLBACK_CAP_CHANGED: { +                // networkAgent can't be null as it has been accessed a few lines above.                  final NetworkCapabilities nc = -                        new NetworkCapabilities(networkAgent.networkCapabilities); -                // TODO : don't remove the UIDs when communicating with processes -                // that have the NETWORK_SETTINGS permission. -                nc.setSingleUid(nri.mUid); +                        networkCapabilitiesWithoutUids(networkAgent.networkCapabilities);                  putParcelable(bundle, nc);                  break;              } @@ -5464,6 +5481,10 @@ public class ConnectivityService extends IConnectivityManager.Stub              if (networkAgent.getCurrentScore() != oldScore) {                  rematchAllNetworksAndRequests(networkAgent, oldScore);              } +            updateCapabilities(networkAgent.getCurrentScore(), networkAgent, +                    networkAgent.networkCapabilities); +            // TODO (b/73132094) : remove this call once the few users of onSuspended and +            // onResumed have been removed.              notifyNetworkCallbacks(networkAgent, (state == NetworkInfo.State.SUSPENDED ?                      ConnectivityManager.CALLBACK_SUSPENDED :                      ConnectivityManager.CALLBACK_RESUMED)); @@ -5500,14 +5521,6 @@ public class ConnectivityService extends IConnectivityManager.Stub          }          callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE, 0); -        // Whether a network is currently suspended is also an important -        // element of state to be transferred (it would not otherwise be -        // delivered by any currently available mechanism). -        if (nai.networkInfo.getState() == NetworkInfo.State.SUSPENDED) { -            callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_SUSPENDED, 0); -        } -        callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_CAP_CHANGED, 0); -        callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_IP_CHANGED, 0);      }      private void sendLegacyNetworkBroadcast(NetworkAgentInfo nai, DetailedState state, int type) { diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java index 85b70ca0ffcd..a24f97e53570 100644 --- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java +++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java @@ -392,6 +392,15 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {          return !isVPN() && numForegroundNetworkRequests() == 0 && mNumBackgroundNetworkRequests > 0;      } +    /** +     * Returns whether this network is currently suspended. A network is suspended if it is still +     * connected but data temporarily fails to transfer. See {@link NetworkInfo.State#SUSPENDED} +     * and {@link NetworkCapabilities#NET_CAPABILITY_NOT_SUSPENDED}. +     */ +    public boolean isSuspended() { +        return networkInfo.getState() == NetworkInfo.State.SUSPENDED; +    } +      // Does this network satisfy request?      public boolean satisfies(NetworkRequest request) {          return created && @@ -458,7 +467,7 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {      public NetworkState getNetworkState() {          synchronized (this) { -            // Network objects are outwardly immutable so there is no point to duplicating. +            // Network objects are outwardly immutable so there is no point in duplicating.              // Duplicating also precludes sharing socket factories and connection pools.              final String subscriberId = (networkMisc != null) ? networkMisc.subscriberId : null;              return new NetworkState(new NetworkInfo(networkInfo), diff --git a/tests/net/java/android/net/ConnectivityManagerTest.java b/tests/net/java/android/net/ConnectivityManagerTest.java index cc792cc749d9..03a617c354fa 100644 --- a/tests/net/java/android/net/ConnectivityManagerTest.java +++ b/tests/net/java/android/net/ConnectivityManagerTest.java @@ -38,6 +38,7 @@ import static org.junit.Assert.assertNull;  import static org.junit.Assert.assertTrue;  import static org.junit.Assert.fail;  import static org.mockito.Mockito.any; +import static org.mockito.Mockito.anyBoolean;  import static org.mockito.Mockito.anyInt;  import static org.mockito.Mockito.mock;  import static org.mockito.Mockito.timeout; @@ -217,7 +218,8 @@ public class ConnectivityManagerTest {          // callback triggers          captor.getValue().send(makeMessage(request, ConnectivityManager.CALLBACK_AVAILABLE)); -        verify(callback, timeout(500).times(1)).onAvailable(any()); +        verify(callback, timeout(500).times(1)).onAvailable(any(Network.class), +                any(NetworkCapabilities.class), any(LinkProperties.class));          // unregister callback          manager.unregisterNetworkCallback(callback); @@ -244,7 +246,8 @@ public class ConnectivityManagerTest {          // callback triggers          captor.getValue().send(makeMessage(req1, ConnectivityManager.CALLBACK_AVAILABLE)); -        verify(callback, timeout(100).times(1)).onAvailable(any()); +        verify(callback, timeout(100).times(1)).onAvailable(any(Network.class), +                any(NetworkCapabilities.class), any(LinkProperties.class));          // unregister callback          manager.unregisterNetworkCallback(callback); @@ -335,6 +338,10 @@ public class ConnectivityManagerTest {      static Message makeMessage(NetworkRequest req, int messageType) {          Bundle bundle = new Bundle();          bundle.putParcelable(NetworkRequest.class.getSimpleName(), req); +        // Pass default objects as we don't care which get passed here +        bundle.putParcelable(Network.class.getSimpleName(), new Network(1)); +        bundle.putParcelable(NetworkCapabilities.class.getSimpleName(), new NetworkCapabilities()); +        bundle.putParcelable(LinkProperties.class.getSimpleName(), new LinkProperties());          Message msg = Message.obtain();          msg.what = messageType;          msg.setData(bundle); diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index e7abede4cda4..24639e9e3f76 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -35,6 +35,7 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;  import static android.net.NetworkCapabilities.NET_CAPABILITY_MMS;  import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;  import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED; +import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED;  import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;  import static android.net.NetworkCapabilities.NET_CAPABILITY_RCS;  import static android.net.NetworkCapabilities.NET_CAPABILITY_SUPL; @@ -528,6 +529,11 @@ public class ConnectivityServiceTest {              mNetworkAgent.sendNetworkInfo(mNetworkInfo);          } +        public void resume() { +            mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, null); +            mNetworkAgent.sendNetworkInfo(mNetworkInfo); +        } +          public void disconnect() {              mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, null);              mNetworkAgent.sendNetworkInfo(mNetworkInfo); @@ -569,6 +575,10 @@ public class ConnectivityServiceTest {              assertTrue(mNetworkStatusReceived.block(TIMEOUT_MS));              return mRedirectUrl;          } + +        public NetworkCapabilities getNetworkCapabilities() { +            return mNetworkCapabilities; +        }      }      /** @@ -1273,6 +1283,7 @@ public class ConnectivityServiceTest {          NETWORK_CAPABILITIES,          LINK_PROPERTIES,          SUSPENDED, +        RESUMED,          LOSING,          LOST,          UNAVAILABLE @@ -1344,6 +1355,11 @@ public class ConnectivityServiceTest {          }          @Override +        public void onNetworkResumed(Network network) { +            setLastCallback(CallbackState.RESUMED, network, null); +        } + +        @Override          public void onLosing(Network network, int maxMsToLive) {              setLastCallback(CallbackState.LOSING, network, maxMsToLive /* autoboxed int */);          } @@ -2459,16 +2475,31 @@ public class ConnectivityServiceTest {          // Suspend the network.          mCellNetworkAgent.suspend(); +        cellNetworkCallback.expectCapabilitiesWithout(NET_CAPABILITY_NOT_SUSPENDED, +                mCellNetworkAgent);          cellNetworkCallback.expectCallback(CallbackState.SUSPENDED, mCellNetworkAgent);          cellNetworkCallback.assertNoCallback();          // Register a garden variety default network request. -        final TestNetworkCallback dfltNetworkCallback = new TestNetworkCallback(); +        TestNetworkCallback dfltNetworkCallback = new TestNetworkCallback();          mCm.registerDefaultNetworkCallback(dfltNetworkCallback);          // We should get onAvailable(), onCapabilitiesChanged(), onLinkPropertiesChanged(),          // as well as onNetworkSuspended() in rapid succession.          dfltNetworkCallback.expectAvailableAndSuspendedCallbacks(mCellNetworkAgent, true);          dfltNetworkCallback.assertNoCallback(); +        mCm.unregisterNetworkCallback(dfltNetworkCallback); + +        mCellNetworkAgent.resume(); +        cellNetworkCallback.expectCapabilitiesWith(NET_CAPABILITY_NOT_SUSPENDED, +                mCellNetworkAgent); +        cellNetworkCallback.expectCallback(CallbackState.RESUMED, mCellNetworkAgent); +        cellNetworkCallback.assertNoCallback(); + +        dfltNetworkCallback = new TestNetworkCallback(); +        mCm.registerDefaultNetworkCallback(dfltNetworkCallback); +        // This time onNetworkSuspended should not be called. +        dfltNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); +        dfltNetworkCallback.assertNoCallback();          mCm.unregisterNetworkCallback(dfltNetworkCallback);          mCm.unregisterNetworkCallback(cellNetworkCallback); @@ -3682,8 +3713,7 @@ public class ConnectivityServiceTest {          vpnNetworkCallback.expectAvailableCallbacksUnvalidated(vpnNetworkAgent);          genericNetworkCallback.expectCallback(CallbackState.NETWORK_CAPABILITIES, vpnNetworkAgent); -        vpnNetworkCallback.expectCapabilitiesLike( -                nc -> nc.appliesToUid(uid) && !nc.appliesToUid(uid + 1), vpnNetworkAgent); +        vpnNetworkCallback.expectCapabilitiesLike(nc -> null == nc.getUids(), vpnNetworkAgent);          ranges.clear();          vpnNetworkAgent.setUids(ranges);  |