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

Commit 68f24bba authored by Lorenzo Colitti's avatar Lorenzo Colitti Committed by Automerger Merge Worker
Browse files

Merge changes from topic "blocked-reasons-callback-tests" am: 2108a924 am:...

Merge changes from topic "blocked-reasons-callback-tests" am: 2108a924 am: 6456359a am: 8afa9811 am: 58ee2621

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1652214

Change-Id: I87769a17f14e2db5a62317c20c9a292aa0b04062
parents 72c909d0 58ee2621
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.net;

import static android.app.ActivityManager.procStateToString;
import static android.content.pm.PackageManager.GET_SIGNATURES;
import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_MASK;
import static android.net.ConnectivityManager.BLOCKED_REASON_NONE;

import android.annotation.IntDef;
@@ -204,9 +205,6 @@ public class NetworkPolicyManager {
    })
    public @interface SubscriptionOverrideMask {}

    /** @hide */
    public static final int BLOCKED_METERED_REASON_MASK = 0xffff0000;

    /**
     * Flag to indicate that app is not exempt from any network restrictions.
     *
+6 −0
Original line number Diff line number Diff line
@@ -31,10 +31,12 @@ package android.net {
    field public static final String ACTION_PROMPT_UNVALIDATED = "android.net.action.PROMPT_UNVALIDATED";
    field public static final int BLOCKED_METERED_REASON_ADMIN_DISABLED = 262144; // 0x40000
    field public static final int BLOCKED_METERED_REASON_DATA_SAVER = 65536; // 0x10000
    field public static final int BLOCKED_METERED_REASON_MASK = -65536; // 0xffff0000
    field public static final int BLOCKED_METERED_REASON_USER_RESTRICTED = 131072; // 0x20000
    field public static final int BLOCKED_REASON_APP_STANDBY = 4; // 0x4
    field public static final int BLOCKED_REASON_BATTERY_SAVER = 1; // 0x1
    field public static final int BLOCKED_REASON_DOZE = 2; // 0x2
    field public static final int BLOCKED_REASON_LOCKDOWN_VPN = 16; // 0x10
    field public static final int BLOCKED_REASON_NONE = 0; // 0x0
    field public static final int BLOCKED_REASON_RESTRICTED_MODE = 8; // 0x8
    field public static final String PRIVATE_DNS_MODE_OFF = "off";
@@ -44,6 +46,10 @@ package android.net {
    field public static final int PROFILE_NETWORK_PREFERENCE_ENTERPRISE = 1; // 0x1
  }

  public static class ConnectivityManager.NetworkCallback {
    method public void onBlockedStatusChanged(@NonNull android.net.Network, int);
  }

  public class ConnectivitySettingsManager {
    method public static void clearGlobalProxy(@NonNull android.content.Context);
    method @Nullable public static String getCaptivePortalHttpUrl(@NonNull android.content.Context);
+64 −6
Original line number Diff line number Diff line
@@ -38,7 +38,9 @@ import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.app.PendingIntent;
import android.app.admin.DevicePolicyManager;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
@@ -874,6 +876,17 @@ public class ConnectivityManager {
    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
    public static final int BLOCKED_REASON_RESTRICTED_MODE = 1 << 3;

    /**
     * Flag to indicate that an app is blocked because it is subject to an always-on VPN but the VPN
     * is not currently connected.
     *
     * @see DevicePolicyManager#setAlwaysOnVpnPackage(ComponentName, String, boolean)
     *
     * @hide
     */
    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
    public static final int BLOCKED_REASON_LOCKDOWN_VPN = 1 << 4;

    /**
     * Flag to indicate that an app is subject to Data saver restrictions that would
     * result in its metered network access being blocked.
@@ -917,6 +930,14 @@ public class ConnectivityManager {
    })
    public @interface BlockedReason {}

    /**
     * Set of blocked reasons that are only applicable on metered networks.
     *
     * @hide
     */
    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
    public static final int BLOCKED_METERED_REASON_MASK = 0xffff0000;

    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562)
    private final IConnectivityManager mService;

@@ -3498,12 +3519,30 @@ public class ConnectivityManager {
         * @param blocked Whether access to the {@link Network} is blocked due to system policy.
         * @hide
         */
        public void onAvailable(@NonNull Network network,
        public final void onAvailable(@NonNull Network network,
                @NonNull NetworkCapabilities networkCapabilities,
                @NonNull LinkProperties linkProperties, boolean blocked) {
                @NonNull LinkProperties linkProperties, @BlockedReason int blocked) {
            // Internally only this method is called when a new network is available, and
            // it calls the callback in the same way and order that older versions used
            // to call so as not to change the behavior.
            onAvailable(network, networkCapabilities, linkProperties, blocked != 0);
            onBlockedStatusChanged(network, blocked);
        }

        /**
         * Legacy variant of onAvailable that takes a boolean blocked reason.
         *
         * This method has never been public API, but it's not final, so there may be apps that
         * implemented it and rely on it being called. Do our best not to break them.
         * Note: such apps will also get a second call to onBlockedStatusChanged immediately after
         * this method is called. There does not seem to be a way to avoid this.
         * TODO: add a compat check to move apps off this method, and eventually stop calling it.
         *
         * @hide
         */
        public void onAvailable(@NonNull Network network,
                @NonNull NetworkCapabilities networkCapabilities,
                @NonNull LinkProperties linkProperties, boolean blocked) {
            onAvailable(network);
            if (!networkCapabilities.hasCapability(
                    NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED)) {
@@ -3511,7 +3550,7 @@ public class ConnectivityManager {
            }
            onCapabilitiesChanged(network, networkCapabilities);
            onLinkPropertiesChanged(network, linkProperties);
            onBlockedStatusChanged(network, blocked);
            // No call to onBlockedStatusChanged here. That is done by the caller.
        }

        /**
@@ -3675,6 +3714,26 @@ public class ConnectivityManager {
         */
        public void onBlockedStatusChanged(@NonNull Network network, boolean blocked) {}

        /**
         * Called when access to the specified network is blocked or unblocked.
         *
         * If a NetworkCallback object implements this method,
         * {@link #onBlockedStatusChanged(Network, boolean)} will not be called.
         *
         * <p>Do NOT call {@link #getNetworkCapabilities(Network)} or
         * {@link #getLinkProperties(Network)} or other synchronous ConnectivityManager methods in
         * this callback as this is prone to race conditions : calling these methods while in a
         * callback may return an outdated or even a null object.
         *
         * @param network The {@link Network} whose blocked status has changed.
         * @param blocked The blocked status of this {@link Network}.
         * @hide
         */
        @SystemApi(client = MODULE_LIBRARIES)
        public void onBlockedStatusChanged(@NonNull Network network, @BlockedReason int blocked) {
            onBlockedStatusChanged(network, blocked != 0);
        }

        private NetworkRequest networkRequest;
        private final int mFlags;
    }
@@ -3789,7 +3848,7 @@ public class ConnectivityManager {
                case CALLBACK_AVAILABLE: {
                    NetworkCapabilities cap = getObject(message, NetworkCapabilities.class);
                    LinkProperties lp = getObject(message, LinkProperties.class);
                    callback.onAvailable(network, cap, lp, message.arg1 != 0);
                    callback.onAvailable(network, cap, lp, message.arg1);
                    break;
                }
                case CALLBACK_LOSING: {
@@ -3823,8 +3882,7 @@ public class ConnectivityManager {
                    break;
                }
                case CALLBACK_BLK_CHANGED: {
                    boolean blocked = message.arg1 != 0;
                    callback.onBlockedStatusChanged(network, blocked);
                    callback.onBlockedStatusChanged(network, message.arg1);
                }
            }
        }
+43 −29
Original line number Diff line number Diff line
@@ -29,6 +29,8 @@ import static android.net.ConnectivityDiagnosticsManager.DataStallReport.DETECTI
import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_DNS_CONSECUTIVE_TIMEOUTS;
import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS;
import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_TCP_PACKET_FAIL_RATE;
import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_MASK;
import static android.net.ConnectivityManager.BLOCKED_REASON_LOCKDOWN_VPN;
import static android.net.ConnectivityManager.BLOCKED_REASON_NONE;
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
@@ -106,6 +108,7 @@ import android.net.ConnectionInfo;
import android.net.ConnectivityDiagnosticsManager.ConnectivityReport;
import android.net.ConnectivityDiagnosticsManager.DataStallReport;
import android.net.ConnectivityManager;
import android.net.ConnectivityManager.BlockedReason;
import android.net.ConnectivityManager.NetworkCallback;
import android.net.ConnectivityManager.RestrictBackgroundStatus;
import android.net.ConnectivityResources;
@@ -2357,15 +2360,15 @@ public class ConnectivityService extends IConnectivityManager.Stub

    private final NetworkPolicyCallback mPolicyCallback = new NetworkPolicyCallback() {
        @Override
        public void onUidBlockedReasonChanged(int uid, int blockedReasons) {
        public void onUidBlockedReasonChanged(int uid, @BlockedReason int blockedReasons) {
            mHandler.sendMessage(mHandler.obtainMessage(EVENT_UID_BLOCKED_REASON_CHANGED,
                    uid, blockedReasons));
        }
    };

    void handleUidBlockedReasonChanged(int uid, int blockedReasons) {
    private void handleUidBlockedReasonChanged(int uid, @BlockedReason int blockedReasons) {
        maybeNotifyNetworkBlockedForNewState(uid, blockedReasons);
        mUidBlockedReasons.put(uid, blockedReasons);
        setUidBlockedReasons(uid, blockedReasons);
    }

    private boolean checkAnyPermissionOf(String... permissions) {
@@ -8190,12 +8193,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
            return;
        }

        final int blockedReasons = mUidBlockedReasons.get(nri.mAsUid, BLOCKED_REASON_NONE);
        final boolean metered = nai.networkCapabilities.isMetered();
        boolean blocked;
        blocked = isUidBlockedByVpn(nri.mAsUid, mVpnBlockedUidRanges);
        blocked |= NetworkPolicyManager.isUidBlocked(
                mUidBlockedReasons.get(nri.mAsUid, BLOCKED_REASON_NONE), metered);
        callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE, blocked ? 1 : 0);
        final boolean vpnBlocked = isUidBlockedByVpn(nri.mAsUid, mVpnBlockedUidRanges);
        callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE,
                getBlockedState(blockedReasons, metered, vpnBlocked));
    }

    // Notify the requests on this NAI that the network is now lingered.
@@ -8204,6 +8206,21 @@ public class ConnectivityService extends IConnectivityManager.Stub
        notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOSING, lingerTime);
    }

    private static int getBlockedState(int reasons, boolean metered, boolean vpnBlocked) {
        if (!metered) reasons &= ~BLOCKED_METERED_REASON_MASK;
        return vpnBlocked
                ? reasons | BLOCKED_REASON_LOCKDOWN_VPN
                : reasons & ~BLOCKED_REASON_LOCKDOWN_VPN;
    }

    private void setUidBlockedReasons(int uid, @BlockedReason int blockedReasons) {
        if (blockedReasons == BLOCKED_REASON_NONE) {
            mUidBlockedReasons.delete(uid);
        } else {
            mUidBlockedReasons.put(uid, blockedReasons);
        }
    }

    /**
     * Notify of the blocked state apps with a registered callback matching a given NAI.
     *
@@ -8211,7 +8228,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
     * any given nai, all requests need to be considered according to the uid who filed it.
     *
     * @param nai The target NetworkAgentInfo.
     * @param oldMetered True if the previous network capabilities is metered.
     * @param oldMetered True if the previous network capabilities were metered.
     * @param newMetered True if the current network capabilities are metered.
     * @param oldBlockedUidRanges list of UID ranges previously blocked by lockdown VPN.
     * @param newBlockedUidRanges list of UID ranges blocked by lockdown VPN.
     */
    private void maybeNotifyNetworkBlocked(NetworkAgentInfo nai, boolean oldMetered,
            boolean newMetered, List<UidRange> oldBlockedUidRanges,
@@ -8220,22 +8240,18 @@ public class ConnectivityService extends IConnectivityManager.Stub
        for (int i = 0; i < nai.numNetworkRequests(); i++) {
            NetworkRequest nr = nai.requestAt(i);
            NetworkRequestInfo nri = mNetworkRequests.get(nr);
            final boolean oldBlocked, newBlocked, oldVpnBlocked, newVpnBlocked;

            oldVpnBlocked = isUidBlockedByVpn(nri.mAsUid, oldBlockedUidRanges);
            newVpnBlocked = (oldBlockedUidRanges != newBlockedUidRanges)
            final int blockedReasons = mUidBlockedReasons.get(nri.mAsUid, BLOCKED_REASON_NONE);
            final boolean oldVpnBlocked = isUidBlockedByVpn(nri.mAsUid, oldBlockedUidRanges);
            final boolean newVpnBlocked = (oldBlockedUidRanges != newBlockedUidRanges)
                    ? isUidBlockedByVpn(nri.mAsUid, newBlockedUidRanges)
                    : oldVpnBlocked;

            final int blockedReasons = mUidBlockedReasons.get(nri.mAsUid, BLOCKED_REASON_NONE);
            oldBlocked = oldVpnBlocked || NetworkPolicyManager.isUidBlocked(
                    blockedReasons, oldMetered);
            newBlocked = newVpnBlocked || NetworkPolicyManager.isUidBlocked(
                    blockedReasons, newMetered);

            if (oldBlocked != newBlocked) {
            final int oldBlockedState = getBlockedState(blockedReasons, oldMetered, oldVpnBlocked);
            final int newBlockedState = getBlockedState(blockedReasons, newMetered, newVpnBlocked);
            if (oldBlockedState != newBlockedState) {
                callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_BLK_CHANGED,
                        encodeBool(newBlocked));
                        newBlockedState);
            }
        }
    }
@@ -8245,25 +8261,23 @@ public class ConnectivityService extends IConnectivityManager.Stub
     * @param uid The uid for which the rules changed.
     * @param blockedReasons The reasons for why an uid is blocked.
     */
    private void maybeNotifyNetworkBlockedForNewState(int uid, int blockedReasons) {
    private void maybeNotifyNetworkBlockedForNewState(int uid, @BlockedReason int blockedReasons) {
        for (final NetworkAgentInfo nai : mNetworkAgentInfos) {
            final boolean metered = nai.networkCapabilities.isMetered();
            final boolean vpnBlocked = isUidBlockedByVpn(uid, mVpnBlockedUidRanges);
            final boolean oldBlocked, newBlocked;

            oldBlocked = vpnBlocked || NetworkPolicyManager.isUidBlocked(
                    mUidBlockedReasons.get(uid, BLOCKED_REASON_NONE), metered);
            newBlocked = vpnBlocked || NetworkPolicyManager.isUidBlocked(
                    blockedReasons, metered);
            if (oldBlocked == newBlocked) {
            final int oldBlockedState = getBlockedState(
                    mUidBlockedReasons.get(uid, BLOCKED_REASON_NONE), metered, vpnBlocked);
            final int newBlockedState = getBlockedState(blockedReasons, metered, vpnBlocked);
            if (oldBlockedState == newBlockedState) {
                continue;
            }
            final int arg = encodeBool(newBlocked);
            for (int i = 0; i < nai.numNetworkRequests(); i++) {
                NetworkRequest nr = nai.requestAt(i);
                NetworkRequestInfo nri = mNetworkRequests.get(nr);
                if (nri != null && nri.mAsUid == uid) {
                    callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_BLK_CHANGED, arg);
                    callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_BLK_CHANGED,
                            newBlockedState);
                }
            }
        }
+1 −1
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_ADMIN_DISABLED;
import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_DATA_SAVER;
import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_MASK;
import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_USER_RESTRICTED;
import static android.net.ConnectivityManager.BLOCKED_REASON_APP_STANDBY;
import static android.net.ConnectivityManager.BLOCKED_REASON_BATTERY_SAVER;
@@ -76,7 +77,6 @@ import static android.net.NetworkPolicyManager.ALLOWED_REASON_POWER_SAVE_ALLOWLI
import static android.net.NetworkPolicyManager.ALLOWED_REASON_POWER_SAVE_EXCEPT_IDLE_ALLOWLIST;
import static android.net.NetworkPolicyManager.ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS;
import static android.net.NetworkPolicyManager.ALLOWED_REASON_SYSTEM;
import static android.net.NetworkPolicyManager.BLOCKED_METERED_REASON_MASK;
import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE;
import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
import static android.net.NetworkPolicyManager.MASK_ALL_NETWORKS;
Loading