diff options
8 files changed, 287 insertions, 8 deletions
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index a39d5c8cdcc7..ed1d777dd2ec 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -412,7 +412,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { public NetworkPolicyManagerService(Context context, IActivityManager activityManager, INetworkStatsService networkStats, INetworkManagementService networkManagement) { this(context, activityManager, networkStats, networkManagement, - NtpTrustedTime.getInstance(context), getSystemDir(), false); + AppGlobals.getPackageManager(), NtpTrustedTime.getInstance(context), getSystemDir(), + false); } private static File getSystemDir() { @@ -421,7 +422,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { public NetworkPolicyManagerService(Context context, IActivityManager activityManager, INetworkStatsService networkStats, INetworkManagementService networkManagement, - TrustedTime time, File systemDir, boolean suppressDefaultPolicy) { + IPackageManager pm, TrustedTime time, File systemDir, boolean suppressDefaultPolicy) { mContext = checkNotNull(context, "missing context"); mActivityManager = checkNotNull(activityManager, "missing activityManager"); mNetworkStats = checkNotNull(networkStats, "missing networkStats"); @@ -430,7 +431,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { Context.DEVICE_IDLE_CONTROLLER)); mTime = checkNotNull(time, "missing TrustedTime"); mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); - mIPm = AppGlobals.getPackageManager(); + mIPm = pm; HandlerThread thread = new HandlerThread(TAG); thread.start(); diff --git a/services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/restrict-background-on.xml b/services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/restrict-background-on.xml new file mode 100644 index 000000000000..034411e0be30 --- /dev/null +++ b/services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/restrict-background-on.xml @@ -0,0 +1,3 @@ +<?xml version='1.0' encoding='utf-8' standalone='yes' ?> +<policy-list version="10" restrictBackground="true" > +</policy-list> diff --git a/services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/uidA-blacklisted-restrict-background-off.xml b/services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/uidA-blacklisted-restrict-background-off.xml new file mode 100644 index 000000000000..5b1c03ce170e --- /dev/null +++ b/services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/uidA-blacklisted-restrict-background-off.xml @@ -0,0 +1,4 @@ +<?xml version='1.0' encoding='utf-8' standalone='yes' ?> +<policy-list version="10" restrictBackground="false"> + <uid-policy uid="10004" policy="1" /> +</policy-list> diff --git a/services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/uidA-blacklisted-restrict-background-on.xml b/services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/uidA-blacklisted-restrict-background-on.xml new file mode 100644 index 000000000000..bec2371cff6f --- /dev/null +++ b/services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/uidA-blacklisted-restrict-background-on.xml @@ -0,0 +1,4 @@ +<?xml version='1.0' encoding='utf-8' standalone='yes' ?> +<policy-list version="10" restrictBackground="true"> + <uid-policy uid="10004" policy="1" /> +</policy-list> diff --git a/services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/uidA-whitelisted-restrict-background-off.xml b/services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/uidA-whitelisted-restrict-background-off.xml new file mode 100644 index 000000000000..196ca28192e4 --- /dev/null +++ b/services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/uidA-whitelisted-restrict-background-off.xml @@ -0,0 +1,4 @@ +<?xml version='1.0' encoding='utf-8' standalone='yes' ?> +<policy-list version="10" restrictBackground="false"> + <uid-policy uid="10004" policy="4" /> +</policy-list> diff --git a/services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/uidA-whitelisted-restrict-background-on.xml b/services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/uidA-whitelisted-restrict-background-on.xml new file mode 100644 index 000000000000..4b7724c05d8d --- /dev/null +++ b/services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/uidA-whitelisted-restrict-background-on.xml @@ -0,0 +1,4 @@ +<?xml version='1.0' encoding='utf-8' standalone='yes' ?> +<policy-list version="10" restrictBackground="true"> + <uid-policy uid="10004" policy="4" /> +</policy-list> diff --git a/services/tests/servicestests/src/com/android/server/BroadcastInterceptingContext.java b/services/tests/servicestests/src/com/android/server/BroadcastInterceptingContext.java index 13657ab7f02d..6b5be580c8c3 100644 --- a/services/tests/servicestests/src/com/android/server/BroadcastInterceptingContext.java +++ b/services/tests/servicestests/src/com/android/server/BroadcastInterceptingContext.java @@ -44,7 +44,17 @@ public class BroadcastInterceptingContext extends ContextWrapper { private final List<BroadcastInterceptor> mInterceptors = Lists.newArrayList(); - public class BroadcastInterceptor extends AbstractFuture<Intent> { + abstract class FutureIntent extends AbstractFuture<Intent> { + public void assertNotReceived() + throws InterruptedException, ExecutionException { + assertNotReceived(5, TimeUnit.SECONDS); + } + + public abstract void assertNotReceived(long timeout, TimeUnit unit) + throws InterruptedException, ExecutionException; + } + + public class BroadcastInterceptor extends FutureIntent { private final BroadcastReceiver mReceiver; private final IntentFilter mFilter; @@ -76,17 +86,32 @@ public class BroadcastInterceptingContext extends ContextWrapper { throw new RuntimeException(e); } } + + @Override + public void assertNotReceived() + throws InterruptedException, ExecutionException { + assertNotReceived(5, TimeUnit.SECONDS); + } + + public void assertNotReceived(long timeout, TimeUnit unit) + throws InterruptedException, ExecutionException { + try { + final Intent intent = get(timeout, unit); + throw new AssertionError("Received intent: " + intent); + } catch (TimeoutException e) { + } + } } public BroadcastInterceptingContext(Context base) { super(base); } - public Future<Intent> nextBroadcastIntent(String action) { + public FutureIntent nextBroadcastIntent(String action) { return nextBroadcastIntent(new IntentFilter(action)); } - public Future<Intent> nextBroadcastIntent(IntentFilter filter) { + public FutureIntent nextBroadcastIntent(IntentFilter filter) { final BroadcastInterceptor interceptor = new BroadcastInterceptor(null, filter); synchronized (mInterceptors) { mInterceptors.add(interceptor); diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java index 064b9159c8cb..c19ae113304a 100644 --- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java @@ -52,9 +52,11 @@ import static org.mockito.Matchers.isA; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.Manifest; import android.app.ActivityManager; import android.app.IActivityManager; import android.app.INotificationManager; @@ -64,9 +66,11 @@ import android.app.usage.UsageStatsManagerInternal; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; +import android.content.pm.IPackageManager; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.Signature; +import android.net.ConnectivityManager; import android.net.IConnectivityManager; import android.net.INetworkManagementEventObserver; import android.net.INetworkPolicyListener; @@ -84,12 +88,14 @@ import android.os.INetworkManagementService; import android.os.PowerManagerInternal; import android.os.UserHandle; import android.support.test.InstrumentationRegistry; +import android.support.test.filters.MediumTest; import android.support.test.runner.AndroidJUnit4; import android.text.TextUtils; import android.text.format.Time; import android.util.Log; import android.util.TrustedTime; +import com.android.server.BroadcastInterceptingContext.FutureIntent; import com.android.server.net.NetworkPolicyManagerInternal; import com.android.server.net.NetworkPolicyManagerService; @@ -136,6 +142,7 @@ import java.util.stream.Collectors; * Tests for {@link NetworkPolicyManagerService}. */ @RunWith(AndroidJUnit4.class) +@MediumTest public class NetworkPolicyManagerServiceTest { private static final String TAG = "NetworkPolicyManagerServiceTest"; @@ -167,6 +174,7 @@ public class NetworkPolicyManagerServiceTest { private @Mock IConnectivityManager mConnManager; private @Mock INotificationManager mNotifManager; private @Mock PackageManager mPackageManager; + private @Mock IPackageManager mIpm; private IUidObserver mUidObserver; private INetworkManagementEventObserver mNetworkObserver; @@ -240,7 +248,7 @@ public class NetworkPolicyManagerServiceTest { }).when(mActivityManager).registerUidObserver(any(), anyInt()); mService = new NetworkPolicyManagerService(mServiceContext, mActivityManager, mStatsService, - mNetworkManager, mTime, mPolicyDir, true); + mNetworkManager, mIpm, mTime, mPolicyDir, true); mService.bindConnectivityManager(mConnManager); mService.bindNotificationManager(mNotifManager); mPolicyListener = new NetworkPolicyListenerAnswer(mService); @@ -275,7 +283,7 @@ public class NetworkPolicyManagerServiceTest { mService.systemReady(); // catch INetworkManagementEventObserver during systemReady() - ArgumentCaptor<INetworkManagementEventObserver> networkObserver = + final ArgumentCaptor<INetworkManagementEventObserver> networkObserver = ArgumentCaptor.forClass(INetworkManagementEventObserver.class); verify(mNetworkManager).registerObserver(networkObserver.capture()); mNetworkObserver = networkObserver.getValue(); @@ -295,6 +303,191 @@ public class NetworkPolicyManagerServiceTest { } @Test + public void testTurnRestrictBackgroundOn() throws Exception { + assertRestrictBackgroundOff(); // Sanity check. + final FutureIntent futureIntent = newRestrictBackgroundChangedFuture(); + setRestrictBackground(true); + assertRestrictBackgroundChangedReceived(futureIntent, null); + } + + @Test + @NetPolicyXml("restrict-background-on.xml") + public void testTurnRestrictBackgroundOff() throws Exception { + assertRestrictBackgroundOn(); // Sanity check. + final FutureIntent futureIntent = newRestrictBackgroundChangedFuture(); + setRestrictBackground(false); + assertRestrictBackgroundChangedReceived(futureIntent, null); + } + + /** + * Adds whitelist when restrict background is on - app should receive an intent. + */ + @Test + @NetPolicyXml("restrict-background-on.xml") + public void testAddRestrictBackgroundWhitelist_restrictBackgroundOn() throws Exception { + assertRestrictBackgroundOn(); // Sanity check. + addRestrictBackgroundWhitelist(true); + } + + /** + * Adds whitelist when restrict background is off - app should not receive an intent. + */ + @Test + public void testAddRestrictBackgroundWhitelist_restrictBackgroundOff() throws Exception { + assertRestrictBackgroundOff(); // Sanity check. + addRestrictBackgroundWhitelist(false); + } + + private void addRestrictBackgroundWhitelist(boolean expectIntent) throws Exception { + assertWhitelistUids(); // Sanity check. + final FutureIntent futureIntent = newRestrictBackgroundChangedFuture(); + mPolicyListener.expect().onRestrictBackgroundWhitelistChanged(anyInt(), anyBoolean()); + + mService.addRestrictBackgroundWhitelistedUid(UID_A); + + assertWhitelistUids(UID_A); + mPolicyListener.waitAndVerify().onRestrictBackgroundWhitelistChanged(APP_ID_A, true); + mPolicyListener.verifyNotCalled().onRestrictBackgroundBlacklistChanged(APP_ID_A, true); + if (expectIntent) { + assertRestrictBackgroundChangedReceived(futureIntent, PKG_NAME_A); + } else { + futureIntent.assertNotReceived(); + } + } + + /** + * Removes whitelist when restrict background is on - app should receive an intent. + */ + @Test + @NetPolicyXml("uidA-whitelisted-restrict-background-on.xml") + public void testRemoveRestrictBackgroundWhitelist_restrictBackgroundOn() throws Exception { + assertRestrictBackgroundOn(); // Sanity check. + removeRestrictBackgroundWhitelist(true); + } + + /** + * Removes whitelist when restrict background is off - app should not receive an intent. + */ + @Test + @NetPolicyXml("uidA-whitelisted-restrict-background-off.xml") + public void testRemoveRestrictBackgroundWhitelist_restrictBackgroundOff() throws Exception { + assertRestrictBackgroundOff(); // Sanity check. + removeRestrictBackgroundWhitelist(false); + } + + private void removeRestrictBackgroundWhitelist(boolean expectIntent) throws Exception { + assertWhitelistUids(UID_A); // Sanity check. + final FutureIntent futureIntent = newRestrictBackgroundChangedFuture(); + mPolicyListener.expect().onRestrictBackgroundWhitelistChanged(anyInt(), anyBoolean()); + + mService.removeRestrictBackgroundWhitelistedUid(UID_A); + + assertWhitelistUids(); + mPolicyListener.waitAndVerify().onRestrictBackgroundWhitelistChanged(APP_ID_A, false); + mPolicyListener.verifyNotCalled().onRestrictBackgroundBlacklistChanged(APP_ID_A, false); + if (expectIntent) { + assertRestrictBackgroundChangedReceived(futureIntent, PKG_NAME_A); + } else { + futureIntent.assertNotReceived(); + } + } + + /** + * Adds blacklist when restrict background is on - app should receive an intent. + */ + @Test + @NetPolicyXml("restrict-background-on.xml") + public void testAddRestrictBackgroundBlacklist_restrictBackgroundOn() throws Exception { + assertRestrictBackgroundOn(); // Sanity check. + addRestrictBackgroundBlacklist(true); + } + + /** + * Adds blacklist when restrict background is off - app should receive an intent. + */ + @Test + public void testAddRestrictBackgroundBlacklist_restrictBackgroundOff() throws Exception { + assertRestrictBackgroundOff(); // Sanity check. + addRestrictBackgroundBlacklist(true); + } + + private void addRestrictBackgroundBlacklist(boolean expectIntent) throws Exception { + assertUidPolicy(UID_A, POLICY_NONE); // Sanity check. + final FutureIntent futureIntent = newRestrictBackgroundChangedFuture(); + mPolicyListener.expect().onRestrictBackgroundBlacklistChanged(anyInt(), anyBoolean()); + + mService.setUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND); + + assertUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND); + mPolicyListener.waitAndVerify().onRestrictBackgroundBlacklistChanged(APP_ID_A, true); + mPolicyListener.verifyNotCalled().onRestrictBackgroundWhitelistChanged(APP_ID_A, true); + if (expectIntent) { + assertRestrictBackgroundChangedReceived(futureIntent, PKG_NAME_A); + } else { + futureIntent.assertNotReceived(); + } + } + + /** + * Removes blacklist when restrict background is on - app should receive an intent. + */ + @Test + @NetPolicyXml("uidA-blacklisted-restrict-background-on.xml") + public void testRemoveRestrictBackgroundBlacklist_restrictBackgroundOn() throws Exception { + assertRestrictBackgroundOn(); // Sanity check. + removeRestrictBackgroundBlacklist(true); + } + + /** + * Removes blacklist when restrict background is off - app should receive an intent. + */ + @Test + @NetPolicyXml("uidA-blacklisted-restrict-background-off.xml") + public void testRemoveRestrictBackgroundBlacklist_restrictBackgroundOff() throws Exception { + assertRestrictBackgroundOff(); // Sanity check. + removeRestrictBackgroundBlacklist(true); + } + + private void removeRestrictBackgroundBlacklist(boolean expectIntent) throws Exception { + assertUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND); // Sanity check. + final FutureIntent futureIntent = newRestrictBackgroundChangedFuture(); + mPolicyListener.expect().onRestrictBackgroundBlacklistChanged(anyInt(), anyBoolean()); + + mService.setUidPolicy(UID_A, POLICY_NONE); + + assertUidPolicy(UID_A, POLICY_NONE); + mPolicyListener.waitAndVerify().onRestrictBackgroundBlacklistChanged(APP_ID_A, false); + mPolicyListener.verifyNotCalled().onRestrictBackgroundWhitelistChanged(APP_ID_A, false); + if (expectIntent) { + assertRestrictBackgroundChangedReceived(futureIntent, PKG_NAME_A); + } else { + futureIntent.assertNotReceived(); + } + } + + @NetPolicyXml("uidA-blacklisted-restrict-background-off.xml") + public void testBlacklistedAppIsNotNotifiedWhenRestrictBackgroundIsOn() throws Exception { + // Sanity checks. + assertRestrictBackgroundOn(); + assertUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND); + + final FutureIntent futureIntent = newRestrictBackgroundChangedFuture(); + setRestrictBackground(true); + futureIntent.assertNotReceived(); + } + + @NetPolicyXml("uidA-whitelisted-restrict-background-off.xml") + public void testWhitelistedAppIsNotNotifiedWhenRestrictBackgroundIsOn() throws Exception { + // Sanity checks. + assertRestrictBackgroundOff(); + assertWhitelistUids(UID_A); + + final FutureIntent futureIntent = newRestrictBackgroundChangedFuture(); + setRestrictBackground(true); + futureIntent.assertNotReceived(); + } + + @Test @NetPolicyXml("restrict-background-lists-whitelist-format.xml") public void testRestrictBackgroundLists_whitelistFormat() throws Exception { restrictBackgroundListsTest(); @@ -771,6 +964,11 @@ public class NetworkPolicyManagerServiceTest { return futureAnswer; } + private void expectHasInternetPermission(int uid, boolean hasIt) throws Exception { + when(mIpm.checkUidPermission(Manifest.permission.INTERNET, uid)).thenReturn( + hasIt ? PackageManager.PERMISSION_GRANTED : PackageManager.PERMISSION_DENIED); + } + private void verifySetInterfaceQuota(String iface, long quotaBytes) throws Exception { verify(mNetworkManager, atLeastOnce()).setInterfaceQuota(iface, quotaBytes); } @@ -857,6 +1055,27 @@ public class NetworkPolicyManagerServiceTest { assertContainsInAnyOrder(mService.getRestrictBackgroundWhitelistedUids(), uids); } + private void assertRestrictBackgroundOn() throws Exception { + assertTrue("restrictBackground should be set", mService.getRestrictBackground()); + } + + private void assertRestrictBackgroundOff() throws Exception { + assertFalse("restrictBackground should not be set", mService.getRestrictBackground()); + } + + private FutureIntent newRestrictBackgroundChangedFuture() { + return mServiceContext + .nextBroadcastIntent(ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED); + } + + private void assertRestrictBackgroundChangedReceived(Future<Intent> future, + String expectedPackage) throws Exception { + final String action = ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED; + final Intent intent = future.get(5, TimeUnit.SECONDS); + assertNotNull("Didn't get a " + action + "intent in 5 seconds"); + assertEquals("Wrong package on " + action + " intent", expectedPackage, intent.getPackage()); + } + // TODO: replace by Truth, Hamcrest, or a similar tool. private void assertContainsInAnyOrder(int[] actual, int...expected) { final StringBuilder errors = new StringBuilder(); @@ -896,6 +1115,16 @@ public class NetworkPolicyManagerServiceTest { mElapsedRealtime += duration; } + private FutureIntent mRestrictBackgroundChanged; + + private void setRestrictBackground(boolean flag) throws Exception { + // Must set expectation, otherwise NMPS will reset value to previous one. + when(mNetworkManager.setDataSaverModeEnabled(flag)).thenReturn(true); + mService.setRestrictBackground(flag); + // Sanity check. + assertEquals("restrictBackground not set", flag, mService.getRestrictBackground()); + } + /** * Creates a mock and registers it to {@link LocalServices}. */ @@ -950,6 +1179,11 @@ public class NetworkPolicyManagerServiceTest { } return verify(listener, atLeastOnce()); } + + INetworkPolicyListener verifyNotCalled() { + return verify(listener, never()); + } + } private void setNetpolicyXml(Context context) throws Exception { |