[FUI19] Migrate ConnectivityService to use NetworkStatsManager
Test: atest FrameworksNetTests Bug: 174123988 Change-Id: Iaefd99f87ae96bc9d97d139bcd92a3fe8de917d2
This commit is contained in:
@@ -148,6 +148,7 @@ import android.app.AlarmManager;
|
||||
import android.app.AppOpsManager;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.usage.NetworkStatsManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
import android.content.ContentProvider;
|
||||
@@ -179,7 +180,6 @@ import android.net.INetd;
|
||||
import android.net.INetworkMonitor;
|
||||
import android.net.INetworkMonitorCallbacks;
|
||||
import android.net.INetworkPolicyListener;
|
||||
import android.net.INetworkStatsService;
|
||||
import android.net.IOnSetOemNetworkPreferenceListener;
|
||||
import android.net.IQosCallback;
|
||||
import android.net.InetAddresses;
|
||||
@@ -202,7 +202,6 @@ import android.net.NetworkRequest;
|
||||
import android.net.NetworkSpecifier;
|
||||
import android.net.NetworkStack;
|
||||
import android.net.NetworkStackClient;
|
||||
import android.net.NetworkStateSnapshot;
|
||||
import android.net.NetworkTestResultParcelable;
|
||||
import android.net.OemNetworkPreferences;
|
||||
import android.net.ProxyInfo;
|
||||
@@ -421,7 +420,7 @@ public class ConnectivityServiceTest {
|
||||
|
||||
@Mock DeviceIdleInternal mDeviceIdleInternal;
|
||||
@Mock INetworkManagementService mNetworkManagementService;
|
||||
@Mock INetworkStatsService mStatsService;
|
||||
@Mock NetworkStatsManager mStatsManager;
|
||||
@Mock IBatteryStats mBatteryStatsService;
|
||||
@Mock IDnsResolver mMockDnsResolver;
|
||||
@Mock INetd mMockNetd;
|
||||
@@ -537,6 +536,7 @@ public class ConnectivityServiceTest {
|
||||
if (Context.ETHERNET_SERVICE.equals(name)) return mEthernetManager;
|
||||
if (Context.NETWORK_POLICY_SERVICE.equals(name)) return mNetworkPolicyManager;
|
||||
if (Context.SYSTEM_CONFIG_SERVICE.equals(name)) return mSystemConfigManager;
|
||||
if (Context.NETWORK_STATS_SERVICE.equals(name)) return mStatsManager;
|
||||
return super.getSystemService(name);
|
||||
}
|
||||
|
||||
@@ -1469,7 +1469,6 @@ public class ConnectivityServiceTest {
|
||||
mDeps = makeDependencies();
|
||||
returnRealCallingUid();
|
||||
mService = new ConnectivityService(mServiceContext,
|
||||
mStatsService,
|
||||
mMockDnsResolver,
|
||||
mock(IpConnectivityLog.class),
|
||||
mMockNetd,
|
||||
@@ -5483,18 +5482,19 @@ public class ConnectivityServiceTest {
|
||||
assertEquals(expectedSet, actualSet);
|
||||
}
|
||||
|
||||
private void expectForceUpdateIfaces(Network[] networks, String defaultIface,
|
||||
private void expectNetworkStatus(Network[] networks, String defaultIface,
|
||||
Integer vpnUid, String vpnIfname, String[] underlyingIfaces) throws Exception {
|
||||
ArgumentCaptor<Network[]> networksCaptor = ArgumentCaptor.forClass(Network[].class);
|
||||
ArgumentCaptor<UnderlyingNetworkInfo[]> vpnInfosCaptor = ArgumentCaptor.forClass(
|
||||
UnderlyingNetworkInfo[].class);
|
||||
ArgumentCaptor<List<Network>> networksCaptor = ArgumentCaptor.forClass(List.class);
|
||||
ArgumentCaptor<List<UnderlyingNetworkInfo>> vpnInfosCaptor =
|
||||
ArgumentCaptor.forClass(List.class);
|
||||
|
||||
verify(mStatsService, atLeastOnce()).forceUpdateIfaces(networksCaptor.capture(),
|
||||
any(NetworkStateSnapshot[].class), eq(defaultIface), vpnInfosCaptor.capture());
|
||||
verify(mStatsManager, atLeastOnce()).notifyNetworkStatus(networksCaptor.capture(),
|
||||
any(List.class), eq(defaultIface), vpnInfosCaptor.capture());
|
||||
|
||||
assertSameElementsNoDuplicates(networksCaptor.getValue(), networks);
|
||||
assertSameElementsNoDuplicates(networksCaptor.getValue().toArray(), networks);
|
||||
|
||||
UnderlyingNetworkInfo[] infos = vpnInfosCaptor.getValue();
|
||||
UnderlyingNetworkInfo[] infos =
|
||||
vpnInfosCaptor.getValue().toArray(new UnderlyingNetworkInfo[0]);
|
||||
if (vpnUid != null) {
|
||||
assertEquals("Should have exactly one VPN:", 1, infos.length);
|
||||
UnderlyingNetworkInfo info = infos[0];
|
||||
@@ -5508,8 +5508,9 @@ public class ConnectivityServiceTest {
|
||||
}
|
||||
}
|
||||
|
||||
private void expectForceUpdateIfaces(Network[] networks, String defaultIface) throws Exception {
|
||||
expectForceUpdateIfaces(networks, defaultIface, null, null, new String[0]);
|
||||
private void expectNetworkStatus(
|
||||
Network[] networks, String defaultIface) throws Exception {
|
||||
expectNetworkStatus(networks, defaultIface, null, null, new String[0]);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -5529,46 +5530,46 @@ public class ConnectivityServiceTest {
|
||||
mCellNetworkAgent.connect(false);
|
||||
mCellNetworkAgent.sendLinkProperties(cellLp);
|
||||
waitForIdle();
|
||||
expectForceUpdateIfaces(onlyCell, MOBILE_IFNAME);
|
||||
reset(mStatsService);
|
||||
expectNetworkStatus(onlyCell, MOBILE_IFNAME);
|
||||
reset(mStatsManager);
|
||||
|
||||
// Default network switch should update ifaces.
|
||||
mWiFiNetworkAgent.connect(false);
|
||||
mWiFiNetworkAgent.sendLinkProperties(wifiLp);
|
||||
waitForIdle();
|
||||
assertEquals(wifiLp, mService.getActiveLinkProperties());
|
||||
expectForceUpdateIfaces(onlyWifi, WIFI_IFNAME);
|
||||
reset(mStatsService);
|
||||
expectNetworkStatus(onlyWifi, WIFI_IFNAME);
|
||||
reset(mStatsManager);
|
||||
|
||||
// Disconnect should update ifaces.
|
||||
mWiFiNetworkAgent.disconnect();
|
||||
waitForIdle();
|
||||
expectForceUpdateIfaces(onlyCell, MOBILE_IFNAME);
|
||||
reset(mStatsService);
|
||||
expectNetworkStatus(onlyCell, MOBILE_IFNAME);
|
||||
reset(mStatsManager);
|
||||
|
||||
// Metered change should update ifaces
|
||||
mCellNetworkAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
|
||||
waitForIdle();
|
||||
expectForceUpdateIfaces(onlyCell, MOBILE_IFNAME);
|
||||
reset(mStatsService);
|
||||
expectNetworkStatus(onlyCell, MOBILE_IFNAME);
|
||||
reset(mStatsManager);
|
||||
|
||||
mCellNetworkAgent.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
|
||||
waitForIdle();
|
||||
expectForceUpdateIfaces(onlyCell, MOBILE_IFNAME);
|
||||
reset(mStatsService);
|
||||
expectNetworkStatus(onlyCell, MOBILE_IFNAME);
|
||||
reset(mStatsManager);
|
||||
|
||||
// Temp metered change shouldn't update ifaces
|
||||
mCellNetworkAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED);
|
||||
waitForIdle();
|
||||
verify(mStatsService, never()).forceUpdateIfaces(eq(onlyCell), any(
|
||||
NetworkStateSnapshot[].class), eq(MOBILE_IFNAME), eq(new UnderlyingNetworkInfo[0]));
|
||||
reset(mStatsService);
|
||||
verify(mStatsManager, never()).notifyNetworkStatus(eq(Arrays.asList(onlyCell)),
|
||||
any(List.class), eq(MOBILE_IFNAME), any(List.class));
|
||||
reset(mStatsManager);
|
||||
|
||||
// Roaming change should update ifaces
|
||||
mCellNetworkAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING);
|
||||
waitForIdle();
|
||||
expectForceUpdateIfaces(onlyCell, MOBILE_IFNAME);
|
||||
reset(mStatsService);
|
||||
expectNetworkStatus(onlyCell, MOBILE_IFNAME);
|
||||
reset(mStatsManager);
|
||||
|
||||
// Test VPNs.
|
||||
final LinkProperties lp = new LinkProperties();
|
||||
@@ -5581,7 +5582,7 @@ public class ConnectivityServiceTest {
|
||||
mCellNetworkAgent.getNetwork(), mMockVpn.getNetwork()};
|
||||
|
||||
// A VPN with default (null) underlying networks sets the underlying network's interfaces...
|
||||
expectForceUpdateIfaces(cellAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME,
|
||||
expectNetworkStatus(cellAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME,
|
||||
new String[]{MOBILE_IFNAME});
|
||||
|
||||
// ...and updates them as the default network switches.
|
||||
@@ -5598,9 +5599,9 @@ public class ConnectivityServiceTest {
|
||||
|
||||
waitForIdle();
|
||||
assertEquals(wifiLp, mService.getActiveLinkProperties());
|
||||
expectForceUpdateIfaces(wifiAndVpn, WIFI_IFNAME, Process.myUid(), VPN_IFNAME,
|
||||
expectNetworkStatus(wifiAndVpn, WIFI_IFNAME, Process.myUid(), VPN_IFNAME,
|
||||
new String[]{WIFI_IFNAME});
|
||||
reset(mStatsService);
|
||||
reset(mStatsManager);
|
||||
|
||||
// A VPN that sets its underlying networks passes the underlying interfaces, and influences
|
||||
// the default interface sent to NetworkStatsService by virtue of applying to the system
|
||||
@@ -5610,22 +5611,22 @@ public class ConnectivityServiceTest {
|
||||
// applies to the system server UID should not have any bearing on network stats.
|
||||
mMockVpn.setUnderlyingNetworks(onlyCell);
|
||||
waitForIdle();
|
||||
expectForceUpdateIfaces(wifiAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME,
|
||||
expectNetworkStatus(wifiAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME,
|
||||
new String[]{MOBILE_IFNAME});
|
||||
reset(mStatsService);
|
||||
reset(mStatsManager);
|
||||
|
||||
mMockVpn.setUnderlyingNetworks(cellAndWifi);
|
||||
waitForIdle();
|
||||
expectForceUpdateIfaces(wifiAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME,
|
||||
expectNetworkStatus(wifiAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME,
|
||||
new String[]{MOBILE_IFNAME, WIFI_IFNAME});
|
||||
reset(mStatsService);
|
||||
reset(mStatsManager);
|
||||
|
||||
// Null underlying networks are ignored.
|
||||
mMockVpn.setUnderlyingNetworks(cellNullAndWifi);
|
||||
waitForIdle();
|
||||
expectForceUpdateIfaces(wifiAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME,
|
||||
expectNetworkStatus(wifiAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME,
|
||||
new String[]{MOBILE_IFNAME, WIFI_IFNAME});
|
||||
reset(mStatsService);
|
||||
reset(mStatsManager);
|
||||
|
||||
// If an underlying network disconnects, that interface should no longer be underlying.
|
||||
// This doesn't actually work because disconnectAndDestroyNetwork only notifies
|
||||
@@ -5637,17 +5638,17 @@ public class ConnectivityServiceTest {
|
||||
mCellNetworkAgent.disconnect();
|
||||
waitForIdle();
|
||||
assertNull(mService.getLinkProperties(mCellNetworkAgent.getNetwork()));
|
||||
expectForceUpdateIfaces(wifiAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME,
|
||||
expectNetworkStatus(wifiAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME,
|
||||
new String[]{MOBILE_IFNAME, WIFI_IFNAME});
|
||||
|
||||
// Confirm that we never tell NetworkStatsService that cell is no longer the underlying
|
||||
// network for the VPN...
|
||||
verify(mStatsService, never()).forceUpdateIfaces(any(Network[].class),
|
||||
any(NetworkStateSnapshot[].class), any() /* anyString() doesn't match null */,
|
||||
argThat(infos -> infos[0].underlyingIfaces.size() == 1
|
||||
&& WIFI_IFNAME.equals(infos[0].underlyingIfaces.get(0))));
|
||||
verifyNoMoreInteractions(mStatsService);
|
||||
reset(mStatsService);
|
||||
verify(mStatsManager, never()).notifyNetworkStatus(any(List.class),
|
||||
any(List.class), any() /* anyString() doesn't match null */,
|
||||
argThat(infos -> infos.get(0).underlyingIfaces.size() == 1
|
||||
&& WIFI_IFNAME.equals(infos.get(0).underlyingIfaces.get(0))));
|
||||
verifyNoMoreInteractions(mStatsManager);
|
||||
reset(mStatsManager);
|
||||
|
||||
// ... but if something else happens that causes notifyIfacesChangedForNetworkStats to be
|
||||
// called again, it does. For example, connect Ethernet, but with a low score, such that it
|
||||
@@ -5656,13 +5657,13 @@ public class ConnectivityServiceTest {
|
||||
mEthernetNetworkAgent.adjustScore(-40);
|
||||
mEthernetNetworkAgent.connect(false);
|
||||
waitForIdle();
|
||||
verify(mStatsService).forceUpdateIfaces(any(Network[].class),
|
||||
any(NetworkStateSnapshot[].class), any() /* anyString() doesn't match null */,
|
||||
argThat(vpnInfos -> vpnInfos[0].underlyingIfaces.size() == 1
|
||||
&& WIFI_IFNAME.equals(vpnInfos[0].underlyingIfaces.get(0))));
|
||||
verify(mStatsManager).notifyNetworkStatus(any(List.class),
|
||||
any(List.class), any() /* anyString() doesn't match null */,
|
||||
argThat(vpnInfos -> vpnInfos.get(0).underlyingIfaces.size() == 1
|
||||
&& WIFI_IFNAME.equals(vpnInfos.get(0).underlyingIfaces.get(0))));
|
||||
mEthernetNetworkAgent.disconnect();
|
||||
waitForIdle();
|
||||
reset(mStatsService);
|
||||
reset(mStatsManager);
|
||||
|
||||
// When a VPN declares no underlying networks (i.e., no connectivity), getAllVpnInfo
|
||||
// does not return the VPN, so CS does not pass it to NetworkStatsService. This causes
|
||||
@@ -5672,27 +5673,27 @@ public class ConnectivityServiceTest {
|
||||
// Also, for the same reason as above, the active interface passed in is null.
|
||||
mMockVpn.setUnderlyingNetworks(new Network[0]);
|
||||
waitForIdle();
|
||||
expectForceUpdateIfaces(wifiAndVpn, null);
|
||||
reset(mStatsService);
|
||||
expectNetworkStatus(wifiAndVpn, null);
|
||||
reset(mStatsManager);
|
||||
|
||||
// Specifying only a null underlying network is the same as no networks.
|
||||
mMockVpn.setUnderlyingNetworks(onlyNull);
|
||||
waitForIdle();
|
||||
expectForceUpdateIfaces(wifiAndVpn, null);
|
||||
reset(mStatsService);
|
||||
expectNetworkStatus(wifiAndVpn, null);
|
||||
reset(mStatsManager);
|
||||
|
||||
// Specifying networks that are all disconnected is the same as specifying no networks.
|
||||
mMockVpn.setUnderlyingNetworks(onlyCell);
|
||||
waitForIdle();
|
||||
expectForceUpdateIfaces(wifiAndVpn, null);
|
||||
reset(mStatsService);
|
||||
expectNetworkStatus(wifiAndVpn, null);
|
||||
reset(mStatsManager);
|
||||
|
||||
// Passing in null again means follow the default network again.
|
||||
mMockVpn.setUnderlyingNetworks(null);
|
||||
waitForIdle();
|
||||
expectForceUpdateIfaces(wifiAndVpn, WIFI_IFNAME, Process.myUid(), VPN_IFNAME,
|
||||
expectNetworkStatus(wifiAndVpn, WIFI_IFNAME, Process.myUid(), VPN_IFNAME,
|
||||
new String[]{WIFI_IFNAME});
|
||||
reset(mStatsService);
|
||||
reset(mStatsManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user