• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy of
6  * the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations under
14  * the License.
15  */
16 
17 package com.google.android.mobly.snippet.bundled;
18 
19 import android.app.DownloadManager;
20 import android.content.BroadcastReceiver;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.content.IntentFilter;
24 import android.net.Uri;
25 import android.os.Environment;
26 import androidx.test.platform.app.InstrumentationRegistry;
27 import com.google.android.mobly.snippet.Snippet;
28 import com.google.android.mobly.snippet.bundled.utils.Utils;
29 import com.google.android.mobly.snippet.rpc.Rpc;
30 import com.google.android.mobly.snippet.util.Log;
31 import java.io.IOException;
32 import java.net.InetAddress;
33 import java.net.Socket;
34 import java.net.UnknownHostException;
35 import java.util.List;
36 import java.util.Locale;
37 
38 /** Snippet class for networking RPCs. */
39 public class NetworkingSnippet implements Snippet {
40 
41     private final Context mContext;
42     private final DownloadManager mDownloadManager;
43     private volatile boolean mIsDownloadComplete = false;
44     private volatile long mReqid = 0;
45 
NetworkingSnippet()46     public NetworkingSnippet() {
47         mContext = InstrumentationRegistry.getInstrumentation().getContext();
48         mDownloadManager = (DownloadManager) mContext.getSystemService(Context.DOWNLOAD_SERVICE);
49     }
50 
51     private static class NetworkingSnippetException extends Exception {
52 
53         private static final long serialVersionUID = 8080L;
54 
NetworkingSnippetException(String msg)55         public NetworkingSnippetException(String msg) {
56             super(msg);
57         }
58     }
59 
60     @Rpc(description = "Check if a host and port are connectable using a TCP connection attempt.")
networkIsTcpConnectable(String host, int port)61     public boolean networkIsTcpConnectable(String host, int port) {
62         InetAddress addr;
63         try {
64             addr = InetAddress.getByName(host);
65         } catch (UnknownHostException uherr) {
66             Log.d("Host name lookup failure: " + uherr.getMessage());
67             return false;
68         }
69 
70         try {
71             Socket sock = new Socket(addr, port);
72             sock.close();
73         } catch (IOException ioerr) {
74             Log.d("Did not make connection to host: " + ioerr.getMessage());
75             return false;
76         }
77         return true;
78     }
79 
80     @Rpc(
81             description =
82                     "Download a file using HTTP. Return content Uri (file remains on device). "
83                             + "The Uri should be treated as an opaque handle for further operations.")
networkHttpDownload(String url)84     public String networkHttpDownload(String url)
85             throws IllegalArgumentException, NetworkingSnippetException {
86 
87         Uri uri = Uri.parse(url);
88         List<String> pathsegments = uri.getPathSegments();
89         if (pathsegments.size() < 1) {
90             throw new IllegalArgumentException(
91                     String.format(Locale.US, "The Uri %s does not have a path.", uri.toString()));
92         }
93         DownloadManager.Request request = new DownloadManager.Request(uri);
94         request.setDestinationInExternalPublicDir(
95                 Environment.DIRECTORY_DOWNLOADS, pathsegments.get(pathsegments.size() - 1));
96         mIsDownloadComplete = false;
97         mReqid = 0;
98         IntentFilter filter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
99         BroadcastReceiver receiver = new DownloadReceiver();
100         mContext.registerReceiver(receiver, filter);
101         try {
102             mReqid = mDownloadManager.enqueue(request);
103             Log.d(
104                     String.format(
105                             Locale.US,
106                             "networkHttpDownload download of %s with id %d",
107                             url,
108                             mReqid));
109             if (!Utils.waitUntil(() -> mIsDownloadComplete, 30)) {
110                 Log.d(
111                         String.format(
112                                 Locale.US, "networkHttpDownload timed out waiting for completion"));
113                 throw new NetworkingSnippetException("networkHttpDownload timed out.");
114             }
115         } finally {
116             mContext.unregisterReceiver(receiver);
117         }
118         Uri resp = mDownloadManager.getUriForDownloadedFile(mReqid);
119         if (resp != null) {
120             Log.d(String.format(Locale.US, "networkHttpDownload completed to %s", resp.toString()));
121             mReqid = 0;
122             return resp.toString();
123         } else {
124             Log.d(
125                     String.format(
126                             Locale.US,
127                             "networkHttpDownload Failed to download %s",
128                             uri.toString()));
129             throw new NetworkingSnippetException("networkHttpDownload didn't get downloaded file.");
130         }
131     }
132 
133     private class DownloadReceiver extends BroadcastReceiver {
134 
135         @Override
onReceive(Context context, Intent intent)136         public void onReceive(Context context, Intent intent) {
137             String action = intent.getAction();
138             long gotid = (long) intent.getExtras().get("extra_download_id");
139             if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action) && gotid == mReqid) {
140                 mIsDownloadComplete = true;
141             }
142         }
143     }
144 
145     @Override
shutdown()146     public void shutdown() {
147         if (mReqid != 0) {
148             mDownloadManager.remove(mReqid);
149         }
150     }
151 }
152