Merge changes If539cf5d,I9765f1c9,I6d3007a1 am: 2206e976c1
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1652262 Change-Id: Iab7a5cdb9d50314b0bdb982b88a9335b64ddb276
This commit is contained in:
@@ -219,7 +219,7 @@ package android.net {
|
|||||||
method public void onAutomaticReconnectDisabled();
|
method public void onAutomaticReconnectDisabled();
|
||||||
method public void onBandwidthUpdateRequested();
|
method public void onBandwidthUpdateRequested();
|
||||||
method public void onNetworkCreated();
|
method public void onNetworkCreated();
|
||||||
method public void onNetworkDisconnected();
|
method public void onNetworkDestroyed();
|
||||||
method public void onNetworkUnwanted();
|
method public void onNetworkUnwanted();
|
||||||
method public void onQosCallbackRegistered(int, @NonNull android.net.QosFilter);
|
method public void onQosCallbackRegistered(int, @NonNull android.net.QosFilter);
|
||||||
method public void onQosCallbackUnregistered(int);
|
method public void onQosCallbackUnregistered(int);
|
||||||
@@ -238,6 +238,7 @@ package android.net {
|
|||||||
method public final void sendQosSessionLost(int, int, int);
|
method public final void sendQosSessionLost(int, int, int);
|
||||||
method public final void sendSocketKeepaliveEvent(int, int);
|
method public final void sendSocketKeepaliveEvent(int, int);
|
||||||
method @Deprecated public void setLegacySubtype(int, @NonNull String);
|
method @Deprecated public void setLegacySubtype(int, @NonNull String);
|
||||||
|
method public void setTeardownDelayMs(@IntRange(from=0, to=0x1388) int);
|
||||||
method public final void setUnderlyingNetworks(@Nullable java.util.List<android.net.Network>);
|
method public final void setUnderlyingNetworks(@Nullable java.util.List<android.net.Network>);
|
||||||
method public void unregister();
|
method public void unregister();
|
||||||
field public static final int VALIDATION_STATUS_NOT_VALID = 2; // 0x2
|
field public static final int VALIDATION_STATUS_NOT_VALID = 2; // 0x2
|
||||||
|
|||||||
@@ -921,6 +921,7 @@ public class ConnectivityManager {
|
|||||||
BLOCKED_REASON_DOZE,
|
BLOCKED_REASON_DOZE,
|
||||||
BLOCKED_REASON_APP_STANDBY,
|
BLOCKED_REASON_APP_STANDBY,
|
||||||
BLOCKED_REASON_RESTRICTED_MODE,
|
BLOCKED_REASON_RESTRICTED_MODE,
|
||||||
|
BLOCKED_REASON_LOCKDOWN_VPN,
|
||||||
BLOCKED_METERED_REASON_DATA_SAVER,
|
BLOCKED_METERED_REASON_DATA_SAVER,
|
||||||
BLOCKED_METERED_REASON_USER_RESTRICTED,
|
BLOCKED_METERED_REASON_USER_RESTRICTED,
|
||||||
BLOCKED_METERED_REASON_ADMIN_DISABLED,
|
BLOCKED_METERED_REASON_ADMIN_DISABLED,
|
||||||
@@ -3659,7 +3660,8 @@ public class ConnectivityManager {
|
|||||||
public void onBlockedStatusChanged(@NonNull Network network, boolean blocked) {}
|
public void onBlockedStatusChanged(@NonNull Network network, boolean blocked) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when access to the specified network is blocked or unblocked.
|
* Called when access to the specified network is blocked or unblocked, or the reason for
|
||||||
|
* access being blocked changes.
|
||||||
*
|
*
|
||||||
* If a NetworkCallback object implements this method,
|
* If a NetworkCallback object implements this method,
|
||||||
* {@link #onBlockedStatusChanged(Network, boolean)} will not be called.
|
* {@link #onBlockedStatusChanged(Network, boolean)} will not be called.
|
||||||
|
|||||||
@@ -47,5 +47,5 @@ oneway interface INetworkAgent {
|
|||||||
void onQosFilterCallbackRegistered(int qosCallbackId, in QosFilterParcelable filterParcel);
|
void onQosFilterCallbackRegistered(int qosCallbackId, in QosFilterParcelable filterParcel);
|
||||||
void onQosCallbackUnregistered(int qosCallbackId);
|
void onQosCallbackUnregistered(int qosCallbackId);
|
||||||
void onNetworkCreated();
|
void onNetworkCreated();
|
||||||
void onNetworkDisconnected();
|
void onNetworkDestroyed();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,4 +41,5 @@ oneway interface INetworkAgentRegistry {
|
|||||||
void sendNrQosSessionAvailable(int callbackId, in QosSession session, in NrQosSessionAttributes attributes);
|
void sendNrQosSessionAvailable(int callbackId, in QosSession session, in NrQosSessionAttributes attributes);
|
||||||
void sendQosSessionLost(int qosCallbackId, in QosSession session);
|
void sendQosSessionLost(int qosCallbackId, in QosSession session);
|
||||||
void sendQosCallbackError(int qosCallbackId, int exceptionType);
|
void sendQosCallbackError(int qosCallbackId, int exceptionType);
|
||||||
|
void sendTeardownDelayMs(int teardownDelayMs);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -184,6 +184,20 @@ public abstract class NetworkAgent {
|
|||||||
*/
|
*/
|
||||||
public static final int EVENT_UNDERLYING_NETWORKS_CHANGED = BASE + 5;
|
public static final int EVENT_UNDERLYING_NETWORKS_CHANGED = BASE + 5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sent by the NetworkAgent to ConnectivityService to pass the current value of the teardown
|
||||||
|
* delay.
|
||||||
|
* arg1 = teardown delay in milliseconds
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public static final int EVENT_TEARDOWN_DELAY_CHANGED = BASE + 6;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maximum value for the teardown delay, in milliseconds.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public static final int MAX_TEARDOWN_DELAY_MS = 5000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sent by ConnectivityService to the NetworkAgent to inform the agent of the
|
* Sent by ConnectivityService to the NetworkAgent to inform the agent of the
|
||||||
* networks status - whether we could use the network or could not, due to
|
* networks status - whether we could use the network or could not, due to
|
||||||
@@ -197,7 +211,6 @@ public abstract class NetworkAgent {
|
|||||||
*/
|
*/
|
||||||
public static final int CMD_REPORT_NETWORK_STATUS = BASE + 7;
|
public static final int CMD_REPORT_NETWORK_STATUS = BASE + 7;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Network validation suceeded.
|
* Network validation suceeded.
|
||||||
* Corresponds to {@link NetworkCapabilities.NET_CAPABILITY_VALIDATED}.
|
* Corresponds to {@link NetworkCapabilities.NET_CAPABILITY_VALIDATED}.
|
||||||
@@ -376,7 +389,7 @@ public abstract class NetworkAgent {
|
|||||||
*
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public static final int CMD_NETWORK_DISCONNECTED = BASE + 23;
|
public static final int CMD_NETWORK_DESTROYED = BASE + 23;
|
||||||
|
|
||||||
private static NetworkInfo getLegacyNetworkInfo(final NetworkAgentConfig config) {
|
private static NetworkInfo getLegacyNetworkInfo(final NetworkAgentConfig config) {
|
||||||
final NetworkInfo ni = new NetworkInfo(config.legacyType, config.legacySubType,
|
final NetworkInfo ni = new NetworkInfo(config.legacyType, config.legacySubType,
|
||||||
@@ -581,8 +594,8 @@ public abstract class NetworkAgent {
|
|||||||
onNetworkCreated();
|
onNetworkCreated();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_NETWORK_DISCONNECTED: {
|
case CMD_NETWORK_DESTROYED: {
|
||||||
onNetworkDisconnected();
|
onNetworkDestroyed();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -732,8 +745,8 @@ public abstract class NetworkAgent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onNetworkDisconnected() {
|
public void onNetworkDestroyed() {
|
||||||
mHandler.sendMessage(mHandler.obtainMessage(CMD_NETWORK_DISCONNECTED));
|
mHandler.sendMessage(mHandler.obtainMessage(CMD_NETWORK_DESTROYED));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -850,6 +863,29 @@ public abstract class NetworkAgent {
|
|||||||
queueOrSendNetworkInfo(mNetworkInfo);
|
queueOrSendNetworkInfo(mNetworkInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the value of the teardown delay.
|
||||||
|
*
|
||||||
|
* The teardown delay is the time between when the network disconnects and when the native
|
||||||
|
* network corresponding to this {@code NetworkAgent} is destroyed. By default, the native
|
||||||
|
* network is destroyed immediately. If {@code teardownDelayMs} is non-zero, then when this
|
||||||
|
* network disconnects, the system will instead immediately mark the network as restricted
|
||||||
|
* and unavailable to unprivileged apps, but will defer destroying the native network until the
|
||||||
|
* teardown delay timer expires.
|
||||||
|
*
|
||||||
|
* The interfaces in use by this network will remain in use until the native network is
|
||||||
|
* destroyed and cannot be reused until {@link #onNetworkDestroyed()} is called.
|
||||||
|
*
|
||||||
|
* This method may be called at any time while the network is connected. It has no effect if
|
||||||
|
* the network is already disconnected and the teardown delay timer is running.
|
||||||
|
*
|
||||||
|
* @param teardownDelayMs the teardown delay to set, or 0 to disable teardown delay.
|
||||||
|
*/
|
||||||
|
public void setTeardownDelayMs(
|
||||||
|
@IntRange(from = 0, to = MAX_TEARDOWN_DELAY_MS) int teardownDelayMs) {
|
||||||
|
queueOrSendMessage(reg -> reg.sendTeardownDelayMs(teardownDelayMs));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Change the legacy subtype of this network agent.
|
* Change the legacy subtype of this network agent.
|
||||||
*
|
*
|
||||||
@@ -1053,7 +1089,7 @@ public abstract class NetworkAgent {
|
|||||||
/**
|
/**
|
||||||
* Called when ConnectivityService has successfully destroy this NetworkAgent's native network.
|
* Called when ConnectivityService has successfully destroy this NetworkAgent's native network.
|
||||||
*/
|
*/
|
||||||
public void onNetworkDisconnected() {}
|
public void onNetworkDestroyed() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Requests that the network hardware send the specified packet at the specified interval.
|
* Requests that the network hardware send the specified packet at the specified interval.
|
||||||
|
|||||||
@@ -1551,16 +1551,16 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
mNetworkInfoBlockingLogs.log(action + " " + uid);
|
mNetworkInfoBlockingLogs.log(action + " " + uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void maybeLogBlockedStatusChanged(NetworkRequestInfo nri, Network net,
|
private void maybeLogBlockedStatusChanged(NetworkRequestInfo nri, Network net, int blocked) {
|
||||||
boolean blocked) {
|
|
||||||
if (nri == null || net == null || !LOGD_BLOCKED_NETWORKINFO) {
|
if (nri == null || net == null || !LOGD_BLOCKED_NETWORKINFO) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final String action = blocked ? "BLOCKED" : "UNBLOCKED";
|
final String action = (blocked != 0) ? "BLOCKED" : "UNBLOCKED";
|
||||||
final int requestId = nri.getActiveRequest() != null
|
final int requestId = nri.getActiveRequest() != null
|
||||||
? nri.getActiveRequest().requestId : nri.mRequests.get(0).requestId;
|
? nri.getActiveRequest().requestId : nri.mRequests.get(0).requestId;
|
||||||
mNetworkInfoBlockingLogs.log(String.format(
|
mNetworkInfoBlockingLogs.log(String.format(
|
||||||
"%s %d(%d) on netId %d", action, nri.mAsUid, requestId, net.getNetId()));
|
"%s %d(%d) on netId %d: %s", action, nri.mAsUid, requestId, net.getNetId(),
|
||||||
|
blockedReasonsToString(blocked)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -3122,6 +3122,13 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case NetworkAgent.EVENT_TEARDOWN_DELAY_CHANGED: {
|
||||||
|
if (msg.arg1 >= 0 && msg.arg1 <= NetworkAgent.MAX_TEARDOWN_DELAY_MS) {
|
||||||
|
nai.teardownDelayMs = msg.arg1;
|
||||||
|
} else {
|
||||||
|
logwtf(nai.toShortString() + " set invalid teardown delay " + msg.arg1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3692,6 +3699,23 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
mLegacyTypeTracker.remove(nai, wasDefault);
|
mLegacyTypeTracker.remove(nai, wasDefault);
|
||||||
rematchAllNetworksAndRequests();
|
rematchAllNetworksAndRequests();
|
||||||
mLingerMonitor.noteDisconnect(nai);
|
mLingerMonitor.noteDisconnect(nai);
|
||||||
|
|
||||||
|
// Immediate teardown.
|
||||||
|
if (nai.teardownDelayMs == 0) {
|
||||||
|
destroyNetwork(nai);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delayed teardown.
|
||||||
|
try {
|
||||||
|
mNetd.networkSetPermissionForNetwork(nai.network.netId, INetd.PERMISSION_SYSTEM);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Log.d(TAG, "Error marking network restricted during teardown: " + e);
|
||||||
|
}
|
||||||
|
mHandler.postDelayed(() -> destroyNetwork(nai), nai.teardownDelayMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void destroyNetwork(NetworkAgentInfo nai) {
|
||||||
if (nai.created) {
|
if (nai.created) {
|
||||||
// Tell netd to clean up the configuration for this network
|
// Tell netd to clean up the configuration for this network
|
||||||
// (routing rules, DNS, etc).
|
// (routing rules, DNS, etc).
|
||||||
@@ -3704,7 +3728,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
mDnsManager.removeNetwork(nai.network);
|
mDnsManager.removeNetwork(nai.network);
|
||||||
}
|
}
|
||||||
mNetIdManager.releaseNetId(nai.network.getNetId());
|
mNetIdManager.releaseNetId(nai.network.getNetId());
|
||||||
nai.onNetworkDisconnected();
|
nai.onNetworkDestroyed();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean createNativeNetwork(@NonNull NetworkAgentInfo networkAgent) {
|
private boolean createNativeNetwork(@NonNull NetworkAgentInfo networkAgent) {
|
||||||
@@ -7348,7 +7372,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ConnectivityManager.CALLBACK_BLK_CHANGED: {
|
case ConnectivityManager.CALLBACK_BLK_CHANGED: {
|
||||||
maybeLogBlockedStatusChanged(nri, networkAgent.network, arg1 != 0);
|
maybeLogBlockedStatusChanged(nri, networkAgent.network, arg1);
|
||||||
msg.arg1 = arg1;
|
msg.arg1 = arg1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -201,6 +201,9 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
|
|||||||
// Set to true when partial connectivity was detected.
|
// Set to true when partial connectivity was detected.
|
||||||
public boolean partialConnectivity;
|
public boolean partialConnectivity;
|
||||||
|
|
||||||
|
// Delay between when the network is disconnected and when the native network is destroyed.
|
||||||
|
public int teardownDelayMs;
|
||||||
|
|
||||||
// Captive portal info of the network from RFC8908, if any.
|
// Captive portal info of the network from RFC8908, if any.
|
||||||
// Obtained by ConnectivityService and merged into NetworkAgent-provided information.
|
// Obtained by ConnectivityService and merged into NetworkAgent-provided information.
|
||||||
public CaptivePortalData capportApiData;
|
public CaptivePortalData capportApiData;
|
||||||
@@ -589,13 +592,13 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notify the NetworkAgent that the network is disconnected and destroyed.
|
* Notify the NetworkAgent that the native network has been destroyed.
|
||||||
*/
|
*/
|
||||||
public void onNetworkDisconnected() {
|
public void onNetworkDestroyed() {
|
||||||
try {
|
try {
|
||||||
networkAgent.onNetworkDisconnected();
|
networkAgent.onNetworkDestroyed();
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(TAG, "Error sending network disconnected event", e);
|
Log.e(TAG, "Error sending network destroyed event", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -675,6 +678,12 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
|
|||||||
@QosCallbackException.ExceptionType final int exceptionType) {
|
@QosCallbackException.ExceptionType final int exceptionType) {
|
||||||
mQosCallbackTracker.sendEventQosCallbackError(qosCallbackId, exceptionType);
|
mQosCallbackTracker.sendEventQosCallbackError(qosCallbackId, exceptionType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendTeardownDelayMs(int teardownDelayMs) {
|
||||||
|
mHandler.obtainMessage(NetworkAgent.EVENT_TEARDOWN_DELAY_CHANGED,
|
||||||
|
teardownDelayMs, 0, new Pair<>(NetworkAgentInfo.this, null)).sendToTarget();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -716,6 +716,9 @@ public class ConnectivityServiceTest {
|
|||||||
private int mProbesSucceeded;
|
private int mProbesSucceeded;
|
||||||
private String mNmValidationRedirectUrl = null;
|
private String mNmValidationRedirectUrl = null;
|
||||||
private boolean mNmProvNotificationRequested = false;
|
private boolean mNmProvNotificationRequested = false;
|
||||||
|
private Runnable mCreatedCallback;
|
||||||
|
private Runnable mUnwantedCallback;
|
||||||
|
private Runnable mDisconnectedCallback;
|
||||||
|
|
||||||
private final ConditionVariable mNetworkStatusReceived = new ConditionVariable();
|
private final ConditionVariable mNetworkStatusReceived = new ConditionVariable();
|
||||||
// Contains the redirectUrl from networkStatus(). Before reading, wait for
|
// Contains the redirectUrl from networkStatus(). Before reading, wait for
|
||||||
@@ -770,6 +773,24 @@ public class ConnectivityServiceTest {
|
|||||||
mRedirectUrl = redirectUrl;
|
mRedirectUrl = redirectUrl;
|
||||||
mNetworkStatusReceived.open();
|
mNetworkStatusReceived.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNetworkCreated() {
|
||||||
|
super.onNetworkCreated();
|
||||||
|
if (mCreatedCallback != null) mCreatedCallback.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNetworkUnwanted() {
|
||||||
|
super.onNetworkUnwanted();
|
||||||
|
if (mUnwantedCallback != null) mUnwantedCallback.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNetworkDestroyed() {
|
||||||
|
super.onNetworkDestroyed();
|
||||||
|
if (mDisconnectedCallback != null) mDisconnectedCallback.run();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
assertEquals(na.getNetwork().netId, nmNetworkCaptor.getValue().netId);
|
assertEquals(na.getNetwork().netId, nmNetworkCaptor.getValue().netId);
|
||||||
@@ -971,6 +992,18 @@ public class ConnectivityServiceTest {
|
|||||||
p.timestampMillis = DATA_STALL_TIMESTAMP;
|
p.timestampMillis = DATA_STALL_TIMESTAMP;
|
||||||
mNmCallbacks.notifyDataStallSuspected(p);
|
mNmCallbacks.notifyDataStallSuspected(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setCreatedCallback(Runnable r) {
|
||||||
|
mCreatedCallback = r;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUnwantedCallback(Runnable r) {
|
||||||
|
mUnwantedCallback = r;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDisconnectedCallback(Runnable r) {
|
||||||
|
mDisconnectedCallback = r;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2810,6 +2843,94 @@ public class ConnectivityServiceTest {
|
|||||||
mCm.unregisterNetworkCallback(callback);
|
mCm.unregisterNetworkCallback(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNetworkAgentCallbacks() throws Exception {
|
||||||
|
// Keeps track of the order of events that happen in this test.
|
||||||
|
final LinkedBlockingQueue<String> eventOrder = new LinkedBlockingQueue<>();
|
||||||
|
|
||||||
|
final NetworkRequest request = new NetworkRequest.Builder()
|
||||||
|
.addTransportType(TRANSPORT_WIFI).build();
|
||||||
|
final TestNetworkCallback callback = new TestNetworkCallback();
|
||||||
|
final AtomicReference<Network> wifiNetwork = new AtomicReference<>();
|
||||||
|
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
|
||||||
|
|
||||||
|
// Expectations for state when various callbacks fire. These expectations run on the handler
|
||||||
|
// thread and not on the test thread because they need to prevent the handler thread from
|
||||||
|
// advancing while they examine state.
|
||||||
|
|
||||||
|
// 1. When onCreated fires, netd has been told to create the network.
|
||||||
|
mWiFiNetworkAgent.setCreatedCallback(() -> {
|
||||||
|
eventOrder.offer("onNetworkCreated");
|
||||||
|
wifiNetwork.set(mWiFiNetworkAgent.getNetwork());
|
||||||
|
assertNotNull(wifiNetwork.get());
|
||||||
|
try {
|
||||||
|
verify(mMockNetd).networkCreatePhysical(wifiNetwork.get().getNetId(),
|
||||||
|
INetd.PERMISSION_NONE);
|
||||||
|
} catch (RemoteException impossible) {
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 2. onNetworkUnwanted isn't precisely ordered with respect to any particular events. Just
|
||||||
|
// check that it is fired at some point after disconnect.
|
||||||
|
mWiFiNetworkAgent.setUnwantedCallback(() -> eventOrder.offer("onNetworkUnwanted"));
|
||||||
|
|
||||||
|
// 3. While the teardown timer is running, connectivity APIs report the network is gone, but
|
||||||
|
// netd has not yet been told to destroy it.
|
||||||
|
final Runnable duringTeardown = () -> {
|
||||||
|
eventOrder.offer("timePasses");
|
||||||
|
assertNull(mCm.getLinkProperties(wifiNetwork.get()));
|
||||||
|
try {
|
||||||
|
verify(mMockNetd, never()).networkDestroy(wifiNetwork.get().getNetId());
|
||||||
|
} catch (RemoteException impossible) {
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 4. After onNetworkDisconnected is called, connectivity APIs report the network is gone,
|
||||||
|
// and netd has been told to destroy it.
|
||||||
|
mWiFiNetworkAgent.setDisconnectedCallback(() -> {
|
||||||
|
eventOrder.offer("onNetworkDisconnected");
|
||||||
|
assertNull(mCm.getLinkProperties(wifiNetwork.get()));
|
||||||
|
try {
|
||||||
|
verify(mMockNetd).networkDestroy(wifiNetwork.get().getNetId());
|
||||||
|
} catch (RemoteException impossible) {
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Connect a network, and file a request for it after it has come up, to ensure the nascent
|
||||||
|
// timer is cleared and the test does not have to wait for it. Filing the request after the
|
||||||
|
// network has come up is necessary because ConnectivityService does not appear to clear the
|
||||||
|
// nascent timer if the first request satisfied by the network was filed before the network
|
||||||
|
// connected.
|
||||||
|
// TODO: fix this bug, file the request before connecting, and remove the waitForIdle.
|
||||||
|
mWiFiNetworkAgent.connectWithoutInternet();
|
||||||
|
waitForIdle();
|
||||||
|
mCm.requestNetwork(request, callback);
|
||||||
|
callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
|
||||||
|
|
||||||
|
// Set teardown delay and make sure CS has processed it.
|
||||||
|
mWiFiNetworkAgent.getNetworkAgent().setTeardownDelayMs(300);
|
||||||
|
waitForIdle();
|
||||||
|
|
||||||
|
// Post the duringTeardown lambda to the handler so it fires while teardown is in progress.
|
||||||
|
// The delay must be long enough it will run after the unregisterNetworkCallback has torn
|
||||||
|
// down the network and started the teardown timer, and short enough that the lambda is
|
||||||
|
// scheduled to run before the teardown timer.
|
||||||
|
final Handler h = new Handler(mCsHandlerThread.getLooper());
|
||||||
|
h.postDelayed(duringTeardown, 150);
|
||||||
|
|
||||||
|
// Disconnect the network and check that events happened in the right order.
|
||||||
|
mCm.unregisterNetworkCallback(callback);
|
||||||
|
assertEquals("onNetworkCreated", eventOrder.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS));
|
||||||
|
assertEquals("onNetworkUnwanted", eventOrder.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS));
|
||||||
|
assertEquals("timePasses", eventOrder.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS));
|
||||||
|
assertEquals("onNetworkDisconnected", eventOrder.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS));
|
||||||
|
|
||||||
|
mCm.unregisterNetworkCallback(callback);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testExplicitlySelected() throws Exception {
|
public void testExplicitlySelected() throws Exception {
|
||||||
NetworkRequest request = new NetworkRequest.Builder()
|
NetworkRequest request = new NetworkRequest.Builder()
|
||||||
|
|||||||
Reference in New Issue
Block a user