diff --git a/mobile/res/layout/http_authentication.xml b/mobile/res/layout/http_authentication.xml
new file mode 100644
index 00000000..7309f27c
--- /dev/null
+++ b/mobile/res/layout/http_authentication.xml
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mobile/res/values/strings.xml b/mobile/res/values/strings.xml
index ed36fa12..56802e6c 100644
--- a/mobile/res/values/strings.xml
+++ b/mobile/res/values/strings.xml
@@ -219,6 +219,23 @@
Copied to clipboard…
Do not show again
+
+ Sign in to %1$s %2$s"
+
+ Name
+
+ Password
+
+ Sign in
+
+ Save bookmark
+
+ Browser
+
+ Cancel
+
+ OK
+
Locate
Share
Intel
diff --git a/mobile/src/com/cradle/iitc_mobile/HttpAuthenticationDialog.java b/mobile/src/com/cradle/iitc_mobile/HttpAuthenticationDialog.java
new file mode 100644
index 00000000..1b92aac5
--- /dev/null
+++ b/mobile/src/com/cradle/iitc_mobile/HttpAuthenticationDialog.java
@@ -0,0 +1,166 @@
+/*
+* Copyright (C) 2010 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package com.cradle.iitc_mobile;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.WindowManager;
+import android.view.inputmethod.EditorInfo;
+import android.widget.TextView;
+import android.widget.TextView.OnEditorActionListener;
+
+/**
+* HTTP authentication dialog.
+*/
+public class HttpAuthenticationDialog {
+
+ private final Context mContext;
+
+ private final String mHost;
+ private final String mRealm;
+
+ private AlertDialog mDialog;
+ private TextView mUsernameView;
+ private TextView mPasswordView;
+
+ private OkListener mOkListener;
+ private CancelListener mCancelListener;
+
+ /**
+* Creates an HTTP authentication dialog.
+*/
+ public HttpAuthenticationDialog(Context context, String host, String realm) {
+ mContext = context;
+ mHost = host;
+ mRealm = realm;
+ createDialog();
+ }
+
+ private String getUsername() {
+ return mUsernameView.getText().toString();
+ }
+
+ private String getPassword() {
+ return mPasswordView.getText().toString();
+ }
+
+ /**
+* Sets the listener that will be notified when the user submits the credentials.
+*/
+ public void setOkListener(OkListener okListener) {
+ mOkListener = okListener;
+ }
+
+ /**
+* Sets the listener that will be notified when the user cancels the authentication
+* dialog.
+*/
+ public void setCancelListener(CancelListener cancelListener) {
+ mCancelListener = cancelListener;
+ }
+
+ /**
+* Shows the dialog.
+*/
+ public void show() {
+ mDialog.show();
+ mUsernameView.requestFocus();
+ }
+
+ /**
+* Hides, recreates, and shows the dialog. This can be used to handle configuration changes.
+*/
+ public void reshow() {
+ String username = getUsername();
+ String password = getPassword();
+ int focusId = mDialog.getCurrentFocus().getId();
+ mDialog.dismiss();
+ createDialog();
+ mDialog.show();
+ if (username != null) {
+ mUsernameView.setText(username);
+ }
+ if (password != null) {
+ mPasswordView.setText(password);
+ }
+ if (focusId != 0) {
+ mDialog.findViewById(focusId).requestFocus();
+ } else {
+ mUsernameView.requestFocus();
+ }
+ }
+
+ private void createDialog() {
+ LayoutInflater factory = LayoutInflater.from(mContext);
+ View v = factory.inflate(R.layout.http_authentication, null);
+ mUsernameView = (TextView) v.findViewById(R.id.username_edit);
+ mPasswordView = (TextView) v.findViewById(R.id.password_edit);
+ mPasswordView.setOnEditorActionListener(new OnEditorActionListener() {
+ @Override
+ public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+ if (actionId == EditorInfo.IME_ACTION_DONE) {
+ mDialog.getButton(AlertDialog.BUTTON_POSITIVE).performClick();
+ return true;
+ }
+ return false;
+ }
+ });
+
+ String title = mContext.getText(R.string.sign_in_to).toString();
+ title = String.format(title, mHost, mRealm);
+
+ mDialog = new AlertDialog.Builder(mContext)
+ .setTitle(title)
+ .setIconAttribute(android.R.attr.alertDialogIcon)
+ .setView(v)
+ .setPositiveButton(R.string.action, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int whichButton) {
+ if (mOkListener != null) {
+ mOkListener.onOk(mHost, mRealm, getUsername(), getPassword());
+ }
+ }})
+ .setNegativeButton(R.string.cancel,new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int whichButton) {
+ if (mCancelListener != null) mCancelListener.onCancel();
+ }})
+ .setOnCancelListener(new DialogInterface.OnCancelListener() {
+ public void onCancel(DialogInterface dialog) {
+ if (mCancelListener != null) mCancelListener.onCancel();
+ }})
+ .create();
+
+ // Make the IME appear when the dialog is displayed if applicable.
+ mDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
+ }
+
+ /**
+* Interface for listeners that are notified when the user submits the credentials.
+*/
+ public interface OkListener {
+ void onOk(String host, String realm, String username, String password);
+ }
+
+ /**
+* Interface for listeners that are notified when the user cancels the dialog.
+*/
+ public interface CancelListener {
+ void onCancel();
+ }
+}
diff --git a/mobile/src/com/cradle/iitc_mobile/IITC_Mobile.java b/mobile/src/com/cradle/iitc_mobile/IITC_Mobile.java
index 4b54fe96..b713de95 100644
--- a/mobile/src/com/cradle/iitc_mobile/IITC_Mobile.java
+++ b/mobile/src/com/cradle/iitc_mobile/IITC_Mobile.java
@@ -31,6 +31,7 @@ import android.view.Window;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.webkit.CookieManager;
+import android.webkit.HttpAuthHandler;
import android.webkit.WebView;
import android.widget.EditText;
import android.widget.ImageButton;
diff --git a/mobile/src/com/cradle/iitc_mobile/IITC_WebViewClient.java b/mobile/src/com/cradle/iitc_mobile/IITC_WebViewClient.java
index 84886807..c5b036a9 100644
--- a/mobile/src/com/cradle/iitc_mobile/IITC_WebViewClient.java
+++ b/mobile/src/com/cradle/iitc_mobile/IITC_WebViewClient.java
@@ -1,5 +1,6 @@
package com.cradle.iitc_mobile;
+import android.app.ActionBar;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
@@ -7,6 +8,7 @@ import android.net.http.SslError;
import android.os.Environment;
import android.preference.PreferenceManager;
import android.text.TextUtils;
+import android.webkit.HttpAuthHandler;
import android.webkit.SslErrorHandler;
import android.webkit.WebResourceResponse;
import android.webkit.WebView;
@@ -168,6 +170,44 @@ public class IITC_WebViewClient extends WebViewClient {
}
}
+ @Override
+ public void onReceivedHttpAuthRequest(WebView view, final HttpAuthHandler handler,
+ final String host, final String realm) {
+ String username = null;
+ String password = null;
+
+ boolean reuseHttpAuthUsernamePassword
+ = handler.useHttpAuthUsernamePassword();
+
+ if (reuseHttpAuthUsernamePassword && view != null) {
+ String[] credentials = view.getHttpAuthUsernamePassword(host, realm);
+ if (credentials != null && credentials.length == 2) {
+ username = credentials[0];
+ password = credentials[1];
+ }
+ }
+
+ if (username != null && password != null) {
+ handler.proceed(username, password);
+ } else {
+ HttpAuthenticationDialog dialog = new HttpAuthenticationDialog(mIitc, host, realm);
+
+ dialog.setOkListener(new HttpAuthenticationDialog.OkListener() {
+ public void onOk(String host, String realm, String username, String password) {
+ handler.proceed(username, password);
+ }
+ });
+
+ dialog.setCancelListener(new HttpAuthenticationDialog.CancelListener() {
+ public void onCancel() {
+ handler.cancel();
+ }
+ });
+
+ dialog.show();
+ }
+ }
+
public void reset() {
mIitcInjected = false;
}