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

Commit d08ab5a6 authored by Benedict Wong's avatar Benedict Wong
Browse files

DO NOT MERGE: Fix ConnectivityController meteredness checks

This patch corrects ConnectivityController's meteredness checks to
perform correct meteredness checks while VPNs are running. This fixes a
bug in O-MR1 where any apps using the DownloadProvider with unmetered
network constraints fail to start while the VPN is enabled.

This change adds a bespoke method for ConnectivityController, allowing
it to correctly identify the meteredness without affecting public API
surfaces.

Bug: 78644887
Test: Built, flashed on Walleye, and tested.
Test: Additional test coverage in subsequent patch(es).
Change-Id: Ie1d11d93d51d936ce81cd5984af61bde30325983
parent aa55d5db
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -2504,6 +2504,28 @@ public class ConnectivityManager {
        }
    }

    /**
     * Returns if the active data network for the given UID is metered. A network
     * is classified as metered when the user is sensitive to heavy data usage on
     * that connection due to monetary costs, data limitations or
     * battery/performance issues. You should check this before doing large
     * data transfers, and warn the user or delay the operation until another
     * network is available.
     *
     * @return {@code true} if large transfers should be avoided, otherwise
     *        {@code false}.
     *
     * @hide
     */
    @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL)
    public boolean isActiveNetworkMeteredForUid(int uid) {
        try {
            return mService.isActiveNetworkMeteredForUid(uid);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * If the LockdownVpn mechanism is enabled, updates the vpn
     * with a reload of its profile.
+1 −0
Original line number Diff line number Diff line
@@ -66,6 +66,7 @@ interface IConnectivityManager

    NetworkQuotaInfo getActiveNetworkQuotaInfo();
    boolean isActiveNetworkMetered();
    boolean isActiveNetworkMeteredForUid(int uid);

    boolean requestRouteToHostAddress(int networkType, in byte[] hostAddress);

+11 −1
Original line number Diff line number Diff line
@@ -1339,7 +1339,17 @@ public class ConnectivityService extends IConnectivityManager.Stub
    public boolean isActiveNetworkMetered() {
        enforceAccessPermission();

        final int uid = Binder.getCallingUid();
        return isActiveNetworkMeteredCommon(Binder.getCallingUid());
    }

    @Override
    public boolean isActiveNetworkMeteredForUid(int uid) {
        enforceConnectivityInternalPermission();

        return isActiveNetworkMeteredCommon(uid);
    }

    private boolean isActiveNetworkMeteredCommon(int uid) {
        final NetworkCapabilities caps = getUnfilteredActiveNetworkState(uid).networkCapabilities;
        if (caps != null) {
            return !caps.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
+2 −4
Original line number Diff line number Diff line
@@ -112,10 +112,8 @@ public final class ConnectivityController extends StateController implements
        final boolean connected = (info != null) && info.isConnected();
        final boolean connectionUsable = connected && validated;

        final boolean metered = connected && (capabilities != null)
                && !capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
        final boolean unmetered = connected && (capabilities != null)
                && capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
        final boolean metered = connected && mConnManager.isActiveNetworkMeteredForUid(jobUid);
        final boolean unmetered = connected && !mConnManager.isActiveNetworkMeteredForUid(jobUid);
        final boolean notRoaming = connected && (info != null)
                && !info.isRoaming();