Snap for 9571855 from b5e2d9cdc40a7a644067108254102624c02eaa11 to mainline-uwb-release
Change-Id: I82828d54009ca3ca876be366d924f9ef8a31824c
diff --git a/Cronet/tests/cts/src/android/net/http/cts/UrlRequestTest.java b/Cronet/tests/cts/src/android/net/http/cts/UrlRequestTest.java
index d7d3679..54c1ee3 100644
--- a/Cronet/tests/cts/src/android/net/http/cts/UrlRequestTest.java
+++ b/Cronet/tests/cts/src/android/net/http/cts/UrlRequestTest.java
@@ -21,6 +21,7 @@
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.greaterThan;
+import static org.junit.Assert.assertSame;
import android.content.Context;
import android.net.http.HttpEngine;
@@ -91,4 +92,17 @@
request.getStatus(statusListener);
statusListener.expectStatus(Status.INVALID);
}
+
+ @Test
+ public void testUrlRequestCancel_CancelCalled() throws Exception {
+ UrlRequest request = buildUrlRequest(mTestServer.getSuccessUrl());
+ mCallback.setAutoAdvance(false);
+
+ request.start();
+ mCallback.waitForNextStep();
+ assertSame(mCallback.mResponseStep, ResponseStep.ON_RESPONSE_STARTED);
+
+ request.cancel();
+ mCallback.expectCallback(ResponseStep.ON_CANCELED);
+ }
}
diff --git a/Cronet/tests/cts/src/android/net/http/cts/util/HttpCtsTestServer.kt b/Cronet/tests/cts/src/android/net/http/cts/util/HttpCtsTestServer.kt
index 87d5108..5196544 100644
--- a/Cronet/tests/cts/src/android/net/http/cts/util/HttpCtsTestServer.kt
+++ b/Cronet/tests/cts/src/android/net/http/cts/util/HttpCtsTestServer.kt
@@ -18,9 +18,40 @@
import android.content.Context
import android.webkit.cts.CtsTestServer
+import java.net.URI
+import org.apache.http.HttpEntityEnclosingRequest
+import org.apache.http.HttpRequest
+import org.apache.http.HttpResponse
+import org.apache.http.HttpStatus
+import org.apache.http.HttpVersion
+import org.apache.http.message.BasicHttpResponse
+
+private const val ECHO_BODY_PATH = "/echo_body"
/** Extends CtsTestServer to handle POST requests and other test specific requests */
class HttpCtsTestServer(context: Context) : CtsTestServer(context) {
+ val echoBodyUrl: String = baseUri + ECHO_BODY_PATH
val successUrl: String = getAssetUrl("html/hello_world.html")
+
+ override fun onPost(req: HttpRequest): HttpResponse? {
+ val path = URI.create(req.requestLine.uri).path
+ var response: HttpResponse? = null
+
+ if (path.startsWith(ECHO_BODY_PATH)) {
+ if (req !is HttpEntityEnclosingRequest) {
+ return BasicHttpResponse(
+ HttpVersion.HTTP_1_0,
+ HttpStatus.SC_INTERNAL_SERVER_ERROR,
+ "Expected req to be of type HttpEntityEnclosingRequest but got ${req.javaClass}"
+ )
+ }
+
+ response = BasicHttpResponse(HttpVersion.HTTP_1_0, HttpStatus.SC_OK, null)
+ response.entity = req.entity
+ response.addHeader("Content-Length", req.entity.contentLength.toString())
+ }
+
+ return response
+ }
}
diff --git a/Tethering/src/com/android/networkstack/tethering/Tethering.java b/Tethering/src/com/android/networkstack/tethering/Tethering.java
index e48019c..2e71fda 100644
--- a/Tethering/src/com/android/networkstack/tethering/Tethering.java
+++ b/Tethering/src/com/android/networkstack/tethering/Tethering.java
@@ -88,7 +88,6 @@
import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.Network;
-import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.TetherStatesParcel;
import android.net.TetheredClient;
@@ -1856,8 +1855,11 @@
final Network newUpstream = (ns != null) ? ns.network : null;
if (mTetherUpstream != newUpstream) {
mTetherUpstream = newUpstream;
- mUpstreamNetworkMonitor.setCurrentUpstream(mTetherUpstream);
- reportUpstreamChanged(ns);
+ reportUpstreamChanged(mTetherUpstream);
+ // Need to notify capabilities change after upstream network changed because new
+ // network's capabilities should be checked every time.
+ mNotificationUpdater.onUpstreamCapabilitiesChanged(
+ (ns != null) ? ns.networkCapabilities : null);
}
}
@@ -2085,6 +2087,7 @@
if (mTetherUpstream != null) {
mTetherUpstream = null;
reportUpstreamChanged(null);
+ mNotificationUpdater.onUpstreamCapabilitiesChanged(null);
}
mBpfCoordinator.stopPolling();
}
@@ -2439,10 +2442,8 @@
}
}
- private void reportUpstreamChanged(UpstreamNetworkState ns) {
+ private void reportUpstreamChanged(final Network network) {
final int length = mTetheringEventCallbacks.beginBroadcast();
- final Network network = (ns != null) ? ns.network : null;
- final NetworkCapabilities capabilities = (ns != null) ? ns.networkCapabilities : null;
try {
for (int i = 0; i < length; i++) {
try {
@@ -2454,9 +2455,6 @@
} finally {
mTetheringEventCallbacks.finishBroadcast();
}
- // Need to notify capabilities change after upstream network changed because new network's
- // capabilities should be checked every time.
- mNotificationUpdater.onUpstreamCapabilitiesChanged(capabilities);
}
private void reportConfigurationChanged(TetheringConfigurationParcel config) {
diff --git a/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkMonitor.java b/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkMonitor.java
index 16c031b..ac2aa7b 100644
--- a/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkMonitor.java
+++ b/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkMonitor.java
@@ -133,8 +133,6 @@
private boolean mIsDefaultCellularUpstream;
// The current system default network (not really used yet).
private Network mDefaultInternetNetwork;
- // The current upstream network used for tethering.
- private Network mTetheringUpstreamNetwork;
private boolean mPreferTestNetworks;
public UpstreamNetworkMonitor(Context ctx, StateMachine tgt, SharedLog log, int what) {
@@ -191,7 +189,6 @@
releaseCallback(mListenAllCallback);
mListenAllCallback = null;
- mTetheringUpstreamNetwork = null;
mNetworkMap.clear();
}
@@ -342,11 +339,6 @@
return findFirstDunNetwork(mNetworkMap.values());
}
- /** Tell UpstreamNetworkMonitor which network is the current upstream of tethering. */
- public void setCurrentUpstream(Network upstream) {
- mTetheringUpstreamNetwork = upstream;
- }
-
/** Return local prefixes. */
public Set<IpPrefix> getLocalPrefixes() {
return (Set<IpPrefix>) mLocalPrefixes.clone();
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
index f90b3a4..98a3b1d 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
@@ -261,6 +261,8 @@
private static final int DHCPSERVER_START_TIMEOUT_MS = 1000;
+ private static final Network[] NULL_NETWORK = new Network[] {null};
+
@Mock private ApplicationInfo mApplicationInfo;
@Mock private Context mContext;
@Mock private NetworkStatsManager mStatsManager;
@@ -303,6 +305,7 @@
private MockContentResolver mContentResolver;
private BroadcastReceiver mBroadcastReceiver;
private Tethering mTethering;
+ private TestTetheringEventCallback mTetheringEventCallback;
private PhoneStateListener mPhoneStateListener;
private InterfaceConfigurationParcel mInterfaceConfiguration;
private TetheringConfiguration mConfig;
@@ -670,6 +673,7 @@
verify(mStatsManager, times(1)).registerNetworkStatsProvider(anyString(), any());
verify(mNetd).registerUnsolicitedEventListener(any());
verifyDefaultNetworkRequestFiled();
+ mTetheringEventCallback = registerTetheringEventCallback();
final ArgumentCaptor<PhoneStateListener> phoneListenerCaptor =
ArgumentCaptor.forClass(PhoneStateListener.class);
@@ -745,6 +749,16 @@
return request;
}
+ @NonNull
+ private TestTetheringEventCallback registerTetheringEventCallback() {
+ TestTetheringEventCallback callback = new TestTetheringEventCallback();
+ mTethering.registerTetheringEventCallback(callback);
+ mLooper.dispatchAll();
+ // Pull the first event which is filed immediately after the callback registration.
+ callback.expectUpstreamChanged(NULL_NETWORK);
+ return callback;
+ }
+
@After
public void tearDown() {
mServiceContext.unregisterReceiver(mBroadcastReceiver);
@@ -924,9 +938,9 @@
// tetherMatchingInterfaces() which starts by fetching all interfaces).
verify(mNetd, times(1)).interfaceGetList();
- // UpstreamNetworkMonitor should receive selected upstream
+ // Event callback should receive selected upstream
verify(mUpstreamNetworkMonitor, times(1)).getCurrentPreferredUpstream();
- verify(mUpstreamNetworkMonitor, times(1)).setCurrentUpstream(upstreamState.network);
+ mTetheringEventCallback.expectUpstreamChanged(upstreamState.network);
}
@Test
@@ -1181,7 +1195,7 @@
verify(mUpstreamNetworkMonitor, times(1)).getCurrentPreferredUpstream();
verify(mUpstreamNetworkMonitor, never()).selectPreferredUpstreamType(any());
- verify(mUpstreamNetworkMonitor, times(1)).setCurrentUpstream(upstreamState.network);
+ mTetheringEventCallback.expectUpstreamChanged(upstreamState.network);
}
private void verifyDisableTryCellWhenTetheringStop(InOrder inOrder) {
@@ -1206,14 +1220,14 @@
mobile.fakeConnect();
mCm.makeDefaultNetwork(mobile, BROADCAST_FIRST);
mLooper.dispatchAll();
- inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(mobile.networkId);
+ mTetheringEventCallback.expectUpstreamChanged(mobile.networkId);
// Switch upstream to wifi.
wifi.fakeConnect();
mCm.makeDefaultNetwork(wifi, BROADCAST_FIRST);
mLooper.dispatchAll();
inOrder.verify(mUpstreamNetworkMonitor).setTryCell(false);
- inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(wifi.networkId);
+ mTetheringEventCallback.expectUpstreamChanged(wifi.networkId);
}
private void verifyAutomaticUpstreamSelection(boolean configAutomatic) throws Exception {
@@ -1230,30 +1244,30 @@
// Switch upstreams a few times.
mCm.makeDefaultNetwork(mobile, BROADCAST_FIRST, doDispatchAll);
mLooper.dispatchAll();
- inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(mobile.networkId);
+ mTetheringEventCallback.expectUpstreamChanged(mobile.networkId);
mCm.makeDefaultNetwork(wifi, BROADCAST_FIRST, doDispatchAll);
mLooper.dispatchAll();
inOrder.verify(mUpstreamNetworkMonitor).setTryCell(false);
- inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(wifi.networkId);
+ mTetheringEventCallback.expectUpstreamChanged(wifi.networkId);
mCm.makeDefaultNetwork(mobile, CALLBACKS_FIRST);
mLooper.dispatchAll();
- inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(mobile.networkId);
+ mTetheringEventCallback.expectUpstreamChanged(mobile.networkId);
mCm.makeDefaultNetwork(wifi, CALLBACKS_FIRST);
mLooper.dispatchAll();
inOrder.verify(mUpstreamNetworkMonitor).setTryCell(false);
- inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(wifi.networkId);
+ mTetheringEventCallback.expectUpstreamChanged(wifi.networkId);
mCm.makeDefaultNetwork(mobile, CALLBACKS_FIRST, doDispatchAll);
mLooper.dispatchAll();
- inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(mobile.networkId);
+ mTetheringEventCallback.expectUpstreamChanged(mobile.networkId);
// Wifi disconnecting should not have any affect since it's not the current upstream.
wifi.fakeDisconnect();
mLooper.dispatchAll();
- inOrder.verify(mUpstreamNetworkMonitor, never()).setCurrentUpstream(any());
+ mTetheringEventCallback.assertNoUpstreamChangeCallback();
// Lose and regain upstream.
assertTrue(mUpstreamNetworkMonitor.getCurrentPreferredUpstream().linkProperties
@@ -1263,13 +1277,13 @@
mobile.fakeDisconnect();
mLooper.dispatchAll();
inOrder.verify(mUpstreamNetworkMonitor).setTryCell(true);
- inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(null);
+ mTetheringEventCallback.expectUpstreamChanged(NULL_NETWORK);
mobile = new TestNetworkAgent(mCm, buildMobile464xlatUpstreamState());
mobile.fakeConnect();
mCm.makeDefaultNetwork(mobile, BROADCAST_FIRST, doDispatchAll);
mLooper.dispatchAll();
- inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(mobile.networkId);
+ mTetheringEventCallback.expectUpstreamChanged(mobile.networkId);
// Check the IP addresses to ensure that the upstream is indeed not the same as the previous
// mobile upstream, even though the netId is (unrealistically) the same.
@@ -1281,13 +1295,13 @@
mobile.fakeDisconnect();
mLooper.dispatchAll();
inOrder.verify(mUpstreamNetworkMonitor).setTryCell(true);
- inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(null);
+ mTetheringEventCallback.expectUpstreamChanged(NULL_NETWORK);
mobile = new TestNetworkAgent(mCm, buildMobileDualStackUpstreamState());
mobile.fakeConnect();
mCm.makeDefaultNetwork(mobile, CALLBACKS_FIRST, doDispatchAll);
mLooper.dispatchAll();
- inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(mobile.networkId);
+ mTetheringEventCallback.expectUpstreamChanged(mobile.networkId);
assertTrue(mUpstreamNetworkMonitor.getCurrentPreferredUpstream().linkProperties
.hasIPv4Address());
@@ -1328,27 +1342,27 @@
mLooper.dispatchAll();
mCm.makeDefaultNetwork(mobile, CALLBACKS_FIRST, null);
mLooper.dispatchAll();
- inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(mobile.networkId);
+ mTetheringEventCallback.expectUpstreamChanged(mobile.networkId);
wifi.fakeConnect();
mLooper.dispatchAll();
mCm.makeDefaultNetwork(wifi, CALLBACKS_FIRST, null);
mLooper.dispatchAll();
inOrder.verify(mUpstreamNetworkMonitor).setTryCell(false);
- inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(wifi.networkId);
+ mTetheringEventCallback.expectUpstreamChanged(wifi.networkId);
verifyDisableTryCellWhenTetheringStop(inOrder);
}
private void verifyWifiUpstreamAndUnregisterDunCallback(@NonNull final InOrder inOrder,
- @NonNull final TestNetworkAgent wifi,
- @NonNull final NetworkCallback currentDunCallack) throws Exception {
+ @NonNull final TestNetworkAgent wifi, @NonNull final NetworkCallback currentDunCallack)
+ throws Exception {
assertNotNull(currentDunCallack);
inOrder.verify(mUpstreamNetworkMonitor).setTryCell(false);
inOrder.verify(mCm).unregisterNetworkCallback(eq(currentDunCallack));
- inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(wifi.networkId);
- inOrder.verify(mUpstreamNetworkMonitor, never()).setCurrentUpstream(any());
+ mTetheringEventCallback.expectUpstreamChanged(wifi.networkId);
+ mTetheringEventCallback.assertNoUpstreamChangeCallback();
}
@Nullable
@@ -1363,11 +1377,11 @@
captor.capture());
dunNetworkCallback = captor.getValue();
}
- inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(null);
+ mTetheringEventCallback.expectUpstreamChanged(NULL_NETWORK);
final Runnable doDispatchAll = () -> mLooper.dispatchAll();
dun.fakeConnect(CALLBACKS_FIRST, doDispatchAll);
mLooper.dispatchAll();
- inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(dun.networkId);
+ mTetheringEventCallback.expectUpstreamChanged(dun.networkId);
if (needToRequestNetwork) {
assertNotNull(dunNetworkCallback);
@@ -1484,11 +1498,11 @@
dun.fakeDisconnect(CALLBACKS_FIRST, doDispatchAll);
mLooper.dispatchAll();
inOrder.verify(mUpstreamNetworkMonitor).setTryCell(true);
- inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(null);
+ mTetheringEventCallback.expectUpstreamChanged(NULL_NETWORK);
inOrder.verify(mCm, never()).unregisterNetworkCallback(any(NetworkCallback.class));
dun.fakeConnect(CALLBACKS_FIRST, doDispatchAll);
mLooper.dispatchAll();
- inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(dun.networkId);
+ mTetheringEventCallback.expectUpstreamChanged(dun.networkId);
verifyDisableTryCellWhenTetheringStop(inOrder);
}
@@ -1543,8 +1557,8 @@
// automatic mode would request dun again and choose it as upstream.
mCm.makeDefaultNetwork(mobile, CALLBACKS_FIRST);
mLooper.dispatchAll();
- final NetworkCallback dunNetworkCallback2 =
- verifyDunUpstream(inOrder, dun, true /* needToRequestNetwork */);
+ final NetworkCallback dunNetworkCallback2 = verifyDunUpstream(inOrder, dun,
+ true /* needToRequestNetwork */);
// [3] When default network switch to wifi and mobile is still connected,
// unregister dun request and choose wifi as upstream.
@@ -1556,7 +1570,7 @@
final Runnable doDispatchAll = () -> mLooper.dispatchAll();
mobile.fakeDisconnect(CALLBACKS_FIRST, doDispatchAll);
mLooper.dispatchAll();
- inOrder.verify(mUpstreamNetworkMonitor, never()).setCurrentUpstream(any());
+ mTetheringEventCallback.assertNoUpstreamChangeCallback();
verifyDisableTryCellWhenTetheringStop(inOrder);
}
@@ -1627,19 +1641,19 @@
final Runnable doDispatchAll = () -> mLooper.dispatchAll();
dun.fakeConnect(CALLBACKS_FIRST, doDispatchAll);
mLooper.dispatchAll();
- inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(dun.networkId);
+ mTetheringEventCallback.expectUpstreamChanged(dun.networkId);
// [6] When mobile is connected and default network switch to mobile, keep dun as upstream.
mobile.fakeConnect();
mCm.makeDefaultNetwork(mobile, CALLBACKS_FIRST);
mLooper.dispatchAll();
- inOrder.verify(mUpstreamNetworkMonitor, never()).setCurrentUpstream(any());
+ mTetheringEventCallback.assertNoUpstreamChangeCallback();
// [7] When mobile is disconnected, keep dun as upstream.
mCm.makeDefaultNetwork(null, CALLBACKS_FIRST, doDispatchAll);
mobile.fakeDisconnect(CALLBACKS_FIRST, doDispatchAll);
mLooper.dispatchAll();
- inOrder.verify(mUpstreamNetworkMonitor, never()).setCurrentUpstream(any());
+ mTetheringEventCallback.assertNoUpstreamChangeCallback();
verifyDisableTryCellWhenTetheringStop(inOrder);
}
@@ -1670,7 +1684,7 @@
final Runnable doDispatchAll = () -> mLooper.dispatchAll();
dun.fakeConnect(CALLBACKS_FIRST, doDispatchAll);
mLooper.dispatchAll();
- inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(dun.networkId);
+ mTetheringEventCallback.expectUpstreamChanged(dun.networkId);
// [8] Lose and regain upstream again.
dun.fakeDisconnect(CALLBACKS_FIRST, doDispatchAll);
@@ -1714,7 +1728,7 @@
final Runnable doDispatchAll = () -> mLooper.dispatchAll();
dun.fakeConnect(CALLBACKS_FIRST, doDispatchAll);
mLooper.dispatchAll();
- inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(dun.networkId);
+ mTetheringEventCallback.expectUpstreamChanged(dun.networkId);
// [9] When wifi is connected and default network switch to wifi, unregister dun request
// and choose wifi as upstream. When dun is disconnected, keep wifi as upstream.
@@ -1724,7 +1738,7 @@
verifyWifiUpstreamAndUnregisterDunCallback(inOrder, wifi, dunNetworkCallback);
dun.fakeDisconnect(CALLBACKS_FIRST, doDispatchAll);
mLooper.dispatchAll();
- inOrder.verify(mUpstreamNetworkMonitor, never()).setCurrentUpstream(any());
+ mTetheringEventCallback.assertNoUpstreamChangeCallback();
// [10] When mobile and mobile are connected and default network switch to mobile
// (may have low signal), automatic mode would request dun again and choose it as
@@ -1752,7 +1766,7 @@
mCm.makeDefaultNetwork(mobile, CALLBACKS_FIRST);
mLooper.dispatchAll();
inOrder.verify(mUpstreamNetworkMonitor).setTryCell(false);
- inOrder.verify(mUpstreamNetworkMonitor, never()).setCurrentUpstream(any());
+ mTetheringEventCallback.assertNoUpstreamChangeCallback();
// BUG: when wifi disconnect, the dun request would not be filed again because wifi is
// no longer be default network which do not have CONNECTIVIY_ACTION broadcast.
wifi.fakeDisconnect();
@@ -1799,20 +1813,21 @@
}
private void chooseDunUpstreamTestCommon(final boolean automatic, InOrder inOrder,
- TestNetworkAgent mobile, TestNetworkAgent wifi, TestNetworkAgent dun) throws Exception {
+ TestNetworkAgent mobile, TestNetworkAgent wifi, TestNetworkAgent dun)
+ throws Exception {
final NetworkCallback dunNetworkCallback = setupDunUpstreamTest(automatic, inOrder);
// Pretend cellular connected and expect the upstream to be not set.
mobile.fakeConnect();
mCm.makeDefaultNetwork(mobile, BROADCAST_FIRST);
mLooper.dispatchAll();
- inOrder.verify(mUpstreamNetworkMonitor, never()).setCurrentUpstream(mobile.networkId);
+ mTetheringEventCallback.assertNoUpstreamChangeCallback();
// Pretend dun connected and expect choose dun as upstream.
final Runnable doDispatchAll = () -> mLooper.dispatchAll();
dun.fakeConnect(BROADCAST_FIRST, doDispatchAll);
mLooper.dispatchAll();
- inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(dun.networkId);
+ mTetheringEventCallback.expectUpstreamChanged(dun.networkId);
// When wifi connected, unregister dun request and choose wifi as upstream.
wifi.fakeConnect();
@@ -1821,7 +1836,7 @@
verifyWifiUpstreamAndUnregisterDunCallback(inOrder, wifi, dunNetworkCallback);
dun.fakeDisconnect(BROADCAST_FIRST, doDispatchAll);
mLooper.dispatchAll();
- inOrder.verify(mUpstreamNetworkMonitor, never()).setCurrentUpstream(any());
+ mTetheringEventCallback.assertNoUpstreamChangeCallback();
}
private void runNcmTethering() {
@@ -2268,7 +2283,7 @@
mTethering.registerTetheringEventCallback(callback);
mLooper.dispatchAll();
callback.expectTetheredClientChanged(Collections.emptyList());
- callback.expectUpstreamChanged(new Network[] {null});
+ callback.expectUpstreamChanged(NULL_NETWORK);
callback.expectConfigurationChanged(
mTethering.getTetheringConfiguration().toStableParcelable());
TetherStatesParcel tetherState = callback.pollTetherStatesChanged();
@@ -2316,7 +2331,7 @@
tetherState = callback2.pollTetherStatesChanged();
assertArrayEquals(tetherState.availableList, new TetheringInterface[] {wifiIface});
mLooper.dispatchAll();
- callback2.expectUpstreamChanged(new Network[] {null});
+ callback2.expectUpstreamChanged(NULL_NETWORK);
callback2.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
callback.assertNoCallback();
}
@@ -2663,12 +2678,19 @@
public void testUpstreamNetworkChanged() {
final Tethering.TetherMainSM stateMachine = (Tethering.TetherMainSM)
mTetheringDependencies.mUpstreamNetworkMonitorSM;
+ // Gain upstream.
final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
initTetheringUpstream(upstreamState);
stateMachine.chooseUpstreamType(true);
+ mTetheringEventCallback.expectUpstreamChanged(upstreamState.network);
+ verify(mNotificationUpdater)
+ .onUpstreamCapabilitiesChanged(upstreamState.networkCapabilities);
- verify(mUpstreamNetworkMonitor, times(1)).setCurrentUpstream(eq(upstreamState.network));
- verify(mNotificationUpdater, times(1)).onUpstreamCapabilitiesChanged(any());
+ // Lose upstream.
+ initTetheringUpstream(null);
+ stateMachine.chooseUpstreamType(true);
+ mTetheringEventCallback.expectUpstreamChanged(NULL_NETWORK);
+ verify(mNotificationUpdater).onUpstreamCapabilitiesChanged(null);
}
@Test
@@ -2682,7 +2704,8 @@
stateMachine.handleUpstreamNetworkMonitorCallback(EVENT_ON_CAPABILITIES, upstreamState);
// Should have two onUpstreamCapabilitiesChanged().
// One is called by reportUpstreamChanged(). One is called by EVENT_ON_CAPABILITIES.
- verify(mNotificationUpdater, times(2)).onUpstreamCapabilitiesChanged(any());
+ verify(mNotificationUpdater, times(2))
+ .onUpstreamCapabilitiesChanged(upstreamState.networkCapabilities);
reset(mNotificationUpdater);
// Verify that onUpstreamCapabilitiesChanged won't be called if not current upstream network
@@ -2695,6 +2718,27 @@
}
@Test
+ public void testUpstreamCapabilitiesChanged_startStopTethering() throws Exception {
+ final TestNetworkAgent wifi = new TestNetworkAgent(mCm, buildWifiUpstreamState());
+
+ // Start USB tethering with no current upstream.
+ prepareUsbTethering();
+ sendUsbBroadcast(true, true, TETHER_USB_RNDIS_FUNCTION);
+
+ // Pretend wifi connected and expect the upstream to be set.
+ wifi.fakeConnect();
+ mCm.makeDefaultNetwork(wifi, CALLBACKS_FIRST);
+ mLooper.dispatchAll();
+ verify(mNotificationUpdater).onUpstreamCapabilitiesChanged(
+ wifi.networkCapabilities);
+
+ // Stop tethering.
+ // Expect that TetherModeAliveState#exit sends capabilities change notification to null.
+ runStopUSBTethering();
+ verify(mNotificationUpdater).onUpstreamCapabilitiesChanged(null);
+ }
+
+ @Test
public void testDumpTetheringLog() throws Exception {
final FileDescriptor mockFd = mock(FileDescriptor.class);
final PrintWriter mockPw = mock(PrintWriter.class);
diff --git a/framework-t/api/current.txt b/framework-t/api/current.txt
index 5532853..86745d4 100644
--- a/framework-t/api/current.txt
+++ b/framework-t/api/current.txt
@@ -228,8 +228,8 @@
}
public static interface NsdManager.ResolveListener {
+ method public default void onResolutionStopped(@NonNull android.net.nsd.NsdServiceInfo);
method public void onResolveFailed(android.net.nsd.NsdServiceInfo, int);
- method public default void onResolveStopped(@NonNull android.net.nsd.NsdServiceInfo);
method public void onServiceResolved(android.net.nsd.NsdServiceInfo);
method public default void onStopResolutionFailed(@NonNull android.net.nsd.NsdServiceInfo, int);
}
diff --git a/framework-t/src/android/net/nsd/NsdManager.java b/framework-t/src/android/net/nsd/NsdManager.java
index 122e3a0..e38ae8e 100644
--- a/framework-t/src/android/net/nsd/NsdManager.java
+++ b/framework-t/src/android/net/nsd/NsdManager.java
@@ -767,18 +767,18 @@
* Called on the internal thread or with an executor passed to
* {@link NsdManager#resolveService} to report the resolution was stopped.
*
- * A stop resolution operation would call either onResolveStopped or onStopResolutionFailed
- * once based on the result.
+ * A stop resolution operation would call either onResolutionStopped or
+ * onStopResolutionFailed once based on the result.
*/
- default void onResolveStopped(@NonNull NsdServiceInfo serviceInfo) { }
+ default void onResolutionStopped(@NonNull NsdServiceInfo serviceInfo) { }
/**
* Called once on the internal thread or with an executor passed to
* {@link NsdManager#resolveService} to report that stopping resolution failed with an
* error.
*
- * A stop resolution operation would call either onResolveStopped or onStopResolutionFailed
- * once based on the result.
+ * A stop resolution operation would call either onResolutionStopped or
+ * onStopResolutionFailed once based on the result.
*/
default void onStopResolutionFailed(@NonNull NsdServiceInfo serviceInfo,
@StopOperationFailureCode int errorCode) { }
@@ -929,7 +929,7 @@
break;
case STOP_RESOLUTION_SUCCEEDED:
removeListener(key);
- executor.execute(() -> ((ResolveListener) listener).onResolveStopped(
+ executor.execute(() -> ((ResolveListener) listener).onResolutionStopped(
ns));
break;
case REGISTER_SERVICE_CALLBACK_FAILED:
@@ -1301,7 +1301,7 @@
/**
* Stop service resolution initiated with {@link #resolveService}.
*
- * A successful stop is notified with a call to {@link ResolveListener#onResolveStopped}.
+ * A successful stop is notified with a call to {@link ResolveListener#onResolutionStopped}.
*
* <p> Upon failure to stop service resolution for example if resolution is done or the
* requester stops resolution repeatedly, the application is notified
diff --git a/framework/src/android/net/NetworkAgent.java b/framework/src/android/net/NetworkAgent.java
index 62e4fe1..3ec00d9 100644
--- a/framework/src/android/net/NetworkAgent.java
+++ b/framework/src/android/net/NetworkAgent.java
@@ -491,7 +491,7 @@
* TCP sockets are open over a VPN. The system will check periodically for presence of
* such open sockets, and this message is what triggers the re-evaluation.
*
- * obj = AutomaticOnOffKeepaliveObject.
+ * obj = A Binder object associated with the keepalive.
* @hide
*/
public static final int CMD_MONITOR_AUTOMATIC_KEEPALIVE = BASE + 30;
diff --git a/service-t/native/libs/libnetworkstats/NetworkTraceHandler.cpp b/service-t/native/libs/libnetworkstats/NetworkTraceHandler.cpp
index 4c37b8d..aeadb4a 100644
--- a/service-t/native/libs/libnetworkstats/NetworkTraceHandler.cpp
+++ b/service-t/native/libs/libnetworkstats/NetworkTraceHandler.cpp
@@ -50,6 +50,7 @@
void NetworkTraceHandler::InitPerfettoTracing() {
perfetto::TracingInitArgs args = {};
args.backends |= perfetto::kSystemBackend;
+ args.enable_system_consumer = false;
perfetto::Tracing::Initialize(args);
NetworkTraceHandler::RegisterDataSource();
}
diff --git a/service-t/src/com/android/server/NsdService.java b/service-t/src/com/android/server/NsdService.java
index 49c6ef0..4ad39e1 100644
--- a/service-t/src/com/android/server/NsdService.java
+++ b/service-t/src/com/android/server/NsdService.java
@@ -118,13 +118,15 @@
private final NsdStateMachine mNsdStateMachine;
private final MDnsManager mMDnsManager;
private final MDnsEventCallback mMDnsEventCallback;
- @Nullable
+ @NonNull
+ private final Dependencies mDeps;
+ @NonNull
private final MdnsMultinetworkSocketClient mMdnsSocketClient;
- @Nullable
+ @NonNull
private final MdnsDiscoveryManager mMdnsDiscoveryManager;
- @Nullable
+ @NonNull
private final MdnsSocketProvider mMdnsSocketProvider;
- @Nullable
+ @NonNull
private final MdnsAdvertiser mAdvertiser;
// WARNING : Accessing these values in any thread is not safe, it must only be changed in the
// state machine thread. If change this outside state machine, it will need to introduce
@@ -311,21 +313,14 @@
mIsMonitoringSocketsStarted = true;
}
- private void maybeStopMonitoringSockets() {
- if (!mIsMonitoringSocketsStarted) {
- if (DBG) Log.d(TAG, "Socket monitoring has not been started.");
- return;
- }
+ private void maybeStopMonitoringSocketsIfNoActiveRequest() {
+ if (!mIsMonitoringSocketsStarted) return;
+ if (isAnyRequestActive()) return;
+
mMdnsSocketProvider.stopMonitoringSockets();
mIsMonitoringSocketsStarted = false;
}
- private void maybeStopMonitoringSocketsIfNoActiveRequest() {
- if (!isAnyRequestActive()) {
- maybeStopMonitoringSockets();
- }
- }
-
NsdStateMachine(String name, Handler handler) {
super(name, handler);
addState(mDefaultState);
@@ -362,9 +357,7 @@
mLegacyClientCount -= 1;
}
}
- if (mMdnsDiscoveryManager != null || mAdvertiser != null) {
- maybeStopMonitoringSocketsIfNoActiveRequest();
- }
+ maybeStopMonitoringSocketsIfNoActiveRequest();
maybeScheduleStop();
break;
case NsdManager.DISCOVER_SERVICES:
@@ -579,7 +572,7 @@
final NsdServiceInfo info = args.serviceInfo;
id = getUniqueId();
- if (mMdnsDiscoveryManager != null) {
+ if (mDeps.isMdnsDiscoveryManagerEnabled(mContext)) {
final String serviceType = constructServiceType(info.getServiceType());
if (serviceType == null) {
clientInfo.onDiscoverServicesFailed(clientId,
@@ -634,6 +627,9 @@
break;
}
id = request.mGlobalId;
+ // Note isMdnsDiscoveryManagerEnabled may have changed to false at this
+ // point, so this needs to check the type of the original request to
+ // unregister instead of looking at the flag value.
if (request instanceof DiscoveryManagerRequest) {
final MdnsListener listener =
((DiscoveryManagerRequest) request).mListener;
@@ -671,7 +667,7 @@
}
id = getUniqueId();
- if (mAdvertiser != null) {
+ if (mDeps.isMdnsAdvertiserEnabled(mContext)) {
final NsdServiceInfo serviceInfo = args.serviceInfo;
final String serviceType = serviceInfo.getServiceType();
final String registerServiceType = constructServiceType(serviceType);
@@ -722,7 +718,10 @@
id = request.mGlobalId;
removeRequestMap(clientId, id, clientInfo);
- if (mAdvertiser != null) {
+ // Note isMdnsAdvertiserEnabled may have changed to false at this point,
+ // so this needs to check the type of the original request to unregister
+ // instead of looking at the flag value.
+ if (request instanceof AdvertiserClientRequest) {
mAdvertiser.removeService(id);
clientInfo.onUnregisterServiceSucceeded(clientId);
} else {
@@ -749,7 +748,7 @@
final NsdServiceInfo info = args.serviceInfo;
id = getUniqueId();
- if (mMdnsDiscoveryManager != null) {
+ if (mDeps.isMdnsDiscoveryManagerEnabled(mContext)) {
final String serviceType = constructServiceType(info.getServiceType());
if (serviceType == null) {
clientInfo.onResolveServiceFailed(clientId,
@@ -1241,32 +1240,16 @@
mNsdStateMachine.start();
mMDnsManager = ctx.getSystemService(MDnsManager.class);
mMDnsEventCallback = new MDnsEventCallback(mNsdStateMachine);
+ mDeps = deps;
- final boolean discoveryManagerEnabled = deps.isMdnsDiscoveryManagerEnabled(ctx);
- final boolean advertiserEnabled = deps.isMdnsAdvertiserEnabled(ctx);
- if (discoveryManagerEnabled || advertiserEnabled) {
- mMdnsSocketProvider = deps.makeMdnsSocketProvider(ctx, handler.getLooper());
- } else {
- mMdnsSocketProvider = null;
- }
-
- if (discoveryManagerEnabled) {
- mMdnsSocketClient =
- new MdnsMultinetworkSocketClient(handler.getLooper(), mMdnsSocketProvider);
- mMdnsDiscoveryManager =
- deps.makeMdnsDiscoveryManager(new ExecutorProvider(), mMdnsSocketClient);
- handler.post(() -> mMdnsSocketClient.setCallback(mMdnsDiscoveryManager));
- } else {
- mMdnsSocketClient = null;
- mMdnsDiscoveryManager = null;
- }
-
- if (advertiserEnabled) {
- mAdvertiser = deps.makeMdnsAdvertiser(handler.getLooper(), mMdnsSocketProvider,
- new AdvertiserCallback());
- } else {
- mAdvertiser = null;
- }
+ mMdnsSocketProvider = deps.makeMdnsSocketProvider(ctx, handler.getLooper());
+ mMdnsSocketClient =
+ new MdnsMultinetworkSocketClient(handler.getLooper(), mMdnsSocketProvider);
+ mMdnsDiscoveryManager =
+ deps.makeMdnsDiscoveryManager(new ExecutorProvider(), mMdnsSocketClient);
+ handler.post(() -> mMdnsSocketClient.setCallback(mMdnsDiscoveryManager));
+ mAdvertiser = deps.makeMdnsAdvertiser(handler.getLooper(), mMdnsSocketProvider,
+ new AdvertiserCallback());
}
/**
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index 330a1da..2371911 100755
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -107,6 +107,7 @@
import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.AppOpsManager;
import android.app.BroadcastOptions;
@@ -3038,6 +3039,8 @@
sendStickyBroadcast(makeGeneralIntent(info, bcastType));
}
+ // TODO(b/193460475): Remove when tooling supports SystemApi to public API.
+ @SuppressLint("NewApi")
// TODO: Set the mini sdk to 31 and remove @TargetApi annotation when b/205923322 is addressed.
@TargetApi(Build.VERSION_CODES.S)
private void sendStickyBroadcast(Intent intent) {
@@ -5547,7 +5550,9 @@
break;
}
case NetworkAgent.CMD_MONITOR_AUTOMATIC_KEEPALIVE: {
- final AutomaticOnOffKeepalive ki = (AutomaticOnOffKeepalive) msg.obj;
+ final AutomaticOnOffKeepalive ki =
+ mKeepaliveTracker.getKeepaliveForBinder((IBinder) msg.obj);
+ if (null == ki) return; // The callback was unregistered before the alarm fired
final Network network = ki.getNetwork();
boolean networkFound = false;
@@ -8516,6 +8521,8 @@
// else not handled
}
+ // TODO(b/193460475): Remove when tooling supports SystemApi to public API.
+ @SuppressLint("NewApi")
private void sendIntent(PendingIntent pendingIntent, Intent intent) {
mPendingIntentWakeLock.acquire();
try {
diff --git a/service/src/com/android/server/connectivity/AutomaticOnOffKeepaliveTracker.java b/service/src/com/android/server/connectivity/AutomaticOnOffKeepaliveTracker.java
index 46fff6c..18e2dd8 100644
--- a/service/src/com/android/server/connectivity/AutomaticOnOffKeepaliveTracker.java
+++ b/service/src/com/android/server/connectivity/AutomaticOnOffKeepaliveTracker.java
@@ -45,6 +45,7 @@
import android.net.Network;
import android.net.NetworkAgent;
import android.net.SocketKeepalive.InvalidSocketException;
+import android.os.Bundle;
import android.os.FileUtils;
import android.os.Handler;
import android.os.IBinder;
@@ -60,6 +61,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.IndentingPrintWriter;
import com.android.modules.utils.build.SdkLevel;
+import com.android.net.module.util.BinderUtils;
import com.android.net.module.util.CollectionUtils;
import com.android.net.module.util.DeviceConfigUtils;
import com.android.net.module.util.HexDump;
@@ -92,8 +94,7 @@
private static final int[] ADDRESS_FAMILIES = new int[] {AF_INET6, AF_INET};
private static final String ACTION_TCP_POLLING_ALARM =
"com.android.server.connectivity.KeepaliveTracker.TCP_POLLING_ALARM";
- private static final String EXTRA_NETWORK = "network_id";
- private static final String EXTRA_SLOT = "slot";
+ private static final String EXTRA_BINDER_TOKEN = "token";
private static final long DEFAULT_TCP_POLLING_INTERVAL_MS = 120_000L;
private static final String AUTOMATIC_ON_OFF_KEEPALIVE_VERSION =
"automatic_on_off_keepalive_version";
@@ -159,11 +160,10 @@
public void onReceive(Context context, Intent intent) {
if (ACTION_TCP_POLLING_ALARM.equals(intent.getAction())) {
Log.d(TAG, "Received TCP polling intent");
- final Network network = intent.getParcelableExtra(EXTRA_NETWORK);
- final int slot = intent.getIntExtra(EXTRA_SLOT, -1);
+ final IBinder token = intent.getBundleExtra(EXTRA_BINDER_TOKEN).getBinder(
+ EXTRA_BINDER_TOKEN);
mConnectivityServiceHandler.obtainMessage(
- NetworkAgent.CMD_MONITOR_AUTOMATIC_KEEPALIVE,
- slot, 0 , network).sendToTarget();
+ NetworkAgent.CMD_MONITOR_AUTOMATIC_KEEPALIVE, token).sendToTarget();
}
}
};
@@ -183,6 +183,8 @@
public class AutomaticOnOffKeepalive {
@NonNull
private final KeepaliveTracker.KeepaliveInfo mKi;
+ @NonNull
+ private final ISocketKeepaliveCallback mCallback;
@Nullable
private final FileDescriptor mFd;
@Nullable
@@ -193,6 +195,7 @@
AutomaticOnOffKeepalive(@NonNull final KeepaliveTracker.KeepaliveInfo ki,
final boolean autoOnOff, @NonNull Context context) throws InvalidSocketException {
this.mKi = Objects.requireNonNull(ki);
+ mCallback = ki.mCallback;
if (autoOnOff && mDependencies.isFeatureEnabled(AUTOMATIC_ON_OFF_KEEPALIVE_VERSION)) {
mAutomaticOnOffState = STATE_ENABLED;
if (null == ki.mFd) {
@@ -205,8 +208,7 @@
Log.e(TAG, "Cannot dup fd: ", e);
throw new InvalidSocketException(ERROR_INVALID_SOCKET, e);
}
- mTcpPollingAlarm = createTcpPollingAlarmIntent(
- context, ki.getNai().network(), ki.getSlot());
+ mTcpPollingAlarm = createTcpPollingAlarmIntent(context, mCallback.asBinder());
} else {
mAutomaticOnOffState = STATE_ALWAYS_ON;
// A null fd is acceptable in KeepaliveInfo for backward compatibility of
@@ -226,12 +228,14 @@
}
private PendingIntent createTcpPollingAlarmIntent(@NonNull Context context,
- @NonNull Network network, int slot) {
+ @NonNull IBinder token) {
final Intent intent = new Intent(ACTION_TCP_POLLING_ALARM);
- intent.putExtra(EXTRA_NETWORK, network);
- intent.putExtra(EXTRA_SLOT, slot);
- return PendingIntent.getBroadcast(
- context, 0 /* requestCode */, intent, PendingIntent.FLAG_IMMUTABLE);
+ // Intent doesn't expose methods to put extra Binders, but Bundle does.
+ final Bundle b = new Bundle();
+ b.putBinder(EXTRA_BINDER_TOKEN, token);
+ intent.putExtra(EXTRA_BINDER_TOKEN, b);
+ return BinderUtils.withCleanCallingIdentity(() -> PendingIntent.getBroadcast(
+ context, 0 /* requestCode */, intent, PendingIntent.FLAG_IMMUTABLE));
}
}
@@ -318,13 +322,14 @@
newKi = autoKi.mKi.withFd(autoKi.mFd);
} catch (InvalidSocketException | IllegalArgumentException | SecurityException e) {
Log.e(TAG, "Fail to construct keepalive", e);
- mKeepaliveTracker.notifyErrorCallback(autoKi.mKi.mCallback, ERROR_INVALID_SOCKET);
+ mKeepaliveTracker.notifyErrorCallback(autoKi.mCallback, ERROR_INVALID_SOCKET);
return;
}
autoKi.mAutomaticOnOffState = STATE_ENABLED;
handleResumeKeepalive(newKi);
}
+ // TODO : this method should be removed ; the keepalives should always be indexed by callback
private int findAutomaticOnOffKeepaliveIndex(@NonNull Network network, int slot) {
ensureRunningOnHandlerThread();
@@ -338,6 +343,7 @@
return -1;
}
+ // TODO : this method should be removed ; the keepalives should always be indexed by callback
@Nullable
private AutomaticOnOffKeepalive findAutomaticOnOffKeepalive(@NonNull Network network,
int slot) {
@@ -348,6 +354,18 @@
}
/**
+ * Find the AutomaticOnOffKeepalive associated with a given callback.
+ * @return the keepalive associated with this callback, or null if none
+ */
+ @Nullable
+ public AutomaticOnOffKeepalive getKeepaliveForBinder(@NonNull final IBinder token) {
+ ensureRunningOnHandlerThread();
+
+ return CollectionUtils.findFirst(mAutomaticOnOffKeepalives,
+ it -> it.mCallback.asBinder().equals(token));
+ }
+
+ /**
* Handle keepalive events from lower layer.
*
* Forward to KeepaliveTracker.
diff --git a/service/src/com/android/server/connectivity/KeepaliveTracker.java b/service/src/com/android/server/connectivity/KeepaliveTracker.java
index 63b76c7..7cb613b 100644
--- a/service/src/com/android/server/connectivity/KeepaliveTracker.java
+++ b/service/src/com/android/server/connectivity/KeepaliveTracker.java
@@ -125,8 +125,9 @@
* which is only returned when the hardware has successfully started the keepalive.
*/
class KeepaliveInfo implements IBinder.DeathRecipient {
- // Bookkeeping data.
+ // TODO : remove this member. Only AutoOnOffKeepalive should have a reference to this.
public final ISocketKeepaliveCallback mCallback;
+ // Bookkeeping data.
private final int mUid;
private final int mPid;
private final boolean mPrivileged;
diff --git a/tests/common/AndroidTest_Coverage.xml b/tests/common/AndroidTest_Coverage.xml
index 48d26b8..c94ec27 100644
--- a/tests/common/AndroidTest_Coverage.xml
+++ b/tests/common/AndroidTest_Coverage.xml
@@ -13,7 +13,7 @@
limitations under the License.
-->
<configuration description="Runs coverage tests for Connectivity">
- <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
+ <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="test-file-name" value="ConnectivityCoverageTests.apk" />
<option name="install-arg" value="-t" />
</target_preparer>
diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
index d4b23a3..ccba983 100644
--- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
@@ -1140,11 +1140,8 @@
.setPackage(mContext.getPackageName());
// While ConnectivityService would put extra info such as network or request id before
// broadcasting the inner intent. The MUTABLE flag needs to be added accordingly.
- // TODO: replace with PendingIntent.FLAG_MUTABLE when this code compiles against S+ or
- // shims.
- final int pendingIntentFlagMutable = 1 << 25;
final PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0 /*requestCode*/,
- intent, PendingIntent.FLAG_CANCEL_CURRENT | pendingIntentFlagMutable);
+ intent, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_MUTABLE);
// We will register for a WIFI network being available or lost.
mCm.registerNetworkCallback(makeWifiNetworkRequest(), pendingIntent);
@@ -1184,15 +1181,13 @@
// Avoid receiving broadcasts from other runs by appending a timestamp
final String broadcastAction = NETWORK_CALLBACK_ACTION + System.currentTimeMillis();
try {
- // TODO: replace with PendingIntent.FLAG_MUTABLE when this code compiles against S+
// Intent is mutable to receive EXTRA_NETWORK_REQUEST from ConnectivityService
- final int pendingIntentFlagMutable = 1 << 25;
final String extraBoolKey = "extra_bool";
firstIntent = PendingIntent.getBroadcast(mContext,
0 /* requestCode */,
new Intent(broadcastAction).putExtra(extraBoolKey, false)
.setPackage(mContext.getPackageName()),
- PendingIntent.FLAG_UPDATE_CURRENT | pendingIntentFlagMutable);
+ PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
if (useListen) {
mCm.registerNetworkCallback(firstRequest, firstIntent);
@@ -1206,7 +1201,7 @@
0 /* requestCode */,
new Intent(broadcastAction).putExtra(extraBoolKey, true)
.setPackage(mContext.getPackageName()),
- PendingIntent.FLAG_UPDATE_CURRENT | pendingIntentFlagMutable);
+ PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
// Because secondIntent.intentFilterEquals the first, the request should be replaced
if (useListen) {
diff --git a/tests/cts/net/src/android/net/cts/NsdManagerTest.kt b/tests/cts/net/src/android/net/cts/NsdManagerTest.kt
index 66e7713..9b27df5 100644
--- a/tests/cts/net/src/android/net/cts/NsdManagerTest.kt
+++ b/tests/cts/net/src/android/net/cts/NsdManagerTest.kt
@@ -41,7 +41,7 @@
import android.net.cts.NsdManagerTest.NsdRegistrationRecord.RegistrationEvent.ServiceUnregistered
import android.net.cts.NsdManagerTest.NsdRegistrationRecord.RegistrationEvent.UnregistrationFailed
import android.net.cts.NsdManagerTest.NsdResolveRecord.ResolveEvent.ResolveFailed
-import android.net.cts.NsdManagerTest.NsdResolveRecord.ResolveEvent.ResolveStopped
+import android.net.cts.NsdManagerTest.NsdResolveRecord.ResolveEvent.ResolutionStopped
import android.net.cts.NsdManagerTest.NsdResolveRecord.ResolveEvent.ServiceResolved
import android.net.cts.NsdManagerTest.NsdResolveRecord.ResolveEvent.StopResolutionFailed
import android.net.cts.NsdManagerTest.NsdServiceInfoCallbackRecord.ServiceInfoCallbackEvent.RegisterCallbackFailed
@@ -273,7 +273,7 @@
ResolveEvent()
data class ServiceResolved(val serviceInfo: NsdServiceInfo) : ResolveEvent()
- data class ResolveStopped(val serviceInfo: NsdServiceInfo) : ResolveEvent()
+ data class ResolutionStopped(val serviceInfo: NsdServiceInfo) : ResolveEvent()
data class StopResolutionFailed(val serviceInfo: NsdServiceInfo, val errorCode: Int) :
ResolveEvent()
}
@@ -286,8 +286,8 @@
add(ServiceResolved(si))
}
- override fun onResolveStopped(si: NsdServiceInfo) {
- add(ResolveStopped(si))
+ override fun onResolutionStopped(si: NsdServiceInfo) {
+ add(ResolutionStopped(si))
}
override fun onStopResolutionFailed(si: NsdServiceInfo, err: Int) {
@@ -798,10 +798,10 @@
val resolveRecord = NsdResolveRecord()
// Try to resolve an unknown service then stop it immediately.
- // Expected ResolveStopped callback.
+ // Expected ResolutionStopped callback.
nsdShim.resolveService(nsdManager, si, { it.run() }, resolveRecord)
nsdShim.stopServiceResolution(nsdManager, resolveRecord)
- val stoppedCb = resolveRecord.expectCallback<ResolveStopped>()
+ val stoppedCb = resolveRecord.expectCallback<ResolutionStopped>()
assertEquals(si.serviceName, stoppedCb.serviceInfo.serviceName)
assertEquals(si.serviceType, stoppedCb.serviceInfo.serviceType)
}
diff --git a/tests/unit/Android.bp b/tests/unit/Android.bp
index e0de246..8db307d 100644
--- a/tests/unit/Android.bp
+++ b/tests/unit/Android.bp
@@ -114,6 +114,7 @@
"service-connectivity-pre-jarjar",
"service-connectivity-tiramisu-pre-jarjar",
"services.core-vpn",
+ "testables",
"cts-net-utils"
],
libs: [
diff --git a/tests/unit/java/com/android/server/NsdServiceTest.java b/tests/unit/java/com/android/server/NsdServiceTest.java
index 98a8ed2..5a3bc64 100644
--- a/tests/unit/java/com/android/server/NsdServiceTest.java
+++ b/tests/unit/java/com/android/server/NsdServiceTest.java
@@ -45,6 +45,7 @@
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import android.compat.testing.PlatformCompatChangeRule;
@@ -170,6 +171,9 @@
doReturn(true).when(mMockMDnsM).resolve(
anyInt(), anyString(), anyString(), anyString(), anyInt());
doReturn(false).when(mDeps).isMdnsDiscoveryManagerEnabled(any(Context.class));
+ doReturn(mDiscoveryManager).when(mDeps).makeMdnsDiscoveryManager(any(), any());
+ doReturn(mSocketProvider).when(mDeps).makeMdnsSocketProvider(any(), any());
+ doReturn(mAdvertiser).when(mDeps).makeMdnsAdvertiser(any(), any(), any());
mService = makeService();
}
@@ -625,7 +629,7 @@
waitForIdle();
verify(mMockMDnsM).stopOperation(resolveId);
- verify(resolveListener, timeout(TIMEOUT_MS)).onResolveStopped(argThat(ns ->
+ verify(resolveListener, timeout(TIMEOUT_MS)).onResolutionStopped(argThat(ns ->
request.getServiceName().equals(ns.getServiceName())
&& request.getServiceType().equals(ns.getServiceType())));
}
@@ -692,7 +696,7 @@
waitForIdle();
verify(mMockMDnsM).stopOperation(getAddrId);
- verify(resolveListener, timeout(TIMEOUT_MS)).onResolveStopped(argThat(ns ->
+ verify(resolveListener, timeout(TIMEOUT_MS)).onResolutionStopped(argThat(ns ->
request.getServiceName().equals(ns.getServiceName())
&& request.getServiceType().equals(ns.getServiceType())));
}
@@ -824,40 +828,50 @@
client.unregisterServiceInfoCallback(serviceInfoCallback));
}
- private void makeServiceWithMdnsDiscoveryManagerEnabled() {
+ private void setMdnsDiscoveryManagerEnabled() {
doReturn(true).when(mDeps).isMdnsDiscoveryManagerEnabled(any(Context.class));
- doReturn(mDiscoveryManager).when(mDeps).makeMdnsDiscoveryManager(any(), any());
- doReturn(mSocketProvider).when(mDeps).makeMdnsSocketProvider(any(), any());
-
- mService = makeService();
- verify(mDeps).makeMdnsDiscoveryManager(any(), any());
- verify(mDeps).makeMdnsSocketProvider(any(), any());
}
- private void makeServiceWithMdnsAdvertiserEnabled() {
+ private void setMdnsAdvertiserEnabled() {
doReturn(true).when(mDeps).isMdnsAdvertiserEnabled(any(Context.class));
- doReturn(mAdvertiser).when(mDeps).makeMdnsAdvertiser(any(), any(), any());
- doReturn(mSocketProvider).when(mDeps).makeMdnsSocketProvider(any(), any());
-
- mService = makeService();
- verify(mDeps).makeMdnsAdvertiser(any(), any(), any());
- verify(mDeps).makeMdnsSocketProvider(any(), any());
}
@Test
public void testMdnsDiscoveryManagerFeature() {
// Create NsdService w/o feature enabled.
- connectClient(mService);
- verify(mDeps, never()).makeMdnsDiscoveryManager(any(), any());
- verify(mDeps, never()).makeMdnsSocketProvider(any(), any());
+ final NsdManager client = connectClient(mService);
+ final DiscoveryListener discListenerWithoutFeature = mock(DiscoveryListener.class);
+ client.discoverServices(SERVICE_TYPE, PROTOCOL, discListenerWithoutFeature);
+ waitForIdle();
- // Create NsdService again w/ feature enabled.
- makeServiceWithMdnsDiscoveryManagerEnabled();
+ final ArgumentCaptor<Integer> legacyIdCaptor = ArgumentCaptor.forClass(Integer.class);
+ verify(mMockMDnsM).discover(legacyIdCaptor.capture(), any(), anyInt());
+ verifyNoMoreInteractions(mDiscoveryManager);
+
+ setMdnsDiscoveryManagerEnabled();
+ final DiscoveryListener discListenerWithFeature = mock(DiscoveryListener.class);
+ client.discoverServices(SERVICE_TYPE, PROTOCOL, discListenerWithFeature);
+ waitForIdle();
+
+ final String serviceTypeWithLocalDomain = SERVICE_TYPE + ".local";
+ final ArgumentCaptor<MdnsServiceBrowserListener> listenerCaptor =
+ ArgumentCaptor.forClass(MdnsServiceBrowserListener.class);
+ verify(mDiscoveryManager).registerListener(eq(serviceTypeWithLocalDomain),
+ listenerCaptor.capture(), any());
+
+ client.stopServiceDiscovery(discListenerWithoutFeature);
+ waitForIdle();
+ verify(mMockMDnsM).stopOperation(legacyIdCaptor.getValue());
+
+ client.stopServiceDiscovery(discListenerWithFeature);
+ waitForIdle();
+ verify(mDiscoveryManager).unregisterListener(serviceTypeWithLocalDomain,
+ listenerCaptor.getValue());
}
@Test
public void testDiscoveryWithMdnsDiscoveryManager() {
- makeServiceWithMdnsDiscoveryManagerEnabled();
+ setMdnsDiscoveryManagerEnabled();
final NsdManager client = connectClient(mService);
final DiscoveryListener discListener = mock(DiscoveryListener.class);
@@ -922,7 +936,7 @@
@Test
public void testDiscoveryWithMdnsDiscoveryManager_FailedWithInvalidServiceType() {
- makeServiceWithMdnsDiscoveryManagerEnabled();
+ setMdnsDiscoveryManagerEnabled();
final NsdManager client = connectClient(mService);
final DiscoveryListener discListener = mock(DiscoveryListener.class);
@@ -951,7 +965,7 @@
@Test
public void testResolutionWithMdnsDiscoveryManager() throws UnknownHostException {
- makeServiceWithMdnsDiscoveryManagerEnabled();
+ setMdnsDiscoveryManagerEnabled();
final NsdManager client = connectClient(mService);
final ResolveListener resolveListener = mock(ResolveListener.class);
@@ -1005,8 +1019,43 @@
}
@Test
+ public void testMdnsAdvertiserFeatureFlagging() {
+ // Create NsdService w/o feature enabled.
+ final NsdManager client = connectClient(mService);
+ final NsdServiceInfo regInfo = new NsdServiceInfo(SERVICE_NAME, SERVICE_TYPE);
+ regInfo.setHost(parseNumericAddress("192.0.2.123"));
+ regInfo.setPort(12345);
+ final RegistrationListener regListenerWithoutFeature = mock(RegistrationListener.class);
+ client.registerService(regInfo, PROTOCOL, regListenerWithoutFeature);
+ waitForIdle();
+
+ final ArgumentCaptor<Integer> legacyIdCaptor = ArgumentCaptor.forClass(Integer.class);
+ verify(mMockMDnsM).registerService(legacyIdCaptor.capture(), any(), any(), anyInt(),
+ any(), anyInt());
+ verifyNoMoreInteractions(mAdvertiser);
+
+ setMdnsAdvertiserEnabled();
+ final RegistrationListener regListenerWithFeature = mock(RegistrationListener.class);
+ client.registerService(regInfo, PROTOCOL, regListenerWithFeature);
+ waitForIdle();
+
+ final ArgumentCaptor<Integer> serviceIdCaptor = ArgumentCaptor.forClass(Integer.class);
+ verify(mAdvertiser).addService(serviceIdCaptor.capture(),
+ argThat(info -> matches(info, regInfo)));
+
+ client.unregisterService(regListenerWithoutFeature);
+ waitForIdle();
+ verify(mMockMDnsM).stopOperation(legacyIdCaptor.getValue());
+ verify(mAdvertiser, never()).removeService(anyInt());
+
+ client.unregisterService(regListenerWithFeature);
+ waitForIdle();
+ verify(mAdvertiser).removeService(serviceIdCaptor.getValue());
+ }
+
+ @Test
public void testAdvertiseWithMdnsAdvertiser() {
- makeServiceWithMdnsAdvertiserEnabled();
+ setMdnsAdvertiserEnabled();
final NsdManager client = connectClient(mService);
final RegistrationListener regListener = mock(RegistrationListener.class);
@@ -1045,7 +1094,7 @@
@Test
public void testAdvertiseWithMdnsAdvertiser_FailedWithInvalidServiceType() {
- makeServiceWithMdnsAdvertiserEnabled();
+ setMdnsAdvertiserEnabled();
final NsdManager client = connectClient(mService);
final RegistrationListener regListener = mock(RegistrationListener.class);
@@ -1070,7 +1119,7 @@
@Test
public void testAdvertiseWithMdnsAdvertiser_LongServiceName() {
- makeServiceWithMdnsAdvertiserEnabled();
+ setMdnsAdvertiserEnabled();
final NsdManager client = connectClient(mService);
final RegistrationListener regListener = mock(RegistrationListener.class);
diff --git a/tests/unit/java/com/android/server/connectivity/NetworkNotificationManagerTest.java b/tests/unit/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
index 9a5298d..e038c44 100644
--- a/tests/unit/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
+++ b/tests/unit/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
@@ -56,8 +56,10 @@
import android.net.NetworkInfo;
import android.os.Build;
import android.os.Bundle;
+import android.os.PowerManager;
import android.os.UserHandle;
import android.telephony.TelephonyManager;
+import android.testing.PollingCheck;
import android.util.DisplayMetrics;
import android.widget.TextView;
@@ -391,7 +393,15 @@
final Instrumentation instr = InstrumentationRegistry.getInstrumentation();
final UiDevice uiDevice = UiDevice.getInstance(instr);
- UiDevice.getInstance(instr).pressHome();
+ final Context ctx = instr.getContext();
+ final PowerManager pm = ctx.getSystemService(PowerManager.class);
+
+ // Wake up the device (it has no effect if the device is already awake).
+ uiDevice.executeShellCommand("input keyevent KEYCODE_WAKEUP");
+ uiDevice.executeShellCommand("wm dismiss-keyguard");
+ PollingCheck.check("Wait for the screen to be turned on failed, timeout=" + TEST_TIMEOUT_MS,
+ TEST_TIMEOUT_MS, () -> pm.isInteractive());
+ uiDevice.pressHome();
// UiDevice.getLauncherPackageName() requires the test manifest to have a <queries> tag for
// the launcher intent.
@@ -404,7 +414,6 @@
// Non-"no internet" notifications are not affected
verify(mNotificationManager).notify(eq(TEST_NOTIF_TAG), eq(NETWORK_SWITCH.eventId), any());
- final Context ctx = instr.getContext();
final String testAction = "com.android.connectivity.coverage.TEST_DIALOG";
final Intent intent = new Intent(testAction)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)