Improve the Connectivity section of the Dev Tools app.
1. Remove one more usage of startUsingNetworkFeature.
2. Use new APIs for bound HTTP requests.
Bug: 25824776
Change-Id: Ic2f30ce9ffc873be198f6ad29cf928dc33574d84
diff --git a/apps/Development/res/layout/connectivity.xml b/apps/Development/res/layout/connectivity.xml
index c596f19..23bbb2e 100644
--- a/apps/Development/res/layout/connectivity.xml
+++ b/apps/Development/res/layout/connectivity.xml
@@ -303,35 +303,10 @@
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/netid" />
- <EditText android:id="@+id/netid"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:minEms="5" />
- <Button android:id="@+id/add_default_route"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/add_default_route" />
- <Button android:id="@+id/remove_default_route"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/remove_default_route" />
- </LinearLayout>
- <LinearLayout
- android:orientation="horizontal"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
<Button android:id="@+id/default_request"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/default_request" />
- <Button android:id="@+id/default_socket"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/default_socket" />
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
@@ -346,22 +321,24 @@
android:layout_height="wrap_content"
android:text="@string/bound_socket_request" />
</LinearLayout>
+
<LinearLayout
- android:orientation="horizontal"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
- <Button android:id="@+id/routed_http_request"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/routed_http_request" />
- <Button android:id="@+id/routed_socket_request"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/routed_socket_request" />
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+ <TextView
+ android:id="@+id/http_response"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
</LinearLayout>
<!-- divider line -->
<View android:background="#FFFFFFFF"
+ android:layout_width="match_parent"
+ android:layout_height="3dip" />
+
+ <!-- divider line -->
+ <View android:background="#FFFFFFFF"
android:layout_width="match_parent"
android:layout_height="3dip" />
<LinearLayout
diff --git a/apps/Development/res/values/strings.xml b/apps/Development/res/values/strings.xml
index dd6cefd..bbcb30d 100644
--- a/apps/Development/res/values/strings.xml
+++ b/apps/Development/res/values/strings.xml
@@ -48,16 +48,9 @@
<string name="release_cell">Release cell</string>
<string name="report_all_bad">Report all bad</string>
- <string name="netid">NetId</string>
- <string name="add_default_route">Add Default Route</string>
- <string name="remove_default_route">Remove Default Route</string>
- <string name="default_request">Make a http request</string>
- <string name="default_socket">Make a raw request</string>
+ <string name="default_request">Make http request</string>
<string name="bound_http_request">Make bound http request</string>
<string name="bound_socket_request">Make bound socket request</string>
- <string name="routed_http_request">Make routed http request</string>
- <string name="routed_socket_request">Make routed socket request</string>
-
<string name="device_info_default">unknown</string>
<string name="device_info_uptime">Uptime</string>
diff --git a/apps/Development/src/com/android/development/Connectivity.java b/apps/Development/src/com/android/development/Connectivity.java
index 347612a..06bd06e 100644
--- a/apps/Development/src/com/android/development/Connectivity.java
+++ b/apps/Development/src/com/android/development/Connectivity.java
@@ -52,6 +52,7 @@
import android.os.SystemClock;
import android.provider.Settings;
import android.os.Bundle;
+import android.text.TextUtils;
import android.util.Log;
import android.view.IWindowManager;
import android.view.View;
@@ -66,29 +67,29 @@
import android.widget.AdapterView.OnItemSelectedListener;
import com.android.internal.telephony.Phone;
+import libcore.io.IoUtils;
+import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
+import java.io.InputStreamReader;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
import java.io.PrintWriter;
+import java.net.HttpURLConnection;
import java.net.InetAddress;
-import java.net.NetworkInterface;
+import java.net.Proxy;
import java.net.Socket;
+import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
-
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.conn.params.ConnRouteParams;
-import org.apache.http.params.BasicHttpParams;
-import org.apache.http.params.HttpParams;
-import org.apache.http.HttpResponse;
-import org.apache.http.impl.client.DefaultHttpClient;
+import java.util.Random;
import static android.net.NetworkCapabilities.*;
public class Connectivity extends Activity {
- private static final String TAG = "DevTools - Connectivity";
+ private static final String TAG = "DevToolsConnectivity";
private static final String GET_SCAN_RES = "Get Results";
private static final String START_SCAN = "Start Scan";
private static final String PROGRESS_SCAN = "In Progress";
@@ -126,6 +127,7 @@
private long mTotalScanCount = 0;
private TextView mLinkStatsResults;
+ private TextView mHttpRequestResults;
private String mTdlsAddr = null;
@@ -292,6 +294,7 @@
private final NetworkRequest mRequest;
private final int mRequestButton, mReleaseButton;
private NetworkCallback mCallback;
+ private Network mNetwork;
public RequestableNetwork(NetworkRequest request, int requestButton, int releaseButton) {
mRequest = request;
@@ -321,7 +324,18 @@
public void request() {
if (mCallback == null) {
- mCallback = new NetworkCallback();
+ mCallback = new NetworkCallback() {
+ @Override
+ public void onAvailable(Network network) {
+ mNetwork = network;
+ onHttpRequestResults(null);
+ }
+ @Override
+ public void onLost(Network network) {
+ mNetwork = null;
+ onHttpRequestResults(null);
+ }
+ };
mCm.requestNetwork(mRequest, mCallback);
setRequested(true);
}
@@ -329,14 +343,22 @@
public void release() {
if (mCallback != null) {
+ mNetwork = null;
+ onHttpRequestResults(null);
mCm.unregisterNetworkCallback(mCallback);
mCallback = null;
setRequested(false);
}
}
+
+ public Network getNetwork() {
+ return mNetwork;
+ }
}
private final ArrayList<RequestableNetwork> mRequestableNetworks = new ArrayList<>();
+ private final RequestableNetwork mBoundTestNetwork;
+ private boolean mRequestRunning;
private void addRequestableNetwork(int capability, int requestButton, int releaseButton) {
mRequestableNetworks.add(new RequestableNetwork(capability, requestButton, releaseButton));
@@ -347,6 +369,7 @@
addRequestableNetwork(NET_CAPABILITY_MMS, R.id.request_mms, R.id.release_mms);
addRequestableNetwork(NET_CAPABILITY_SUPL, R.id.request_supl, R.id.release_supl);
addRequestableNetwork(NET_CAPABILITY_INTERNET, R.id.request_cell, R.id.release_cell);
+ mBoundTestNetwork = mRequestableNetworks.get(mRequestableNetworks.size() - 1);
}
final NetworkRequest mEmptyRequest = new NetworkRequest.Builder().clearCapabilities().build();
@@ -402,26 +425,26 @@
findViewById(R.id.report_all_bad).setOnClickListener(mClickListener);
- findViewById(R.id.add_default_route).setOnClickListener(mClickListener);
- findViewById(R.id.remove_default_route).setOnClickListener(mClickListener);
+ findViewById(R.id.default_request).setOnClickListener(mClickListener);
findViewById(R.id.bound_http_request).setOnClickListener(mClickListener);
findViewById(R.id.bound_socket_request).setOnClickListener(mClickListener);
- findViewById(R.id.routed_http_request).setOnClickListener(mClickListener);
- findViewById(R.id.routed_socket_request).setOnClickListener(mClickListener);
- findViewById(R.id.default_request).setOnClickListener(mClickListener);
- findViewById(R.id.default_socket).setOnClickListener(mClickListener);
+
findViewById(R.id.link_stats).setOnClickListener(mClickListener);
for (RequestableNetwork network : mRequestableNetworks) {
network.setRequested(false);
network.addOnClickListener();
}
+ onHttpRequestResults(null);
registerReceiver(mReceiver, new IntentFilter(CONNECTIVITY_TEST_ALARM));
mLinkStatsResults = (TextView)findViewById(R.id.stats);
mLinkStatsResults.setVisibility(View.VISIBLE);
+ mHttpRequestResults = (TextView)findViewById(R.id.http_response);
+ mHttpRequestResults.setVisibility(View.VISIBLE);
+
mCallback = new DevToolsNetworkCallback();
mCm.registerNetworkCallback(mEmptyRequest, mCallback);
}
@@ -473,29 +496,14 @@
case R.id.stopTdls:
onStopTdls();
break;
- case R.id.default_socket:
- onDefaultSocket();
- break;
case R.id.default_request:
- onDefaultRequest();
- break;
- case R.id.routed_socket_request:
- onRoutedSocketRequest();
- break;
- case R.id.routed_http_request:
- onRoutedHttpRequest();
- break;
- case R.id.bound_socket_request:
- onBoundSocketRequest();
+ onHttpRequest(DEFAULT);
break;
case R.id.bound_http_request:
- onBoundHttpRequest();
+ onHttpRequest(HTTPS);
break;
- case R.id.remove_default_route:
- onRemoveDefaultRoute();
- break;
- case R.id.add_default_route:
- onAddDefaultRoute();
+ case R.id.bound_socket_request:
+ onHttpRequest(SOCKET);
break;
case R.id.report_all_bad:
onReportAllBad();
@@ -649,190 +657,108 @@
}
- private void onAddDefaultRoute() {
- try {
- int netId = Integer.valueOf(((TextView) findViewById(R.id.netid)).getText().toString());
- mNetd.addRoute(netId, new RouteInfo((LinkAddress) null,
- NetworkUtils.numericToInetAddress("8.8.8.8")));
- } catch (Exception e) {
- Log.e(TAG, "onAddDefaultRoute got exception: " + e.toString());
- }
- }
-
- private void onRemoveDefaultRoute() {
- try {
- int netId = Integer.valueOf(((TextView) findViewById(R.id.netid)).getText().toString());
- mNetd.removeRoute(netId, new RouteInfo((LinkAddress) null,
- NetworkUtils.numericToInetAddress("8.8.8.8")));
- } catch (Exception e) {
- Log.e(TAG, "onRemoveDefaultRoute got exception: " + e.toString());
- }
- }
-
- private void onRoutedHttpRequest() {
- onRoutedRequest(HTTP);
- }
-
- private void onRoutedSocketRequest() {
- onRoutedRequest(SOCKET);
- }
-
+ private final static int DEFAULT = 0;
private final static int SOCKET = 1;
- private final static int HTTP = 2;
+ private final static int HTTPS = 2;
- private void onRoutedRequest(int type) {
- String url = "www.google.com";
+ private void onHttpRequestResults(final String results) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ boolean enabled = !mRequestRunning;
+ findViewById(R.id.default_request).setEnabled(enabled);
- InetAddress inetAddress = null;
- try {
- inetAddress = InetAddress.getByName(url);
- } catch (Exception e) {
- Log.e(TAG, "error fetching address for " + url);
- return;
- }
+ enabled = !mRequestRunning && mBoundTestNetwork.getNetwork() != null;
+ findViewById(R.id.bound_http_request).setEnabled(enabled);
+ findViewById(R.id.bound_socket_request).setEnabled(enabled);
- mCm.requestRouteToHostAddress(ConnectivityManager.TYPE_MOBILE_HIPRI, inetAddress);
-
- switch (type) {
- case SOCKET:
- onBoundSocketRequest();
- break;
- case HTTP:
- HttpGet get = new HttpGet("http://" + url);
- HttpClient client = new DefaultHttpClient();
- try {
- HttpResponse httpResponse = client.execute(get);
- Log.d(TAG, "routed http request gives " + httpResponse.getStatusLine());
- } catch (Exception e) {
- Log.e(TAG, "routed http request exception = " + e);
+ if (!TextUtils.isEmpty(results) || !mRequestRunning) {
+ ((TextView) findViewById(R.id.http_response)).setText(results);
}
- }
-
+ }
+ });
}
- private void onBoundHttpRequest() {
- NetworkInterface networkInterface = null;
+ private String doSocketRequest(Network network, String host, String path) throws IOException {
+ Socket sock = network.getSocketFactory().createSocket(host, 80);
try {
- networkInterface = NetworkInterface.getByName("rmnet0");
- Log.d(TAG, "networkInterface is " + networkInterface);
- } catch (Exception e) {
- Log.e(TAG, " exception getByName: " + e);
- return;
- }
- if (networkInterface != null) {
- Enumeration inetAddressess = networkInterface.getInetAddresses();
- while(inetAddressess.hasMoreElements()) {
- Log.d(TAG, " inetAddress:" + ((InetAddress)inetAddressess.nextElement()));
+ sock.setSoTimeout(5000);
+ OutputStreamWriter writer = new OutputStreamWriter(sock.getOutputStream());
+ String request = String.format(
+ "GET %s HTTP/1.1\nHost: %s\nConnection: close\n\n", path, host);
+ writer.write(request);
+ writer.flush();
+ BufferedReader reader = new BufferedReader(new InputStreamReader(sock.getInputStream()));
+ String line = reader.readLine();
+
+ if (line == null || !line.startsWith("HTTP/1.1 200")) {
+ // Error.
+ return "Error: " + line;
+ }
+
+ do {
+ // Consume headers.
+ line = reader.readLine();
+ } while (!TextUtils.isEmpty(line));
+
+ // Return first line of body.
+ return reader.readLine();
+ } finally {
+ if (sock != null) {
+ IoUtils.closeQuietly(sock);
}
}
-
- HttpParams httpParams = new BasicHttpParams();
- if (networkInterface != null) {
- ConnRouteParams.setLocalAddress(httpParams,
- networkInterface.getInetAddresses().nextElement());
- }
- HttpGet get = new HttpGet("http://www.bbc.com");
- HttpClient client = new DefaultHttpClient(httpParams);
- try {
- HttpResponse response = client.execute(get);
- Log.d(TAG, "response code = " + response.getStatusLine());
- } catch (Exception e) {
- Log.e(TAG, "Exception = "+ e );
- }
}
- private void onBoundSocketRequest() {
- NetworkInterface networkInterface = null;
- try {
- networkInterface = NetworkInterface.getByName("rmnet0");
- } catch (Exception e) {
- Log.e(TAG, "exception getByName: " + e);
- return;
- }
- if (networkInterface == null) {
- try {
- Log.d(TAG, "getting any networkInterface");
- networkInterface = NetworkInterface.getNetworkInterfaces().nextElement();
- } catch (Exception e) {
- Log.e(TAG, "exception getting any networkInterface: " + e);
- return;
+ private void onHttpRequest(final int type) {
+ mRequestRunning = true;
+ onHttpRequestResults(null);
+
+ Thread requestThread = new Thread() {
+ public void run() {
+ final String path = "/ip.js?fmt=text";
+ final String randomHost =
+ "h" + Integer.toString(new Random().nextInt()) + ".ds.ipv6test.google.com";
+ final String fixedHost = "google-ipv6test.appspot.com";
+
+ Network network = mBoundTestNetwork.getNetwork();
+ HttpURLConnection conn = null;
+ InputStreamReader in = null;
+
+ try {
+ final URL httpsUrl = new URL("https", fixedHost, path);
+ BufferedReader reader;
+
+ switch (type) {
+ case DEFAULT:
+ conn = (HttpURLConnection) httpsUrl.openConnection(Proxy.NO_PROXY);
+ in = new InputStreamReader(conn.getInputStream());
+ reader = new BufferedReader(in);
+ onHttpRequestResults(reader.readLine());
+ break;
+ case SOCKET:
+ String response = doSocketRequest(network, randomHost, path);
+ onHttpRequestResults(response);
+ break;
+ case HTTPS:
+ conn = (HttpURLConnection) network.openConnection(httpsUrl,
+ Proxy.NO_PROXY);
+ in = new InputStreamReader(conn.getInputStream());
+ reader = new BufferedReader(in);
+ onHttpRequestResults(reader.readLine());
+ break;
+ default:
+ throw new IllegalArgumentException("Cannot happen");
+ }
+ } catch(IOException e) {
+ onHttpRequestResults("Error! ");
+ } finally {
+ mRequestRunning = false;
+ if (in != null) IoUtils.closeQuietly(in);
+ if (conn != null) conn.disconnect();
+ }
}
- }
- if (networkInterface == null) {
- Log.e(TAG, "couldn't find a local interface");
- return;
- }
- Enumeration inetAddressess = networkInterface.getInetAddresses();
- while(inetAddressess.hasMoreElements()) {
- Log.d(TAG, " addr:" + ((InetAddress)inetAddressess.nextElement()));
- }
- InetAddress local = null;
- InetAddress remote = null;
- try {
- local = networkInterface.getInetAddresses().nextElement();
- } catch (Exception e) {
- Log.e(TAG, "exception getting local InetAddress: " + e);
- return;
- }
- try {
- remote = InetAddress.getByName("www.flickr.com");
- } catch (Exception e) {
- Log.e(TAG, "exception getting remote InetAddress: " + e);
- return;
- }
- Log.d(TAG, "remote addr ="+remote);
- Log.d(TAG, "local addr ="+local);
- Socket socket = null;
- try {
- socket = new Socket(remote, 80, local, 6000);
- } catch (Exception e) {
- Log.e(TAG, "Exception creating socket: " + e);
- return;
- }
- try {
- PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
- out.println("Hi flickr");
- } catch (Exception e) {
- Log.e(TAG, "Exception writing to socket: " + e);
- return;
- }
- }
-
- private void onDefaultRequest() {
- HttpParams params = new BasicHttpParams();
- HttpGet get = new HttpGet("http://www.cnn.com");
- HttpClient client = new DefaultHttpClient(params);
- try {
- HttpResponse response = client.execute(get);
- Log.e(TAG, "response code = " + response.getStatusLine());
- } catch (Exception e) {
- Log.e(TAG, "Exception = " + e);
- }
- }
-
- private void onDefaultSocket() {
- InetAddress remote = null;
- try {
- remote = InetAddress.getByName("www.flickr.com");
- } catch (Exception e) {
- Log.e(TAG, "exception getting remote InetAddress: " + e);
- return;
- }
- Log.e(TAG, "remote addr =" + remote);
- Socket socket = null;
- try {
- socket = new Socket(remote, 80);
- } catch (Exception e) {
- Log.e(TAG, "Exception creating socket: " + e);
- return;
- }
- try {
- PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
- out.println("Hi flickr");
- Log.e(TAG, "written");
- } catch (Exception e) {
- Log.e(TAG, "Exception writing to socket: " + e);
- return;
- }
+ };
+ requestThread.start();
}
}