From 27e1316c337fe96920061ebe2ac0120b1de50536 Mon Sep 17 00:00:00 2001 From: junyulai Date: Wed, 20 Mar 2019 14:45:10 +0800 Subject: [PATCH] Add cts test cases for NetworkCallback.onBlockedStatusChanged Bug: 118862340 Test: atest HostsideNetworkCallbackTests Change-Id: Ic19b3b648a94adf4449393beb9b30ad7a7dc2283 --- ...ractRestrictBackgroundNetworkTestCase.java | 17 ++ .../cts/net/hostside/DataSaverModeTest.java | 17 -- .../cts/net/hostside/NetworkCallbackTest.java | 241 ++++++++++++++++++ .../cts/net/HostsideNetworkCallbackTests.java | 42 +++ 4 files changed, 300 insertions(+), 17 deletions(-) create mode 100644 tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java create mode 100644 tests/cts/hostside/src/com/android/cts/net/HostsideNetworkCallbackTests.java diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index d15913d85c..bbc0354e2f 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -369,6 +369,23 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation fail("App2 is not on foreground service state after " + maxTries + " attempts: " + state ); } + /** + * As per CDD requirements, if the device doesn't support data saver mode then + * ConnectivityManager.getRestrictBackgroundStatus() will always return + * RESTRICT_BACKGROUND_STATUS_DISABLED. So, enable the data saver mode and check if + * ConnectivityManager.getRestrictBackgroundStatus() for an app in background returns + * RESTRICT_BACKGROUND_STATUS_DISABLED or not. + */ + protected boolean isDataSaverSupported() throws Exception { + assertMyRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); + try { + setRestrictBackground(true); + return !isMyRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); + } finally { + setRestrictBackground(false); + } + } + /** * Returns whether an app state should be considered "background" for restriction purposes. */ diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java index 599a31ce1c..72563d499e 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java @@ -73,23 +73,6 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase return mIsDataSaverSupported && super.isSupported(); } - /** - * As per CDD requirements, if the device doesn't support data saver mode then - * ConnectivityManager.getRestrictBackgroundStatus() will always return - * RESTRICT_BACKGROUND_STATUS_DISABLED. So, enable the data saver mode and check if - * ConnectivityManager.getRestrictBackgroundStatus() for an app in background returns - * RESTRICT_BACKGROUND_STATUS_DISABLED or not. - */ - private boolean isDataSaverSupported() throws Exception { - assertMyRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); - try { - setRestrictBackground(true); - return !isMyRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); - } finally { - setRestrictBackground(false); - } - } - public void testGetRestrictBackgroundStatus_disabled() throws Exception { if (!isSupported()) return; diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java new file mode 100644 index 0000000000..24dde9d356 --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java @@ -0,0 +1,241 @@ +/* + * Copyright (C) 2019 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 android.net.Network; + +import java.util.Objects; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +public class NetworkCallbackTest extends AbstractRestrictBackgroundNetworkTestCase { + + private boolean mIsDataSaverSupported; + private Network mNetwork; + private final TestNetworkCallback mTestNetworkCallback = new TestNetworkCallback(); + + enum CallbackState { + NONE, + AVAILABLE, + LOST, + BLOCKED_STATUS + } + + private static class CallbackInfo { + public final CallbackState state; + public final Network network; + public final Object arg; + + CallbackInfo(CallbackState s, Network n, Object o) { + state = s; network = n; arg = o; + } + + public String toString() { + return String.format("%s (%s) (%s)", state, network, arg); + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof CallbackInfo)) return false; + // Ignore timeMs, since it's unpredictable. + final CallbackInfo other = (CallbackInfo) o; + return (state == other.state) && Objects.equals(network, other.network) + && Objects.equals(arg, other.arg); + } + + @Override + public int hashCode() { + return Objects.hash(state, network, arg); + } + } + + private class TestNetworkCallback extends INetworkCallback.Stub { + private static final int TEST_CALLBACK_TIMEOUT_MS = 200; + + private final LinkedBlockingQueue mCallbacks = new LinkedBlockingQueue<>(); + + protected void setLastCallback(CallbackState state, Network network, Object o) { + mCallbacks.offer(new CallbackInfo(state, network, o)); + } + + CallbackInfo nextCallback(int timeoutMs) { + CallbackInfo cb = null; + try { + cb = mCallbacks.poll(timeoutMs, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + } + if (cb == null) { + fail("Did not receive callback after " + timeoutMs + "ms"); + } + return cb; + } + + CallbackInfo expectCallback(CallbackState state, Network expectedNetwork, Object o) { + final CallbackInfo expected = new CallbackInfo(state, expectedNetwork, o); + final CallbackInfo actual = nextCallback(TEST_CALLBACK_TIMEOUT_MS); + assertEquals("Unexpected callback:", expected, actual); + return actual; + } + + @Override + public void onAvailable(Network network) { + setLastCallback(CallbackState.AVAILABLE, network, null); + } + + @Override + public void onLost(Network network) { + setLastCallback(CallbackState.LOST, network, null); + } + + @Override + public void onBlockedStatusChanged(Network network, boolean blocked) { + setLastCallback(CallbackState.BLOCKED_STATUS, network, blocked); + } + + public void expectLostCallback(Network expectedNetwork) { + expectCallback(CallbackState.LOST, expectedNetwork, null); + } + + public void expectAvailableCallback(Network expectedNetwork) { + expectCallback(CallbackState.AVAILABLE, expectedNetwork, null); + } + + public void expectBlockedStatusCallback(Network expectedNetwork, boolean expectBlocked) { + expectCallback(CallbackState.BLOCKED_STATUS, expectedNetwork, + expectBlocked); + } + + void assertNoCallback() { + CallbackInfo cb = null; + try { + cb = mCallbacks.poll(TEST_CALLBACK_TIMEOUT_MS, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + // Expected. + } + if (cb != null) { + assertNull("Unexpected callback: " + cb, cb); + } + } + } + + @Override + public void setUp() throws Exception { + super.setUp(); + + mIsDataSaverSupported = isDataSaverSupported(); + + mNetwork = mCm.getActiveNetwork(); + + // Set initial state. + setBatterySaverMode(false); + registerBroadcastReceiver(); + + if (!mIsDataSaverSupported) return; + setRestrictBackground(false); + removeRestrictBackgroundWhitelist(mUid); + removeRestrictBackgroundBlacklist(mUid); + assertRestrictBackgroundChangedReceived(0); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + + if (!mIsDataSaverSupported) return; + + try { + resetMeteredNetwork(); + } finally { + setRestrictBackground(false); + } + } + + public void testOnBlockedStatusChanged_data_saver() throws Exception { + if (!mIsDataSaverSupported) return; + + // Prepare metered wifi + if (!setMeteredNetwork()) return; + + // Register callback + registerNetworkCallback((INetworkCallback.Stub) mTestNetworkCallback); + mTestNetworkCallback.expectAvailableCallback(mNetwork); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); + + // Enable restrict background + setRestrictBackground(true); + assertBackgroundNetworkAccess(false); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); + + // Add to whitelist + addRestrictBackgroundWhitelist(mUid); + assertBackgroundNetworkAccess(true); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); + + // Remove from whitelist + removeRestrictBackgroundWhitelist(mUid); + assertBackgroundNetworkAccess(false); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); + + // Set to non-metered network + setUnmeteredNetwork(); + assertBackgroundNetworkAccess(true); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); + + // Disable restrict background, should not trigger callback + setRestrictBackground(false); + assertBackgroundNetworkAccess(true); + mTestNetworkCallback.assertNoCallback(); + } + + + public void testOnBlockedStatusChanged_power_saver() throws Exception { + // Prepare metered wifi + if (!setMeteredNetwork()) return; + + // Register callback + registerNetworkCallback((INetworkCallback.Stub) mTestNetworkCallback); + mTestNetworkCallback.expectAvailableCallback(mNetwork); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); + + // Enable Power Saver + setBatterySaverMode(true); + assertBackgroundNetworkAccess(false); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); + + // Disable Power Saver + setBatterySaverMode(false); + assertBackgroundNetworkAccess(true); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); + + // Set to non-metered network + setUnmeteredNetwork(); + mTestNetworkCallback.assertNoCallback(); + + // Enable Power Saver + setBatterySaverMode(true); + assertBackgroundNetworkAccess(false); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); + + // Disable Power Saver + setBatterySaverMode(false); + assertBackgroundNetworkAccess(true); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); + } + + // TODO: 1. test against VPN lockdown. + // 2. test against multiple networks. +} diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkCallbackTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkCallbackTests.java new file mode 100644 index 0000000000..8d6c4acd7d --- /dev/null +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkCallbackTests.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2019 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; +public class HostsideNetworkCallbackTests extends HostsideNetworkTestCase { + + @Override + protected void setUp() throws Exception { + super.setUp(); + uninstallPackage(TEST_APP2_PKG, false); + installPackage(TEST_APP2_APK); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + uninstallPackage(TEST_APP2_PKG, true); + } + + public void testOnBlockedStatusChanged_data_saver() throws Exception { + runDeviceTests(TEST_PKG, + TEST_PKG + ".NetworkCallbackTest", "testOnBlockedStatusChanged_data_saver"); + } + + public void testOnBlockedStatusChanged_power_saver() throws Exception { + runDeviceTests(TEST_PKG, + TEST_PKG + ".NetworkCallbackTest", "testOnBlockedStatusChanged_power_saver"); + } +} +