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

Commit 8fc27e8b authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Support metered Wi-Fi NetworkPolicy.

Add networkId field to NetworkIdentity to identify Wi-Fi networks by
SSID.  Add support for policies without usage cycles.

Only apply mobile policies when SIM state is ready, which is cleaner
than just checking for airplane mode.  Also avoids creating no-op
default policies when subscriberId is null.

Bug: 3001465, 3291052
Change-Id: I1f8aaa49a5db306df022c402ea7f3f5d4bc0cfc7
parent 1c35d117
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -1097,6 +1097,18 @@ public class DownloadManager {
        }
    }

    /** {@hide} */
    public static boolean isActiveNetworkExpensive(Context context) {
        // TODO: connect to NetworkPolicyManager
        return false;
    }

    /** {@hide} */
    public static long getActiveNetworkWarningBytes(Context context) {
        // TODO: connect to NetworkPolicyManager
        return -1;
    }

    /**
     * Adds a file to the downloads database system, so it could appear in Downloads App
     * (and thus become eligible for management by the Downloads App).
+6 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import static com.android.internal.util.Preconditions.checkNotNull;

import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.content.Context;
import android.os.Binder;
import android.os.Build.VERSION_CODES;
import android.os.RemoteException;
@@ -610,6 +611,11 @@ public class ConnectivityManager {
        mService = checkNotNull(service, "missing IConnectivityManager");
    }

    /** {@hide} */
    public static ConnectivityManager from(Context context) {
        return (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    }

    /**
     * {@hide}
     */
+50 −24
Original line number Diff line number Diff line
@@ -16,9 +16,13 @@

package android.net;

import static android.net.ConnectivityManager.TYPE_WIFI;
import static android.net.ConnectivityManager.getNetworkTypeName;
import static android.net.ConnectivityManager.isNetworkTypeMobile;

import android.content.Context;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.telephony.TelephonyManager;

@@ -42,18 +46,21 @@ public class NetworkIdentity {
    final int mType;
    final int mSubType;
    final String mSubscriberId;
    final String mNetworkId;
    final boolean mRoaming;

    public NetworkIdentity(int type, int subType, String subscriberId, boolean roaming) {
        this.mType = type;
        this.mSubType = COMBINE_SUBTYPE_ENABLED ? SUBTYPE_COMBINED : subType;
        this.mSubscriberId = subscriberId;
        this.mRoaming = roaming;
    public NetworkIdentity(
            int type, int subType, String subscriberId, String networkId, boolean roaming) {
        mType = type;
        mSubType = COMBINE_SUBTYPE_ENABLED ? SUBTYPE_COMBINED : subType;
        mSubscriberId = subscriberId;
        mNetworkId = networkId;
        mRoaming = roaming;
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(mType, mSubType, mSubscriberId, mRoaming);
        return Objects.hashCode(mType, mSubType, mSubscriberId, mNetworkId, mRoaming);
    }

    @Override
@@ -61,27 +68,34 @@ public class NetworkIdentity {
        if (obj instanceof NetworkIdentity) {
            final NetworkIdentity ident = (NetworkIdentity) obj;
            return mType == ident.mType && mSubType == ident.mSubType && mRoaming == ident.mRoaming
                    && Objects.equal(mSubscriberId, ident.mSubscriberId);
                    && Objects.equal(mSubscriberId, ident.mSubscriberId)
                    && Objects.equal(mNetworkId, ident.mNetworkId);
        }
        return false;
    }

    @Override
    public String toString() {
        final String typeName = ConnectivityManager.getNetworkTypeName(mType);
        final String subTypeName;
        final StringBuilder builder = new StringBuilder("[");
        builder.append("type=").append(getNetworkTypeName(mType));
        builder.append(", subType=");
        if (COMBINE_SUBTYPE_ENABLED) {
            subTypeName = "COMBINED";
            builder.append("COMBINED");
        } else if (ConnectivityManager.isNetworkTypeMobile(mType)) {
            subTypeName = TelephonyManager.getNetworkTypeName(mSubType);
            builder.append(TelephonyManager.getNetworkTypeName(mSubType));
        } else {
            subTypeName = Integer.toString(mSubType);
            builder.append(mSubType);
        }

        final String scrubSubscriberId = scrubSubscriberId(mSubscriberId);
        final String roaming = mRoaming ? ", ROAMING" : "";
        return "[type=" + typeName + ", subType=" + subTypeName + ", subscriberId="
                + scrubSubscriberId + roaming + "]";
        if (mSubscriberId != null) {
            builder.append(", subscriberId=").append(scrubSubscriberId(mSubscriberId));
        }
        if (mNetworkId != null) {
            builder.append(", networkId=").append(mNetworkId);
        }
        if (mRoaming) {
            builder.append(", ROAMING");
        }
        return builder.append("]").toString();
    }

    public int getType() {
@@ -96,6 +110,10 @@ public class NetworkIdentity {
        return mSubscriberId;
    }

    public String getNetworkId() {
        return mNetworkId;
    }

    public boolean getRoaming() {
        return mRoaming;
    }
@@ -106,8 +124,11 @@ public class NetworkIdentity {
    public static String scrubSubscriberId(String subscriberId) {
        if ("eng".equals(Build.TYPE)) {
            return subscriberId;
        } else if (subscriberId != null) {
            // TODO: parse this as MCC+MNC instead of hard-coding
            return subscriberId.substring(0, Math.min(6, subscriberId.length())) + "...";
        } else {
            return subscriberId != null ? "valid" : "null";
            return "null";
        }
    }

@@ -122,8 +143,10 @@ public class NetworkIdentity {
        // TODO: consider moving subscriberId over to LinkCapabilities, so it
        // comes from an authoritative source.

        final String subscriberId;
        final boolean roaming;
        String subscriberId = null;
        String networkId = null;
        boolean roaming = false;

        if (isNetworkTypeMobile(type)) {
            final TelephonyManager telephony = (TelephonyManager) context.getSystemService(
                    Context.TELEPHONY_SERVICE);
@@ -133,10 +156,13 @@ public class NetworkIdentity {
            } else {
                subscriberId = telephony.getSubscriberId();
            }
        } else {
            subscriberId = null;
            roaming = false;

        } else if (type == TYPE_WIFI) {
            final WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
            final WifiInfo info = wifi.getConnectionInfo();
            networkId = info != null ? info.getSSID() : null;
        }
        return new NetworkIdentity(type, subType, subscriberId, roaming);

        return new NetworkIdentity(type, subType, subscriberId, networkId, roaming);
    }
}
+19 −4
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import com.android.internal.util.Objects;
 * @hide
 */
public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> {
    public static final int CYCLE_NONE = -1;
    public static final long WARNING_DISABLED = -1;
    public static final long LIMIT_DISABLED = -1;
    public static final long SNOOZE_NEVER = -1;
@@ -123,6 +124,13 @@ public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> {
        lastLimitSnooze = SNOOZE_NEVER;
    }

    /**
     * Test if this policy has a cycle defined, after which usage should reset.
     */
    public boolean hasCycle() {
        return cycleDay != CYCLE_NONE;
    }

    @Override
    public int compareTo(NetworkPolicy another) {
        if (another == null || another.limitBytes == LIMIT_DISABLED) {
@@ -159,10 +167,17 @@ public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> {

    @Override
    public String toString() {
        return "NetworkPolicy[" + template + "]: cycleDay=" + cycleDay + ", cycleTimezone="
                + cycleTimezone + ", warningBytes=" + warningBytes + ", limitBytes=" + limitBytes
                + ", lastWarningSnooze=" + lastWarningSnooze + ", lastLimitSnooze="
                + lastLimitSnooze + ", metered=" + metered + ", inferred=" + inferred;
        final StringBuilder builder = new StringBuilder("NetworkPolicy");
        builder.append("[").append(template).append("]:");
        builder.append(" cycleDay=").append(cycleDay);
        builder.append(", cycleTimezone=").append(cycleTimezone);
        builder.append(", warningBytes=").append(warningBytes);
        builder.append(", limitBytes=").append(limitBytes);
        builder.append(", lastWarningSnooze=").append(lastWarningSnooze);
        builder.append(", lastLimitSnooze=").append(lastLimitSnooze);
        builder.append(", metered=").append(metered);
        builder.append(", inferred=").append(inferred);
        return builder.toString();
    }

    public static final Creator<NetworkPolicy> CREATOR = new Creator<NetworkPolicy>() {
+40 −18
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package android.net;

import static android.content.pm.PackageManager.GET_SIGNATURES;
import static android.net.NetworkPolicy.CYCLE_NONE;
import static android.text.format.Time.MONTH_DAY;

import android.content.Context;
@@ -66,27 +67,10 @@ public class NetworkPolicyManager {
        mService = service;
    }

    public static NetworkPolicyManager getSystemService(Context context) {
    public static NetworkPolicyManager from(Context context) {
        return (NetworkPolicyManager) context.getSystemService(Context.NETWORK_POLICY_SERVICE);
    }

    /** {@hide} */
    public void setNetworkPolicies(NetworkPolicy[] policies) {
        try {
            mService.setNetworkPolicies(policies);
        } catch (RemoteException e) {
        }
    }

    /** {@hide} */
    public NetworkPolicy[] getNetworkPolicies() {
        try {
            return mService.getNetworkPolicies();
        } catch (RemoteException e) {
            return null;
        }
    }

    /**
     * Set policy flags for specific application.
     *
@@ -122,6 +106,36 @@ public class NetworkPolicyManager {
        }
    }

    public void setNetworkPolicies(NetworkPolicy[] policies) {
        try {
            mService.setNetworkPolicies(policies);
        } catch (RemoteException e) {
        }
    }

    public NetworkPolicy[] getNetworkPolicies() {
        try {
            return mService.getNetworkPolicies();
        } catch (RemoteException e) {
            return null;
        }
    }

    public void setRestrictBackground(boolean restrictBackground) {
        try {
            mService.setRestrictBackground(restrictBackground);
        } catch (RemoteException e) {
        }
    }

    public boolean getRestrictBackground() {
        try {
            return mService.getRestrictBackground();
        } catch (RemoteException e) {
            return false;
        }
    }

    /**
     * Compute the last cycle boundary for the given {@link NetworkPolicy}. For
     * example, if cycle day is 20th, and today is June 15th, it will return May
@@ -131,6 +145,10 @@ public class NetworkPolicyManager {
     * @hide
     */
    public static long computeLastCycleBoundary(long currentTime, NetworkPolicy policy) {
        if (policy.cycleDay == CYCLE_NONE) {
            throw new IllegalArgumentException("Unable to compute boundary without cycleDay");
        }

        final Time now = new Time(policy.cycleTimezone);
        now.set(currentTime);

@@ -157,6 +175,10 @@ public class NetworkPolicyManager {

    /** {@hide} */
    public static long computeNextCycleBoundary(long currentTime, NetworkPolicy policy) {
        if (policy.cycleDay == CYCLE_NONE) {
            throw new IllegalArgumentException("Unable to compute boundary without cycleDay");
        }

        final Time now = new Time(policy.cycleTimezone);
        now.set(currentTime);

Loading