CaptivePortalLoginActivity.java revision 71b645fe9cb8106dfcbf025a3fd7f58698c051bb
1869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen/* 2869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen * Copyright (C) 2014 The Android Open Source Project 3869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen * 4869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen * Licensed under the Apache License, Version 2.0 (the "License"); 5869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen * you may not use this file except in compliance with the License. 6869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen * You may obtain a copy of the License at 7869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen * 8869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen * http://www.apache.org/licenses/LICENSE-2.0 9869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen * 10869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen * Unless required by applicable law or agreed to in writing, software 11869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen * distributed under the License is distributed on an "AS IS" BASIS, 12869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen * See the License for the specific language governing permissions and 14869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen * limitations under the License. 15869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen */ 16869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen 17869868be653cb8eedd338e8347dfee1520d38cecPaul Jensenpackage com.android.captiveportallogin; 18869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen 19869868be653cb8eedd338e8347dfee1520d38cecPaul Jensenimport android.app.Activity; 2088eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensenimport android.app.LoadedApk; 2188eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensenimport android.content.Context; 22869868be653cb8eedd338e8347dfee1520d38cecPaul Jensenimport android.content.Intent; 23869868be653cb8eedd338e8347dfee1520d38cecPaul Jensenimport android.graphics.Bitmap; 24869868be653cb8eedd338e8347dfee1520d38cecPaul Jensenimport android.net.ConnectivityManager; 258df099df1516d23c113be3121635dcd34984a4a0Paul Jensenimport android.net.ConnectivityManager.NetworkCallback; 2688eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensenimport android.net.LinkProperties; 27869868be653cb8eedd338e8347dfee1520d38cecPaul Jensenimport android.net.Network; 288df099df1516d23c113be3121635dcd34984a4a0Paul Jensenimport android.net.NetworkCapabilities; 298df099df1516d23c113be3121635dcd34984a4a0Paul Jensenimport android.net.NetworkRequest; 3088eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensenimport android.net.Proxy; 3188eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensenimport android.net.ProxyInfo; 3288eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensenimport android.net.Uri; 33869868be653cb8eedd338e8347dfee1520d38cecPaul Jensenimport android.os.Bundle; 34869868be653cb8eedd338e8347dfee1520d38cecPaul Jensenimport android.provider.Settings; 35869868be653cb8eedd338e8347dfee1520d38cecPaul Jensenimport android.provider.Settings.Global; 3688eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensenimport android.util.ArrayMap; 3788eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensenimport android.util.Log; 38869868be653cb8eedd338e8347dfee1520d38cecPaul Jensenimport android.view.Menu; 39869868be653cb8eedd338e8347dfee1520d38cecPaul Jensenimport android.view.MenuItem; 408f333f19222ac9415152e31f10e0df2b571b0b77Paul Jensenimport android.view.View; 41869868be653cb8eedd338e8347dfee1520d38cecPaul Jensenimport android.view.Window; 42869868be653cb8eedd338e8347dfee1520d38cecPaul Jensenimport android.webkit.WebChromeClient; 43869868be653cb8eedd338e8347dfee1520d38cecPaul Jensenimport android.webkit.WebSettings; 44869868be653cb8eedd338e8347dfee1520d38cecPaul Jensenimport android.webkit.WebView; 45869868be653cb8eedd338e8347dfee1520d38cecPaul Jensenimport android.webkit.WebViewClient; 468f333f19222ac9415152e31f10e0df2b571b0b77Paul Jensenimport android.widget.ProgressBar; 47869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen 48869868be653cb8eedd338e8347dfee1520d38cecPaul Jensenimport java.io.IOException; 49869868be653cb8eedd338e8347dfee1520d38cecPaul Jensenimport java.net.HttpURLConnection; 50869868be653cb8eedd338e8347dfee1520d38cecPaul Jensenimport java.net.MalformedURLException; 51869868be653cb8eedd338e8347dfee1520d38cecPaul Jensenimport java.net.URL; 52869868be653cb8eedd338e8347dfee1520d38cecPaul Jensenimport java.lang.InterruptedException; 5388eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensenimport java.lang.reflect.Field; 5488eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensenimport java.lang.reflect.Method; 55869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen 56869868be653cb8eedd338e8347dfee1520d38cecPaul Jensenpublic class CaptivePortalLoginActivity extends Activity { 5788eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen private static final String TAG = "CaptivePortalLogin"; 58869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen private static final String DEFAULT_SERVER = "clients3.google.com"; 59869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen private static final int SOCKET_TIMEOUT_MS = 10000; 60869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen 61869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen // Keep this in sync with NetworkMonitor. 62869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen // Intent broadcast to ConnectivityService indicating sign-in is complete. 63869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen // Extras: 64869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen // EXTRA_TEXT = netId 6571b645fe9cb8106dfcbf025a3fd7f58698c051bbPaul Jensen // LOGGED_IN_RESULT = one of the CAPTIVE_PORTAL_APP_RETURN_* values below. 6671b645fe9cb8106dfcbf025a3fd7f58698c051bbPaul Jensen // RESPONSE_TOKEN = data fragment from launching Intent 67869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen private static final String ACTION_CAPTIVE_PORTAL_LOGGED_IN = 68869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen "android.net.netmon.captive_portal_logged_in"; 69869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen private static final String LOGGED_IN_RESULT = "result"; 7071b645fe9cb8106dfcbf025a3fd7f58698c051bbPaul Jensen private static final int CAPTIVE_PORTAL_APP_RETURN_APPEASED = 0; 7171b645fe9cb8106dfcbf025a3fd7f58698c051bbPaul Jensen private static final int CAPTIVE_PORTAL_APP_RETURN_UNWANTED = 1; 7271b645fe9cb8106dfcbf025a3fd7f58698c051bbPaul Jensen private static final int CAPTIVE_PORTAL_APP_RETURN_WANTED_AS_IS = 2; 7371b645fe9cb8106dfcbf025a3fd7f58698c051bbPaul Jensen private static final String RESPONSE_TOKEN = "response_token"; 74869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen 75869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen private URL mURL; 76869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen private int mNetId; 7771b645fe9cb8106dfcbf025a3fd7f58698c051bbPaul Jensen private String mResponseToken; 788df099df1516d23c113be3121635dcd34984a4a0Paul Jensen private NetworkCallback mNetworkCallback; 79869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen 80869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen @Override 81869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen protected void onCreate(Bundle savedInstanceState) { 82869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen super.onCreate(savedInstanceState); 83869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen 84869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen String server = Settings.Global.getString(getContentResolver(), "captive_portal_server"); 85869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen if (server == null) server = DEFAULT_SERVER; 86869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen try { 8771b645fe9cb8106dfcbf025a3fd7f58698c051bbPaul Jensen mURL = new URL("http", server, "/generate_204"); 8871b645fe9cb8106dfcbf025a3fd7f58698c051bbPaul Jensen final Uri dataUri = getIntent().getData(); 8971b645fe9cb8106dfcbf025a3fd7f58698c051bbPaul Jensen if (!dataUri.getScheme().equals("netid")) { 9071b645fe9cb8106dfcbf025a3fd7f58698c051bbPaul Jensen throw new MalformedURLException(); 9171b645fe9cb8106dfcbf025a3fd7f58698c051bbPaul Jensen } 9271b645fe9cb8106dfcbf025a3fd7f58698c051bbPaul Jensen mNetId = Integer.parseInt(dataUri.getSchemeSpecificPart()); 9371b645fe9cb8106dfcbf025a3fd7f58698c051bbPaul Jensen mResponseToken = dataUri.getFragment(); 9471b645fe9cb8106dfcbf025a3fd7f58698c051bbPaul Jensen } catch (MalformedURLException|NumberFormatException e) { 9571b645fe9cb8106dfcbf025a3fd7f58698c051bbPaul Jensen // System misconfigured, bail out in a way that at least provides network access. 9671b645fe9cb8106dfcbf025a3fd7f58698c051bbPaul Jensen done(CAPTIVE_PORTAL_APP_RETURN_WANTED_AS_IS); 97869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen } 98869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen 998df099df1516d23c113be3121635dcd34984a4a0Paul Jensen final Network network = new Network(mNetId); 1008df099df1516d23c113be3121635dcd34984a4a0Paul Jensen ConnectivityManager.setProcessDefaultNetwork(network); 1018df099df1516d23c113be3121635dcd34984a4a0Paul Jensen 10288eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen // Set HTTP proxy system properties to those of the selected Network. 10388eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen final LinkProperties lp = ConnectivityManager.from(this).getLinkProperties(network); 10488eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen if (lp != null) { 10588eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen final ProxyInfo proxyInfo = lp.getHttpProxy(); 10688eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen String host = ""; 10788eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen String port = ""; 10888eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen String exclList = ""; 10988eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen Uri pacFileUrl = Uri.EMPTY; 11088eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen if (proxyInfo != null) { 11188eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen host = proxyInfo.getHost(); 11288eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen port = Integer.toString(proxyInfo.getPort()); 11388eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen exclList = proxyInfo.getExclusionListAsString(); 11488eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen pacFileUrl = proxyInfo.getPacFileUrl(); 11588eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen } 11688eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen Proxy.setHttpProxySystemProperty(host, port, exclList, pacFileUrl); 11788eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen Log.v(TAG, "Set proxy system properties to " + proxyInfo); 11888eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen } 11988eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen 12088eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen // Proxy system properties must be initialized before setContentView is called because 12188eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen // setContentView initializes the WebView logic which in turn reads the system properties. 12288eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen setContentView(R.layout.activity_captive_portal_login); 12388eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen 12488eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen getActionBar().setDisplayShowHomeEnabled(false); 12588eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen 1268df099df1516d23c113be3121635dcd34984a4a0Paul Jensen // Exit app if Network disappears. 1278df099df1516d23c113be3121635dcd34984a4a0Paul Jensen final NetworkCapabilities networkCapabilities = 1288df099df1516d23c113be3121635dcd34984a4a0Paul Jensen ConnectivityManager.from(this).getNetworkCapabilities(network); 1298df099df1516d23c113be3121635dcd34984a4a0Paul Jensen if (networkCapabilities == null) { 1308df099df1516d23c113be3121635dcd34984a4a0Paul Jensen finish(); 1318df099df1516d23c113be3121635dcd34984a4a0Paul Jensen return; 1328df099df1516d23c113be3121635dcd34984a4a0Paul Jensen } 1338df099df1516d23c113be3121635dcd34984a4a0Paul Jensen mNetworkCallback = new NetworkCallback() { 1348df099df1516d23c113be3121635dcd34984a4a0Paul Jensen @Override 1358df099df1516d23c113be3121635dcd34984a4a0Paul Jensen public void onLost(Network lostNetwork) { 13671b645fe9cb8106dfcbf025a3fd7f58698c051bbPaul Jensen if (network.equals(lostNetwork)) done(CAPTIVE_PORTAL_APP_RETURN_UNWANTED); 1378df099df1516d23c113be3121635dcd34984a4a0Paul Jensen } 1388df099df1516d23c113be3121635dcd34984a4a0Paul Jensen }; 1398df099df1516d23c113be3121635dcd34984a4a0Paul Jensen final NetworkRequest.Builder builder = new NetworkRequest.Builder(); 1408df099df1516d23c113be3121635dcd34984a4a0Paul Jensen for (int transportType : networkCapabilities.getTransportTypes()) { 1418df099df1516d23c113be3121635dcd34984a4a0Paul Jensen builder.addTransportType(transportType); 1428df099df1516d23c113be3121635dcd34984a4a0Paul Jensen } 1438df099df1516d23c113be3121635dcd34984a4a0Paul Jensen ConnectivityManager.from(this).registerNetworkCallback(builder.build(), mNetworkCallback); 144869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen 14588eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen final WebView myWebView = (WebView) findViewById(R.id.webview); 14688eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen myWebView.clearCache(true); 147869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen WebSettings webSettings = myWebView.getSettings(); 148869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen webSettings.setJavaScriptEnabled(true); 149869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen myWebView.setWebViewClient(new MyWebViewClient()); 150869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen myWebView.setWebChromeClient(new MyWebChromeClient()); 15188eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen // Start initial page load so WebView finishes loading proxy settings. 15288eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen // Actual load of mUrl is initiated by MyWebViewClient. 15388eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen myWebView.loadData("", "text/html", null); 15488eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen } 15588eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen 15688eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen // Find WebView's proxy BroadcastReceiver and prompt it to read proxy system properties. 15788eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen private void setWebViewProxy() { 15888eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen LoadedApk loadedApk = getApplication().mLoadedApk; 15988eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen try { 16088eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen Field receiversField = LoadedApk.class.getDeclaredField("mReceivers"); 16188eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen receiversField.setAccessible(true); 16288eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen ArrayMap receivers = (ArrayMap) receiversField.get(loadedApk); 16388eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen for (Object receiverMap : receivers.values()) { 16488eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen for (Object rec : ((ArrayMap) receiverMap).keySet()) { 16588eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen Class clazz = rec.getClass(); 16688eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen if (clazz.getName().contains("ProxyChangeListener")) { 16788eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen Method onReceiveMethod = clazz.getDeclaredMethod("onReceive", Context.class, 16888eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen Intent.class); 16988eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION); 17088eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen onReceiveMethod.invoke(rec, getApplicationContext(), intent); 17188eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen Log.v(TAG, "Prompting WebView proxy reload."); 17288eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen } 17388eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen } 17488eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen } 17588eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen } catch (Exception e) { 17688eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen Log.e(TAG, "Exception while setting WebView proxy: " + e); 17788eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen } 178869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen } 179869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen 18071b645fe9cb8106dfcbf025a3fd7f58698c051bbPaul Jensen private void done(int result) { 18171b645fe9cb8106dfcbf025a3fd7f58698c051bbPaul Jensen if (mNetworkCallback != null) { 18271b645fe9cb8106dfcbf025a3fd7f58698c051bbPaul Jensen ConnectivityManager.from(this).unregisterNetworkCallback(mNetworkCallback); 18371b645fe9cb8106dfcbf025a3fd7f58698c051bbPaul Jensen } 184869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen Intent intent = new Intent(ACTION_CAPTIVE_PORTAL_LOGGED_IN); 185869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen intent.putExtra(Intent.EXTRA_TEXT, String.valueOf(mNetId)); 18671b645fe9cb8106dfcbf025a3fd7f58698c051bbPaul Jensen intent.putExtra(LOGGED_IN_RESULT, String.valueOf(result)); 18771b645fe9cb8106dfcbf025a3fd7f58698c051bbPaul Jensen intent.putExtra(RESPONSE_TOKEN, mResponseToken); 188869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen sendBroadcast(intent); 189869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen finish(); 190869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen } 191869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen 192869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen @Override 193869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen public boolean onCreateOptionsMenu(Menu menu) { 194869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen getMenuInflater().inflate(R.menu.captive_portal_login, menu); 195869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen return true; 196869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen } 197869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen 198869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen @Override 199b6ea9ee6fe6fc205f4f8be593ca993d594e8d504Paul Jensen public void onBackPressed() { 200b6ea9ee6fe6fc205f4f8be593ca993d594e8d504Paul Jensen WebView myWebView = (WebView) findViewById(R.id.webview); 201b6ea9ee6fe6fc205f4f8be593ca993d594e8d504Paul Jensen if (myWebView.canGoBack()) { 202b6ea9ee6fe6fc205f4f8be593ca993d594e8d504Paul Jensen myWebView.goBack(); 203b6ea9ee6fe6fc205f4f8be593ca993d594e8d504Paul Jensen } else { 204b6ea9ee6fe6fc205f4f8be593ca993d594e8d504Paul Jensen super.onBackPressed(); 205b6ea9ee6fe6fc205f4f8be593ca993d594e8d504Paul Jensen } 206b6ea9ee6fe6fc205f4f8be593ca993d594e8d504Paul Jensen } 207b6ea9ee6fe6fc205f4f8be593ca993d594e8d504Paul Jensen 208b6ea9ee6fe6fc205f4f8be593ca993d594e8d504Paul Jensen @Override 209869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen public boolean onOptionsItemSelected(MenuItem item) { 210869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen int id = item.getItemId(); 211869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen if (id == R.id.action_use_network) { 21271b645fe9cb8106dfcbf025a3fd7f58698c051bbPaul Jensen done(CAPTIVE_PORTAL_APP_RETURN_WANTED_AS_IS); 213869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen return true; 214869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen } 215869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen if (id == R.id.action_do_not_use_network) { 21671b645fe9cb8106dfcbf025a3fd7f58698c051bbPaul Jensen done(CAPTIVE_PORTAL_APP_RETURN_UNWANTED); 217869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen return true; 218869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen } 219869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen return super.onOptionsItemSelected(item); 220869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen } 221869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen 222869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen private void testForCaptivePortal() { 223869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen new Thread(new Runnable() { 224869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen public void run() { 225869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen // Give time for captive portal to open. 226869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen try { 227869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen Thread.sleep(1000); 228869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen } catch (InterruptedException e) { 229869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen } 230869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen HttpURLConnection urlConnection = null; 231869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen int httpResponseCode = 500; 232869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen try { 233869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen urlConnection = (HttpURLConnection) mURL.openConnection(); 234869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen urlConnection.setInstanceFollowRedirects(false); 235869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen urlConnection.setConnectTimeout(SOCKET_TIMEOUT_MS); 236869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen urlConnection.setReadTimeout(SOCKET_TIMEOUT_MS); 237869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen urlConnection.setUseCaches(false); 238869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen urlConnection.getInputStream(); 239869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen httpResponseCode = urlConnection.getResponseCode(); 240869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen } catch (IOException e) { 241869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen } finally { 242869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen if (urlConnection != null) urlConnection.disconnect(); 243869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen } 244869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen if (httpResponseCode == 204) { 24571b645fe9cb8106dfcbf025a3fd7f58698c051bbPaul Jensen done(CAPTIVE_PORTAL_APP_RETURN_APPEASED); 246869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen } 247869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen } 248869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen }).start(); 249869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen } 250869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen 251869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen private class MyWebViewClient extends WebViewClient { 25288eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen private boolean firstPageLoad = true; 25388eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen 254869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen @Override 255869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen public void onPageStarted(WebView view, String url, Bitmap favicon) { 25688eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen if (firstPageLoad) return; 257869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen testForCaptivePortal(); 258869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen } 259869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen 260869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen @Override 261869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen public void onPageFinished(WebView view, String url) { 26288eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen if (firstPageLoad) { 26388eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen firstPageLoad = false; 26488eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen // Now that WebView has loaded at least one page we know it has read in the proxy 26588eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen // settings. Now prompt the WebView read the Network-specific proxy settings. 26688eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen setWebViewProxy(); 26788eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen // Load the real page. 26888eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen view.loadUrl(mURL.toString()); 26988eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen return; 27088eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen } 271869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen testForCaptivePortal(); 272869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen } 273869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen } 274869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen 275869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen private class MyWebChromeClient extends WebChromeClient { 276869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen @Override 277869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen public void onProgressChanged(WebView view, int newProgress) { 2788f333f19222ac9415152e31f10e0df2b571b0b77Paul Jensen ProgressBar myProgressBar = (ProgressBar) findViewById(R.id.progress_bar); 2798f333f19222ac9415152e31f10e0df2b571b0b77Paul Jensen myProgressBar.setProgress(newProgress); 2808f333f19222ac9415152e31f10e0df2b571b0b77Paul Jensen myProgressBar.setVisibility(newProgress == 100 ? View.GONE : View.VISIBLE); 281869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen } 282869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen } 283869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen} 284