diff options
author | Jeff Sharkey <jsharkey@android.com> | 2011-06-16 15:07:48 -0700 |
---|---|---|
committer | Jeff Sharkey <jsharkey@android.com> | 2011-06-17 16:49:21 -0700 |
commit | fdfef57f498e3021a34342538aef9f1c7ccbae78 (patch) | |
tree | 612e86ac458b3b99c6a527544c26d4993dad8051 | |
parent | 5bfa752f71cf7e6a5e7490d48eaef4054f99bebc (diff) | |
download | frameworks_base-fdfef57f498e3021a34342538aef9f1c7ccbae78.zip frameworks_base-fdfef57f498e3021a34342538aef9f1c7ccbae78.tar.gz frameworks_base-fdfef57f498e3021a34342538aef9f1c7ccbae78.tar.bz2 |
Notify policy listeners about metered ifaces.
Currently, kernel definition of metered networks is applied at the
interface level. This change maintain list of those metered ifaces
and notifies policy listeners, like ConnectivityService. (This gives
us a consistent picture of when a network would be blocked.)
Bug: 4601393
Change-Id: I277d5ca96ab967a1c1c3f1da8f9587557cd6d74c
7 files changed, 151 insertions, 76 deletions
diff --git a/core/java/android/app/DownloadManager.java b/core/java/android/app/DownloadManager.java index 28559cc..ad8d41f 100644 --- a/core/java/android/app/DownloadManager.java +++ b/core/java/android/app/DownloadManager.java @@ -226,6 +226,14 @@ public class DownloadManager { public final static int ERROR_FILE_ALREADY_EXISTS = 1009; /** + * Value of {@link #COLUMN_REASON} when the download has failed because of + * {@link NetworkPolicyManager} controls on the requesting application. + * + * @hide + */ + public final static int ERROR_BLOCKED = 1010; + + /** * Value of {@link #COLUMN_REASON} when the download is paused because some network error * occurred and the download manager is waiting before retrying the request. */ @@ -249,14 +257,6 @@ public class DownloadManager { public final static int PAUSED_UNKNOWN = 4; /** - * Value of {@link #COLUMN_REASON} when the download has been paused because - * of {@link NetworkPolicyManager} controls on the requesting application. - * - * @hide - */ - public final static int PAUSED_BY_POLICY = 5; - - /** * Broadcast intent action sent by the download manager when a download completes. */ public final static String ACTION_DOWNLOAD_COMPLETE = "android.intent.action.DOWNLOAD_COMPLETE"; @@ -804,7 +804,6 @@ public class DownloadManager { parts.add(statusClause("=", Downloads.Impl.STATUS_WAITING_TO_RETRY)); parts.add(statusClause("=", Downloads.Impl.STATUS_WAITING_FOR_NETWORK)); parts.add(statusClause("=", Downloads.Impl.STATUS_QUEUED_FOR_WIFI)); - parts.add(statusClause("=", Downloads.Impl.STATUS_PAUSED_BY_POLICY)); } if ((mStatusFlags & STATUS_SUCCESSFUL) != 0) { parts.add(statusClause("=", Downloads.Impl.STATUS_SUCCESS)); @@ -1275,9 +1274,6 @@ public class DownloadManager { case Downloads.Impl.STATUS_QUEUED_FOR_WIFI: return PAUSED_QUEUED_FOR_WIFI; - case Downloads.Impl.STATUS_PAUSED_BY_POLICY: - return PAUSED_BY_POLICY; - default: return PAUSED_UNKNOWN; } @@ -1316,6 +1312,9 @@ public class DownloadManager { case Downloads.Impl.STATUS_FILE_ALREADY_EXISTS_ERROR: return ERROR_FILE_ALREADY_EXISTS; + case Downloads.Impl.STATUS_BLOCKED: + return ERROR_BLOCKED; + default: return ERROR_UNKNOWN; } @@ -1333,7 +1332,6 @@ public class DownloadManager { case Downloads.Impl.STATUS_WAITING_TO_RETRY: case Downloads.Impl.STATUS_WAITING_FOR_NETWORK: case Downloads.Impl.STATUS_QUEUED_FOR_WIFI: - case Downloads.Impl.STATUS_PAUSED_BY_POLICY: return STATUS_PAUSED; case Downloads.Impl.STATUS_SUCCESS: diff --git a/core/java/android/net/INetworkPolicyListener.aidl b/core/java/android/net/INetworkPolicyListener.aidl index 9230151..a45ec54 100644 --- a/core/java/android/net/INetworkPolicyListener.aidl +++ b/core/java/android/net/INetworkPolicyListener.aidl @@ -19,6 +19,7 @@ package android.net; /** {@hide} */ oneway interface INetworkPolicyListener { - void onRulesChanged(int uid, int uidRules); + void onUidRulesChanged(int uid, int uidRules); + void onMeteredIfacesChanged(in String[] meteredIfaces); } diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java index 0d4d9a9..bfea168 100644 --- a/core/java/android/net/NetworkPolicyManager.java +++ b/core/java/android/net/NetworkPolicyManager.java @@ -34,13 +34,13 @@ public class NetworkPolicyManager { /** No specific network policy, use system default. */ public static final int POLICY_NONE = 0x0; - /** Reject network usage on paid networks when application in background. */ - public static final int POLICY_REJECT_PAID_BACKGROUND = 0x1; + /** Reject network usage on metered networks when application in background. */ + public static final int POLICY_REJECT_METERED_BACKGROUND = 0x1; /** All network traffic should be allowed. */ public static final int RULE_ALLOW_ALL = 0x0; - /** Reject traffic on paid networks. */ - public static final int RULE_REJECT_PAID = 0x1; + /** Reject traffic on metered networks. */ + public static final int RULE_REJECT_METERED = 0x1; /** * {@link Intent} action launched when user selects {@link NetworkPolicy} @@ -98,7 +98,7 @@ public class NetworkPolicyManager { * Set policy flags for specific UID. * * @param policy {@link #POLICY_NONE} or combination of flags like - * {@link #POLICY_REJECT_PAID_BACKGROUND}. + * {@link #POLICY_REJECT_METERED_BACKGROUND}. */ public void setUidPolicy(int uid, int policy) { try { @@ -217,8 +217,8 @@ public class NetworkPolicyManager { /** {@hide} */ public static void dumpPolicy(PrintWriter fout, int policy) { fout.write("["); - if ((policy & POLICY_REJECT_PAID_BACKGROUND) != 0) { - fout.write("REJECT_PAID_BACKGROUND"); + if ((policy & POLICY_REJECT_METERED_BACKGROUND) != 0) { + fout.write("REJECT_METERED_BACKGROUND"); } fout.write("]"); } @@ -226,8 +226,8 @@ public class NetworkPolicyManager { /** {@hide} */ public static void dumpRules(PrintWriter fout, int rules) { fout.write("["); - if ((rules & RULE_REJECT_PAID) != 0) { - fout.write("REJECT_PAID"); + if ((rules & RULE_REJECT_METERED) != 0) { + fout.write("REJECT_METERED"); } fout.write("]"); } diff --git a/core/java/android/provider/Downloads.java b/core/java/android/provider/Downloads.java index 0a8c3ca..ba4804d 100644 --- a/core/java/android/provider/Downloads.java +++ b/core/java/android/provider/Downloads.java @@ -548,14 +548,6 @@ public final class Downloads { } /** - * This download has been paused because requesting application has been - * blocked by {@link NetworkPolicyManager}. - * - * @hide - */ - public static final int STATUS_PAUSED_BY_POLICY = 189; - - /** * This download hasn't stated yet */ public static final int STATUS_PENDING = 190; @@ -704,6 +696,14 @@ public final class Downloads { public static final int STATUS_TOO_MANY_REDIRECTS = 497; /** + * This download has failed because requesting application has been + * blocked by {@link NetworkPolicyManager}. + * + * @hide + */ + public static final int STATUS_BLOCKED = 498; + + /** * This download is visible but only shows in the notifications * while it's in progress. */ diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java index 07855d9..aa3dfa6 100644 --- a/services/java/com/android/server/ConnectivityService.java +++ b/services/java/com/android/server/ConnectivityService.java @@ -19,7 +19,7 @@ package com.android.server; import static android.Manifest.permission.MANAGE_NETWORK_POLICY; import static android.net.ConnectivityManager.isNetworkTypeValid; import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL; -import static android.net.NetworkPolicyManager.RULE_REJECT_PAID; +import static android.net.NetworkPolicyManager.RULE_REJECT_METERED; import android.bluetooth.BluetoothTetheringDataTracker; import android.content.ContentResolver; @@ -71,6 +71,7 @@ import com.android.server.connectivity.Tethering; import com.android.server.connectivity.Vpn; import com.google.android.collect.Lists; +import com.google.android.collect.Sets; import java.io.FileDescriptor; import java.io.IOException; @@ -78,8 +79,10 @@ import java.io.PrintWriter; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.GregorianCalendar; +import java.util.HashSet; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; @@ -108,8 +111,12 @@ public class ConnectivityService extends IConnectivityManager.Stub { private Vpn mVpn; + /** Lock around {@link #mUidRules} and {@link #mMeteredIfaces}. */ + private Object mRulesLock = new Object(); /** Currently active network rules by UID. */ private SparseIntArray mUidRules = new SparseIntArray(); + /** Set of ifaces that are costly. */ + private HashSet<String> mMeteredIfaces = Sets.newHashSet(); /** * Sometimes we want to refer to the individual network state @@ -570,31 +577,35 @@ public class ConnectivityService extends IConnectivityManager.Stub { } /** - * Check if UID is blocked from using the given {@link NetworkInfo}. + * Check if UID should be blocked from using the network represented by the + * given {@link NetworkStateTracker}. */ - private boolean isNetworkBlocked(NetworkInfo info, int uid) { - synchronized (mUidRules) { - // TODO: expand definition of "paid" network to cover tethered or - // paid hotspot use cases. - final boolean networkIsPaid = info.getType() != ConnectivityManager.TYPE_WIFI; - final int uidRules = mUidRules.get(uid, RULE_ALLOW_ALL); + private boolean isNetworkBlocked(NetworkStateTracker tracker, int uid) { + final String iface = tracker.getLinkProperties().getInterfaceName(); - if (networkIsPaid && (uidRules & RULE_REJECT_PAID) != 0) { - return true; - } + final boolean networkCostly; + final int uidRules; + synchronized (mRulesLock) { + networkCostly = mMeteredIfaces.contains(iface); + uidRules = mUidRules.get(uid, RULE_ALLOW_ALL); + } - // no restrictive rules; network is visible - return false; + if (networkCostly && (uidRules & RULE_REJECT_METERED) != 0) { + return true; } + + // no restrictive rules; network is visible + return false; } /** - * Return a filtered version of the given {@link NetworkInfo}, potentially - * marked {@link DetailedState#BLOCKED} based on - * {@link #isNetworkBlocked(NetworkInfo, int)}. + * Return a filtered {@link NetworkInfo}, potentially marked + * {@link DetailedState#BLOCKED} based on + * {@link #isNetworkBlocked(NetworkStateTracker, int)}. */ - private NetworkInfo filterNetworkInfo(NetworkInfo info, int uid) { - if (isNetworkBlocked(info, uid)) { + private NetworkInfo getFilteredNetworkInfo(NetworkStateTracker tracker, int uid) { + NetworkInfo info = tracker.getNetworkInfo(); + if (isNetworkBlocked(tracker, uid)) { // network is blocked; clone and override state info = new NetworkInfo(info); info.setDetailedState(DetailedState.BLOCKED, null, null); @@ -634,7 +645,7 @@ public class ConnectivityService extends IConnectivityManager.Stub { if (isNetworkTypeValid(networkType)) { final NetworkStateTracker tracker = mNetTrackers[networkType]; if (tracker != null) { - info = filterNetworkInfo(tracker.getNetworkInfo(), uid); + info = getFilteredNetworkInfo(tracker, uid); } } return info; @@ -645,10 +656,10 @@ public class ConnectivityService extends IConnectivityManager.Stub { enforceAccessPermission(); final int uid = Binder.getCallingUid(); final ArrayList<NetworkInfo> result = Lists.newArrayList(); - synchronized (mUidRules) { + synchronized (mRulesLock) { for (NetworkStateTracker tracker : mNetTrackers) { if (tracker != null) { - result.add(filterNetworkInfo(tracker.getNetworkInfo(), uid)); + result.add(getFilteredNetworkInfo(tracker, uid)); } } } @@ -685,10 +696,10 @@ public class ConnectivityService extends IConnectivityManager.Stub { enforceAccessPermission(); final int uid = Binder.getCallingUid(); final ArrayList<NetworkState> result = Lists.newArrayList(); - synchronized (mUidRules) { + synchronized (mRulesLock) { for (NetworkStateTracker tracker : mNetTrackers) { if (tracker != null) { - final NetworkInfo info = filterNetworkInfo(tracker.getNetworkInfo(), uid); + final NetworkInfo info = getFilteredNetworkInfo(tracker, uid); result.add(new NetworkState( info, tracker.getLinkProperties(), tracker.getLinkCapabilities())); } @@ -1139,15 +1150,15 @@ public class ConnectivityService extends IConnectivityManager.Stub { private INetworkPolicyListener mPolicyListener = new INetworkPolicyListener.Stub() { @Override - public void onRulesChanged(int uid, int uidRules) { + public void onUidRulesChanged(int uid, int uidRules) { // only someone like NPMS should only be calling us mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); if (LOGD_RULES) { - Slog.d(TAG, "onRulesChanged(uid=" + uid + ", uidRules=" + uidRules + ")"); + Slog.d(TAG, "onUidRulesChanged(uid=" + uid + ", uidRules=" + uidRules + ")"); } - synchronized (mUidRules) { + synchronized (mRulesLock) { // skip update when we've already applied rules final int oldRules = mUidRules.get(uid, RULE_ALLOW_ALL); if (oldRules == uidRules) return; @@ -1158,6 +1169,24 @@ public class ConnectivityService extends IConnectivityManager.Stub { // TODO: dispatch into NMS to push rules towards kernel module // TODO: notify UID when it has requested targeted updates } + + @Override + public void onMeteredIfacesChanged(String[] meteredIfaces) { + // only someone like NPMS should only be calling us + mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); + + if (LOGD_RULES) { + Slog.d(TAG, + "onMeteredIfacesChanged(ifaces=" + Arrays.toString(meteredIfaces) + ")"); + } + + synchronized (mRulesLock) { + mMeteredIfaces.clear(); + for (String iface : meteredIfaces) { + mMeteredIfaces.add(iface); + } + } + } }; /** diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java index 9cbe82d..43f3c63 100644 --- a/services/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java @@ -29,9 +29,9 @@ import static android.net.NetworkPolicyManager.ACTION_DATA_USAGE_LIMIT; import static android.net.NetworkPolicyManager.ACTION_DATA_USAGE_WARNING; import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE; import static android.net.NetworkPolicyManager.POLICY_NONE; -import static android.net.NetworkPolicyManager.POLICY_REJECT_PAID_BACKGROUND; +import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND; import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL; -import static android.net.NetworkPolicyManager.RULE_REJECT_PAID; +import static android.net.NetworkPolicyManager.RULE_REJECT_METERED; import static android.net.NetworkPolicyManager.computeLastCycleBoundary; import static android.net.NetworkPolicyManager.dumpPolicy; import static android.net.NetworkPolicyManager.dumpRules; @@ -87,6 +87,7 @@ import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.Objects; import com.google.android.collect.Lists; import com.google.android.collect.Maps; +import com.google.android.collect.Sets; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -103,6 +104,7 @@ import java.net.ProtocolException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; +import java.util.HashSet; import libcore.io.IoUtils; @@ -164,6 +166,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { /** Current derived network rules for each UID. */ private SparseIntArray mUidRules = new SparseIntArray(); + /** Set of ifaces that are metered. */ + private HashSet<String> mMeteredIfaces = Sets.newHashSet(); + /** Foreground at both UID and PID granularity. */ private SparseBooleanArray mUidForeground = new SparseBooleanArray(); private SparseArray<SparseBooleanArray> mUidPidForeground = new SparseArray< @@ -536,6 +541,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis() : System.currentTimeMillis(); + mMeteredIfaces.clear(); + // apply each policy that we found ifaces for; compute remaining data // based on current cycle and historical stats, and push to kernel. for (NetworkPolicy policy : rules.keySet()) { @@ -566,8 +573,27 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { // remaining "quota" is based on usage in current cycle final long quota = Math.max(0, policy.limitBytes - total); //kernelSetIfacesQuota(ifaces, quota); + + for (String iface : ifaces) { + mMeteredIfaces.add(iface); + } } } + + // dispatch changed rule to existing listeners + // TODO: dispatch outside of holding lock + final String[] meteredIfaces = mMeteredIfaces.toArray(new String[mMeteredIfaces.size()]); + final int length = mListeners.beginBroadcast(); + for (int i = 0; i < length; i++) { + final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); + if (listener != null) { + try { + listener.onMeteredIfacesChanged(meteredIfaces); + } catch (RemoteException e) { + } + } + } + mListeners.finishBroadcast(); } /** @@ -754,17 +780,29 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { synchronized (mRulesLock) { // dispatch any existing rules to new listeners + // TODO: dispatch outside of holding lock final int size = mUidRules.size(); for (int i = 0; i < size; i++) { final int uid = mUidRules.keyAt(i); final int uidRules = mUidRules.valueAt(i); if (uidRules != RULE_ALLOW_ALL) { try { - listener.onRulesChanged(uid, uidRules); + listener.onUidRulesChanged(uid, uidRules); } catch (RemoteException e) { } } } + + // dispatch any metered ifaces to new listeners + // TODO: dispatch outside of holding lock + if (mMeteredIfaces.size() > 0) { + final String[] meteredIfaces = mMeteredIfaces.toArray( + new String[mMeteredIfaces.size()]); + try { + listener.onMeteredIfacesChanged(meteredIfaces); + } catch (RemoteException e) { + } + } } } @@ -921,9 +959,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { // derive active rules based on policy and active state int uidRules = RULE_ALLOW_ALL; - if (!uidForeground && (uidPolicy & POLICY_REJECT_PAID_BACKGROUND) != 0) { - // uid in background, and policy says to block paid data - uidRules = RULE_REJECT_PAID; + if (!uidForeground && (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0) { + // uid in background, and policy says to block metered data + uidRules = RULE_REJECT_METERED; } // TODO: only dispatch when rules actually change @@ -931,16 +969,17 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { // record rule locally to dispatch to new listeners mUidRules.put(uid, uidRules); - final boolean rejectPaid = (uidRules & RULE_REJECT_PAID) != 0; + final boolean rejectMetered = (uidRules & RULE_REJECT_METERED) != 0; //kernelSetUidRejectPaid(uid, rejectPaid); // dispatch changed rule to existing listeners + // TODO: dispatch outside of holding lock final int length = mListeners.beginBroadcast(); for (int i = 0; i < length; i++) { final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); if (listener != null) { try { - listener.onRulesChanged(uid, uidRules); + listener.onUidRulesChanged(uid, uidRules); } catch (RemoteException e) { } } diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java index edccf6c..5cb1763 100644 --- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java @@ -19,13 +19,14 @@ package com.android.server; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; import static android.net.ConnectivityManager.TYPE_WIFI; import static android.net.NetworkPolicyManager.POLICY_NONE; -import static android.net.NetworkPolicyManager.POLICY_REJECT_PAID_BACKGROUND; +import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND; import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL; -import static android.net.NetworkPolicyManager.RULE_REJECT_PAID; +import static android.net.NetworkPolicyManager.RULE_REJECT_METERED; import static android.net.NetworkPolicyManager.computeLastCycleBoundary; import static android.net.NetworkStats.UID_ALL; import static android.net.TrafficStats.TEMPLATE_WIFI; import static org.easymock.EasyMock.anyInt; +import static org.easymock.EasyMock.aryEq; import static org.easymock.EasyMock.capture; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.eq; @@ -182,7 +183,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { final Future<Intent> backgroundChanged = mServiceContext.nextBroadcastIntent( ConnectivityManager.ACTION_BACKGROUND_DATA_SETTING_CHANGED); - mService.setUidPolicy(UID_A, POLICY_REJECT_PAID_BACKGROUND); + mService.setUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND); backgroundChanged.get(); } @@ -225,12 +226,12 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { expectRulesChanged(UID_A, RULE_ALLOW_ALL); replay(); mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, true); - mService.setUidPolicy(UID_A, POLICY_REJECT_PAID_BACKGROUND); + mService.setUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND); verifyAndReset(); // now turn screen off and verify REJECT rule expect(mPowerManager.isScreenOn()).andReturn(false).atLeastOnce(); - expectRulesChanged(UID_A, RULE_REJECT_PAID); + expectRulesChanged(UID_A, RULE_REJECT_METERED); replay(); mServiceContext.sendBroadcast(new Intent(Intent.ACTION_SCREEN_OFF)); verifyAndReset(); @@ -260,9 +261,9 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { public void testPolicyReject() throws Exception { // POLICY_REJECT should RULE_ALLOW in background - expectRulesChanged(UID_A, RULE_REJECT_PAID); + expectRulesChanged(UID_A, RULE_REJECT_METERED); replay(); - mService.setUidPolicy(UID_A, POLICY_REJECT_PAID_BACKGROUND); + mService.setUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND); verifyAndReset(); // POLICY_REJECT should RULE_ALLOW in foreground @@ -272,7 +273,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { verifyAndReset(); // POLICY_REJECT should RULE_REJECT in background - expectRulesChanged(UID_A, RULE_REJECT_PAID); + expectRulesChanged(UID_A, RULE_REJECT_METERED); replay(); mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, false); verifyAndReset(); @@ -287,9 +288,9 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { verifyAndReset(); // adding POLICY_REJECT should cause RULE_REJECT - expectRulesChanged(UID_A, RULE_REJECT_PAID); + expectRulesChanged(UID_A, RULE_REJECT_METERED); replay(); - mService.setUidPolicy(UID_A, POLICY_REJECT_PAID_BACKGROUND); + mService.setUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND); verifyAndReset(); // removing POLICY_REJECT should return us to RULE_ALLOW @@ -353,6 +354,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { state = new NetworkState[] { buildWifi() }; expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce(); expectTime(TIME_MAR_10 + elapsedRealtime); + expectMeteredIfacesChanged(); replay(); mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION)); @@ -373,6 +375,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { // TODO: write up NetworkManagementService mock expectClearNotifications(); + expectMeteredIfacesChanged(TEST_IFACE); replay(); setNetworkPolicies(new NetworkPolicy(TEMPLATE_WIFI, null, CYCLE_DAY, 1024L, 2048L)); @@ -411,7 +414,12 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { } private void expectRulesChanged(int uid, int policy) throws Exception { - mPolicyListener.onRulesChanged(eq(uid), eq(policy)); + mPolicyListener.onUidRulesChanged(eq(uid), eq(policy)); + expectLastCall().atLeastOnce(); + } + + private void expectMeteredIfacesChanged(String... ifaces) throws Exception { + mPolicyListener.onMeteredIfacesChanged(aryEq(ifaces)); expectLastCall().atLeastOnce(); } |