Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 27c751dc authored by Jeff Sharkey's avatar Jeff Sharkey Committed by Android (Google) Code Review
Browse files

Merge "Restrict app data on metered networks."

parents 24ef465d f60d0afd
Loading
Loading
Loading
Loading
+11 −6
Original line number Diff line number Diff line
@@ -39,16 +39,18 @@ public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> {
    public long warningBytes;
    public long limitBytes;
    public long lastSnooze;
    public boolean metered;

    private static final long DEFAULT_MTU = 1500;

    public NetworkPolicy(NetworkTemplate template, int cycleDay, long warningBytes, long limitBytes,
            long lastSnooze) {
            long lastSnooze, boolean metered) {
        this.template = checkNotNull(template, "missing NetworkTemplate");
        this.cycleDay = cycleDay;
        this.warningBytes = warningBytes;
        this.limitBytes = limitBytes;
        this.lastSnooze = lastSnooze;
        this.metered = metered;
    }

    public NetworkPolicy(Parcel in) {
@@ -57,6 +59,7 @@ public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> {
        warningBytes = in.readLong();
        limitBytes = in.readLong();
        lastSnooze = in.readLong();
        metered = in.readInt() != 0;
    }

    /** {@inheritDoc} */
@@ -66,6 +69,7 @@ public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> {
        dest.writeLong(warningBytes);
        dest.writeLong(limitBytes);
        dest.writeLong(lastSnooze);
        dest.writeInt(metered ? 1 : 0);
    }

    /** {@inheritDoc} */
@@ -99,16 +103,16 @@ public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> {

    @Override
    public int hashCode() {
        return Objects.hashCode(template, cycleDay, warningBytes, limitBytes, lastSnooze);
        return Objects.hashCode(template, cycleDay, warningBytes, limitBytes, lastSnooze, metered);
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof NetworkPolicy) {
            final NetworkPolicy other = (NetworkPolicy) obj;
            return Objects.equal(template, other.template) && cycleDay == other.cycleDay
                    && warningBytes == other.warningBytes && limitBytes == other.limitBytes
                    && lastSnooze == other.lastSnooze;
            return cycleDay == other.cycleDay && warningBytes == other.warningBytes
                    && limitBytes == other.limitBytes && lastSnooze == other.lastSnooze
                    && metered == other.metered && Objects.equal(template, other.template);
        }
        return false;
    }
@@ -116,7 +120,8 @@ public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> {
    @Override
    public String toString() {
        return "NetworkPolicy[" + template + "]: cycleDay=" + cycleDay + ", warningBytes="
                + warningBytes + ", limitBytes=" + limitBytes + ", lastSnooze=" + lastSnooze;
                + warningBytes + ", limitBytes=" + limitBytes + ", lastSnooze=" + lastSnooze
                + ", metered=" + metered;
    }

    public static final Creator<NetworkPolicy> CREATOR = new Creator<NetworkPolicy>() {
+26 −5
Original line number Diff line number Diff line
@@ -153,6 +153,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
    private static final int VERSION_INIT = 1;
    private static final int VERSION_ADDED_SNOOZE = 2;
    private static final int VERSION_ADDED_RESTRICT_BACKGROUND = 3;
    private static final int VERSION_ADDED_METERED = 4;

    private static final long KB_IN_BYTES = 1024;
    private static final long MB_IN_BYTES = KB_IN_BYTES * 1024;
@@ -175,6 +176,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
    private static final String ATTR_WARNING_BYTES = "warningBytes";
    private static final String ATTR_LIMIT_BYTES = "limitBytes";
    private static final String ATTR_LAST_SNOOZE = "lastSnooze";
    private static final String ATTR_METERED = "metered";
    private static final String ATTR_UID = "uid";
    private static final String ATTR_POLICY = "policy";

@@ -819,9 +821,13 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
            }

            final boolean hasLimit = policy.limitBytes != LIMIT_DISABLED;
            if (hasLimit) {
            if (hasLimit || policy.metered) {
                final long quotaBytes;
                if (policy.lastSnooze >= start) {
                if (!hasLimit) {
                    // metered network, but no policy limit; we still need to
                    // restrict apps, so push really high quota.
                    quotaBytes = Long.MAX_VALUE;
                } else if (policy.lastSnooze >= start) {
                    // snoozing past quota, but we still need to restrict apps,
                    // so push really high quota.
                    quotaBytes = Long.MAX_VALUE;
@@ -891,7 +897,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {

            final NetworkTemplate template = buildTemplateMobileAll(subscriberId);
            mNetworkPolicy.put(template, new NetworkPolicy(
                    template, cycleDay, warningBytes, LIMIT_DISABLED, SNOOZE_NEVER));
                    template, cycleDay, warningBytes, LIMIT_DISABLED, SNOOZE_NEVER, true));
            writePolicyLocked();
        }
    }
@@ -935,11 +941,25 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
                        } else {
                            lastSnooze = SNOOZE_NEVER;
                        }
                        final boolean metered;
                        if (version >= VERSION_ADDED_METERED) {
                            metered = readBooleanAttribute(in, ATTR_METERED);
                        } else {
                            switch (networkTemplate) {
                                case MATCH_MOBILE_3G_LOWER:
                                case MATCH_MOBILE_4G:
                                case MATCH_MOBILE_ALL:
                                    metered = true;
                                    break;
                                default:
                                    metered = false;
                            }
                        }

                        final NetworkTemplate template = new NetworkTemplate(
                                networkTemplate, subscriberId);
                        mNetworkPolicy.put(template, new NetworkPolicy(
                                template, cycleDay, warningBytes, limitBytes, lastSnooze));
                                template, cycleDay, warningBytes, limitBytes, lastSnooze, metered));

                    } else if (TAG_UID_POLICY.equals(tag)) {
                        final int uid = readIntAttribute(in, ATTR_UID);
@@ -994,7 +1014,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
            out.startDocument(null, true);

            out.startTag(null, TAG_POLICY_LIST);
            writeIntAttribute(out, ATTR_VERSION, VERSION_ADDED_RESTRICT_BACKGROUND);
            writeIntAttribute(out, ATTR_VERSION, VERSION_ADDED_METERED);
            writeBooleanAttribute(out, ATTR_RESTRICT_BACKGROUND, mRestrictBackground);

            // write all known network policies
@@ -1011,6 +1031,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
                writeLongAttribute(out, ATTR_WARNING_BYTES, policy.warningBytes);
                writeLongAttribute(out, ATTR_LIMIT_BYTES, policy.limitBytes);
                writeLongAttribute(out, ATTR_LAST_SNOOZE, policy.lastSnooze);
                writeBooleanAttribute(out, ATTR_METERED, policy.metered);
                out.endTag(null, TAG_NETWORK_POLICY);
            }

+49 −9
Original line number Diff line number Diff line
@@ -434,7 +434,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
        final long expectedCycle = parseTime("2007-11-05T00:00:00.000Z");

        final NetworkPolicy policy = new NetworkPolicy(
                sTemplateWifi, 5, 1024L, 1024L, SNOOZE_NEVER);
                sTemplateWifi, 5, 1024L, 1024L, SNOOZE_NEVER, false);
        final long actualCycle = computeLastCycleBoundary(currentTime, policy);
        assertTimeEquals(expectedCycle, actualCycle);
    }
@@ -445,7 +445,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
        final long expectedCycle = parseTime("2007-10-20T00:00:00.000Z");

        final NetworkPolicy policy = new NetworkPolicy(
                sTemplateWifi, 20, 1024L, 1024L, SNOOZE_NEVER);
                sTemplateWifi, 20, 1024L, 1024L, SNOOZE_NEVER, false);
        final long actualCycle = computeLastCycleBoundary(currentTime, policy);
        assertTimeEquals(expectedCycle, actualCycle);
    }
@@ -456,7 +456,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
        final long expectedCycle = parseTime("2007-01-30T00:00:00.000Z");

        final NetworkPolicy policy = new NetworkPolicy(
                sTemplateWifi, 30, 1024L, 1024L, SNOOZE_NEVER);
                sTemplateWifi, 30, 1024L, 1024L, SNOOZE_NEVER, false);
        final long actualCycle = computeLastCycleBoundary(currentTime, policy);
        assertTimeEquals(expectedCycle, actualCycle);
    }
@@ -467,14 +467,14 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
        final long expectedCycle = parseTime("2007-02-28T23:59:59.000Z");

        final NetworkPolicy policy = new NetworkPolicy(
                sTemplateWifi, 30, 1024L, 1024L, SNOOZE_NEVER);
                sTemplateWifi, 30, 1024L, 1024L, SNOOZE_NEVER, false);
        final long actualCycle = computeLastCycleBoundary(currentTime, policy);
        assertTimeEquals(expectedCycle, actualCycle);
    }

    public void testNextCycleSane() throws Exception {
        final NetworkPolicy policy = new NetworkPolicy(
                sTemplateWifi, 31, WARNING_DISABLED, LIMIT_DISABLED, SNOOZE_NEVER);
                sTemplateWifi, 31, WARNING_DISABLED, LIMIT_DISABLED, SNOOZE_NEVER, false);
        final LinkedHashSet<Long> seen = new LinkedHashSet<Long>();

        // walk forwards, ensuring that cycle boundaries don't get stuck
@@ -489,7 +489,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {

    public void testLastCycleSane() throws Exception {
        final NetworkPolicy policy = new NetworkPolicy(
                sTemplateWifi, 31, WARNING_DISABLED, LIMIT_DISABLED, SNOOZE_NEVER);
                sTemplateWifi, 31, WARNING_DISABLED, LIMIT_DISABLED, SNOOZE_NEVER, false);
        final LinkedHashSet<Long> seen = new LinkedHashSet<Long>();

        // walk backwards, ensuring that cycle boundaries look sane
@@ -547,7 +547,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {

        replay();
        setNetworkPolicies(new NetworkPolicy(
                sTemplateWifi, CYCLE_DAY, 1 * MB_IN_BYTES, 2 * MB_IN_BYTES, SNOOZE_NEVER));
                sTemplateWifi, CYCLE_DAY, 1 * MB_IN_BYTES, 2 * MB_IN_BYTES, SNOOZE_NEVER, false));
        future.get();
        verifyAndReset();
    }
@@ -604,8 +604,9 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
            future = expectMeteredIfacesChanged();

            replay();
            setNetworkPolicies(new NetworkPolicy(
                    sTemplateWifi, CYCLE_DAY, 1 * MB_IN_BYTES, 2 * MB_IN_BYTES, SNOOZE_NEVER));
            setNetworkPolicies(
                    new NetworkPolicy(sTemplateWifi, CYCLE_DAY, 1 * MB_IN_BYTES, 2 * MB_IN_BYTES,
                            SNOOZE_NEVER, false));
            future.get();
            verifyAndReset();
        }
@@ -704,6 +705,45 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
        }
    }

    public void testMeteredNetworkWithoutLimit() throws Exception {
        NetworkState[] state = null;
        NetworkStats stats = null;
        Future<Void> future;
        Future<String> tagFuture;

        final long TIME_FEB_15 = 1171497600000L;
        final long TIME_MAR_10 = 1173484800000L;
        final int CYCLE_DAY = 15;

        setCurrentTimeMillis(TIME_MAR_10);

        // bring up wifi network with metered policy
        state = new NetworkState[] { buildWifi() };
        stats = new NetworkStats(getElapsedRealtime(), 1)
                .addIfaceValues(TEST_IFACE, 0L, 0L, 0L, 0L);

        {
            expectCurrentTime();
            expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce();
            expect(mStatsService.getSummaryForNetwork(sTemplateWifi, TIME_FEB_15, currentTimeMillis()))
                    .andReturn(stats).atLeastOnce();
            expectPolicyDataEnable(TYPE_WIFI, true);

            expectRemoveInterfaceQuota(TEST_IFACE);
            expectSetInterfaceQuota(TEST_IFACE, Long.MAX_VALUE);

            expectClearNotifications();
            future = expectMeteredIfacesChanged(TEST_IFACE);

            replay();
            setNetworkPolicies(
                    new NetworkPolicy(sTemplateWifi, CYCLE_DAY, WARNING_DISABLED, LIMIT_DISABLED,
                            SNOOZE_NEVER, true));
            future.get();
            verifyAndReset();
        }
    }

    private static long parseTime(String time) {
        final Time result = new Time();
        result.parse3339(time);
+2 −0
Original line number Diff line number Diff line
@@ -802,6 +802,8 @@ public class NetworkStatsServiceTest extends AndroidTestCase {

        mNetManager.setGlobalAlert(anyLong());
        expectLastCall().atLeastOnce();

        expect(mNetManager.isBandwidthControlEnabled()).andReturn(true).atLeastOnce();
    }

    private void expectNetworkState(NetworkState... state) throws Exception {