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
This commit is contained in:
Benedict Wong
2018-05-03 21:07:58 -07:00
parent 97f679b04f
commit 687aa58f2e
3 changed files with 34 additions and 1 deletions

View File

@@ -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.

View File

@@ -66,6 +66,7 @@ interface IConnectivityManager
NetworkQuotaInfo getActiveNetworkQuotaInfo();
boolean isActiveNetworkMetered();
boolean isActiveNetworkMeteredForUid(int uid);
boolean requestRouteToHostAddress(int networkType, in byte[] hostAddress);

View File

@@ -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);