summaryrefslogtreecommitdiffstats
path: root/packages/CaptivePortalLogin
diff options
context:
space:
mode:
authorPaul Jensen <pauljensen@google.com>2014-10-02 13:43:39 -0400
committerPaul Jensen <pauljensen@google.com>2014-10-03 13:21:12 -0400
commit88eb0fa8eec7da1b7a3bd39f9d9844909911bc64 (patch)
tree55ab51718ccbdf6026d2ed27bce20fdbf1f73c68 /packages/CaptivePortalLogin
parent8df099df1516d23c113be3121635dcd34984a4a0 (diff)
downloadframeworks_base-88eb0fa8eec7da1b7a3bd39f9d9844909911bc64.zip
frameworks_base-88eb0fa8eec7da1b7a3bd39f9d9844909911bc64.tar.gz
frameworks_base-88eb0fa8eec7da1b7a3bd39f9d9844909911bc64.tar.bz2
Use network-specific HTTP proxy settings in captive portal login app.
The HTTP proxy system properties are set based on the proxy configured for the network the captive portal login app is operating on. These system properties are subsequently read by the WebView used to perform the sign-in. This is a short-term fix using reflection. This allows users with cellular providers that use proxies to sign into WiFi captive portals. The long-term fix could involve: 1. Sending out a network-specific proxy config changed broadcast, and 2. Modifying the ActivityThread to set proxy system properties for Networks selected with setProcessDefaultNetwork(), and 3. Modifying WebView to read from the proxy system properties when PROXY_CHANGE_ACTION broadcasts are received. bug:17679789 Change-Id: I3ada0470ad085df1a4452b4a655ac35f310d2241
Diffstat (limited to 'packages/CaptivePortalLogin')
-rw-r--r--packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java82
1 files changed, 76 insertions, 6 deletions
diff --git a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
index b3a6e88..7a262de 100644
--- a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
+++ b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
@@ -17,16 +17,24 @@
package com.android.captiveportallogin;
import android.app.Activity;
+import android.app.LoadedApk;
+import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.ConnectivityManager;
import android.net.ConnectivityManager.NetworkCallback;
+import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
+import android.net.Proxy;
+import android.net.ProxyInfo;
+import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;
import android.provider.Settings.Global;
+import android.util.ArrayMap;
+import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
@@ -42,8 +50,11 @@ import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.lang.InterruptedException;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
public class CaptivePortalLoginActivity extends Activity {
+ private static final String TAG = "CaptivePortalLogin";
private static final String DEFAULT_SERVER = "clients3.google.com";
private static final int SOCKET_TIMEOUT_MS = 10000;
@@ -72,14 +83,34 @@ public class CaptivePortalLoginActivity extends Activity {
done(true);
}
- setContentView(R.layout.activity_captive_portal_login);
-
- getActionBar().setDisplayShowHomeEnabled(false);
-
mNetId = Integer.parseInt(getIntent().getStringExtra(Intent.EXTRA_TEXT));
final Network network = new Network(mNetId);
ConnectivityManager.setProcessDefaultNetwork(network);
+ // Set HTTP proxy system properties to those of the selected Network.
+ final LinkProperties lp = ConnectivityManager.from(this).getLinkProperties(network);
+ if (lp != null) {
+ final ProxyInfo proxyInfo = lp.getHttpProxy();
+ String host = "";
+ String port = "";
+ String exclList = "";
+ Uri pacFileUrl = Uri.EMPTY;
+ if (proxyInfo != null) {
+ host = proxyInfo.getHost();
+ port = Integer.toString(proxyInfo.getPort());
+ exclList = proxyInfo.getExclusionListAsString();
+ pacFileUrl = proxyInfo.getPacFileUrl();
+ }
+ Proxy.setHttpProxySystemProperty(host, port, exclList, pacFileUrl);
+ Log.v(TAG, "Set proxy system properties to " + proxyInfo);
+ }
+
+ // Proxy system properties must be initialized before setContentView is called because
+ // setContentView initializes the WebView logic which in turn reads the system properties.
+ setContentView(R.layout.activity_captive_portal_login);
+
+ getActionBar().setDisplayShowHomeEnabled(false);
+
// Exit app if Network disappears.
final NetworkCapabilities networkCapabilities =
ConnectivityManager.from(this).getNetworkCapabilities(network);
@@ -99,12 +130,39 @@ public class CaptivePortalLoginActivity extends Activity {
}
ConnectivityManager.from(this).registerNetworkCallback(builder.build(), mNetworkCallback);
- WebView myWebView = (WebView) findViewById(R.id.webview);
+ final WebView myWebView = (WebView) findViewById(R.id.webview);
+ myWebView.clearCache(true);
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
myWebView.setWebViewClient(new MyWebViewClient());
myWebView.setWebChromeClient(new MyWebChromeClient());
- myWebView.loadUrl(mURL.toString());
+ // Start initial page load so WebView finishes loading proxy settings.
+ // Actual load of mUrl is initiated by MyWebViewClient.
+ myWebView.loadData("", "text/html", null);
+ }
+
+ // Find WebView's proxy BroadcastReceiver and prompt it to read proxy system properties.
+ private void setWebViewProxy() {
+ LoadedApk loadedApk = getApplication().mLoadedApk;
+ try {
+ Field receiversField = LoadedApk.class.getDeclaredField("mReceivers");
+ receiversField.setAccessible(true);
+ ArrayMap receivers = (ArrayMap) receiversField.get(loadedApk);
+ for (Object receiverMap : receivers.values()) {
+ for (Object rec : ((ArrayMap) receiverMap).keySet()) {
+ Class clazz = rec.getClass();
+ if (clazz.getName().contains("ProxyChangeListener")) {
+ Method onReceiveMethod = clazz.getDeclaredMethod("onReceive", Context.class,
+ Intent.class);
+ Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION);
+ onReceiveMethod.invoke(rec, getApplicationContext(), intent);
+ Log.v(TAG, "Prompting WebView proxy reload.");
+ }
+ }
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Exception while setting WebView proxy: " + e);
+ }
}
private void done(boolean use_network) {
@@ -176,13 +234,25 @@ public class CaptivePortalLoginActivity extends Activity {
}
private class MyWebViewClient extends WebViewClient {
+ private boolean firstPageLoad = true;
+
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
+ if (firstPageLoad) return;
testForCaptivePortal();
}
@Override
public void onPageFinished(WebView view, String url) {
+ if (firstPageLoad) {
+ firstPageLoad = false;
+ // Now that WebView has loaded at least one page we know it has read in the proxy
+ // settings. Now prompt the WebView read the Network-specific proxy settings.
+ setWebViewProxy();
+ // Load the real page.
+ view.loadUrl(mURL.toString());
+ return;
+ }
testForCaptivePortal();
}
}