Merge "CTS for default background network restrictions" into main
This commit is contained in:
commit
a65d8f3a4c
17 changed files with 527 additions and 25 deletions
|
|
@ -27,7 +27,10 @@ java_test_host {
|
|||
name: "CtsHostsideNetworkTests",
|
||||
defaults: ["cts_defaults"],
|
||||
// Only compile source java files in this apk.
|
||||
srcs: ["src/**/*.java"],
|
||||
srcs: [
|
||||
"src/**/*.java",
|
||||
":ArgumentConstants",
|
||||
],
|
||||
libs: [
|
||||
"net-tests-utils-host-device-common",
|
||||
"cts-tradefed",
|
||||
|
|
|
|||
|
|
@ -36,7 +36,10 @@ java_defaults {
|
|||
"android.test.runner",
|
||||
"android.test.base",
|
||||
],
|
||||
srcs: ["src/**/*.java"],
|
||||
srcs: [
|
||||
"src/**/*.java",
|
||||
":ArgumentConstants",
|
||||
],
|
||||
// Tag this module as a cts test artifact
|
||||
test_suites: [
|
||||
"general-tests",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Copyright (C) 2024 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.cts.net.hostside;
|
||||
|
||||
import static android.app.ActivityManager.PROCESS_STATE_TOP_SLEEPING;
|
||||
|
||||
import static org.junit.Assume.assumeTrue;
|
||||
|
||||
import android.os.SystemClock;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Base class for default, always-on network restrictions.
|
||||
*/
|
||||
abstract class AbstractDefaultRestrictionsTest extends AbstractRestrictBackgroundNetworkTestCase {
|
||||
|
||||
@Before
|
||||
public final void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
removePowerSaveModeWhitelist(TEST_APP2_PKG);
|
||||
removePowerSaveModeExceptIdleWhitelist(TEST_APP2_PKG);
|
||||
|
||||
registerBroadcastReceiver();
|
||||
assumeTrue("Feature not enabled", isNetworkBlockedForTopSleepingAndAbove());
|
||||
}
|
||||
|
||||
@After
|
||||
public final void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
|
||||
removePowerSaveModeWhitelist(TEST_APP2_PKG);
|
||||
removePowerSaveModeExceptIdleWhitelist(TEST_APP2_PKG);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFgsNetworkAccess() throws Exception {
|
||||
assertProcessStateBelow(PROCESS_STATE_TOP_SLEEPING);
|
||||
SystemClock.sleep(PROCESS_STATE_TRANSITION_DELAY_MS);
|
||||
assertNetworkAccess(false, null);
|
||||
|
||||
launchComponentAndAssertNetworkAccess(TYPE_COMPONENT_FOREGROUND_SERVICE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testActivityNetworkAccess() throws Exception {
|
||||
assertProcessStateBelow(PROCESS_STATE_TOP_SLEEPING);
|
||||
SystemClock.sleep(PROCESS_STATE_TRANSITION_DELAY_MS);
|
||||
assertNetworkAccess(false, null);
|
||||
|
||||
launchComponentAndAssertNetworkAccess(TYPE_COMPONENT_ACTIVTIY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBackgroundNetworkAccess_inFullAllowlist() throws Exception {
|
||||
assertProcessStateBelow(PROCESS_STATE_TOP_SLEEPING);
|
||||
SystemClock.sleep(PROCESS_STATE_TRANSITION_DELAY_MS);
|
||||
assertNetworkAccess(false, null);
|
||||
|
||||
addPowerSaveModeWhitelist(TEST_APP2_PKG);
|
||||
assertProcessStateBelow(PROCESS_STATE_TOP_SLEEPING);
|
||||
assertNetworkAccess(true, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBackgroundNetworkAccess_inExceptIdleAllowlist() throws Exception {
|
||||
assertProcessStateBelow(PROCESS_STATE_TOP_SLEEPING);
|
||||
SystemClock.sleep(PROCESS_STATE_TRANSITION_DELAY_MS);
|
||||
assertNetworkAccess(false, null);
|
||||
|
||||
addPowerSaveModeExceptIdleWhitelist(TEST_APP2_PKG);
|
||||
assertProcessStateBelow(PROCESS_STATE_TOP_SLEEPING);
|
||||
assertNetworkAccess(true, null);
|
||||
}
|
||||
}
|
||||
|
|
@ -23,6 +23,7 @@ import static android.app.job.JobScheduler.RESULT_SUCCESS;
|
|||
import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED;
|
||||
import static android.os.BatteryManager.BATTERY_PLUGGED_ANY;
|
||||
|
||||
import static com.android.cts.net.arguments.InstrumentationArguments.ARG_WAIVE_BIND_PRIORITY;
|
||||
import static com.android.cts.net.hostside.NetworkPolicyTestUtils.executeShellCommand;
|
||||
import static com.android.cts.net.hostside.NetworkPolicyTestUtils.forceRunJob;
|
||||
import static com.android.cts.net.hostside.NetworkPolicyTestUtils.getConnectivityManager;
|
||||
|
|
@ -65,11 +66,13 @@ import android.util.Log;
|
|||
import android.util.Pair;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.test.platform.app.InstrumentationRegistry;
|
||||
|
||||
import com.android.compatibility.common.util.AmUtils;
|
||||
import com.android.compatibility.common.util.BatteryUtils;
|
||||
import com.android.compatibility.common.util.DeviceConfigStateHelper;
|
||||
import com.android.compatibility.common.util.ThrowingRunnable;
|
||||
import com.android.modules.utils.build.SdkLevel;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.rules.RuleChain;
|
||||
|
|
@ -90,6 +93,8 @@ public abstract class AbstractRestrictBackgroundNetworkTestCase {
|
|||
|
||||
protected static final String TEST_PKG = "com.android.cts.net.hostside";
|
||||
protected static final String TEST_APP2_PKG = "com.android.cts.net.hostside.app2";
|
||||
// TODO(b/321797685): Configure it via device-config once it is available.
|
||||
protected static final long PROCESS_STATE_TRANSITION_DELAY_MS = TimeUnit.SECONDS.toMillis(5);
|
||||
|
||||
private static final String TEST_APP2_ACTIVITY_CLASS = TEST_APP2_PKG + ".MyActivity";
|
||||
private static final String TEST_APP2_SERVICE_CLASS = TEST_APP2_PKG + ".MyForegroundService";
|
||||
|
|
@ -97,7 +102,6 @@ public abstract class AbstractRestrictBackgroundNetworkTestCase {
|
|||
|
||||
private static final ComponentName TEST_JOB_COMPONENT = new ComponentName(
|
||||
TEST_APP2_PKG, TEST_APP2_JOB_SERVICE_CLASS);
|
||||
|
||||
private static final int TEST_JOB_ID = 7357437;
|
||||
|
||||
private static final int SLEEP_TIME_SEC = 1;
|
||||
|
|
@ -152,8 +156,6 @@ public abstract class AbstractRestrictBackgroundNetworkTestCase {
|
|||
private static final IntentFilter BATTERY_CHANGED_FILTER =
|
||||
new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
|
||||
|
||||
private static final String APP_NOT_FOREGROUND_ERROR = "app_not_fg";
|
||||
|
||||
protected static final long TEMP_POWERSAVE_WHITELIST_DURATION_MS = 20_000; // 20 sec
|
||||
|
||||
private static final long BROADCAST_TIMEOUT_MS = 5_000;
|
||||
|
|
@ -181,7 +183,16 @@ public abstract class AbstractRestrictBackgroundNetworkTestCase {
|
|||
mUid = getUid(TEST_APP2_PKG);
|
||||
mMyUid = getUid(mContext.getPackageName());
|
||||
mServiceClient = new MyServiceClient(mContext);
|
||||
mServiceClient.bind();
|
||||
|
||||
final Bundle args = InstrumentationRegistry.getArguments();
|
||||
final int bindPriorityFlags;
|
||||
if (Boolean.valueOf(args.getString(ARG_WAIVE_BIND_PRIORITY, "false"))) {
|
||||
bindPriorityFlags = Context.BIND_WAIVE_PRIORITY;
|
||||
} else {
|
||||
bindPriorityFlags = Context.BIND_NOT_FOREGROUND;
|
||||
}
|
||||
mServiceClient.bind(bindPriorityFlags);
|
||||
|
||||
mPowerManager = mContext.getSystemService(PowerManager.class);
|
||||
executeShellCommand("cmd netpolicy start-watching " + mUid);
|
||||
// Some of the test cases assume that Data saver mode is initially disabled, which might not
|
||||
|
|
@ -205,6 +216,22 @@ public abstract class AbstractRestrictBackgroundNetworkTestCase {
|
|||
if (null != lock && lock.isHeld()) lock.release();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the feature blocking network for top_sleeping and lower priority proc-states is
|
||||
* enabled. This is a manual check because the feature flag infrastructure may not be available
|
||||
* in all the branches that will get this code.
|
||||
* TODO: b/322115994 - Use @RequiresFlagsEnabled with
|
||||
* Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE once the tests are moved to cts.
|
||||
*/
|
||||
protected boolean isNetworkBlockedForTopSleepingAndAbove() {
|
||||
if (!SdkLevel.isAtLeastV()) {
|
||||
return false;
|
||||
}
|
||||
final String output = executeShellCommand("device_config get backstage_power"
|
||||
+ " com.android.server.net.network_blocked_for_top_sleeping_and_above");
|
||||
return Boolean.parseBoolean(output);
|
||||
}
|
||||
|
||||
protected int getUid(String packageName) throws Exception {
|
||||
return mContext.getPackageManager().getPackageUid(packageName, 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package com.android.cts.net.hostside;
|
|||
|
||||
|
||||
import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
|
||||
import static android.app.ActivityManager.PROCESS_STATE_TOP_SLEEPING;
|
||||
|
||||
import static com.android.cts.net.hostside.NetworkPolicyTestUtils.getUiDevice;
|
||||
import static com.android.cts.net.hostside.NetworkPolicyTestUtils.setRestrictBackground;
|
||||
|
|
@ -28,8 +29,13 @@ import static com.android.cts.net.hostside.Property.DOZE_MODE;
|
|||
import static com.android.cts.net.hostside.Property.METERED_NETWORK;
|
||||
import static com.android.cts.net.hostside.Property.NON_METERED_NETWORK;
|
||||
|
||||
import static org.junit.Assume.assumeTrue;
|
||||
|
||||
import android.os.SystemClock;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.compatibility.common.util.ThrowingRunnable;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
|
@ -63,14 +69,14 @@ public class ConnOnActivityStartTest extends AbstractRestrictBackgroundNetworkTe
|
|||
@RequiredProperties({BATTERY_SAVER_MODE})
|
||||
public void testStartActivity_batterySaver() throws Exception {
|
||||
setBatterySaverMode(true);
|
||||
assertLaunchedActivityHasNetworkAccess("testStartActivity_batterySaver");
|
||||
assertLaunchedActivityHasNetworkAccess("testStartActivity_batterySaver", null);
|
||||
}
|
||||
|
||||
@Test
|
||||
@RequiredProperties({DATA_SAVER_MODE, METERED_NETWORK})
|
||||
public void testStartActivity_dataSaver() throws Exception {
|
||||
setRestrictBackground(true);
|
||||
assertLaunchedActivityHasNetworkAccess("testStartActivity_dataSaver");
|
||||
assertLaunchedActivityHasNetworkAccess("testStartActivity_dataSaver", null);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -79,7 +85,7 @@ public class ConnOnActivityStartTest extends AbstractRestrictBackgroundNetworkTe
|
|||
setDozeMode(true);
|
||||
// TODO (235284115): We need to turn on Doze every time before starting
|
||||
// the activity.
|
||||
assertLaunchedActivityHasNetworkAccess("testStartActivity_doze");
|
||||
assertLaunchedActivityHasNetworkAccess("testStartActivity_doze", null);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -89,11 +95,24 @@ public class ConnOnActivityStartTest extends AbstractRestrictBackgroundNetworkTe
|
|||
setAppIdle(true);
|
||||
// TODO (235284115): We need to put the app into app standby mode every
|
||||
// time before starting the activity.
|
||||
assertLaunchedActivityHasNetworkAccess("testStartActivity_appStandby");
|
||||
assertLaunchedActivityHasNetworkAccess("testStartActivity_appStandby", null);
|
||||
}
|
||||
|
||||
private void assertLaunchedActivityHasNetworkAccess(String testName) throws Exception {
|
||||
@Test
|
||||
public void testStartActivity_default() throws Exception {
|
||||
assumeTrue("Feature not enabled", isNetworkBlockedForTopSleepingAndAbove());
|
||||
assertLaunchedActivityHasNetworkAccess("testStartActivity_default", () -> {
|
||||
assertProcessStateBelow(PROCESS_STATE_TOP_SLEEPING);
|
||||
SystemClock.sleep(PROCESS_STATE_TRANSITION_DELAY_MS);
|
||||
});
|
||||
}
|
||||
|
||||
private void assertLaunchedActivityHasNetworkAccess(String testName,
|
||||
ThrowingRunnable onBeginIteration) throws Exception {
|
||||
for (int i = 0; i < TEST_ITERATION_COUNT; ++i) {
|
||||
if (onBeginIteration != null) {
|
||||
onBeginIteration.run();
|
||||
}
|
||||
Log.i(TAG, testName + " start #" + i);
|
||||
launchComponentAndAssertNetworkAccess(TYPE_COMPONENT_ACTIVTIY);
|
||||
getUiDevice().pressHome();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright (C) 2024 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.cts.net.hostside;
|
||||
|
||||
import static com.android.cts.net.hostside.Property.METERED_NETWORK;
|
||||
|
||||
@RequiredProperties({METERED_NETWORK})
|
||||
public class DefaultRestrictionsMeteredTest extends AbstractDefaultRestrictionsTest {
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright (C) 2024 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.cts.net.hostside;
|
||||
|
||||
import static com.android.cts.net.hostside.Property.NON_METERED_NETWORK;
|
||||
|
||||
@RequiredProperties({NON_METERED_NETWORK})
|
||||
public class DefaultRestrictionsNonMeteredTest extends AbstractDefaultRestrictionsTest {
|
||||
}
|
||||
|
|
@ -34,26 +34,30 @@ public class MyServiceClient {
|
|||
|
||||
private Context mContext;
|
||||
private ServiceConnection mServiceConnection;
|
||||
private IMyService mService;
|
||||
private volatile IMyService mService;
|
||||
private final ConditionVariable mServiceCondition = new ConditionVariable();
|
||||
|
||||
public MyServiceClient(Context context) {
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
public void bind() {
|
||||
/**
|
||||
* Binds to a service in the test app to communicate state.
|
||||
* @param bindPriorityFlags Flags to influence the process-state of the bound app.
|
||||
*/
|
||||
public void bind(int bindPriorityFlags) {
|
||||
if (mService != null) {
|
||||
throw new IllegalStateException("Already bound");
|
||||
}
|
||||
|
||||
final ConditionVariable cv = new ConditionVariable();
|
||||
mServiceConnection = new ServiceConnection() {
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||
mService = IMyService.Stub.asInterface(service);
|
||||
cv.open();
|
||||
mServiceCondition.open();
|
||||
}
|
||||
@Override
|
||||
public void onServiceDisconnected(ComponentName name) {
|
||||
mServiceCondition.close();
|
||||
mService = null;
|
||||
}
|
||||
};
|
||||
|
|
@ -63,12 +67,8 @@ public class MyServiceClient {
|
|||
// Needs to use BIND_NOT_FOREGROUND so app2 does not run in
|
||||
// the same process state as app
|
||||
mContext.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE
|
||||
| Context.BIND_NOT_FOREGROUND);
|
||||
cv.block(TIMEOUT_MS);
|
||||
if (mService == null) {
|
||||
throw new IllegalStateException(
|
||||
"Could not bind to MyService service after " + TIMEOUT_MS + "ms");
|
||||
}
|
||||
| bindPriorityFlags);
|
||||
ensureServiceConnection();
|
||||
}
|
||||
|
||||
public void unbind() {
|
||||
|
|
@ -77,37 +77,56 @@ public class MyServiceClient {
|
|||
}
|
||||
}
|
||||
|
||||
private void ensureServiceConnection() {
|
||||
if (mService != null) {
|
||||
return;
|
||||
}
|
||||
mServiceCondition.block(TIMEOUT_MS);
|
||||
if (mService == null) {
|
||||
throw new IllegalStateException(
|
||||
"Could not bind to MyService service after " + TIMEOUT_MS + "ms");
|
||||
}
|
||||
}
|
||||
|
||||
public void registerBroadcastReceiver() throws RemoteException {
|
||||
ensureServiceConnection();
|
||||
mService.registerBroadcastReceiver();
|
||||
}
|
||||
|
||||
public int getCounters(String receiverName, String action) throws RemoteException {
|
||||
ensureServiceConnection();
|
||||
return mService.getCounters(receiverName, action);
|
||||
}
|
||||
|
||||
public String checkNetworkStatus() throws RemoteException {
|
||||
ensureServiceConnection();
|
||||
return mService.checkNetworkStatus();
|
||||
}
|
||||
|
||||
public String getRestrictBackgroundStatus() throws RemoteException {
|
||||
ensureServiceConnection();
|
||||
return mService.getRestrictBackgroundStatus();
|
||||
}
|
||||
|
||||
public void sendNotification(int notificationId, String notificationType)
|
||||
throws RemoteException {
|
||||
ensureServiceConnection();
|
||||
mService.sendNotification(notificationId, notificationType);
|
||||
}
|
||||
|
||||
public void registerNetworkCallback(final NetworkRequest request, INetworkCallback cb)
|
||||
throws RemoteException {
|
||||
ensureServiceConnection();
|
||||
mService.registerNetworkCallback(request, cb);
|
||||
}
|
||||
|
||||
public void unregisterNetworkCallback() throws RemoteException {
|
||||
ensureServiceConnection();
|
||||
mService.unregisterNetworkCallback();
|
||||
}
|
||||
|
||||
public int scheduleJob(JobInfo jobInfo) throws RemoteException {
|
||||
ensureServiceConnection();
|
||||
return mService.scheduleJob(jobInfo);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package com.android.cts.net.hostside;
|
||||
|
||||
import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
|
||||
import static android.app.ActivityManager.PROCESS_STATE_TOP_SLEEPING;
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
|
||||
import static android.net.NetworkCapabilities.SIGNAL_STRENGTH_UNSPECIFIED;
|
||||
|
||||
|
|
@ -34,6 +35,7 @@ import android.net.Network;
|
|||
import android.net.NetworkCapabilities;
|
||||
import android.net.NetworkRequest;
|
||||
import android.net.cts.util.CtsNetUtils;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.modules.utils.build.SdkLevel;
|
||||
|
|
@ -43,6 +45,7 @@ import org.junit.Before;
|
|||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
|
@ -145,12 +148,22 @@ public class NetworkCallbackTest extends AbstractRestrictBackgroundNetworkTestCa
|
|||
public Network expectAvailableCallbackAndGetNetwork() {
|
||||
final CallbackInfo cb = nextCallback(TEST_CONNECT_TIMEOUT_MS);
|
||||
if (cb.state != CallbackState.AVAILABLE) {
|
||||
fail("Network is not available. Instead obtained the following callback :"
|
||||
+ cb);
|
||||
fail("Network is not available. Instead obtained the following callback :" + cb);
|
||||
}
|
||||
return cb.network;
|
||||
}
|
||||
|
||||
public void drainAndWaitForIdle() {
|
||||
try {
|
||||
do {
|
||||
mCallbacks.drainTo(new ArrayList<>());
|
||||
} while (mCallbacks.poll(TEST_CALLBACK_TIMEOUT_MS, TimeUnit.MILLISECONDS) != null);
|
||||
} catch (InterruptedException ie) {
|
||||
Log.e(TAG, "Interrupted while draining callback queue", ie);
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
public void expectBlockedStatusCallback(Network expectedNetwork, boolean expectBlocked) {
|
||||
expectCallback(CallbackState.BLOCKED_STATUS, expectedNetwork, expectBlocked);
|
||||
}
|
||||
|
|
@ -225,7 +238,7 @@ public class NetworkCallbackTest extends AbstractRestrictBackgroundNetworkTestCa
|
|||
// Check that the network is metered.
|
||||
mTestNetworkCallback.expectCapabilitiesCallbackEventually(mNetwork,
|
||||
false /* hasCapability */, NET_CAPABILITY_NOT_METERED);
|
||||
mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false);
|
||||
mTestNetworkCallback.drainAndWaitForIdle();
|
||||
|
||||
// Before Android T, DNS queries over private DNS should be but are not restricted by Power
|
||||
// Saver or Data Saver. The issue is fixed in mainline update and apps can no longer request
|
||||
|
|
@ -357,6 +370,58 @@ public class NetworkCallbackTest extends AbstractRestrictBackgroundNetworkTestCa
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnBlockedStatusChanged_default() throws Exception {
|
||||
assumeTrue("Feature not enabled", isNetworkBlockedForTopSleepingAndAbove());
|
||||
|
||||
try {
|
||||
assertProcessStateBelow(PROCESS_STATE_TOP_SLEEPING);
|
||||
assertNetworkAccess(false, null);
|
||||
assertNetworkAccessBlockedByBpf(true, mUid, true /* metered */);
|
||||
|
||||
launchActivity();
|
||||
assertTopState();
|
||||
assertNetworkAccess(true, null);
|
||||
mTestNetworkCallback.expectBlockedStatusCallbackEventually(mNetwork, false);
|
||||
assertNetworkAccessBlockedByBpf(false, mUid, true /* metered */);
|
||||
|
||||
finishActivity();
|
||||
assertProcessStateBelow(PROCESS_STATE_TOP_SLEEPING);
|
||||
SystemClock.sleep(PROCESS_STATE_TRANSITION_DELAY_MS);
|
||||
assertNetworkAccess(false, null);
|
||||
mTestNetworkCallback.expectBlockedStatusCallbackEventually(mNetwork, true);
|
||||
assertNetworkAccessBlockedByBpf(true, mUid, true /* metered */);
|
||||
|
||||
} finally {
|
||||
mMeterednessConfiguration.resetNetworkMeteredness();
|
||||
}
|
||||
|
||||
// Set to non-metered network
|
||||
mMeterednessConfiguration.configureNetworkMeteredness(false);
|
||||
mTestNetworkCallback.expectCapabilitiesCallbackEventually(mNetwork,
|
||||
true /* hasCapability */, NET_CAPABILITY_NOT_METERED);
|
||||
try {
|
||||
assertProcessStateBelow(PROCESS_STATE_TOP_SLEEPING);
|
||||
assertNetworkAccess(false, null);
|
||||
assertNetworkAccessBlockedByBpf(true, mUid, false /* metered */);
|
||||
|
||||
launchActivity();
|
||||
assertTopState();
|
||||
assertNetworkAccess(true, null);
|
||||
mTestNetworkCallback.expectBlockedStatusCallbackEventually(mNetwork, false);
|
||||
assertNetworkAccessBlockedByBpf(false, mUid, false /* metered */);
|
||||
|
||||
finishActivity();
|
||||
assertProcessStateBelow(PROCESS_STATE_TOP_SLEEPING);
|
||||
SystemClock.sleep(PROCESS_STATE_TRANSITION_DELAY_MS);
|
||||
assertNetworkAccess(false, null);
|
||||
mTestNetworkCallback.expectBlockedStatusCallbackEventually(mNetwork, true);
|
||||
assertNetworkAccessBlockedByBpf(true, mUid, false /* metered */);
|
||||
} finally {
|
||||
mMeterednessConfiguration.resetNetworkMeteredness();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: 1. test against VPN lockdown.
|
||||
// 2. test against multiple networks.
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package com.android.cts.net.hostside;
|
||||
|
||||
import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
|
||||
import static android.app.ActivityManager.PROCESS_STATE_TOP_SLEEPING;
|
||||
import static android.os.Process.SYSTEM_UID;
|
||||
|
||||
import static com.android.cts.net.hostside.NetworkPolicyTestUtils.assertIsUidRestrictedOnMeteredNetworks;
|
||||
|
|
@ -28,6 +29,9 @@ import static com.android.cts.net.hostside.Property.DATA_SAVER_MODE;
|
|||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assume.assumeTrue;
|
||||
|
||||
import android.os.SystemClock;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
|
|
@ -238,4 +242,33 @@ public class NetworkPolicyManagerTest extends AbstractRestrictBackgroundNetworkT
|
|||
assertIsUidRestrictedOnMeteredNetworks(mUid, false /* expectedResult */);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsUidNetworkingBlocked_whenInBackground() throws Exception {
|
||||
assumeTrue("Feature not enabled", isNetworkBlockedForTopSleepingAndAbove());
|
||||
|
||||
try {
|
||||
assertProcessStateBelow(PROCESS_STATE_TOP_SLEEPING);
|
||||
SystemClock.sleep(PROCESS_STATE_TRANSITION_DELAY_MS);
|
||||
assertNetworkingBlockedStatusForUid(mUid, METERED, true /* expectedResult */);
|
||||
assertTrue(isUidNetworkingBlocked(mUid, NON_METERED));
|
||||
|
||||
launchActivity();
|
||||
assertTopState();
|
||||
assertNetworkingBlockedStatusForUid(mUid, METERED, false /* expectedResult */);
|
||||
assertFalse(isUidNetworkingBlocked(mUid, NON_METERED));
|
||||
|
||||
finishActivity();
|
||||
assertProcessStateBelow(PROCESS_STATE_TOP_SLEEPING);
|
||||
SystemClock.sleep(PROCESS_STATE_TRANSITION_DELAY_MS);
|
||||
assertNetworkingBlockedStatusForUid(mUid, METERED, true /* expectedResult */);
|
||||
assertTrue(isUidNetworkingBlocked(mUid, NON_METERED));
|
||||
|
||||
addPowerSaveModeWhitelist(TEST_APP2_PKG);
|
||||
assertNetworkingBlockedStatusForUid(mUid, METERED, false /* expectedResult */);
|
||||
assertFalse(isUidNetworkingBlocked(mUid, NON_METERED));
|
||||
} finally {
|
||||
removePowerSaveModeWhitelist(TEST_APP2_PKG);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
22
tests/cts/hostside/instrumentation_arguments/Android.bp
Normal file
22
tests/cts/hostside/instrumentation_arguments/Android.bp
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
// Copyright (C) 2024 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package {
|
||||
default_applicable_licenses: ["Android-Apache-2.0"],
|
||||
}
|
||||
|
||||
filegroup {
|
||||
name: "ArgumentConstants",
|
||||
srcs: ["src/**/*.java"],
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Copyright (C) 2024 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.cts.net.arguments;
|
||||
|
||||
public interface InstrumentationArguments {
|
||||
String ARG_WAIVE_BIND_PRIORITY = "waive_bind_priority";
|
||||
}
|
||||
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
package com.android.cts.net;
|
||||
|
||||
import static com.android.cts.net.arguments.InstrumentationArguments.ARG_WAIVE_BIND_PRIORITY;
|
||||
|
||||
import android.platform.test.annotations.FlakyTest;
|
||||
|
||||
import com.android.testutils.SkipPresubmit;
|
||||
|
|
@ -26,9 +28,12 @@ import com.android.tradefed.testtype.junit4.BeforeClassWithInfo;
|
|||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@SkipPresubmit(reason = "Out of SLO flakiness")
|
||||
public class HostsideConnOnActivityStartTest extends HostsideNetworkTestCase {
|
||||
private static final String TEST_CLASS = TEST_PKG + ".ConnOnActivityStartTest";
|
||||
|
||||
@BeforeClassWithInfo
|
||||
public static void setUpOnce(TestInformation testInfo) throws Exception {
|
||||
uninstallPackage(testInfo, TEST_APP2_PKG, false);
|
||||
|
|
@ -60,4 +65,11 @@ public class HostsideConnOnActivityStartTest extends HostsideNetworkTestCase {
|
|||
public void testStartActivity_appStandby() throws Exception {
|
||||
runDeviceTests(TEST_PKG, TEST_CLASS, "testStartActivity_appStandby");
|
||||
}
|
||||
|
||||
// TODO(b/321848487): Annotate with @RequiresFlagsEnabled to mirror the device-side test.
|
||||
@Test
|
||||
public void testStartActivity_default() throws Exception {
|
||||
runDeviceTestsWithArgs(TEST_PKG, TEST_CLASS, "testStartActivity_default",
|
||||
Map.of(ARG_WAIVE_BIND_PRIORITY, "true"));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Copyright (C) 2024 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.cts.net;
|
||||
|
||||
import static com.android.cts.net.arguments.InstrumentationArguments.ARG_WAIVE_BIND_PRIORITY;
|
||||
|
||||
import com.android.testutils.SkipPresubmit;
|
||||
import com.android.tradefed.device.DeviceNotAvailableException;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
// TODO(b/321848487): Annotate with @RequiresFlagsEnabled to mirror the device-side tests.
|
||||
@SkipPresubmit(reason = "Monitoring for flakiness")
|
||||
public class HostsideDefaultNetworkRestrictionsTests extends HostsideNetworkTestCase {
|
||||
private static final String METERED_TEST_CLASS = TEST_PKG + ".DefaultRestrictionsMeteredTest";
|
||||
private static final String NON_METERED_TEST_CLASS =
|
||||
TEST_PKG + ".DefaultRestrictionsNonMeteredTest";
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
uninstallPackage(TEST_APP2_PKG, false);
|
||||
installPackage(TEST_APP2_APK);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
uninstallPackage(TEST_APP2_PKG, true);
|
||||
}
|
||||
|
||||
private void runMeteredTest(String methodName) throws DeviceNotAvailableException {
|
||||
runDeviceTestsWithArgs(TEST_PKG, METERED_TEST_CLASS, methodName,
|
||||
Map.of(ARG_WAIVE_BIND_PRIORITY, "true"));
|
||||
}
|
||||
|
||||
private void runNonMeteredTest(String methodName) throws DeviceNotAvailableException {
|
||||
runDeviceTestsWithArgs(TEST_PKG, NON_METERED_TEST_CLASS, methodName,
|
||||
Map.of(ARG_WAIVE_BIND_PRIORITY, "true"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMeteredNetworkAccess_defaultRestrictions_testActivityNetworkAccess()
|
||||
throws Exception {
|
||||
runMeteredTest("testActivityNetworkAccess");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMeteredNetworkAccess_defaultRestrictions_testFgsNetworkAccess()
|
||||
throws Exception {
|
||||
runMeteredTest("testFgsNetworkAccess");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMeteredNetworkAccess_defaultRestrictions_inFullAllowlist() throws Exception {
|
||||
runMeteredTest("testBackgroundNetworkAccess_inFullAllowlist");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMeteredNetworkAccess_defaultRestrictions_inExceptIdleAllowlist()
|
||||
throws Exception {
|
||||
runMeteredTest("testBackgroundNetworkAccess_inExceptIdleAllowlist");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonMeteredNetworkAccess_defaultRestrictions_testActivityNetworkAccess()
|
||||
throws Exception {
|
||||
runNonMeteredTest("testActivityNetworkAccess");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonMeteredNetworkAccess_defaultRestrictions_testFgsNetworkAccess()
|
||||
throws Exception {
|
||||
runNonMeteredTest("testFgsNetworkAccess");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonMeteredNetworkAccess_defaultRestrictions_inFullAllowlist() throws Exception {
|
||||
runNonMeteredTest("testBackgroundNetworkAccess_inFullAllowlist");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonMeteredNetworkAccess_defaultRestrictions_inExceptIdleAllowlist()
|
||||
throws Exception {
|
||||
runNonMeteredTest("testBackgroundNetworkAccess_inExceptIdleAllowlist");
|
||||
}
|
||||
}
|
||||
|
|
@ -15,12 +15,16 @@
|
|||
*/
|
||||
package com.android.cts.net;
|
||||
|
||||
import static com.android.cts.net.arguments.InstrumentationArguments.ARG_WAIVE_BIND_PRIORITY;
|
||||
|
||||
import com.android.testutils.SkipPresubmit;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@SkipPresubmit(reason = "Out of SLO flakiness")
|
||||
public class HostsideNetworkCallbackTests extends HostsideNetworkTestCase {
|
||||
|
||||
|
|
@ -46,5 +50,12 @@ public class HostsideNetworkCallbackTests extends HostsideNetworkTestCase {
|
|||
runDeviceTests(TEST_PKG,
|
||||
TEST_PKG + ".NetworkCallbackTest", "testOnBlockedStatusChanged_powerSaver");
|
||||
}
|
||||
|
||||
// TODO(b/321848487): Annotate with @RequiresFlagsEnabled to mirror the device-side test.
|
||||
@Test
|
||||
public void testOnBlockedStatusChanged_default() throws Exception {
|
||||
runDeviceTestsWithArgs(TEST_PKG, TEST_PKG + ".NetworkCallbackTest",
|
||||
"testOnBlockedStatusChanged_default", Map.of(ARG_WAIVE_BIND_PRIORITY, "true"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,10 +16,14 @@
|
|||
|
||||
package com.android.cts.net;
|
||||
|
||||
import static com.android.cts.net.arguments.InstrumentationArguments.ARG_WAIVE_BIND_PRIORITY;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class HostsideNetworkPolicyManagerTests extends HostsideNetworkTestCase {
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
|
|
@ -71,4 +75,12 @@ public class HostsideNetworkPolicyManagerTests extends HostsideNetworkTestCase {
|
|||
runDeviceTests(TEST_PKG,
|
||||
TEST_PKG + ".NetworkPolicyManagerTest", "testIsUidRestrictedOnMeteredNetworks");
|
||||
}
|
||||
|
||||
// TODO(b/321848487): Annotate with @RequiresFlagsEnabled to mirror the device-side test.
|
||||
@Test
|
||||
public void testIsUidNetworkingBlocked_whenInBackground() throws Exception {
|
||||
runDeviceTestsWithArgs(TEST_PKG, TEST_PKG + ".NetworkPolicyManagerTest",
|
||||
"testIsUidNetworkingBlocked_whenInBackground",
|
||||
Map.of(ARG_WAIVE_BIND_PRIORITY, "true"));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,10 +31,13 @@ import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
|
|||
import com.android.tradefed.testtype.junit4.AfterClassWithInfo;
|
||||
import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
|
||||
import com.android.tradefed.testtype.junit4.BeforeClassWithInfo;
|
||||
import com.android.tradefed.testtype.junit4.DeviceTestRunOptions;
|
||||
import com.android.tradefed.util.RunUtil;
|
||||
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@RunWith(DeviceJUnit4ClassRunner.class)
|
||||
abstract class HostsideNetworkTestCase extends BaseHostJUnit4Test {
|
||||
protected static final boolean DEBUG = false;
|
||||
|
|
@ -146,6 +149,17 @@ abstract class HostsideNetworkTestCase extends BaseHostJUnit4Test {
|
|||
+ packageName + ", u=" + currentUser);
|
||||
}
|
||||
|
||||
protected boolean runDeviceTestsWithArgs(String packageName, String className,
|
||||
String methodName, Map<String, String> args) throws DeviceNotAvailableException {
|
||||
final DeviceTestRunOptions deviceTestRunOptions = new DeviceTestRunOptions(packageName)
|
||||
.setTestClassName(className)
|
||||
.setTestMethodName(methodName);
|
||||
for (Map.Entry<String, String> arg : args.entrySet()) {
|
||||
deviceTestRunOptions.addInstrumentationArg(arg.getKey(), arg.getValue());
|
||||
}
|
||||
return runDeviceTests(deviceTestRunOptions);
|
||||
}
|
||||
|
||||
protected String runCommand(String command) throws DeviceNotAvailableException {
|
||||
Log.d(TAG, "Command: '" + command + "'");
|
||||
final String output = getDevice().executeShellCommand(command);
|
||||
|
|
|
|||
Loading…
Reference in a new issue