From 26c68db9ccf1983f5d6e8a734f8ffccea3849f10 Mon Sep 17 00:00:00 2001 From: Robin Lee Date: Thu, 24 Mar 2016 12:02:50 +0000 Subject: Implement multi-network downloads Downloads should use the default network for the caller. This prevents applications from, for example, bypassing VPN by routing all requests through the DownloadProvider. Bug: 27074270 Change-Id: I7830226dd2910757d3a5c78f373330f84637ccfa --- src/com/android/providers/downloads/DownloadThread.java | 10 +++++++++- src/com/android/providers/downloads/RealSystemFacade.java | 8 ++++++++ src/com/android/providers/downloads/SystemFacade.java | 3 +++ .../src/com/android/providers/downloads/FakeSystemFacade.java | 7 +++++++ 4 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/com/android/providers/downloads/DownloadThread.java b/src/com/android/providers/downloads/DownloadThread.java index 65142db6..8d51909e 100644 --- a/src/com/android/providers/downloads/DownloadThread.java +++ b/src/com/android/providers/downloads/DownloadThread.java @@ -45,6 +45,7 @@ import android.drm.DrmManagerClient; import android.drm.DrmOutputStream; import android.net.ConnectivityManager; import android.net.INetworkPolicyListener; +import android.net.Network; import android.net.NetworkInfo; import android.net.NetworkPolicyManager; import android.net.TrafficStats; @@ -351,6 +352,13 @@ public class DownloadThread implements Runnable { throw new StopRequestException(STATUS_BAD_REQUEST, e); } + final Network network = mSystemFacade.getActiveNetwork(mInfo.mUid); + if (network == null) { + throw new StopRequestException(Downloads.Impl.STATUS_WAITING_FOR_NETWORK, + "no network associated with requesting UID"); + } + logDebug("Using network: " + network); + boolean cleartextTrafficPermitted = mSystemFacade.isCleartextTrafficPermitted(mInfo.mUid); int redirectionCount = 0; while (redirectionCount++ < Constants.MAX_REDIRECTS) { @@ -367,7 +375,7 @@ public class DownloadThread implements Runnable { HttpURLConnection conn = null; try { checkConnectivity(); - conn = (HttpURLConnection) url.openConnection(); + conn = (HttpURLConnection) network.openConnection(url); conn.setInstanceFollowRedirects(false); conn.setConnectTimeout(DEFAULT_TIMEOUT); conn.setReadTimeout(DEFAULT_TIMEOUT); diff --git a/src/com/android/providers/downloads/RealSystemFacade.java b/src/com/android/providers/downloads/RealSystemFacade.java index b3f170fb..48df2a09 100644 --- a/src/com/android/providers/downloads/RealSystemFacade.java +++ b/src/com/android/providers/downloads/RealSystemFacade.java @@ -26,6 +26,7 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.net.ConnectivityManager; +import android.net.Network; import android.net.NetworkInfo; import android.telephony.TelephonyManager; import android.util.Log; @@ -58,6 +59,13 @@ class RealSystemFacade implements SystemFacade { return activeInfo; } + @Override + public Network getActiveNetwork(int uid) { + ConnectivityManager connectivity = + (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); + return connectivity.getActiveNetworkForUid(uid); + } + @Override public boolean isActiveNetworkMetered() { final ConnectivityManager conn = ConnectivityManager.from(mContext); diff --git a/src/com/android/providers/downloads/SystemFacade.java b/src/com/android/providers/downloads/SystemFacade.java index 83fc7a63..7f97b919 100644 --- a/src/com/android/providers/downloads/SystemFacade.java +++ b/src/com/android/providers/downloads/SystemFacade.java @@ -18,6 +18,7 @@ package com.android.providers.downloads; import android.content.Intent; import android.content.pm.PackageManager.NameNotFoundException; +import android.net.Network; import android.net.NetworkInfo; interface SystemFacade { @@ -32,6 +33,8 @@ interface SystemFacade { */ public NetworkInfo getActiveNetworkInfo(int uid); + public Network getActiveNetwork(int uid); + public boolean isActiveNetworkMetered(); /** diff --git a/tests/src/com/android/providers/downloads/FakeSystemFacade.java b/tests/src/com/android/providers/downloads/FakeSystemFacade.java index 7581e6fa..af5482e1 100644 --- a/tests/src/com/android/providers/downloads/FakeSystemFacade.java +++ b/tests/src/com/android/providers/downloads/FakeSystemFacade.java @@ -3,6 +3,7 @@ package com.android.providers.downloads; import android.content.Intent; import android.content.pm.PackageManager.NameNotFoundException; import android.net.ConnectivityManager; +import android.net.Network; import android.net.NetworkInfo; import android.net.NetworkInfo.DetailedState; @@ -10,6 +11,7 @@ import java.util.ArrayList; import java.util.List; public class FakeSystemFacade implements SystemFacade { long mTimeMillis = 0; + Network mActiveNetwork = null; Integer mActiveNetworkType = ConnectivityManager.TYPE_WIFI; boolean mIsRoaming = false; boolean mIsMetered = false; @@ -42,6 +44,11 @@ public class FakeSystemFacade implements SystemFacade { return mTimeMillis; } + @Override + public Network getActiveNetwork(int uid) { + return mActiveNetwork; + } + @Override public NetworkInfo getActiveNetworkInfo(int uid) { if (mActiveNetworkType == null) { -- cgit v1.2.3 From a8bbae54b9533d560dc3c81c0858de0f99fed0ee Mon Sep 17 00:00:00 2001 From: Robin Lee Date: Fri, 8 Apr 2016 12:01:19 +0100 Subject: Extra comments for multinetwork downloading Bug: 27074270 Change-Id: I7145fcdf0c8af0f0c299ca491f01eaef6204e2cb --- src/com/android/providers/downloads/DownloadThread.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/com/android/providers/downloads/DownloadThread.java b/src/com/android/providers/downloads/DownloadThread.java index 8d51909e..f6b0be6d 100644 --- a/src/com/android/providers/downloads/DownloadThread.java +++ b/src/com/android/providers/downloads/DownloadThread.java @@ -352,6 +352,8 @@ public class DownloadThread implements Runnable { throw new StopRequestException(STATUS_BAD_REQUEST, e); } + // Use the caller's default network to make this connection, since they might be subject to + // restrictions that we shouldn't let them circumvent. final Network network = mSystemFacade.getActiveNetwork(mInfo.mUid); if (network == null) { throw new StopRequestException(Downloads.Impl.STATUS_WAITING_FOR_NETWORK, @@ -374,6 +376,8 @@ public class DownloadThread implements Runnable { // response with body. HttpURLConnection conn = null; try { + // Check that the caller is allowed to make network connections. If so, make one on + // their behalf to open the url. checkConnectivity(); conn = (HttpURLConnection) network.openConnection(url); conn.setInstanceFollowRedirects(false); -- cgit v1.2.3