From 2797e51535fd0906326ba8785159d6d2f96f1e7d Mon Sep 17 00:00:00 2001 From: Keith Dart Date: Thu, 28 Sep 2017 17:54:57 -0700 Subject: Add Rpcs needed to download files via HTTP. (#80) * Add an Rpc to perform an HTTP download using DownloadManager. * Add file operation Rpcs. --- .../mobly/snippet/bundled/NetworkingSnippet.java | 87 +++++++++++++++++++++- 1 file changed, 86 insertions(+), 1 deletion(-) (limited to 'src/main/java/com/google/android/mobly/snippet/bundled/NetworkingSnippet.java') diff --git a/src/main/java/com/google/android/mobly/snippet/bundled/NetworkingSnippet.java b/src/main/java/com/google/android/mobly/snippet/bundled/NetworkingSnippet.java index d72205a..f175fdd 100644 --- a/src/main/java/com/google/android/mobly/snippet/bundled/NetworkingSnippet.java +++ b/src/main/java/com/google/android/mobly/snippet/bundled/NetworkingSnippet.java @@ -16,17 +16,47 @@ package com.google.android.mobly.snippet.bundled; +import java.util.List; import java.net.InetAddress; import java.net.Socket; import java.io.IOException; import java.net.UnknownHostException; +import android.content.Intent; +import android.content.Context; +import android.content.IntentFilter; +import android.content.BroadcastReceiver; +import android.net.Uri; +import android.os.Environment; +import android.os.ParcelFileDescriptor; +import android.app.DownloadManager; +import android.support.test.InstrumentationRegistry; import com.google.android.mobly.snippet.Snippet; +import com.google.android.mobly.snippet.bundled.utils.Utils; import com.google.android.mobly.snippet.rpc.Rpc; import com.google.android.mobly.snippet.util.Log; /** Snippet class for networking RPCs. */ public class NetworkingSnippet implements Snippet { + private final Context mContext; + private final DownloadManager mDownloadManager; + private volatile boolean mIsDownloadComplete = false; + private volatile long mReqid = 0; + + public NetworkingSnippet() { + mContext = InstrumentationRegistry.getContext(); + mDownloadManager = (DownloadManager) mContext.getSystemService(Context.DOWNLOAD_SERVICE); + } + + private static class NetworkingSnippetException extends Exception { + + private static final long serialVersionUID = 8080L; + + public NetworkingSnippetException(String msg) { + super(msg); + } + } + @Rpc(description = "Check if a host and port are connectable using a TCP connection attempt.") public boolean networkIsTcpConnectable(String host, int port) { InetAddress addr; @@ -47,6 +77,61 @@ public class NetworkingSnippet implements Snippet { return true; } + @Rpc(description = "Download a file using HTTP. Return content Uri (file remains on device). " + + "The Uri should be treated as an opaque handle for further operations.") + public String networkHttpDownload(String url) throws IllegalArgumentException, NetworkingSnippetException { + + Uri uri = Uri.parse(url); + List pathsegments = uri.getPathSegments(); + if (pathsegments.size() < 1) { + throw new IllegalArgumentException(String.format("The Uri %s does not have a path.", uri.toString())); + } + DownloadManager.Request request = new DownloadManager.Request(uri); + request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, + pathsegments.get(pathsegments.size() - 1)); + mIsDownloadComplete = false; + mReqid = 0; + IntentFilter filter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE); + BroadcastReceiver receiver = new DownloadReceiver(); + mContext.registerReceiver(receiver, filter); + try { + mReqid = mDownloadManager.enqueue(request); + Log.d(String.format("networkHttpDownload download of %s with id %d", url, mReqid)); + if (!Utils.waitUntil(() -> mIsDownloadComplete, 30)) { + Log.d(String.format("networkHttpDownload timed out waiting for completion")); + throw new NetworkingSnippetException("networkHttpDownload timed out."); + } + } finally { + mContext.unregisterReceiver(receiver); + } + Uri resp = mDownloadManager.getUriForDownloadedFile(mReqid); + if (resp != null) { + Log.d(String.format("networkHttpDownload completed to %s", resp.toString())); + mReqid = 0; + return resp.toString(); + } else { + Log.d(String.format("networkHttpDownload Failed to download %s", uri.toString())); + throw new NetworkingSnippetException("networkHttpDownload didn't get downloaded file."); + } + } + + private class DownloadReceiver extends BroadcastReceiver { + + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + long gotid = (long) intent.getExtras().get("extra_download_id"); + if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action) + && gotid == mReqid) { + mIsDownloadComplete = true; + } + } + } + @Override - public void shutdown() {} + public void shutdown() { + if (mReqid != 0) { + mDownloadManager.remove(mReqid); + } + } } -- cgit v1.2.3