Test Tethering/NetworkStack package existence for SYSTEM and FULL users.

Follow-up from aosp/3405539, it is possible that OEMs do not
install Tethering/NetworkStack for certain user types.
This is undesirable. Therefore, enforce this with CTS test cases.

Flag: TEST_ONLY
Test: m CtsTetheringTest && atest \
      CtsTetheringTest:android.tethering.test.TetheringManagerTest
Fix: 400836850

Change-Id: I176d4930040d288846bde43beda9e30519ecd513
This commit is contained in:
Junyu Lai 2025-03-10 17:12:24 +08:00
commit 90c80840d8
3 changed files with 62 additions and 2 deletions

View file

@ -35,6 +35,7 @@ java_defaults {
static_libs: [
"ConnectivityWifiP2pMultiDevicesSnippetLib",
"Harrier",
"TetheringCommonTests",
"com.android.net.flags-aconfig-java",
"compatibility-device-util-axt",

View file

@ -17,8 +17,16 @@
<option name="test-suite-tag" value="cts" />
<option name="config-descriptor:metadata" key="component" value="networking" />
<option name="config-descriptor:metadata" key="token" value="SIM_CARD" />
<!-- The 'run_on_secondary_user' parameter triggers a second test iteration
targeting secondary users. This is only applicable to tests explicitly marked
with @UserTest(UserType.SECONDARY_USER) or @RequireRunOnSecondaryUser.
-->
<option name="config-descriptor:metadata" key="parameter" value="run_on_secondary_user" />
<option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
<option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
<!-- '[not_]secondary_user' is mandatory to declare the tests could [not] be run on
the secondary user. See CtsConfigLoadingTest#testConfigurationLoad.
-->
<option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
<option name="config-descriptor:metadata" key="mainline-param" value="CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk+com.google.android.resolv.apex+com.google.android.tethering.apex" />
<option name="not-shardable" value="true" />
@ -31,6 +39,12 @@
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="android.tethering.cts" />
<option name="device-listeners" value="com.android.testutils.ConnectivityDiagnosticsCollector" />
<!-- Tests with these annotations should only be ran with their corresponding
configurations, e.g. Tests with the RequireRunOnWorkProfile annotation should be
ran with the run_on_work_profile configuration. Exclude these tests from running
with the normal configuration. See go/bedstead-devicestate#androidtestxml
-->
<option name="exclude-annotation" value="com.android.bedstead.multiuser.annotations.RequireRunOnSecondaryUser" />
</test>
<metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
<!-- Pattern matching the fileKey used by ConnectivityDiagnosticsCollector when calling addFileMetric -->

View file

@ -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<String> 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<ResolveInfo> 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);
}
}