CaptivePortalLoginActivity.java revision 88eb0fa8eec7da1b7a3bd39f9d9844909911bc64
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
65869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen    //     LOGGED_IN_RESULT = "1" if we should use network, "0" if not.
66869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen    private static final String ACTION_CAPTIVE_PORTAL_LOGGED_IN =
67869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen            "android.net.netmon.captive_portal_logged_in";
68869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen    private static final String LOGGED_IN_RESULT = "result";
69869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen
70869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen    private URL mURL;
71869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen    private int mNetId;
728df099df1516d23c113be3121635dcd34984a4a0Paul Jensen    private NetworkCallback mNetworkCallback;
73869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen
74869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen    @Override
75869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen    protected void onCreate(Bundle savedInstanceState) {
76869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen        super.onCreate(savedInstanceState);
77869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen
78869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen        String server = Settings.Global.getString(getContentResolver(), "captive_portal_server");
79869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen        if (server == null) server = DEFAULT_SERVER;
80869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen        try {
81869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen            mURL = new URL("http://" + server + "/generate_204");
82869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen        } catch (MalformedURLException e) {
83869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen            done(true);
84869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen        }
85869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen
86869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen        mNetId = Integer.parseInt(getIntent().getStringExtra(Intent.EXTRA_TEXT));
878df099df1516d23c113be3121635dcd34984a4a0Paul Jensen        final Network network = new Network(mNetId);
888df099df1516d23c113be3121635dcd34984a4a0Paul Jensen        ConnectivityManager.setProcessDefaultNetwork(network);
898df099df1516d23c113be3121635dcd34984a4a0Paul Jensen
9088eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen        // Set HTTP proxy system properties to those of the selected Network.
9188eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen        final LinkProperties lp = ConnectivityManager.from(this).getLinkProperties(network);
9288eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen        if (lp != null) {
9388eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen            final ProxyInfo proxyInfo = lp.getHttpProxy();
9488eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen            String host = "";
9588eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen            String port = "";
9688eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen            String exclList = "";
9788eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen            Uri pacFileUrl = Uri.EMPTY;
9888eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen            if (proxyInfo != null) {
9988eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen                host = proxyInfo.getHost();
10088eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen                port = Integer.toString(proxyInfo.getPort());
10188eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen                exclList = proxyInfo.getExclusionListAsString();
10288eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen                pacFileUrl = proxyInfo.getPacFileUrl();
10388eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen            }
10488eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen            Proxy.setHttpProxySystemProperty(host, port, exclList, pacFileUrl);
10588eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen            Log.v(TAG, "Set proxy system properties to " + proxyInfo);
10688eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen        }
10788eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen
10888eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen        // Proxy system properties must be initialized before setContentView is called because
10988eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen        // setContentView initializes the WebView logic which in turn reads the system properties.
11088eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen        setContentView(R.layout.activity_captive_portal_login);
11188eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen
11288eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen        getActionBar().setDisplayShowHomeEnabled(false);
11388eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen
1148df099df1516d23c113be3121635dcd34984a4a0Paul Jensen        // Exit app if Network disappears.
1158df099df1516d23c113be3121635dcd34984a4a0Paul Jensen        final NetworkCapabilities networkCapabilities =
1168df099df1516d23c113be3121635dcd34984a4a0Paul Jensen                ConnectivityManager.from(this).getNetworkCapabilities(network);
1178df099df1516d23c113be3121635dcd34984a4a0Paul Jensen        if (networkCapabilities == null) {
1188df099df1516d23c113be3121635dcd34984a4a0Paul Jensen            finish();
1198df099df1516d23c113be3121635dcd34984a4a0Paul Jensen            return;
1208df099df1516d23c113be3121635dcd34984a4a0Paul Jensen        }
1218df099df1516d23c113be3121635dcd34984a4a0Paul Jensen        mNetworkCallback = new NetworkCallback() {
1228df099df1516d23c113be3121635dcd34984a4a0Paul Jensen            @Override
1238df099df1516d23c113be3121635dcd34984a4a0Paul Jensen            public void onLost(Network lostNetwork) {
1248df099df1516d23c113be3121635dcd34984a4a0Paul Jensen                if (network.equals(lostNetwork)) done(false);
1258df099df1516d23c113be3121635dcd34984a4a0Paul Jensen            }
1268df099df1516d23c113be3121635dcd34984a4a0Paul Jensen        };
1278df099df1516d23c113be3121635dcd34984a4a0Paul Jensen        final NetworkRequest.Builder builder = new NetworkRequest.Builder();
1288df099df1516d23c113be3121635dcd34984a4a0Paul Jensen        for (int transportType : networkCapabilities.getTransportTypes()) {
1298df099df1516d23c113be3121635dcd34984a4a0Paul Jensen            builder.addTransportType(transportType);
1308df099df1516d23c113be3121635dcd34984a4a0Paul Jensen        }
1318df099df1516d23c113be3121635dcd34984a4a0Paul Jensen        ConnectivityManager.from(this).registerNetworkCallback(builder.build(), mNetworkCallback);
132869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen
13388eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen        final WebView myWebView = (WebView) findViewById(R.id.webview);
13488eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen        myWebView.clearCache(true);
135869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen        WebSettings webSettings = myWebView.getSettings();
136869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen        webSettings.setJavaScriptEnabled(true);
137869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen        myWebView.setWebViewClient(new MyWebViewClient());
138869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen        myWebView.setWebChromeClient(new MyWebChromeClient());
13988eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen        // Start initial page load so WebView finishes loading proxy settings.
14088eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen        // Actual load of mUrl is initiated by MyWebViewClient.
14188eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen        myWebView.loadData("", "text/html", null);
14288eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen    }
14388eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen
14488eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen    // Find WebView's proxy BroadcastReceiver and prompt it to read proxy system properties.
14588eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen    private void setWebViewProxy() {
14688eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen        LoadedApk loadedApk = getApplication().mLoadedApk;
14788eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen        try {
14888eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen            Field receiversField = LoadedApk.class.getDeclaredField("mReceivers");
14988eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen            receiversField.setAccessible(true);
15088eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen            ArrayMap receivers = (ArrayMap) receiversField.get(loadedApk);
15188eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen            for (Object receiverMap : receivers.values()) {
15288eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen                for (Object rec : ((ArrayMap) receiverMap).keySet()) {
15388eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen                    Class clazz = rec.getClass();
15488eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen                    if (clazz.getName().contains("ProxyChangeListener")) {
15588eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen                        Method onReceiveMethod = clazz.getDeclaredMethod("onReceive", Context.class,
15688eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen                                Intent.class);
15788eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen                        Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION);
15888eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen                        onReceiveMethod.invoke(rec, getApplicationContext(), intent);
15988eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen                        Log.v(TAG, "Prompting WebView proxy reload.");
16088eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen                    }
16188eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen                }
16288eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen            }
16388eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen        } catch (Exception e) {
16488eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen            Log.e(TAG, "Exception while setting WebView proxy: " + e);
16588eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen        }
166869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen    }
167869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen
168869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen    private void done(boolean use_network) {
1698df099df1516d23c113be3121635dcd34984a4a0Paul Jensen        ConnectivityManager.from(this).unregisterNetworkCallback(mNetworkCallback);
170869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen        Intent intent = new Intent(ACTION_CAPTIVE_PORTAL_LOGGED_IN);
171869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen        intent.putExtra(Intent.EXTRA_TEXT, String.valueOf(mNetId));
172869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen        intent.putExtra(LOGGED_IN_RESULT, use_network ? "1" : "0");
173869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen        sendBroadcast(intent);
174869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen        finish();
175869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen    }
176869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen
177869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen    @Override
178869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen    public boolean onCreateOptionsMenu(Menu menu) {
179869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen        getMenuInflater().inflate(R.menu.captive_portal_login, menu);
180869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen        return true;
181869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen    }
182869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen
183869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen    @Override
184b6ea9ee6fe6fc205f4f8be593ca993d594e8d504Paul Jensen    public void onBackPressed() {
185b6ea9ee6fe6fc205f4f8be593ca993d594e8d504Paul Jensen        WebView myWebView = (WebView) findViewById(R.id.webview);
186b6ea9ee6fe6fc205f4f8be593ca993d594e8d504Paul Jensen        if (myWebView.canGoBack()) {
187b6ea9ee6fe6fc205f4f8be593ca993d594e8d504Paul Jensen            myWebView.goBack();
188b6ea9ee6fe6fc205f4f8be593ca993d594e8d504Paul Jensen        } else {
189b6ea9ee6fe6fc205f4f8be593ca993d594e8d504Paul Jensen            super.onBackPressed();
190b6ea9ee6fe6fc205f4f8be593ca993d594e8d504Paul Jensen        }
191b6ea9ee6fe6fc205f4f8be593ca993d594e8d504Paul Jensen    }
192b6ea9ee6fe6fc205f4f8be593ca993d594e8d504Paul Jensen
193b6ea9ee6fe6fc205f4f8be593ca993d594e8d504Paul Jensen    @Override
194869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen    public boolean onOptionsItemSelected(MenuItem item) {
195869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen        int id = item.getItemId();
196869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen        if (id == R.id.action_use_network) {
197869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen            done(true);
198869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen            return true;
199869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen        }
200869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen        if (id == R.id.action_do_not_use_network) {
201869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen            done(false);
202869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen            return true;
203869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen        }
204869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen        return super.onOptionsItemSelected(item);
205869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen    }
206869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen
207869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen    private void testForCaptivePortal() {
208869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen        new Thread(new Runnable() {
209869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen            public void run() {
210869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen                // Give time for captive portal to open.
211869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen                try {
212869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen                    Thread.sleep(1000);
213869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen                } catch (InterruptedException e) {
214869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen                }
215869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen                HttpURLConnection urlConnection = null;
216869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen                int httpResponseCode = 500;
217869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen                try {
218869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen                    urlConnection = (HttpURLConnection) mURL.openConnection();
219869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen                    urlConnection.setInstanceFollowRedirects(false);
220869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen                    urlConnection.setConnectTimeout(SOCKET_TIMEOUT_MS);
221869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen                    urlConnection.setReadTimeout(SOCKET_TIMEOUT_MS);
222869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen                    urlConnection.setUseCaches(false);
223869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen                    urlConnection.getInputStream();
224869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen                    httpResponseCode = urlConnection.getResponseCode();
225869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen                } catch (IOException e) {
226869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen                } finally {
227869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen                    if (urlConnection != null) urlConnection.disconnect();
228869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen                }
229869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen                if (httpResponseCode == 204) {
230869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen                    done(true);
231869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen                }
232869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen            }
233869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen        }).start();
234869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen    }
235869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen
236869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen    private class MyWebViewClient extends WebViewClient {
23788eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen        private boolean firstPageLoad = true;
23888eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen
239869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen        @Override
240869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen        public void onPageStarted(WebView view, String url, Bitmap favicon) {
24188eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen            if (firstPageLoad) return;
242869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen            testForCaptivePortal();
243869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen        }
244869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen
245869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen        @Override
246869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen        public void onPageFinished(WebView view, String url) {
24788eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen            if (firstPageLoad) {
24888eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen                firstPageLoad = false;
24988eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen                // Now that WebView has loaded at least one page we know it has read in the proxy
25088eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen                // settings.  Now prompt the WebView read the Network-specific proxy settings.
25188eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen                setWebViewProxy();
25288eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen                // Load the real page.
25388eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen                view.loadUrl(mURL.toString());
25488eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen                return;
25588eb0fa8eec7da1b7a3bd39f9d9844909911bc64Paul Jensen            }
256869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen            testForCaptivePortal();
257869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen        }
258869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen    }
259869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen
260869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen    private class MyWebChromeClient extends WebChromeClient {
261869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen        @Override
262869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen        public void onProgressChanged(WebView view, int newProgress) {
2638f333f19222ac9415152e31f10e0df2b571b0b77Paul Jensen            ProgressBar myProgressBar = (ProgressBar) findViewById(R.id.progress_bar);
2648f333f19222ac9415152e31f10e0df2b571b0b77Paul Jensen            myProgressBar.setProgress(newProgress);
2658f333f19222ac9415152e31f10e0df2b571b0b77Paul Jensen            myProgressBar.setVisibility(newProgress == 100 ? View.GONE : View.VISIBLE);
266869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen        }
267869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen    }
268869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen}
269