Add CTS to verify DownloadManager permission

If DownloadManager doesn't have
CONNECTIVITY_USE_RESTRICTED_NETWORKS permission, it can't bind
socket to VPN when it is in VPN disallowed list but requested
downloading app is in VPN allowed list. Add a new CTS test to
verify that DownloadManager can do the download successfully via
VPN network.

Bug: 165774987
Test: atest HostsideVpnTests
Change-Id: Iba9e2f26ad325d0fdb34ab9a06faaaf9cb623166
This commit is contained in:
paulhu
2020-09-17 16:26:46 +08:00
parent a0ad1c6b11
commit 01f9b00e88
2 changed files with 80 additions and 3 deletions

View File

@@ -17,13 +17,26 @@
package com.android.cts.net.hostside; package com.android.cts.net.hostside;
import static android.os.Process.INVALID_UID; import static android.os.Process.INVALID_UID;
import static android.system.OsConstants.*; import static android.system.OsConstants.AF_INET;
import static android.system.OsConstants.AF_INET6;
import static android.system.OsConstants.ECONNABORTED;
import static android.system.OsConstants.IPPROTO_ICMP;
import static android.system.OsConstants.IPPROTO_ICMPV6;
import static android.system.OsConstants.IPPROTO_TCP;
import static android.system.OsConstants.POLLIN;
import static android.system.OsConstants.SOCK_DGRAM;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.app.DownloadManager;
import android.app.DownloadManager.Query;
import android.app.DownloadManager.Request;
import android.content.BroadcastReceiver;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;
import android.net.ConnectivityManager.NetworkCallback; import android.net.ConnectivityManager.NetworkCallback;
import android.net.LinkProperties; import android.net.LinkProperties;
@@ -32,12 +45,13 @@ import android.net.NetworkCapabilities;
import android.net.NetworkRequest; import android.net.NetworkRequest;
import android.net.Proxy; import android.net.Proxy;
import android.net.ProxyInfo; import android.net.ProxyInfo;
import android.net.Uri;
import android.net.VpnService; import android.net.VpnService;
import android.net.wifi.WifiManager; import android.net.wifi.WifiManager;
import android.provider.Settings;
import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor;
import android.os.Process; import android.os.Process;
import android.os.SystemProperties; import android.os.SystemProperties;
import android.provider.Settings;
import android.support.test.uiautomator.UiDevice; import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject; import android.support.test.uiautomator.UiObject;
import android.support.test.uiautomator.UiSelector; import android.support.test.uiautomator.UiSelector;
@@ -64,12 +78,12 @@ import java.net.InetAddress;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.ServerSocket; import java.net.ServerSocket;
import java.net.Socket; import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Objects; import java.util.Objects;
import java.util.Random; import java.util.Random;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@@ -1087,4 +1101,62 @@ public class VpnTest extends InstrumentationTestCase {
received = true; received = true;
} }
} }
/**
* Verifies that DownloadManager has CONNECTIVITY_USE_RESTRICTED_NETWORKS permission that can
* bind socket to VPN when it is in VPN disallowed list but requested downloading app is in VPN
* allowed list.
* See b/165774987.
*/
public void testDownloadWithDownloadManagerDisallowed() throws Exception {
if (!supportedHardware()) return;
// Start a VPN with DownloadManager package in disallowed list.
startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"},
new String[] {"192.0.2.0/24", "2001:db8::/32"},
"" /* allowedApps */, "com.android.providers.downloads", null /* proxyInfo */,
null /* underlyingNetworks */, false /* isAlwaysMetered */);
final Context context = VpnTest.this.getInstrumentation().getContext();
final DownloadManager dm = context.getSystemService(DownloadManager.class);
final DownloadCompleteReceiver receiver = new DownloadCompleteReceiver();
try {
context.registerReceiver(receiver,
new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
// Enqueue a request and check only one download.
final long id = dm.enqueue(new Request(Uri.parse("https://www.google.com")));
assertEquals(1, getTotalNumberDownloads(dm, new Query()));
assertEquals(1, getTotalNumberDownloads(dm, new Query().setFilterById(id)));
// Wait for download complete and check status.
assertEquals(id, receiver.get(TIMEOUT_MS, TimeUnit.MILLISECONDS));
assertEquals(1, getTotalNumberDownloads(dm,
new Query().setFilterByStatus(DownloadManager.STATUS_SUCCESSFUL)));
// Remove download.
assertEquals(1, dm.remove(id));
assertEquals(0, getTotalNumberDownloads(dm, new Query()));
} finally {
context.unregisterReceiver(receiver);
}
}
private static int getTotalNumberDownloads(final DownloadManager dm, final Query query) {
try (Cursor cursor = dm.query(query)) { return cursor.getCount(); }
}
private static class DownloadCompleteReceiver extends BroadcastReceiver {
private final CompletableFuture<Long> future = new CompletableFuture<>();
@Override
public void onReceive(Context context, Intent intent) {
future.complete(intent.getLongExtra(
DownloadManager.EXTRA_DOWNLOAD_ID, -1 /* defaultValue */));
}
public long get(long timeout, TimeUnit unit) throws Exception {
return future.get(timeout, unit);
}
}
} }

View File

@@ -95,4 +95,9 @@ public class HostsideVpnTests extends HostsideNetworkTestCase {
public void testB141603906() throws Exception { public void testB141603906() throws Exception {
runDeviceTests(TEST_PKG, TEST_PKG + ".VpnTest", "testB141603906"); runDeviceTests(TEST_PKG, TEST_PKG + ".VpnTest", "testB141603906");
} }
public void testDownloadWithDownloadManagerDisallowed() throws Exception {
runDeviceTests(TEST_PKG, TEST_PKG + ".VpnTest",
"testDownloadWithDownloadManagerDisallowed");
}
} }