diff options
| -rw-r--r-- | apex/sdkextensions/framework/Android.bp | 58 | ||||
| -rw-r--r-- | api/module-lib-current.txt | 4 | ||||
| -rw-r--r-- | cmds/statsd/src/atoms.proto | 41 | ||||
| -rw-r--r-- | core/java/android/timezone/CountryTimeZones.java | 32 | ||||
| -rw-r--r-- | core/java/com/android/internal/util/ObjectUtils.java | 8 | ||||
| -rw-r--r-- | core/proto/android/server/connectivity/data_stall_event.proto | 6 | ||||
| -rw-r--r-- | services/core/java/com/android/server/ConnectivityService.java | 125 | ||||
| -rw-r--r-- | services/core/java/com/android/server/connectivity/LingerMonitor.java | 29 | ||||
| -rw-r--r-- | tests/net/java/com/android/server/ConnectivityServiceTest.java | 34 |
9 files changed, 248 insertions, 89 deletions
diff --git a/apex/sdkextensions/framework/Android.bp b/apex/sdkextensions/framework/Android.bp index 245a96b99148..86f4ab7c1128 100644 --- a/apex/sdkextensions/framework/Android.bp +++ b/apex/sdkextensions/framework/Android.bp @@ -44,34 +44,68 @@ java_library { ], } +stubs_defaults { + name: "framework-sdkextensions-stubs-defaults", + srcs: [ ":framework-sdkextensions-sources" ], + libs: [ "framework-annotations-lib" ], + sdk_version: "system_current", +} + droidstubs { - name: "framework-sdkextensions-droidstubs-publicapi", + name: "framework-sdkextensions-stubs-srcs-publicapi", defaults: [ - "framework-sdkextensions-stubs-defaults", "framework-module-stubs-defaults-publicapi", + "framework-sdkextensions-stubs-defaults", ] } droidstubs { - name: "framework-sdkextensions-droidstubs-systemapi", + name: "framework-sdkextensions-stubs-srcs-systemapi", defaults: [ - "framework-sdkextensions-stubs-defaults", "framework-module-stubs-defaults-systemapi", + "framework-sdkextensions-stubs-defaults", ] } -stubs_defaults { - name: "framework-sdkextensions-stubs-defaults", - srcs: [ - ":framework-sdkextensions-sources", - ":framework-annotations", - ], - sdk_version: "system_current", +droidstubs { + name: "framework-sdkextensions-api-module_libs_api", + defaults: [ + "framework-module-api-defaults-module_libs_api", + "framework-sdkextensions-stubs-defaults", + ] +} + +droidstubs { + name: "framework-sdkextensions-stubs-srcs-module_libs_api", + defaults: [ + "framework-module-stubs-defaults-module_libs_api", + "framework-sdkextensions-stubs-defaults", + ] +} + +java_library { + name: "framework-sdkextensions-stubs-publicapi", + srcs: [":framework-sdkextensions-stubs-srcs-publicapi"], + sdk_version: "current", + visibility: [ + "//frameworks/base", // Framework + "//frameworks/base/apex/sdkextensions", // sdkextensions SDK + ] } java_library { name: "framework-sdkextensions-stubs-systemapi", - srcs: [":framework-sdkextensions-droidstubs-systemapi"], + srcs: [":framework-sdkextensions-stubs-srcs-systemapi"], + sdk_version: "system_current", + visibility: [ + "//frameworks/base", // Framework + "//frameworks/base/apex/sdkextensions", // sdkextensions SDK + ] +} + +java_library { + name: "framework-sdkextensions-stubs-module_libs_api", + srcs: [":framework-sdkextensions-stubs-srcs-module_libs_api"], sdk_version: "system_current", visibility: [ "//frameworks/base", // Framework diff --git a/api/module-lib-current.txt b/api/module-lib-current.txt index 278a18654e03..8ba204c68460 100644 --- a/api/module-lib-current.txt +++ b/api/module-lib-current.txt @@ -87,8 +87,8 @@ package android.timezone { method @NonNull public java.util.List<android.timezone.CountryTimeZones.TimeZoneMapping> getEffectiveTimeZoneMappingsAt(long); method public boolean hasUtcZone(long); method public boolean isDefaultTimeZoneBoosted(); - method public boolean isForCountryCode(@NonNull String); method @Nullable public android.timezone.CountryTimeZones.OffsetResult lookupByOffsetWithBias(int, @Nullable Boolean, @Nullable Integer, long, @Nullable android.icu.util.TimeZone); + method public boolean matchesCountryCode(@NonNull String); } public static final class CountryTimeZones.OffsetResult { @@ -98,7 +98,7 @@ package android.timezone { } public static final class CountryTimeZones.TimeZoneMapping { - method @Nullable public android.icu.util.TimeZone getTimeZone(); + method @NonNull public android.icu.util.TimeZone getTimeZone(); method @NonNull public String getTimeZoneId(); } diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index a8ad53c686bc..a50fefbd6500 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -352,6 +352,7 @@ message Atom { PerfettoUploaded perfetto_uploaded = 229 [(log_from_module) = "perfetto"]; VmsClientConnectionStateChanged vms_client_connection_state_changed = 230; + UserspaceRebootReported userspace_reboot_reported = 243; } // Pulled events will start at field 10000. @@ -7076,3 +7077,43 @@ message UpdateEngineSuccessfulUpdateReported { // The number of reboot of the device during a successful update. optional int32 reboot_count = 7; } + +/* + * Logs userspace reboot outcome and duration. + * + * Logged from: + * frameworks/base/core/java/com/android/server/BootReceiver.java + */ +message UserspaceRebootReported { + // Possible outcomes of userspace reboot. + enum Outcome { + // Default value in case platform failed to determine the outcome. + OUTCOME_UNKNOWN = 0; + // Userspace reboot succeeded (i.e. boot completed without a fall back to hard reboot). + SUCCESS = 1; + // Userspace reboot shutdown sequence was aborted. + FAILED_SHUTDOWN_SEQUENCE_ABORTED = 2; + // Remounting userdata into checkpointing mode failed. + FAILED_USERDATA_REMOUNT = 3; + // Device didn't finish booting before timeout and userspace reboot watchdog issued a hard + // reboot. + FAILED_USERSPACE_REBOOT_WATCHDOG_TRIGGERED = 4; + } + // Outcome of userspace reboot. Always set. + optional Outcome outcome = 1; + // Duration of userspace reboot in case it has a successful outcome. + // Duration is measured as time between userspace reboot was initiated and until boot completed + // (e.g. sys.boot_completed=1). + optional int64 duration_millis = 2; + // State of primary user's (user0) credential encryption storage. + enum UserEncryptionState { + // Default value. + USER_ENCRYPTION_STATE_UNKNOWN = 0; + // Credential encrypted storage is unlocked. + UNLOCKED = 1; + // Credential encrypted storage is locked. + LOCKED = 2; + } + // State of primary user's encryption storage at the moment boot completed. Always set. + optional UserEncryptionState user_encryption_state = 3; +} diff --git a/core/java/android/timezone/CountryTimeZones.java b/core/java/android/timezone/CountryTimeZones.java index 5875761bb1c9..970acd0a5b3f 100644 --- a/core/java/android/timezone/CountryTimeZones.java +++ b/core/java/android/timezone/CountryTimeZones.java @@ -51,8 +51,10 @@ public final class CountryTimeZones { } /** - * Returns the ID for this mapping. See also {@link #getTimeZone()} which handles when the - * ID is unrecognized. + * Returns the ID for this mapping. The ID is a tzdb time zone identifier like + * "America/Los_Angeles" that can be used with methods such as {@link + * TimeZone#getFrozenTimeZone(String)}. See {@link #getTimeZone()} which returns a frozen + * {@link TimeZone} object. */ @NonNull public String getTimeZoneId() { @@ -60,10 +62,9 @@ public final class CountryTimeZones { } /** - * Returns a {@link TimeZone} object for this mapping, or {@code null} if the ID is - * unrecognized. + * Returns a frozen {@link TimeZone} object for this mapping. */ - @Nullable + @NonNull public TimeZone getTimeZone() { return mDelegate.getTimeZone(); } @@ -158,9 +159,10 @@ public final class CountryTimeZones { } /** - * Returns true if the ISO code for the country is a match for the one specified. + * Returns true if the ISO code for the country is a case-insensitive match for the one + * supplied. */ - public boolean isForCountryCode(@NonNull String countryIso) { + public boolean matchesCountryCode(@NonNull String countryIso) { return mDelegate.isForCountryCode(countryIso); } @@ -183,15 +185,25 @@ public final class CountryTimeZones { } /** - * Qualifier for a country's default time zone. {@code true} indicates whether the default - * would be a good choice <em>generally</em> when there's no other information available. + * Qualifier for a country's default time zone. {@code true} indicates that the country's + * default time zone would be a good choice <em>generally</em> when there's no UTC offset + * information available. This will only be {@code true} in countries with multiple zones where + * a large majority of the population is covered by only one of them. */ public boolean isDefaultTimeZoneBoosted() { return mDelegate.isDefaultTimeZoneBoosted(); } /** - * Returns true if the country has at least one zone that is the same as UTC at the given time. + * Returns {@code true} if the country has at least one time zone that uses UTC at the given + * time. This is an efficient check when trying to validate received UTC offset information. + * For example, there are situations when a detected zero UTC offset cannot be distinguished + * from "no information available" or a corrupted signal. This method is useful because checking + * offset information for large countries is relatively expensive but it is generally only the + * countries close to the prime meridian that use UTC at <em>any</em> time of the year. + * + * @param whenMillis the time the offset information is for in milliseconds since the beginning + * of the Unix epoch */ public boolean hasUtcZone(long whenMillis) { return mDelegate.hasUtcZone(whenMillis); diff --git a/core/java/com/android/internal/util/ObjectUtils.java b/core/java/com/android/internal/util/ObjectUtils.java index 59e5a6402fb8..a6b345fadbbe 100644 --- a/core/java/com/android/internal/util/ObjectUtils.java +++ b/core/java/com/android/internal/util/ObjectUtils.java @@ -36,4 +36,12 @@ public class ObjectUtils { return (b != null) ? -1 : 0; } } + + /** + * Returns its first argument if non-null, and the second otherwise. + */ + @Nullable + public static <T> T getOrElse(@Nullable final T object, @Nullable final T otherwise) { + return null != object ? object : otherwise; + } } diff --git a/core/proto/android/server/connectivity/data_stall_event.proto b/core/proto/android/server/connectivity/data_stall_event.proto index a82326f67d74..23fcf6ebc2cc 100644 --- a/core/proto/android/server/connectivity/data_stall_event.proto +++ b/core/proto/android/server/connectivity/data_stall_event.proto @@ -34,7 +34,7 @@ enum ApBand { AP_BAND_5GHZ = 2; } -// Refer to definition in ServiceState.java. +// Refer to definition in TelephonyManager.java. enum RadioTech { RADIO_TECHNOLOGY_UNKNOWN = 0; RADIO_TECHNOLOGY_GPRS = 1; @@ -49,8 +49,8 @@ enum RadioTech { RADIO_TECHNOLOGY_HSUPA = 10; RADIO_TECHNOLOGY_HSPA = 11; RADIO_TECHNOLOGY_EVDO_B = 12; - RADIO_TECHNOLOGY_EHRPD = 13; - RADIO_TECHNOLOGY_LTE = 14; + RADIO_TECHNOLOGY_LTE = 13; + RADIO_TECHNOLOGY_EHRPD = 14; RADIO_TECHNOLOGY_HSPAP = 15; RADIO_TECHNOLOGY_GSM = 16; RADIO_TECHNOLOGY_TD_SCDMA = 17; diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 4b9925fe597b..0e17b23249ae 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -6197,12 +6197,16 @@ public class ConnectivityService extends IConnectivityManager.Stub } } - private void sendUpdatedScoreToFactories(NetworkRequest networkRequest, NetworkAgentInfo nai) { - int score = 0; - int serial = 0; + private void sendUpdatedScoreToFactories(@NonNull NetworkRequest networkRequest, + @Nullable NetworkAgentInfo nai) { + final int score; + final int serial; if (nai != null) { score = nai.getCurrentScore(); serial = nai.factorySerialNumber; + } else { + score = 0; + serial = 0; } if (VDBG || DDBG){ log("sending new Min Network Score(" + score + "): " + networkRequest.toString()); @@ -6365,20 +6369,28 @@ public class ConnectivityService extends IConnectivityManager.Stub } } - private void makeDefault(@NonNull final NetworkAgentInfo newNetwork) { + private void makeDefault(@Nullable final NetworkAgentInfo newNetwork) { if (DBG) log("Switching to new default network: " + newNetwork); + mDefaultNetworkNai = newNetwork; + try { - mNMS.setDefaultNetId(newNetwork.network.netId); + if (null != newNetwork) { + mNMS.setDefaultNetId(newNetwork.network.netId); + } else { + mNMS.clearDefaultNetId(); + } } catch (Exception e) { loge("Exception setting default network :" + e); } - mDefaultNetworkNai = newNetwork; notifyLockdownVpn(newNetwork); - handleApplyDefaultProxy(newNetwork.linkProperties.getHttpProxy()); - updateTcpBufferSizes(newNetwork.linkProperties.getTcpBufferSizes()); - mDnsManager.setDefaultDnsSystemProperties(newNetwork.linkProperties.getDnsServers()); + handleApplyDefaultProxy(null != newNetwork + ? newNetwork.linkProperties.getHttpProxy() : null); + updateTcpBufferSizes(null != newNetwork + ? newNetwork.linkProperties.getTcpBufferSizes() : null); + mDnsManager.setDefaultDnsSystemProperties(null != newNetwork + ? newNetwork.linkProperties.getDnsServers() : Collections.EMPTY_LIST); notifyIfacesChangedForNetworkStats(); // Fix up the NetworkCapabilities of any VPNs that don't specify underlying networks. updateAllVpnsCapabilities(); @@ -6457,6 +6469,16 @@ public class ConnectivityService extends IConnectivityManager.Stub void addRematchedNetwork(@NonNull final NetworkBgStatePair network) { mRematchedNetworks.add(network); } + + // Will return null if this reassignment does not change the network assigned to + // the passed request. + @Nullable + private RequestReassignment getReassignment(@NonNull final NetworkRequestInfo nri) { + for (final RequestReassignment event : getRequestReassignments()) { + if (nri == event.mRequest) return event; + } + return null; + } } private ArrayMap<NetworkRequestInfo, NetworkAgentInfo> computeRequestReassignmentForNetwork( @@ -6523,8 +6545,6 @@ public class ConnectivityService extends IConnectivityManager.Stub @NonNull final NetworkAgentInfo newNetwork, final long now) { ensureRunningOnConnectivityServiceThread(); if (!newNetwork.everConnected) return; - boolean isNewDefault = false; - NetworkAgentInfo oldDefaultNetwork = null; changes.addRematchedNetwork(new NetworkReassignment.NetworkBgStatePair(newNetwork, newNetwork.isBackgroundNetwork())); @@ -6541,6 +6561,8 @@ public class ConnectivityService extends IConnectivityManager.Stub final NetworkRequestInfo nri = entry.getKey(); final NetworkAgentInfo previousSatisfier = nri.mSatisfier; final NetworkAgentInfo newSatisfier = entry.getValue(); + changes.addRequestReassignment(new NetworkReassignment.RequestReassignment( + nri, previousSatisfier, newSatisfier)); if (newSatisfier != null) { if (VDBG) log("rematch for " + newSatisfier.name()); if (previousSatisfier != null) { @@ -6553,25 +6575,9 @@ public class ConnectivityService extends IConnectivityManager.Stub if (VDBG || DDBG) log(" accepting network in place of null"); } newSatisfier.unlingerRequest(nri.request); - nri.mSatisfier = newSatisfier; if (!newSatisfier.addRequest(nri.request)) { Slog.wtf(TAG, "BUG: " + newSatisfier.name() + " already has " + nri.request); } - changes.addRequestReassignment(new NetworkReassignment.RequestReassignment( - nri, previousSatisfier, newSatisfier)); - // Tell NetworkProviders about the new score, so they can stop - // trying to connect if they know they cannot match it. - // TODO - this could get expensive if we have a lot of requests for this - // network. Think about if there is a way to reduce this. Push - // netid->request mapping to each provider? - sendUpdatedScoreToFactories(nri.request, newSatisfier); - if (isDefaultRequest(nri)) { - isNewDefault = true; - oldDefaultNetwork = previousSatisfier; - if (previousSatisfier != null) { - mLingerMonitor.noteLingerDefaultNetwork(previousSatisfier, newSatisfier); - } - } } else { // If "newNetwork" is listed as satisfying "nri" but no longer satisfies "nri", // mark it as no longer satisfying "nri". Because networks are processed by @@ -6585,35 +6591,8 @@ public class ConnectivityService extends IConnectivityManager.Stub " request " + nri.request.requestId); } newNetwork.removeRequest(nri.request.requestId); - if (previousSatisfier == newNetwork) { - nri.mSatisfier = null; - if (isDefaultRequest(nri)) mDefaultNetworkNai = null; - sendUpdatedScoreToFactories(nri.request, null); - } else { - Slog.wtf(TAG, "BUG: Removing request " + nri.request.requestId + " from " + - newNetwork.name() + - " without updating mSatisfier or providers!"); - } - // TODO: Technically, sending CALLBACK_LOST here is - // incorrect if there is a replacement network currently - // connected that can satisfy nri, which is a request - // (not a listen). However, the only capability that can both - // a) be requested and b) change is NET_CAPABILITY_TRUSTED, - // so this code is only incorrect for a network that loses - // the TRUSTED capability, which is a rare case. - callCallbackForRequest(nri, newNetwork, ConnectivityManager.CALLBACK_LOST, 0); } - } - - if (isNewDefault) { - updateDataActivityTracking(newNetwork, oldDefaultNetwork); - // Notify system services that this network is up. - makeDefault(newNetwork); - // Log 0 -> X and Y -> X default network transitions, where X is the new default. - mDeps.getMetricsLogger().defaultNetworkMetrics().logDefaultNetworkEvent( - now, newNetwork, oldDefaultNetwork); - // Have a new default network, release the transition wakelock in - scheduleReleaseNetworkTransitionWakelock(); + nri.mSatisfier = newSatisfier; } } @@ -6641,14 +6620,48 @@ public class ConnectivityService extends IConnectivityManager.Stub rematchNetworkAndRequests(changes, nai, now); } - final NetworkAgentInfo newDefaultNetwork = getDefaultNetwork(); + final NetworkRequestInfo defaultRequestInfo = mNetworkRequests.get(mDefaultRequest); + final NetworkReassignment.RequestReassignment reassignment = + changes.getReassignment(defaultRequestInfo); + final NetworkAgentInfo newDefaultNetwork = + null != reassignment ? reassignment.mNewNetwork : oldDefaultNetwork; + + if (oldDefaultNetwork != newDefaultNetwork) { + if (oldDefaultNetwork != null) { + mLingerMonitor.noteLingerDefaultNetwork(oldDefaultNetwork, newDefaultNetwork); + } + updateDataActivityTracking(newDefaultNetwork, oldDefaultNetwork); + // Notify system services of the new default. + makeDefault(newDefaultNetwork); + // Log 0 -> X and Y -> X default network transitions, where X is the new default. + mDeps.getMetricsLogger().defaultNetworkMetrics().logDefaultNetworkEvent( + now, newDefaultNetwork, oldDefaultNetwork); + // Have a new default network, release the transition wakelock in + scheduleReleaseNetworkTransitionWakelock(); + } // Notify requested networks are available after the default net is switched, but // before LegacyTypeTracker sends legacy broadcasts for (final NetworkReassignment.RequestReassignment event : changes.getRequestReassignments()) { + // Tell NetworkProviders about the new score, so they can stop + // trying to connect if they know they cannot match it. + // TODO - this could get expensive if there are a lot of outstanding requests for this + // network. Think of a way to reduce this. Push netid->request mapping to each factory? + sendUpdatedScoreToFactories(event.mRequest.request, event.mNewNetwork); + if (null != event.mNewNetwork) { notifyNetworkAvailable(event.mNewNetwork, event.mRequest); + } else { + // TODO: Technically, sending CALLBACK_LOST here is + // incorrect if there is a replacement network currently + // connected that can satisfy nri, which is a request + // (not a listen). However, the only capability that can both + // a) be requested and b) change is NET_CAPABILITY_TRUSTED, + // so this code is only incorrect for a network that loses + // the TRUSTED capability, which is a rare case. + callCallbackForRequest(event.mRequest, event.mOldNetwork, + ConnectivityManager.CALLBACK_LOST, 0); } } diff --git a/services/core/java/com/android/server/connectivity/LingerMonitor.java b/services/core/java/com/android/server/connectivity/LingerMonitor.java index 929dfc4d1511..707151059869 100644 --- a/services/core/java/com/android/server/connectivity/LingerMonitor.java +++ b/services/core/java/com/android/server/connectivity/LingerMonitor.java @@ -16,6 +16,10 @@ package com.android.server.connectivity; +import static android.net.ConnectivityManager.NETID_UNSET; + +import android.annotation.NonNull; +import android.annotation.Nullable; import android.app.PendingIntent; import android.content.ComponentName; import android.content.Context; @@ -27,18 +31,16 @@ import android.text.TextUtils; import android.text.format.DateUtils; import android.util.Log; import android.util.SparseArray; -import android.util.SparseIntArray; import android.util.SparseBooleanArray; -import java.util.Arrays; -import java.util.HashMap; +import android.util.SparseIntArray; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.MessageUtils; -import com.android.server.connectivity.NetworkNotificationManager; import com.android.server.connectivity.NetworkNotificationManager.NotificationType; -import static android.net.ConnectivityManager.NETID_UNSET; +import java.util.Arrays; +import java.util.HashMap; /** * Class that monitors default network linger events and possibly notifies the user of network @@ -206,8 +208,19 @@ public class LingerMonitor { mEverNotified.put(fromNai.network.netId, true); } + /** + * Put up or dismiss a notification or toast for of a change in the default network if needed. + * + * Putting up a notification when switching from no network to some network is not supported + * and as such this method can't be called with a null |fromNai|. It can be called with a + * null |toNai| if there isn't a default network any more. + * + * @param fromNai switching from this NAI + * @param toNai switching to this NAI + */ // The default network changed from fromNai to toNai due to a change in score. - public void noteLingerDefaultNetwork(NetworkAgentInfo fromNai, NetworkAgentInfo toNai) { + public void noteLingerDefaultNetwork(@NonNull final NetworkAgentInfo fromNai, + @Nullable final NetworkAgentInfo toNai) { if (VDBG) { Log.d(TAG, "noteLingerDefaultNetwork from=" + fromNai.name() + " everValidated=" + fromNai.everValidated + @@ -221,6 +234,10 @@ public class LingerMonitor { // Internet access). maybeStopNotifying(fromNai); + // If the network was simply lost (either because it disconnected or because it stopped + // being the default with no replacement), then don't show a notification. + if (null == toNai) return; + // If this network never validated, don't notify. Otherwise, we could do things like: // // 1. Unvalidated wifi connects. diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index 50f1bbeed0c5..1442b31aa8f1 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -5741,6 +5741,40 @@ public class ConnectivityServiceTest { mCm.unregisterNetworkCallback(defaultCallback); } + @Test + public final void testLoseTrusted() throws Exception { + final NetworkRequest trustedRequest = new NetworkRequest.Builder() + .addCapability(NET_CAPABILITY_TRUSTED) + .build(); + final TestNetworkCallback trustedCallback = new TestNetworkCallback(); + mCm.requestNetwork(trustedRequest, trustedCallback); + + mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); + mCellNetworkAgent.connect(true); + trustedCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); + verify(mNetworkManagementService).setDefaultNetId(eq(mCellNetworkAgent.getNetwork().netId)); + + mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); + mWiFiNetworkAgent.connect(true); + trustedCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); + verify(mNetworkManagementService).setDefaultNetId(eq(mWiFiNetworkAgent.getNetwork().netId)); + + mWiFiNetworkAgent.removeCapability(NET_CAPABILITY_TRUSTED); + // There is currently a bug where losing the TRUSTED capability will send a LOST + // callback to requests before the available callback, in spite of the semantics + // of the requests dictating this should not happen. This is considered benign, but + // ideally should be fixed in the future. + trustedCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); + trustedCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); + verify(mNetworkManagementService).setDefaultNetId(eq(mCellNetworkAgent.getNetwork().netId)); + + mCellNetworkAgent.removeCapability(NET_CAPABILITY_TRUSTED); + trustedCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); + verify(mNetworkManagementService).clearDefaultNetId(); + + mCm.unregisterNetworkCallback(trustedCallback); + } + @Ignore // 40%+ flakiness : figure out why and re-enable. @Test public final void testBatteryStatsNetworkType() throws Exception { |