diff --git a/tests/cts/tethering/Android.bp b/tests/cts/tethering/Android.bp
index 38042851a3..fffc3c7ccd 100644
--- a/tests/cts/tethering/Android.bp
+++ b/tests/cts/tethering/Android.bp
@@ -35,6 +35,7 @@ java_defaults {
static_libs: [
"ConnectivityWifiP2pMultiDevicesSnippetLib",
+ "Harrier",
"TetheringCommonTests",
"com.android.net.flags-aconfig-java",
"compatibility-device-util-axt",
diff --git a/tests/cts/tethering/AndroidTestTemplate.xml b/tests/cts/tethering/AndroidTestTemplate.xml
index 0f2e72caca..215565423b 100644
--- a/tests/cts/tethering/AndroidTestTemplate.xml
+++ b/tests/cts/tethering/AndroidTestTemplate.xml
@@ -17,8 +17,16 @@
+
+
+
@@ -31,6 +39,12 @@
+
+
diff --git a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java
index d9a0ef0748..006eafd8b9 100644
--- a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java
+++ b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java
@@ -15,10 +15,14 @@
*/
package android.tethering.test;
+import static android.Manifest.permission.CREATE_USERS;
+import static android.Manifest.permission.INTERACT_ACROSS_USERS;
import static android.Manifest.permission.MODIFY_PHONE_STATE;
import static android.Manifest.permission.TETHER_PRIVILEGED;
import static android.Manifest.permission.WRITE_SETTINGS;
+import static android.app.ActivityManager.getCurrentUser;
import static android.content.pm.PackageManager.FEATURE_TELEPHONY;
+import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN;
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
@@ -58,6 +62,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.net.ConnectivityManager;
import android.net.LinkAddress;
import android.net.Network;
@@ -79,14 +84,18 @@ import android.os.Build;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.os.ResultReceiver;
+import android.os.UserHandle;
import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import androidx.annotation.NonNull;
import androidx.test.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
+import com.android.bedstead.harrier.BedsteadJUnit4;
+import com.android.bedstead.harrier.DeviceState;
+import com.android.bedstead.harrier.UserType;
+import com.android.bedstead.harrier.annotations.UserTest;
import com.android.modules.utils.build.SdkLevel;
import com.android.testutils.ConnectivityDiagnosticsCollector;
import com.android.testutils.ParcelUtils;
@@ -94,6 +103,7 @@ import com.android.testutils.com.android.testutils.CarrierConfigRule;
import org.junit.After;
import org.junit.Before;
+import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -102,15 +112,19 @@ import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
-@RunWith(AndroidJUnit4.class)
+@RunWith(BedsteadJUnit4.class)
public class TetheringManagerTest {
@Rule
public final CarrierConfigRule mCarrierConfigRule = new CarrierConfigRule();
+ @ClassRule
+ @Rule
+ public static final DeviceState sDeviceState = new DeviceState();
private Context mContext;
@@ -124,6 +138,11 @@ public class TetheringManagerTest {
private CtsTetheringUtils mCtsTetheringUtils;
private static final int DEFAULT_TIMEOUT_MS = 60_000;
+ private static final String TETHERING_CONNECTOR_CLASS = "android.net.ITetheringConnector";
+ // String replacement is needed to prevent the class name from being modified
+ // by NetworkStack JarJar rules.
+ private static final String NETWORKSTACK_CONNECTOR_CLASS =
+ "android$net$INetworkStackConnector".replace('$', '.');
@Before
public void setUp() throws Exception {
@@ -910,4 +929,30 @@ public class TetheringManagerTest {
mCtsTetheringUtils.unregisterTetheringEventCallback(tetherEventCallback);
}
}
+
+ // Verify the existence of the Tethering/NetworkStack package for the current user.
+ // This test will be executed on both SYSTEM and FULL users.
+ @Test
+ @UserTest({UserType.INITIAL_USER, UserType.SECONDARY_USER})
+ public void testCreatePackageContextAsUser() throws PackageManager.NameNotFoundException {
+ final List packageNames = List.of(
+ resolvePackageName(TETHERING_CONNECTOR_CLASS),
+ resolvePackageName(NETWORKSTACK_CONNECTOR_CLASS));
+ // Permission CREATE_USERS is required for Android R or below.
+ final int currentUserId = runAsShell(CREATE_USERS, INTERACT_ACROSS_USERS,
+ () -> getCurrentUser());
+ final UserHandle currentUser = UserHandle.of(currentUserId);
+ for (String packageName : packageNames) {
+ mContext.createPackageContextAsUser(packageName, 0 /* flags */, currentUser);
+ }
+ }
+
+ @NonNull
+ private String resolvePackageName(@NonNull String action) {
+ final Intent intent = new Intent(action);
+ final List resolveInfoList = mContext.getPackageManager()
+ .queryIntentServices(intent, MATCH_SYSTEM_ONLY);
+ assertFalse("Failed to resolve package for " + action, resolveInfoList.isEmpty());
+ return Objects.requireNonNull(resolveInfoList.get(0).getComponentInfo().packageName);
+ }
}