summaryrefslogtreecommitdiffstats
path: root/services/tests
diff options
context:
space:
mode:
authorJeff Sharkey <jsharkey@android.com>2011-05-22 14:59:31 -0700
committerJeff Sharkey <jsharkey@android.com>2011-06-01 17:26:30 -0700
commit9599cc5f21152860af9d18015b1398b50743da76 (patch)
treeb3cd1d7e6b97c81f9c72d86869062acdc0387a5d /services/tests
parent1b861278a2051f53ce7955fb7992fa536dc975d9 (diff)
downloadframeworks_base-9599cc5f21152860af9d18015b1398b50743da76.zip
frameworks_base-9599cc5f21152860af9d18015b1398b50743da76.tar.gz
frameworks_base-9599cc5f21152860af9d18015b1398b50743da76.tar.bz2
Tests for NetworkPolicyManager rule generation.
Verifies that policy changes trigger rule updates that respect current foregroundActivities status. Also verifies logic that promotes a UID based on its most-foreground PID. Verifies that policy changes result in immediate rule changes. Also verifies that BACKGROUND_DATA_SETTING_CHANGED broadcasts are sent by policy changes. Change-Id: I4fd0dad9e1dbccee2c5968244bb1814e6cb2c6e1
Diffstat (limited to 'services/tests')
-rw-r--r--services/tests/servicestests/AndroidManifest.xml4
-rw-r--r--services/tests/servicestests/src/com/android/server/BroadcastInterceptingContext.java132
-rw-r--r--services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java272
-rw-r--r--services/tests/servicestests/src/com/android/server/ThrottleServiceTest.java76
4 files changed, 409 insertions, 75 deletions
diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml
index f8d1426..295d569 100644
--- a/services/tests/servicestests/AndroidManifest.xml
+++ b/services/tests/servicestests/AndroidManifest.xml
@@ -24,7 +24,9 @@
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.BROADCAST_STICKY" />
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
-
+ <uses-permission android:name="android.permission.UPDATE_DEVICE_STATS" />
+ <uses-permission android:name="android.permission.MANAGE_APP_TOKENS" />
+
<application>
<uses-library android:name="android.test.runner" />
diff --git a/services/tests/servicestests/src/com/android/server/BroadcastInterceptingContext.java b/services/tests/servicestests/src/com/android/server/BroadcastInterceptingContext.java
new file mode 100644
index 0000000..fe88793
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/BroadcastInterceptingContext.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2011 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.server;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Handler;
+
+import com.google.common.collect.Lists;
+import com.google.common.util.concurrent.AbstractFuture;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.Future;
+
+/**
+ * {@link ContextWrapper} that can attach listeners for upcoming
+ * {@link Context#sendBroadcast(Intent)}.
+ */
+public class BroadcastInterceptingContext extends ContextWrapper {
+ private static final String TAG = "WatchingContext";
+
+ private final List<BroadcastInterceptor> mInterceptors = Lists.newArrayList();
+
+ public class BroadcastInterceptor extends AbstractFuture<Intent> {
+ private final BroadcastReceiver mReceiver;
+ private final IntentFilter mFilter;
+
+ public BroadcastInterceptor(BroadcastReceiver receiver, IntentFilter filter) {
+ mReceiver = receiver;
+ mFilter = filter;
+ }
+
+ public boolean dispatchBroadcast(Intent intent) {
+ if (mFilter.match(getContentResolver(), intent, false, TAG) > 0) {
+ if (mReceiver != null) {
+ final Context context = BroadcastInterceptingContext.this;
+ mReceiver.onReceive(context, intent);
+ return false;
+ } else {
+ set(intent);
+ return true;
+ }
+ } else {
+ return false;
+ }
+ }
+ }
+
+ public BroadcastInterceptingContext(Context base) {
+ super(base);
+ }
+
+ public Future<Intent> nextBroadcastIntent(String action) {
+ return nextBroadcastIntent(new IntentFilter(action));
+ }
+
+ public Future<Intent> nextBroadcastIntent(IntentFilter filter) {
+ final BroadcastInterceptor interceptor = new BroadcastInterceptor(null, filter);
+ synchronized (mInterceptors) {
+ mInterceptors.add(interceptor);
+ }
+ return interceptor;
+ }
+
+ @Override
+ public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
+ synchronized (mInterceptors) {
+ mInterceptors.add(new BroadcastInterceptor(receiver, filter));
+ }
+ return null;
+ }
+
+ @Override
+ public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
+ String broadcastPermission, Handler scheduler) {
+ return registerReceiver(receiver, filter);
+ }
+
+ @Override
+ public void unregisterReceiver(BroadcastReceiver receiver) {
+ synchronized (mInterceptors) {
+ final Iterator<BroadcastInterceptor> i = mInterceptors.iterator();
+ while (i.hasNext()) {
+ final BroadcastInterceptor interceptor = i.next();
+ if (receiver.equals(interceptor.mReceiver)) {
+ i.remove();
+ }
+ }
+ }
+ }
+
+ @Override
+ public void sendBroadcast(Intent intent) {
+ synchronized (mInterceptors) {
+ final Iterator<BroadcastInterceptor> i = mInterceptors.iterator();
+ while (i.hasNext()) {
+ final BroadcastInterceptor interceptor = i.next();
+ if (interceptor.dispatchBroadcast(intent)) {
+ i.remove();
+ }
+ }
+ }
+ }
+
+ @Override
+ public void sendStickyBroadcast(Intent intent) {
+ sendBroadcast(intent);
+ }
+
+ @Override
+ public void removeStickyBroadcast(Intent intent) {
+ // ignored
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
new file mode 100644
index 0000000..cf1171f
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
@@ -0,0 +1,272 @@
+/*
+ * Copyright (C) 2011 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.server;
+
+import static android.net.NetworkPolicyManager.POLICY_NONE;
+import static android.net.NetworkPolicyManager.POLICY_REJECT_PAID_BACKGROUND;
+import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL;
+import static android.net.NetworkPolicyManager.RULE_REJECT_PAID;
+import static org.easymock.EasyMock.capture;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+
+import android.app.IActivityManager;
+import android.app.IProcessObserver;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.net.ConnectivityManager;
+import android.net.INetworkPolicyListener;
+import android.os.Binder;
+import android.os.IPowerManager;
+import android.test.AndroidTestCase;
+import android.test.mock.MockPackageManager;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.Suppress;
+
+import com.android.server.net.NetworkPolicyManagerService;
+
+import org.easymock.Capture;
+import org.easymock.EasyMock;
+
+import java.util.concurrent.Future;
+
+/**
+ * Tests for {@link NetworkPolicyManagerService}.
+ */
+@LargeTest
+public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
+ private static final String TAG = "NetworkPolicyManagerServiceTest";
+
+ private BroadcastInterceptingContext mServiceContext;
+
+ private IActivityManager mActivityManager;
+ private IPowerManager mPowerManager;
+ private INetworkPolicyListener mPolicyListener;
+
+ private NetworkPolicyManagerService mService;
+ private IProcessObserver mProcessObserver;
+
+ private Binder mStubBinder = new Binder();
+
+ private static final int UID_A = 800;
+ private static final int UID_B = 801;
+
+ private static final int PID_1 = 400;
+ private static final int PID_2 = 401;
+ private static final int PID_3 = 402;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+
+ // intercept various broadcasts, and pretend that uids have packages
+ mServiceContext = new BroadcastInterceptingContext(getContext()) {
+ @Override
+ public PackageManager getPackageManager() {
+ return new MockPackageManager() {
+ @Override
+ public String[] getPackagesForUid(int uid) {
+ return new String[] { "com.example" };
+ }
+ };
+ }
+ };
+
+ mActivityManager = createMock(IActivityManager.class);
+ mPowerManager = createMock(IPowerManager.class);
+ mPolicyListener = createMock(INetworkPolicyListener.class);
+
+ mService = new NetworkPolicyManagerService(
+ mServiceContext, mActivityManager, mPowerManager);
+
+ // RemoteCallbackList needs a binder to use as key
+ expect(mPolicyListener.asBinder()).andReturn(mStubBinder).atLeastOnce();
+ replay();
+ mService.registerListener(mPolicyListener);
+ verifyAndReset();
+
+ // catch the registered IProcessObserver during systemReady()
+ final Capture<IProcessObserver> processObserver = new Capture<IProcessObserver>();
+ mActivityManager.registerProcessObserver(capture(processObserver));
+ expectLastCall().atLeastOnce();
+
+ // expect to answer screen status during systemReady()
+ expect(mPowerManager.isScreenOn()).andReturn(true).atLeastOnce();
+
+ replay();
+ mService.systemReady();
+ verifyAndReset();
+
+ mProcessObserver = processObserver.getValue();
+
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ mServiceContext = null;
+
+ mActivityManager = null;
+ mPowerManager = null;
+ mPolicyListener = null;
+
+ mService = null;
+ mProcessObserver = null;
+
+ super.tearDown();
+ }
+
+ @Suppress
+ public void testPolicyChangeTriggersBroadcast() throws Exception {
+ mService.setUidPolicy(UID_A, POLICY_NONE);
+
+ // change background policy and expect broadcast
+ final Future<Intent> backgroundChanged = mServiceContext.nextBroadcastIntent(
+ ConnectivityManager.ACTION_BACKGROUND_DATA_SETTING_CHANGED);
+
+ mService.setUidPolicy(UID_A, POLICY_REJECT_PAID_BACKGROUND);
+
+ backgroundChanged.get();
+ }
+
+ public void testPidForegroundCombined() throws Exception {
+ // push all uid into background
+ mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, false);
+ mProcessObserver.onForegroundActivitiesChanged(PID_2, UID_A, false);
+ mProcessObserver.onForegroundActivitiesChanged(PID_3, UID_B, false);
+ assertFalse(mService.isUidForeground(UID_A));
+ assertFalse(mService.isUidForeground(UID_B));
+
+ // push one of the shared pids into foreground
+ mProcessObserver.onForegroundActivitiesChanged(PID_2, UID_A, true);
+ assertTrue(mService.isUidForeground(UID_A));
+ assertFalse(mService.isUidForeground(UID_B));
+
+ // and swap another uid into foreground
+ mProcessObserver.onForegroundActivitiesChanged(PID_2, UID_A, false);
+ mProcessObserver.onForegroundActivitiesChanged(PID_3, UID_B, true);
+ assertFalse(mService.isUidForeground(UID_A));
+ assertTrue(mService.isUidForeground(UID_B));
+
+ // push both pid into foreground
+ mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, true);
+ mProcessObserver.onForegroundActivitiesChanged(PID_2, UID_A, true);
+ assertTrue(mService.isUidForeground(UID_A));
+
+ // pull one out, should still be foreground
+ mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, false);
+ assertTrue(mService.isUidForeground(UID_A));
+
+ // pull final pid out, should now be background
+ mProcessObserver.onForegroundActivitiesChanged(PID_2, UID_A, false);
+ assertFalse(mService.isUidForeground(UID_A));
+ }
+
+ public void testScreenChangesRules() throws Exception {
+ // push strict policy for foreground uid, verify ALLOW rule
+ expectRulesChanged(UID_A, RULE_ALLOW_ALL);
+ replay();
+ mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, true);
+ mService.setUidPolicy(UID_A, POLICY_REJECT_PAID_BACKGROUND);
+ verifyAndReset();
+
+ // now turn screen off and verify REJECT rule
+ expect(mPowerManager.isScreenOn()).andReturn(false).atLeastOnce();
+ expectRulesChanged(UID_A, RULE_REJECT_PAID);
+ replay();
+ mServiceContext.sendBroadcast(new Intent(Intent.ACTION_SCREEN_OFF));
+ verifyAndReset();
+
+ // and turn screen back on, verify ALLOW rule restored
+ expect(mPowerManager.isScreenOn()).andReturn(true).atLeastOnce();
+ expectRulesChanged(UID_A, RULE_ALLOW_ALL);
+ replay();
+ mServiceContext.sendBroadcast(new Intent(Intent.ACTION_SCREEN_ON));
+ verifyAndReset();
+ }
+
+ public void testPolicyNone() throws Exception {
+ // POLICY_NONE should RULE_ALLOW in foreground
+ expectRulesChanged(UID_A, RULE_ALLOW_ALL);
+ replay();
+ mService.setUidPolicy(UID_A, POLICY_NONE);
+ mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, true);
+ verifyAndReset();
+
+ // POLICY_NONE should RULE_ALLOW in background
+ expectRulesChanged(UID_A, RULE_ALLOW_ALL);
+ replay();
+ mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, false);
+ verifyAndReset();
+ }
+
+ public void testPolicyReject() throws Exception {
+ // POLICY_REJECT should RULE_ALLOW in background
+ expectRulesChanged(UID_A, RULE_REJECT_PAID);
+ replay();
+ mService.setUidPolicy(UID_A, POLICY_REJECT_PAID_BACKGROUND);
+ verifyAndReset();
+
+ // POLICY_REJECT should RULE_ALLOW in foreground
+ expectRulesChanged(UID_A, RULE_ALLOW_ALL);
+ replay();
+ mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, true);
+ verifyAndReset();
+
+ // POLICY_REJECT should RULE_REJECT in background
+ expectRulesChanged(UID_A, RULE_REJECT_PAID);
+ replay();
+ mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, false);
+ verifyAndReset();
+ }
+
+ public void testPolicyRejectAddRemove() throws Exception {
+ // POLICY_NONE should have RULE_ALLOW in background
+ expectRulesChanged(UID_A, RULE_ALLOW_ALL);
+ replay();
+ mService.setUidPolicy(UID_A, POLICY_NONE);
+ mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, false);
+ verifyAndReset();
+
+ // adding POLICY_REJECT should cause RULE_REJECT
+ expectRulesChanged(UID_A, RULE_REJECT_PAID);
+ replay();
+ mService.setUidPolicy(UID_A, POLICY_REJECT_PAID_BACKGROUND);
+ verifyAndReset();
+
+ // removing POLICY_REJECT should return us to RULE_ALLOW
+ expectRulesChanged(UID_A, RULE_ALLOW_ALL);
+ replay();
+ mService.setUidPolicy(UID_A, POLICY_NONE);
+ verifyAndReset();
+ }
+
+ private void expectRulesChanged(int uid, int policy) throws Exception {
+ mPolicyListener.onRulesChanged(eq(uid), eq(policy));
+ expectLastCall().atLeastOnce();
+ }
+
+ private void replay() {
+ EasyMock.replay(mActivityManager, mPowerManager, mPolicyListener);
+ }
+
+ private void verifyAndReset() {
+ EasyMock.verify(mActivityManager, mPowerManager, mPolicyListener);
+ EasyMock.reset(mActivityManager, mPowerManager, mPolicyListener);
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/ThrottleServiceTest.java b/services/tests/servicestests/src/com/android/server/ThrottleServiceTest.java
index ca33d32..d1ee4f6 100644
--- a/services/tests/servicestests/src/com/android/server/ThrottleServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/ThrottleServiceTest.java
@@ -25,14 +25,9 @@ import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.reset;
import static org.easymock.EasyMock.verify;
-import com.google.common.collect.Lists;
-import com.google.common.util.concurrent.AbstractFuture;
-
import android.content.ContentResolver;
import android.content.Context;
-import android.content.ContextWrapper;
import android.content.Intent;
-import android.content.IntentFilter;
import android.net.INetworkManagementEventObserver;
import android.net.NetworkStats;
import android.net.ThrottleManager;
@@ -48,8 +43,6 @@ import android.text.format.DateUtils;
import android.util.Log;
import android.util.TrustedTime;
-import java.util.Iterator;
-import java.util.List;
import java.util.concurrent.Future;
/**
@@ -66,7 +59,7 @@ public class ThrottleServiceTest extends AndroidTestCase {
private static final String TEST_IFACE = "test0";
- private WatchingContext mWatchingContext;
+ private BroadcastInterceptingContext mWatchingContext;
private INetworkManagementService mMockNMService;
private TrustedTime mMockTime;
@@ -76,7 +69,7 @@ public class ThrottleServiceTest extends AndroidTestCase {
public void setUp() throws Exception {
super.setUp();
- mWatchingContext = new WatchingContext(getContext());
+ mWatchingContext = new BroadcastInterceptingContext(getContext());
mMockNMService = createMock(INetworkManagementService.class);
mMockTime = createMock(TrustedTime.class);
@@ -354,69 +347,4 @@ public class ThrottleServiceTest extends AndroidTestCase {
pollAction.get();
}
-
-
- /**
- * {@link ContextWrapper} that can attach listeners for upcoming
- * {@link Context#sendBroadcast(Intent)}.
- */
- private static class WatchingContext extends ContextWrapper {
- private List<LocalBroadcastReceiver> mReceivers = Lists.newArrayList();
-
- public class LocalBroadcastReceiver extends AbstractFuture<Intent> {
- private IntentFilter mFilter;
-
- public LocalBroadcastReceiver(IntentFilter filter) {
- mFilter = filter;
- }
-
- public boolean dispatchBroadcast(Intent intent) {
- if (mFilter.match(getContentResolver(), intent, false, TAG) > 0) {
- set(intent);
- return true;
- } else {
- return false;
- }
- }
- }
-
- public WatchingContext(Context base) {
- super(base);
- }
-
- public Future<Intent> nextBroadcastIntent(String action) {
- return nextBroadcastIntent(new IntentFilter(action));
- }
-
- public Future<Intent> nextBroadcastIntent(IntentFilter filter) {
- final LocalBroadcastReceiver receiver = new LocalBroadcastReceiver(filter);
- synchronized (mReceivers) {
- mReceivers.add(receiver);
- }
- return receiver;
- }
-
- @Override
- public void sendBroadcast(Intent intent) {
- synchronized (mReceivers) {
- final Iterator<LocalBroadcastReceiver> i = mReceivers.iterator();
- while (i.hasNext()) {
- final LocalBroadcastReceiver receiver = i.next();
- if (receiver.dispatchBroadcast(intent)) {
- i.remove();
- }
- }
- }
- }
-
- @Override
- public void sendStickyBroadcast(Intent intent) {
- sendBroadcast(intent);
- }
-
- @Override
- public void removeStickyBroadcast(Intent intent) {
- // ignored
- }
- }
}