Merge changes from topic "TrafficStats.getTxRxBytes"
* changes:
Exclude lingering traffic from loopback iface stats check
Add CTS for getTx/RxBytes in TrafficStats
diff --git a/Tethering/src/com/android/networkstack/tethering/Tethering.java b/Tethering/src/com/android/networkstack/tethering/Tethering.java
index 5a0c5b0..2c91d10 100644
--- a/Tethering/src/com/android/networkstack/tethering/Tethering.java
+++ b/Tethering/src/com/android/networkstack/tethering/Tethering.java
@@ -1080,8 +1080,13 @@
}
@VisibleForTesting
+ SparseArray<TetheringRequestParcel> getActiveTetheringRequests() {
+ return mActiveTetheringRequests;
+ }
+
+ @VisibleForTesting
boolean isTetheringActive() {
- return mActiveTetheringRequests.size() > 0;
+ return getTetheredIfaces().length > 0;
}
@VisibleForTesting
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 37a4d90..0a37f54 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
@@ -52,6 +52,7 @@
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
import static com.android.net.module.util.Inet4AddressUtils.intToInet4AddressHTH;
+import static com.android.networkstack.tethering.Tethering.UserRestrictionActionListener;
import static com.android.networkstack.tethering.TetheringNotificationUpdater.DOWNSTREAM_NONE;
import static com.android.networkstack.tethering.UpstreamNetworkMonitor.EVENT_ON_CAPABILITIES;
@@ -735,9 +736,12 @@
initTetheringUpstream(upstreamState);
// Emulate pressing the USB tethering button in Settings UI.
- mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB), null);
+ final TetheringRequestParcel request = createTetheringRequestParcel(TETHERING_USB);
+ mTethering.startTethering(request, null);
mLooper.dispatchAll();
verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_RNDIS);
+ assertEquals(1, mTethering.getActiveTetheringRequests().size());
+ assertEquals(request, mTethering.getActiveTetheringRequests().get(TETHERING_USB));
mTethering.interfaceStatusChanged(TEST_USB_IFNAME, true);
}
@@ -1174,20 +1178,26 @@
verifyNoMoreInteractions(mNetd);
}
+ private UserRestrictionActionListener makeUserRestrictionActionListener(
+ final Tethering tethering, final boolean currentDisallow, final boolean nextDisallow) {
+ final Bundle newRestrictions = new Bundle();
+ newRestrictions.putBoolean(UserManager.DISALLOW_CONFIG_TETHERING, nextDisallow);
+ when(mUserManager.getUserRestrictions()).thenReturn(newRestrictions);
+
+ final UserRestrictionActionListener ural =
+ new UserRestrictionActionListener(mUserManager, tethering, mNotificationUpdater);
+ ural.mDisallowTethering = currentDisallow;
+ return ural;
+ }
+
private void runUserRestrictionsChange(
boolean currentDisallow, boolean nextDisallow, boolean isTetheringActive,
int expectedInteractionsWithShowNotification) throws Exception {
- final Bundle newRestrictions = new Bundle();
- newRestrictions.putBoolean(UserManager.DISALLOW_CONFIG_TETHERING, nextDisallow);
final Tethering mockTethering = mock(Tethering.class);
when(mockTethering.isTetheringActive()).thenReturn(isTetheringActive);
- when(mUserManager.getUserRestrictions()).thenReturn(newRestrictions);
- final Tethering.UserRestrictionActionListener ural =
- new Tethering.UserRestrictionActionListener(
- mUserManager, mockTethering, mNotificationUpdater);
- ural.mDisallowTethering = currentDisallow;
-
+ final UserRestrictionActionListener ural =
+ makeUserRestrictionActionListener(mockTethering, currentDisallow, nextDisallow);
ural.onUserRestrictionsChanged();
verify(mNotificationUpdater, times(expectedInteractionsWithShowNotification))
@@ -1256,6 +1266,27 @@
expectedInteractionsWithShowNotification);
}
+ @Test
+ public void testUntetherUsbWhenRestrictionIsOn() {
+ // Start usb tethering and check that usb interface is tethered.
+ final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
+ runUsbTethering(upstreamState);
+ assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_USB_IFNAME);
+ assertTrue(mTethering.isTetheringActive());
+ assertEquals(0, mTethering.getActiveTetheringRequests().size());
+
+ final Tethering.UserRestrictionActionListener ural = makeUserRestrictionActionListener(
+ mTethering, false /* currentDisallow */, true /* nextDisallow */);
+
+ ural.onUserRestrictionsChanged();
+ mLooper.dispatchAll();
+
+ // Verify that restriction notification has showed to user.
+ verify(mNotificationUpdater, times(1)).notifyTetheringDisabledByRestriction();
+ // Verify that usb tethering has been disabled.
+ verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NONE);
+ }
+
private class TestTetheringEventCallback extends ITetheringEventCallback.Stub {
private final ArrayList<Network> mActualUpstreams = new ArrayList<>();
private final ArrayList<TetheringConfigurationParcel> mTetheringConfigs =
diff --git a/tests/cts/net/OWNERS b/tests/cts/net/OWNERS
index d558556..7722bb3 100644
--- a/tests/cts/net/OWNERS
+++ b/tests/cts/net/OWNERS
@@ -1,3 +1,5 @@
# Bug component: 31808
lorenzo@google.com
satk@google.com
+
+per-file src/android/net/cts/NetworkWatchlistTest.java=alanstokes@google.com
diff --git a/tests/cts/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java
index 54509cd..ccbdbd3 100644
--- a/tests/cts/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java
@@ -129,6 +129,12 @@
private static final IBinder BINDER = new Binder();
+ // Lock for accessing Shell Permissions. Use of this lock around adoptShellPermissionIdentity,
+ // runWithShellPermissionIdentity, and callWithShellPermissionIdentity ensures Shell Permission
+ // is not interrupted by another operation (which would drop all previously adopted
+ // permissions).
+ private Object mShellPermissionsIdentityLock = new Object();
+
private Context mContext;
private ConnectivityManager mConnectivityManager;
private ConnectivityDiagnosticsManager mCdm;
@@ -244,20 +250,24 @@
CarrierConfigManager.KEY_CARRIER_CERTIFICATE_STRING_ARRAY,
new String[] {getCertHashForThisPackage()});
- runWithShellPermissionIdentity(
- () -> {
- mCarrierConfigManager.overrideConfig(subId, carrierConfigs);
- mCarrierConfigManager.notifyConfigChangedForSubId(subId);
- },
- android.Manifest.permission.MODIFY_PHONE_STATE);
+ synchronized (mShellPermissionsIdentityLock) {
+ runWithShellPermissionIdentity(
+ () -> {
+ mCarrierConfigManager.overrideConfig(subId, carrierConfigs);
+ mCarrierConfigManager.notifyConfigChangedForSubId(subId);
+ },
+ android.Manifest.permission.MODIFY_PHONE_STATE);
+ }
// TODO(b/157779832): This should use android.permission.CHANGE_NETWORK_STATE. However, the
// shell does not have CHANGE_NETWORK_STATE, so use CONNECTIVITY_INTERNAL until the shell
// permissions are updated.
- runWithShellPermissionIdentity(
- () -> mConnectivityManager.requestNetwork(
- CELLULAR_NETWORK_REQUEST, testNetworkCallback),
- android.Manifest.permission.CONNECTIVITY_INTERNAL);
+ synchronized (mShellPermissionsIdentityLock) {
+ runWithShellPermissionIdentity(
+ () -> mConnectivityManager.requestNetwork(
+ CELLULAR_NETWORK_REQUEST, testNetworkCallback),
+ android.Manifest.permission.CONNECTIVITY_INTERNAL);
+ }
final Network network = testNetworkCallback.waitForAvailable();
assertNotNull(network);
@@ -536,9 +546,18 @@
}
private class CarrierConfigReceiver extends BroadcastReceiver {
+ // CountDownLatch used to wait for this BroadcastReceiver to be notified of a CarrierConfig
+ // change. This latch will be counted down if a broadcast indicates this package has carrier
+ // configs, or if an Exception occurs in #onReceive.
private final CountDownLatch mLatch = new CountDownLatch(1);
private final int mSubId;
+ // #onReceive may encounter Exceptions while running on the Process' main Thread and
+ // #waitForCarrierConfigChanged checks the cached Exception from the test Thread. These
+ // Exceptions must be cached and thrown later, as throwing on the Process' main Thread will
+ // crash the process and cause other tests to fail.
+ private Exception mOnReceiveException;
+
CarrierConfigReceiver(int subId) {
mSubId = subId;
}
@@ -546,6 +565,7 @@
@Override
public void onReceive(Context context, Intent intent) {
if (!CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED.equals(intent.getAction())) {
+ // Received an incorrect broadcast - ignore
return;
}
@@ -553,24 +573,64 @@
intent.getIntExtra(
CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX,
SubscriptionManager.INVALID_SUBSCRIPTION_ID);
- if (mSubId != subId) return;
+ if (mSubId != subId) {
+ // Received a broadcast for the wrong subId - ignore
+ return;
+ }
- final PersistableBundle carrierConfigs = mCarrierConfigManager.getConfigForSubId(subId);
- if (!CarrierConfigManager.isConfigForIdentifiedCarrier(carrierConfigs)) return;
+ final PersistableBundle carrierConfigs;
+ try {
+ synchronized (mShellPermissionsIdentityLock) {
+ carrierConfigs = callWithShellPermissionIdentity(
+ () -> mCarrierConfigManager.getConfigForSubId(subId),
+ android.Manifest.permission.READ_PHONE_STATE);
+ }
+ } catch (Exception exception) {
+ // callWithShellPermissionIdentity() threw an Exception - cache it and allow
+ // waitForCarrierConfigChanged() to throw it
+ mOnReceiveException = exception;
+ mLatch.countDown();
+ return;
+ }
- final String[] certs =
- carrierConfigs.getStringArray(
- CarrierConfigManager.KEY_CARRIER_CERTIFICATE_STRING_ARRAY);
+ if (!CarrierConfigManager.isConfigForIdentifiedCarrier(carrierConfigs)) {
+ // Configs are not for an identified carrier (meaning they are defaults) - ignore
+ return;
+ }
+
+ final String[] certs = carrierConfigs.getStringArray(
+ CarrierConfigManager.KEY_CARRIER_CERTIFICATE_STRING_ARRAY);
try {
if (ArrayUtils.contains(certs, getCertHashForThisPackage())) {
+ // Received an update for this package's cert hash - countdown and exit
mLatch.countDown();
}
- } catch (Exception e) {
+ // Broadcast is for the right subId, but does not show this package as Carrier
+ // Privileged. Keep waiting for a broadcast that indicates Carrier Privileges.
+ } catch (Exception exception) {
+ // getCertHashForThisPackage() threw an Exception - cache it and allow
+ // waitForCarrierConfigChanged() to throw it
+ mOnReceiveException = exception;
+ mLatch.countDown();
}
}
+ /**
+ * Waits for the CarrierConfig changed broadcast to reach this CarrierConfigReceiver.
+ *
+ * <p>Must be called from the Test Thread.
+ *
+ * @throws Exception if an Exception occurred during any #onReceive invocation
+ */
boolean waitForCarrierConfigChanged() throws Exception {
- return mLatch.await(CARRIER_CONFIG_CHANGED_BROADCAST_TIMEOUT, TimeUnit.MILLISECONDS);
+ final boolean result = mLatch.await(CARRIER_CONFIG_CHANGED_BROADCAST_TIMEOUT,
+ TimeUnit.MILLISECONDS);
+
+ if (mOnReceiveException != null) {
+ throw mOnReceiveException;
+ }
+
+ return result;
}
}
}
diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
index db4e3e7..cbf43e7 100644
--- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
@@ -16,6 +16,7 @@
package android.net.cts;
+import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS;
import static android.Manifest.permission.NETWORK_SETTINGS;
import static android.content.pm.PackageManager.FEATURE_ETHERNET;
@@ -1517,7 +1518,10 @@
@Test
public void testGetCaptivePortalServerUrl() {
- final String url = runAsShell(NETWORK_SETTINGS, mCm::getCaptivePortalServerUrl);
+ final String permission = Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q
+ ? CONNECTIVITY_INTERNAL
+ : NETWORK_SETTINGS;
+ final String url = runAsShell(permission, mCm::getCaptivePortalServerUrl);
assertNotNull("getCaptivePortalServerUrl must not be null", url);
try {
final URL parsedUrl = new URL(url);
diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
index 7508228..45a84f8 100644
--- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
+++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
@@ -62,6 +62,7 @@
import com.android.internal.util.AsyncChannel
import com.android.net.module.util.ArrayTrackRecord
import com.android.testutils.DevSdkIgnoreRule
+import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
import com.android.testutils.RecorderCallback.CallbackEntry.Available
import com.android.testutils.RecorderCallback.CallbackEntry.Lost
import com.android.testutils.TestableNetworkCallback
@@ -541,6 +542,7 @@
}
@Test
+ @IgnoreUpTo(android.os.Build.VERSION_CODES.R)
fun testAgentStartsInConnecting() {
val mockContext = mock(Context::class.java)
val mockCm = mock(ConnectivityManager::class.java)
diff --git a/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java b/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java
index 34c6541..0527011 100644
--- a/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java
+++ b/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java
@@ -16,6 +16,7 @@
package android.net.cts.util;
+import static android.Manifest.permission.ACCESS_WIFI_STATE;
import static android.Manifest.permission.NETWORK_SETTINGS;
import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
@@ -331,7 +332,7 @@
* to them.
*/
private void clearWifiBlacklist() {
- runAsShell(NETWORK_SETTINGS, () -> {
+ runAsShell(NETWORK_SETTINGS, ACCESS_WIFI_STATE, () -> {
for (WifiConfiguration cfg : mWifiManager.getConfiguredNetworks()) {
assertTrue(mWifiManager.enableNetwork(cfg.networkId, false /* attemptConnect */));
}