Added CTS tests for RESTRICT_BACKGROUND_CHANGED.
These tests require a second app (besides the test app) that defines a
service; the host-side test then launches the service whose only purpose
is to define a broadcast receiver, which in turn will count the number
of intents received in a shared preferences file. Then the test app will
read the shared preferences and assert the proper number of intents have
been received.
BUG: 26451391
Change-Id: I4c5d5e57c09a0bd57a7f6581820cc9115318dd47
diff --git a/tests/cts/hostside/app/AndroidManifest.xml b/tests/cts/hostside/app/AndroidManifest.xml
index cdde7dc..f44fdd1 100644
--- a/tests/cts/hostside/app/AndroidManifest.xml
+++ b/tests/cts/hostside/app/AndroidManifest.xml
@@ -15,7 +15,8 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.cts.net.hostside">
+ package="com.android.cts.net.hostside"
+ android:sharedUserId="com.android.cts.net.hostside.apps">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/ConnectivityManagerTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/ConnectivityManagerTest.java
index 5d3812c..300e39d 100644
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/ConnectivityManagerTest.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/ConnectivityManagerTest.java
@@ -16,10 +16,14 @@
package com.android.cts.net.hostside;
+import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED;
import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED;
import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED;
import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED;
+
import android.app.Activity;
+import android.content.Context;
+import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.test.InstrumentationTestCase;
import android.util.Log;
@@ -34,6 +38,9 @@
public class ConnectivityManagerTest extends InstrumentationTestCase {
private static final String TAG = "ConnectivityManagerTest";
+ static final String MANIFEST_RECEIVER = "ManifestReceiver";
+ static final String DYNAMIC_RECEIVER = "DynamicReceiver";
+
private ConnectivityManager mCM;
@Override
@@ -41,7 +48,7 @@
super.setUp();
mCM = (ConnectivityManager) getInstrumentation().getContext().getSystemService(
Activity.CONNECTIVITY_SERVICE);
- }
+ }
public void testGetRestrictBackgroundStatus_disabled() {
assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED);
@@ -55,6 +62,46 @@
assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_ENABLED);
}
+ public void testRestrictBackgroundChangedReceivedOnce() throws Exception {
+ assertRestrictBackgroundChangedReceived(DYNAMIC_RECEIVER, 1);
+ assertRestrictBackgroundChangedReceived(MANIFEST_RECEIVER, 0);
+ }
+
+ public void testRestrictBackgroundChangedReceivedTwice() throws Exception {
+ assertRestrictBackgroundChangedReceived(DYNAMIC_RECEIVER, 2);
+ assertRestrictBackgroundChangedReceived(MANIFEST_RECEIVER, 0);
+ }
+
+ private void assertRestrictBackgroundChangedReceived(String receiverName, int expectedCount)
+ throws Exception {
+ int attempts = 0;
+ int count = 0;
+ final int maxAttempts = 5;
+ final int sleepTime = 10;
+ do {
+ attempts++;
+ count = getNumberBroadcastsReceived(getInstrumentation().getContext(), receiverName,
+ ACTION_RESTRICT_BACKGROUND_CHANGED);
+ if (count == expectedCount) {
+ break;
+ }
+ Log.d(TAG, "Count is " + count + " after " + attempts + " attempts; sleeping "
+ + sleepTime + " seconds before trying again");
+ Thread.sleep(sleepTime * 1000);
+ } while (attempts <= maxAttempts);
+ assertEquals("Number of expected broadcasts for " + receiverName + " not reached after "
+ + maxAttempts * sleepTime + " seconds", expectedCount, count);
+ }
+
+ static int getNumberBroadcastsReceived(Context context, String receiverName, String action)
+ throws Exception {
+ final Context sharedContext = context.createPackageContext(
+ "com.android.cts.net.hostside.app2", Context.CONTEXT_IGNORE_SECURITY);
+ final SharedPreferences prefs = sharedContext.getSharedPreferences(receiverName,
+ Context.MODE_PRIVATE);
+ return prefs.getInt(action, 0);
+ }
+
private void assertRestrictBackgroundStatus(int expectedStatus) {
final String expected = toString(expectedStatus);
Log.d(TAG, getName() + " (expecting " + expected + ")");
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyActivity.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyActivity.java
index 375c852..0d0bc58 100644
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyActivity.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyActivity.java
@@ -18,13 +18,9 @@
import android.app.Activity;
import android.content.Intent;
-import android.net.VpnService;
import android.os.Bundle;
-import android.os.ParcelFileDescriptor;
import android.view.WindowManager;
-import java.util.Arrays;
-import java.util.ArrayList;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyVpnService.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyVpnService.java
index a3f400c..90a3ce4 100644
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyVpnService.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyVpnService.java
@@ -26,7 +26,6 @@
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
-import java.util.ArrayList;
public class MyVpnService extends VpnService {
diff --git a/tests/cts/hostside/app2/Android.mk b/tests/cts/hostside/app2/Android.mk
new file mode 100644
index 0000000..e330bf7
--- /dev/null
+++ b/tests/cts/hostside/app2/Android.mk
@@ -0,0 +1,31 @@
+#
+# Copyright (C) 2016 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.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+LOCAL_SDK_VERSION := current
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsHostsideNetworkTestsApp2
+
+LOCAL_PROGUARD_ENABLED := disabled
+LOCAL_DEX_PREOPT := false
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/tests/cts/hostside/app2/AndroidManifest.xml b/tests/cts/hostside/app2/AndroidManifest.xml
new file mode 100644
index 0000000..d69bf56
--- /dev/null
+++ b/tests/cts/hostside/app2/AndroidManifest.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.cts.net.hostside.app2"
+ android:sharedUserId="com.android.cts.net.hostside.apps" >
+
+ <!-- This application is used to listen to RESTRICT_BACKGROUND_CHANGED intents and store
+ them in a shared preferences which is then read by the test app.
+ It defines 2 listeners, one in the manifest and another dynamically registered by
+ a service.
+ -->
+ <application>
+ <service android:name=".MyService" />
+
+ <receiver android:name=".MyBroadcastReceiver" >
+ <intent-filter>
+ <action android:name="android.net.conn.RESTRICT_BACKGROUND_CHANGED" />
+ </intent-filter>
+ </receiver>
+ </application>
+
+</manifest>
\ No newline at end of file
diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java
new file mode 100644
index 0000000..91caeda
--- /dev/null
+++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2016 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.app2;
+
+public final class Common {
+
+ static final String TAG = "CtsNetApp2";
+ static final String MANIFEST_RECEIVER = "ManifestReceiver";
+ static final String DYNAMIC_RECEIVER = "DynamicReceiver";
+}
diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java
new file mode 100644
index 0000000..0cbf360
--- /dev/null
+++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2016 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.app2;
+
+import static com.android.cts.net.hostside.app2.Common.MANIFEST_RECEIVER;
+import static com.android.cts.net.hostside.app2.Common.TAG;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.util.Log;
+
+/**
+ * Receiver that stores received broadcasts in a shared preference.
+ */
+public class MyBroadcastReceiver extends BroadcastReceiver {
+
+ private final String mName;
+
+ public MyBroadcastReceiver() {
+ this(MANIFEST_RECEIVER);
+ }
+
+ MyBroadcastReceiver(String name) {
+ Log.d(TAG, "Constructing MyBroadcastReceiver named " + name);
+ mName = name;
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Log.d(TAG, "onReceive() for " + mName + ": " + intent);
+ final SharedPreferences prefs = context.getSharedPreferences(mName, Context.MODE_PRIVATE);
+ final String pref = intent.getAction();
+ final int value = prefs.getInt(pref, 0) + 1;
+ Log.d(TAG, "Setting " + pref + " = " + value);
+ prefs.edit().putInt(pref, value).apply();
+ }
+}
diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyService.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyService.java
new file mode 100644
index 0000000..882bb62
--- /dev/null
+++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyService.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2016 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.app2;
+
+import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED;
+import static com.android.cts.net.hostside.app2.Common.DYNAMIC_RECEIVER;
+import static com.android.cts.net.hostside.app2.Common.TAG;
+import android.app.Service;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.IBinder;
+import android.util.Log;
+
+/**
+ * Service used to dynamically register a broadcast receiver.
+ */
+public class MyService extends Service {
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ Log.d(TAG, "onStartCommand: " + intent);
+ getApplicationContext().registerReceiver(new MyBroadcastReceiver(DYNAMIC_RECEIVER),
+ new IntentFilter(ACTION_RESTRICT_BACKGROUND_CHANGED));
+ return START_STICKY;
+ }
+}
diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTests.java
index dd2424c..bedfad6 100644
--- a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTests.java
+++ b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTests.java
@@ -42,6 +42,9 @@
private static final String TEST_PKG = "com.android.cts.net.hostside";
private static final String TEST_APK = "CtsHostsideNetworkTestsApp.apk";
+ private static final String TEST_APP2_PKG = "com.android.cts.net.hostside.app2";
+ private static final String TEST_APP2_APK = "CtsHostsideNetworkTestsApp2.apk";
+
private IAbi mAbi;
private IBuildInfo mCtsBuild;
@@ -63,15 +66,22 @@
assertNotNull(mCtsBuild);
setRestrictBackground(false);
- uninstallTestPackage(false);
- installTestPackage();
+
+ uninstallPackage(TEST_PKG, false);
+ installPackage(TEST_APK);
+ // TODO: split this class into HostsideVpnTests and HostsideConnectivityManagerTests so
+ // the former don't need to unnecessarily install app2.
+ uninstallPackage(TEST_APP2_PKG, false);
+ installPackage(TEST_APP2_APK);
}
@Override
protected void tearDown() throws Exception {
super.tearDown();
- uninstallTestPackage(false);
+ uninstallPackage(TEST_PKG, true);
+ uninstallPackage(TEST_APP2_PKG, true);
+
setRestrictBackground(false);
}
@@ -80,26 +90,41 @@
}
public void testConnectivityManager_getRestrictBackgroundStatus_disabled() throws Exception {
+ startBroadcastReceiverService();
final int uid = getUid(TEST_PKG);
+
removeRestrictBackgroundWhitelist(uid);
assertRestrictBackgroundStatusDisabled();
+ assertRestrictBackgroundChangedReceivedOnce();
+
// Sanity check: make sure status is always disabled, never whitelisted
addRestrictBackgroundWhitelist(uid);
assertRestrictBackgroundStatusDisabled();
+ assertRestrictBackgroundChangedReceivedTwice();
}
public void testConnectivityManager_getRestrictBackgroundStatus_whitelisted() throws Exception {
+ startBroadcastReceiverService();
final int uid = getUid(TEST_PKG);
+
setRestrictBackground(true);
+ assertRestrictBackgroundChangedReceivedOnce();
+
addRestrictBackgroundWhitelist(uid);
assertRestrictBackgroundStatusWhitelisted();
+ assertRestrictBackgroundChangedReceivedTwice();
}
public void testConnectivityManager_getRestrictBackgroundStatus_enabled() throws Exception {
+ startBroadcastReceiverService();
final int uid = getUid(TEST_PKG);
+
setRestrictBackground(true);
+ assertRestrictBackgroundChangedReceivedOnce();
+
removeRestrictBackgroundWhitelist(uid);
assertRestrictBackgroundStatusEnabled();
+ assertRestrictBackgroundChangedReceivedTwice();
}
public void testConnectivityManager_getRestrictBackgroundStatus_uninstall() throws Exception {
@@ -108,44 +133,66 @@
addRestrictBackgroundWhitelist(uid);
assertRestrictBackgroundWhitelist(uid, true);
- uninstallTestPackage(true);
+ uninstallPackage(TEST_PKG, true);
assertPackageUninstalled(TEST_PKG);
assertRestrictBackgroundWhitelist(uid, false);
- installTestPackage();
+ installPackage(TEST_APK);
final int newUid = getUid(TEST_PKG);
assertRestrictBackgroundWhitelist(uid, false);
assertRestrictBackgroundWhitelist(newUid, false);
}
- private void installTestPackage() throws DeviceNotAvailableException, FileNotFoundException {
+ private void installPackage(String apk) throws DeviceNotAvailableException,
+ FileNotFoundException {
assertNull(getDevice().installPackage(
- MigrationHelper.getTestFile(mCtsBuild, TEST_APK), false));
+ MigrationHelper.getTestFile(mCtsBuild, apk), false));
}
- private void uninstallTestPackage(boolean shouldSucceed) throws DeviceNotAvailableException {
- final String result = getDevice().uninstallPackage(TEST_PKG);
+ private void uninstallPackage(String packageName, boolean shouldSucceed)
+ throws DeviceNotAvailableException {
+ final String result = getDevice().uninstallPackage(packageName);
if (shouldSucceed) {
- assertNull("uninstallPackage failed: " + result, result);
+ assertNull("uninstallPackage(" + packageName + ") failed: " + result, result);
}
}
- private void assertPackageUninstalled(String packageName) throws DeviceNotAvailableException {
- final String command = "cmd package list packages -f " + packageName;
+ /**
+ * Starts a service that will register a broadcast receiver to receive
+ * {@code RESTRICT_BACKGROUND_CHANGE} intents.
+ * <p>
+ * The service must run in a separate app because otherwise it would be killed every time
+ * {@link #runDeviceTests(String, String)} is executed.
+ */
+ private void startBroadcastReceiverService() throws DeviceNotAvailableException {
+ runCommand("am startservice " + TEST_APP2_PKG + "/.MyService");
+ }
+
+ private void assertPackageUninstalled(String packageName) throws Exception {
+ final String command = "cmd package list packages " + packageName;
final int max_tries = 5;
for (int i = 1; i <= max_tries; i++) {
final String result = runCommand(command);
if (result.trim().isEmpty()) {
return;
}
+ // 'list packages' filters by substring, so we need to iterate with the results
+ // and check one by one, otherwise 'com.android.cts.net.hostside' could return
+ // 'com.android.cts.net.hostside.app2'
+ boolean found = false;
+ for (String line : result.split("[\\r\\n]+")) {
+ if (line.endsWith(packageName)) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ return;
+ }
i++;
Log.v(TAG, "Package " + packageName + " not uninstalled yet (" + result
+ "); sleeping 1s before polling again");
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- }
+ Thread.sleep(1000);
}
fail("Package '" + packageName + "' not uinstalled after " + max_tries + " seconds");
}
@@ -165,6 +212,16 @@
"testGetRestrictBackgroundStatus_enabled");
}
+ private void assertRestrictBackgroundChangedReceivedOnce() throws DeviceNotAvailableException {
+ runDeviceTests(TEST_PKG, TEST_PKG + ".ConnectivityManagerTest",
+ "testRestrictBackgroundChangedReceivedOnce");
+ }
+
+ private void assertRestrictBackgroundChangedReceivedTwice() throws DeviceNotAvailableException {
+ runDeviceTests(TEST_PKG, TEST_PKG + ".ConnectivityManagerTest",
+ "testRestrictBackgroundChangedReceivedTwice");
+ }
+
public void runDeviceTests(String packageName, String testClassName)
throws DeviceNotAvailableException {
runDeviceTests(packageName, testClassName, null);
@@ -176,14 +233,11 @@
"android.support.test.runner.AndroidJUnitRunner", getDevice().getIDevice());
if (testClassName != null) {
- // TODO: figure out why testRunner.setMethodName() / testRunner.setClassName() doesn't
- // work
- final StringBuilder runOptions = new StringBuilder("-e class ").append(testClassName);
if (methodName != null) {
- runOptions.append('#').append(methodName);
+ testRunner.setMethodName(testClassName, methodName);
+ } else {
+ testRunner.setClassName(testClassName);
}
- Log.i(TAG, "Setting runOptions() as " + runOptions);
- testRunner.setRunOptions(runOptions.toString());
}
final CollectingTestListener listener = new CollectingTestListener();
@@ -224,27 +278,31 @@
+ output);
}
- private void addRestrictBackgroundWhitelist(int uid) throws DeviceNotAvailableException {
+ private void addRestrictBackgroundWhitelist(int uid) throws Exception {
runCommand("cmd netpolicy add restrict-background-whitelist " + uid);
assertRestrictBackgroundWhitelist(uid, true);
}
- private void removeRestrictBackgroundWhitelist(int uid) throws DeviceNotAvailableException {
+ private void removeRestrictBackgroundWhitelist(int uid) throws Exception {
runCommand("cmd netpolicy remove restrict-background-whitelist " + uid);
assertRestrictBackgroundWhitelist(uid, false);
}
- private void assertRestrictBackgroundWhitelist(int uid, boolean expected)
- throws DeviceNotAvailableException {
- final String output = runCommand("cmd netpolicy list restrict-background-whitelist ");
- // TODO: use MoreAsserts
- if (expected) {
- assertTrue("Did not find uid '" + uid + "' on '" + output + "'",
- output.contains(Integer.toString(uid)));
- } else {
- assertFalse("Found uid '" + uid + "' on '" + output + "'",
- output.contains(Integer.toString(uid)));
+ private void assertRestrictBackgroundWhitelist(int uid, boolean expected) throws Exception {
+ final int max_tries = 5;
+ boolean actual = false;
+ for (int i = 1; i <= max_tries; i++) {
+ final String output = runCommand("cmd netpolicy list restrict-background-whitelist ");
+ actual = output.contains(Integer.toString(uid));
+ if (expected == actual) {
+ return;
+ }
+ Log.v(TAG, "whitelist check for uid " + uid + " doesn't match yet (expected "
+ + expected + ", got " + actual + "); sleeping 1s before polling again");
+ Thread.sleep(1000);
}
+ fail("whitelist check for uid " + uid + " failed: expected "
+ + expected + ", got " + actual);
}
private void setRestrictBackground(boolean enabled) throws DeviceNotAvailableException {