CaptivePortalLoginActivity.java revision 869868be653cb8eedd338e8347dfee1520d38cec
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; 20869868be653cb8eedd338e8347dfee1520d38cecPaul Jensenimport android.content.Intent; 21869868be653cb8eedd338e8347dfee1520d38cecPaul Jensenimport android.graphics.Bitmap; 22869868be653cb8eedd338e8347dfee1520d38cecPaul Jensenimport android.net.ConnectivityManager; 23869868be653cb8eedd338e8347dfee1520d38cecPaul Jensenimport android.net.Network; 24869868be653cb8eedd338e8347dfee1520d38cecPaul Jensenimport android.os.Bundle; 25869868be653cb8eedd338e8347dfee1520d38cecPaul Jensenimport android.provider.Settings; 26869868be653cb8eedd338e8347dfee1520d38cecPaul Jensenimport android.provider.Settings.Global; 27869868be653cb8eedd338e8347dfee1520d38cecPaul Jensenimport android.view.Menu; 28869868be653cb8eedd338e8347dfee1520d38cecPaul Jensenimport android.view.MenuItem; 29869868be653cb8eedd338e8347dfee1520d38cecPaul Jensenimport android.view.Window; 30869868be653cb8eedd338e8347dfee1520d38cecPaul Jensenimport android.webkit.WebChromeClient; 31869868be653cb8eedd338e8347dfee1520d38cecPaul Jensenimport android.webkit.WebSettings; 32869868be653cb8eedd338e8347dfee1520d38cecPaul Jensenimport android.webkit.WebView; 33869868be653cb8eedd338e8347dfee1520d38cecPaul Jensenimport android.webkit.WebViewClient; 34869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen 35869868be653cb8eedd338e8347dfee1520d38cecPaul Jensenimport java.io.IOException; 36869868be653cb8eedd338e8347dfee1520d38cecPaul Jensenimport java.net.HttpURLConnection; 37869868be653cb8eedd338e8347dfee1520d38cecPaul Jensenimport java.net.MalformedURLException; 38869868be653cb8eedd338e8347dfee1520d38cecPaul Jensenimport java.net.URL; 39869868be653cb8eedd338e8347dfee1520d38cecPaul Jensenimport java.lang.InterruptedException; 40869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen 41869868be653cb8eedd338e8347dfee1520d38cecPaul Jensenpublic class CaptivePortalLoginActivity extends Activity { 42869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen private static final String DEFAULT_SERVER = "clients3.google.com"; 43869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen private static final int SOCKET_TIMEOUT_MS = 10000; 44869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen 45869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen // Keep this in sync with NetworkMonitor. 46869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen // Intent broadcast to ConnectivityService indicating sign-in is complete. 47869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen // Extras: 48869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen // EXTRA_TEXT = netId 49869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen // LOGGED_IN_RESULT = "1" if we should use network, "0" if not. 50869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen private static final String ACTION_CAPTIVE_PORTAL_LOGGED_IN = 51869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen "android.net.netmon.captive_portal_logged_in"; 52869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen private static final String LOGGED_IN_RESULT = "result"; 53869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen 54869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen private URL mURL; 55869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen private int mNetId; 56869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen 57869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen @Override 58869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen protected void onCreate(Bundle savedInstanceState) { 59869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen super.onCreate(savedInstanceState); 60869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen 61869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen String server = Settings.Global.getString(getContentResolver(), "captive_portal_server"); 62869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen if (server == null) server = DEFAULT_SERVER; 63869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen try { 64869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen mURL = new URL("http://" + server + "/generate_204"); 65869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen } catch (MalformedURLException e) { 66869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen done(true); 67869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen } 68869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen 69869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen requestWindowFeature(Window.FEATURE_PROGRESS); 70869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen setContentView(R.layout.activity_captive_portal_login); 71869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen 72869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen getActionBar().setDisplayShowHomeEnabled(false); 73869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen 74869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen mNetId = Integer.parseInt(getIntent().getStringExtra(Intent.EXTRA_TEXT)); 75869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen ConnectivityManager.setProcessDefaultNetwork(new Network(mNetId)); 76869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen 77869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen WebView myWebView = (WebView) findViewById(R.id.webview); 78869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen WebSettings webSettings = myWebView.getSettings(); 79869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen webSettings.setJavaScriptEnabled(true); 80869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen myWebView.setWebViewClient(new MyWebViewClient()); 81869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen myWebView.setWebChromeClient(new MyWebChromeClient()); 82869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen myWebView.loadUrl(mURL.toString()); 83869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen } 84869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen 85869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen private void done(boolean use_network) { 86869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen Intent intent = new Intent(ACTION_CAPTIVE_PORTAL_LOGGED_IN); 87869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen intent.putExtra(Intent.EXTRA_TEXT, String.valueOf(mNetId)); 88869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen intent.putExtra(LOGGED_IN_RESULT, use_network ? "1" : "0"); 89869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen sendBroadcast(intent); 90869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen finish(); 91869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen } 92869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen 93869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen @Override 94869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen public boolean onCreateOptionsMenu(Menu menu) { 95869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen getMenuInflater().inflate(R.menu.captive_portal_login, menu); 96869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen return true; 97869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen } 98869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen 99869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen @Override 100869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen public boolean onOptionsItemSelected(MenuItem item) { 101869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen int id = item.getItemId(); 102869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen if (id == R.id.action_use_network) { 103869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen done(true); 104869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen return true; 105869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen } 106869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen if (id == R.id.action_do_not_use_network) { 107869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen done(false); 108869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen return true; 109869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen } 110869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen return super.onOptionsItemSelected(item); 111869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen } 112869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen 113869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen private void testForCaptivePortal() { 114869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen new Thread(new Runnable() { 115869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen public void run() { 116869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen // Give time for captive portal to open. 117869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen try { 118869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen Thread.sleep(1000); 119869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen } catch (InterruptedException e) { 120869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen } 121869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen HttpURLConnection urlConnection = null; 122869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen int httpResponseCode = 500; 123869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen try { 124869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen urlConnection = (HttpURLConnection) mURL.openConnection(); 125869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen urlConnection.setInstanceFollowRedirects(false); 126869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen urlConnection.setConnectTimeout(SOCKET_TIMEOUT_MS); 127869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen urlConnection.setReadTimeout(SOCKET_TIMEOUT_MS); 128869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen urlConnection.setUseCaches(false); 129869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen urlConnection.getInputStream(); 130869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen httpResponseCode = urlConnection.getResponseCode(); 131869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen } catch (IOException e) { 132869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen } finally { 133869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen if (urlConnection != null) urlConnection.disconnect(); 134869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen } 135869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen if (httpResponseCode == 204) { 136869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen done(true); 137869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen } 138869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen } 139869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen }).start(); 140869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen } 141869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen 142869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen private class MyWebViewClient extends WebViewClient { 143869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen @Override 144869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen public void onPageStarted(WebView view, String url, Bitmap favicon) { 145869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen testForCaptivePortal(); 146869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen } 147869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen 148869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen @Override 149869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen public void onPageFinished(WebView view, String url) { 150869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen testForCaptivePortal(); 151869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen } 152869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen } 153869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen 154869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen private class MyWebChromeClient extends WebChromeClient { 155869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen @Override 156869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen public void onProgressChanged(WebView view, int newProgress) { 157869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen setProgress(newProgress*100); 158869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen } 159869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen } 160869868be653cb8eedd338e8347dfee1520d38cecPaul Jensen} 161