summaryrefslogtreecommitdiffstats
path: root/src/com
diff options
context:
space:
mode:
Diffstat (limited to 'src/com')
-rw-r--r--src/com/android/browser/BaseUi.java13
-rw-r--r--src/com/android/browser/Controller.java13
-rw-r--r--src/com/android/browser/DeviceAccountLogin.java165
-rw-r--r--src/com/android/browser/Tab.java28
-rw-r--r--src/com/android/browser/TitleBarXLarge.java118
-rw-r--r--src/com/android/browser/UI.java5
-rw-r--r--src/com/android/browser/WebViewController.java3
-rw-r--r--src/com/android/browser/XLargeUi.java5
8 files changed, 347 insertions, 3 deletions
diff --git a/src/com/android/browser/BaseUi.java b/src/com/android/browser/BaseUi.java
index 5084e319e..71346ae35 100644
--- a/src/com/android/browser/BaseUi.java
+++ b/src/com/android/browser/BaseUi.java
@@ -240,6 +240,7 @@ public abstract class BaseUi implements UI, WebViewFactory {
onProgressChanged(tab);
boolean incognito = mActiveTab.getWebView().isPrivateBrowsingEnabled();
getTitleBar().setIncognitoMode(incognito);
+ updateAutoLogin(tab, false);
}
Tab getActiveTab() {
@@ -546,11 +547,23 @@ public abstract class BaseUi implements UI, WebViewFactory {
&& mComboView == null;
}
+ @Override
+ public void showAutoLogin(Tab tab) {
+ updateAutoLogin(tab, true);
+ }
+
+ @Override
+ public void hideAutoLogin(Tab tab) {
+ updateAutoLogin(tab, true);
+ }
+
// -------------------------------------------------------------------------
protected void updateNavigationState(Tab tab) {
}
+ protected void updateAutoLogin(Tab tab, boolean animate) {}
+
/**
* Update the lock icon to correspond to our latest state.
*/
diff --git a/src/com/android/browser/Controller.java b/src/com/android/browser/Controller.java
index 19ad40efc..8f546f9b3 100644
--- a/src/com/android/browser/Controller.java
+++ b/src/com/android/browser/Controller.java
@@ -996,6 +996,19 @@ public class Controller
mPageDialogsHandler.showSSLCertificateOnError(view, handler, error);
}
+ @Override
+ public void showAutoLogin(Tab tab) {
+ assert tab.inForeground();
+ // Update the title bar to show the auto-login request.
+ mUi.showAutoLogin(tab);
+ }
+
+ @Override
+ public void hideAutoLogin(Tab tab) {
+ assert tab.inForeground();
+ mUi.hideAutoLogin(tab);
+ }
+
// helper method
/*
diff --git a/src/com/android/browser/DeviceAccountLogin.java b/src/com/android/browser/DeviceAccountLogin.java
new file mode 100644
index 000000000..50b8c979e
--- /dev/null
+++ b/src/com/android/browser/DeviceAccountLogin.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2011 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.android.browser;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.accounts.AccountManagerCallback;
+import android.accounts.AccountManagerFuture;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
+
+public class DeviceAccountLogin implements
+ AccountManagerCallback<Bundle>, DialogInterface.OnClickListener {
+
+ private final Activity mActivity;
+ private final WebView mWebView;
+ private final Tab mTab;
+ private final WebViewController mWebViewController;
+ private final AccountManager mAccountManager;
+ private Account[] mAccounts;
+ private int mCurrentAccount;
+ private AutoLoginCallback mCallback;
+ private String mAuthToken;
+
+ // Current state of the login.
+ private int mState = INITIAL;
+
+ public static final int INITIAL = 0;
+ public static final int FAILED = 1;
+ public static final int PROCESSING = 2;
+
+ public interface AutoLoginCallback {
+ public void setAccount(String account);
+ public void loginFailed();
+ }
+
+ public DeviceAccountLogin(Activity activity, WebView view, Tab tab,
+ WebViewController controller) {
+ mActivity = activity;
+ mWebView = view;
+ mTab = tab;
+ mWebViewController = controller;
+ mAccountManager = AccountManager.get(activity);
+ }
+
+ public void handleLogin(String realm, String account, String args) {
+ mAccounts = mAccountManager.getAccountsByType(realm);
+ mAuthToken = "weblogin:" + args;
+
+ // No need to display UI if there are no accounts.
+ if (mAccounts.length == 0) {
+ return;
+ }
+
+ // Verify the account before using it.
+ for (Account a : mAccounts) {
+ if (a.name.equals(account)) {
+ // Handle the automatic login case where the service gave us an
+ // account to use.
+ mAccountManager.getAuthToken(a, mAuthToken, null,
+ mActivity, this, null);
+ return;
+ }
+ }
+
+ displayLoginUi();
+ }
+
+ @Override
+ public void run(AccountManagerFuture<Bundle> value) {
+ try {
+ String result = value.getResult().getString(
+ AccountManager.KEY_AUTHTOKEN);
+ if (result == null) {
+ loginFailed();
+ } else {
+ mWebView.loadUrl(result);
+ mTab.setDeviceAccountLogin(null);
+ if (mTab.inForeground()) {
+ mWebViewController.hideAutoLogin(mTab);
+ }
+ }
+ } catch (Exception e) {
+ loginFailed();
+ }
+ }
+
+ public int getState() {
+ return mState;
+ }
+
+ private void loginFailed() {
+ mState = FAILED;
+ if (mTab.getDeviceAccountLogin() == null) {
+ displayLoginUi();
+ } else {
+ assert mCallback != null;
+ mCallback.loginFailed();
+ }
+ }
+
+ private void displayLoginUi() {
+ // Display the account picker.
+ mTab.setDeviceAccountLogin(this);
+ if (mTab.inForeground()) {
+ mWebViewController.showAutoLogin(mTab);
+ }
+ }
+
+ public void cancel() {
+ mTab.setDeviceAccountLogin(null);
+ }
+
+ public void login(AutoLoginCallback cb) {
+ mState = PROCESSING;
+ mCallback = cb;
+ mAccountManager.getAuthToken(
+ mAccounts[mCurrentAccount], mAuthToken, null,
+ mActivity, this, null);
+ }
+
+ public void chooseAccount(AutoLoginCallback cb) {
+ mCallback = cb;
+ CharSequence[] names = new CharSequence[mAccounts.length];
+ int i = 0;
+ for (Account a : mAccounts) {
+ names[i++] = a.name;
+ }
+ new AlertDialog.Builder(mActivity)
+ .setTitle(R.string.pref_autologin_title)
+ .setSingleChoiceItems(names, mCurrentAccount, this)
+ .setCancelable(true)
+ .show();
+ }
+
+ public String getCurrentAccount() {
+ return mAccounts[mCurrentAccount].name;
+ }
+
+ @Override
+ public void onClick(DialogInterface d, int which) {
+ assert mCallback != null;
+ mCallback.setAccount(mAccounts[which].name);
+ mCurrentAccount = which;
+ d.dismiss();
+ }
+}
diff --git a/src/com/android/browser/Tab.java b/src/com/android/browser/Tab.java
index 70028ea32..2d194f0c4 100644
--- a/src/com/android/browser/Tab.java
+++ b/src/com/android/browser/Tab.java
@@ -132,6 +132,8 @@ class Tab {
// Listener used to know when we move forward or back in the history list.
private final WebBackForwardListClient mWebBackForwardListClient;
private DataController mDataController;
+ // State of the auto-login request.
+ private DeviceAccountLogin mDeviceAccountLogin;
// AsyncTask for downloading touch icons
DownloadTouchIcon mTouchIconLoader;
@@ -527,6 +529,13 @@ class Tab {
}
}
+ // Cancel the auto-login process.
+ if (mDeviceAccountLogin != null) {
+ mDeviceAccountLogin.cancel();
+ mDeviceAccountLogin = null;
+ mWebViewController.hideAutoLogin(Tab.this);
+ }
+
// finally update the UI in the activity if it is in the foreground
mWebViewController.onPageStarted(Tab.this, view, favicon);
@@ -809,8 +818,27 @@ class Tab {
}
mWebViewController.onUnhandledKeyEvent(event);
}
+
+ @Override
+ public void onReceivedLoginRequest(WebView view, String realm,
+ String account, String args) {
+ new DeviceAccountLogin(mActivity, view, Tab.this, mWebViewController)
+ .handleLogin(realm, account, args);
+ }
+
};
+ // Called by DeviceAccountLogin when the Tab needs to have the auto-login UI
+ // displayed.
+ void setDeviceAccountLogin(DeviceAccountLogin login) {
+ mDeviceAccountLogin = login;
+ }
+
+ // Returns non-null if the title bar should display the auto-login UI.
+ DeviceAccountLogin getDeviceAccountLogin() {
+ return mDeviceAccountLogin;
+ }
+
// -------------------------------------------------------------------------
// WebChromeClient implementation for the main WebView
// -------------------------------------------------------------------------
diff --git a/src/com/android/browser/TitleBarXLarge.java b/src/com/android/browser/TitleBarXLarge.java
index 51cf0c36c..a786fd7df 100644
--- a/src/com/android/browser/TitleBarXLarge.java
+++ b/src/com/android/browser/TitleBarXLarge.java
@@ -26,6 +26,9 @@ import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
+import android.view.animation.Animation;
+import android.view.animation.Animation.AnimationListener;
+import android.view.animation.AnimationUtils;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
@@ -34,9 +37,12 @@ import android.view.View.OnFocusChangeListener;
import android.view.ViewGroup;
import android.webkit.WebView;
import android.widget.AbsoluteLayout;
+import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
+import android.widget.ProgressBar;
+import android.widget.TextView;
import java.util.List;
@@ -44,7 +50,8 @@ import java.util.List;
* tabbed title bar for xlarge screen browser
*/
public class TitleBarXLarge extends TitleBarBase
- implements OnClickListener, OnFocusChangeListener, TextChangeWatcher {
+ implements OnClickListener, OnFocusChangeListener, TextChangeWatcher,
+ DeviceAccountLogin.AutoLoginCallback {
private XLargeUi mUi;
@@ -66,6 +73,14 @@ public class TitleBarXLarge extends TitleBarBase
private PageProgressView mProgressView;
private Drawable mFocusDrawable;
private Drawable mUnfocusDrawable;
+ // Auto-login UI
+ private View mAutoLogin;
+ private Button mAutoLoginAccount;
+ private Button mAutoLoginLogin;
+ private ProgressBar mAutoLoginProgress;
+ private TextView mAutoLoginError;
+ private ImageButton mAutoLoginCancel;
+ private DeviceAccountLogin mAutoLoginHandler;
private boolean mInLoad;
private boolean mUseQuickControls;
@@ -133,6 +148,18 @@ public class TitleBarXLarge extends TitleBarBase
mUrlInput.setOnFocusChangeListener(this);
mUrlInput.setSelectAllOnFocus(true);
mUrlInput.addQueryTextWatcher(this);
+ mAutoLogin = findViewById(R.id.autologin);
+ mAutoLoginAccount = (Button) findViewById(R.id.autologin_account);
+ mAutoLoginAccount.setOnClickListener(this);
+ mAutoLoginLogin = (Button) findViewById(R.id.autologin_login);
+ mAutoLoginLogin.setOnClickListener(this);
+ mAutoLoginProgress =
+ (ProgressBar) findViewById(R.id.autologin_progress);
+ mAutoLoginError = (TextView) findViewById(R.id.autologin_error);
+ mAutoLoginCancel =
+ (ImageButton) mAutoLogin.findViewById(R.id.autologin_close);
+ mAutoLoginCancel.setOnClickListener(this);
+
setFocusState(false);
}
@@ -148,6 +175,45 @@ public class TitleBarXLarge extends TitleBarBase
}
}
+ void updateAutoLogin(Tab tab, boolean animate) {
+ DeviceAccountLogin login = tab.getDeviceAccountLogin();
+ if (login != null) {
+ mAutoLoginHandler = login;
+ mAutoLogin.setVisibility(View.VISIBLE);
+ mAutoLoginAccount.setText(login.getCurrentAccount());
+ mAutoLoginAccount.setEnabled(true);
+ mAutoLoginLogin.setEnabled(true);
+ mAutoLoginProgress.setVisibility(View.GONE);
+ mAutoLoginError.setVisibility(View.GONE);
+ switch (login.getState()) {
+ case DeviceAccountLogin.PROCESSING:
+ mAutoLoginAccount.setEnabled(false);
+ mAutoLoginLogin.setEnabled(false);
+ mAutoLoginProgress.setVisibility(View.VISIBLE);
+ break;
+ case DeviceAccountLogin.FAILED:
+ mAutoLoginProgress.setVisibility(View.GONE);
+ mAutoLoginError.setVisibility(View.VISIBLE);
+ break;
+ case DeviceAccountLogin.INITIAL:
+ break;
+ default:
+ throw new IllegalStateException();
+ }
+ if (animate) {
+ mAutoLogin.startAnimation(AnimationUtils.loadAnimation(
+ getContext(), R.anim.autologin_enter));
+ }
+ } else {
+ mAutoLoginHandler = null;
+ if (animate) {
+ hideAutoLogin();
+ } else if (mAutoLogin.getAnimation() == null) {
+ mAutoLogin.setVisibility(View.GONE);
+ }
+ }
+ }
+
private ViewGroup.LayoutParams makeLayoutParams() {
if (mUseQuickControls) {
return new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT,
@@ -161,7 +227,11 @@ public class TitleBarXLarge extends TitleBarBase
@Override
public int getEmbeddedHeight() {
- return mContainer.getHeight();
+ int height = mContainer.getHeight();
+ if (mAutoLogin.getVisibility() == View.VISIBLE) {
+ height += mAutoLogin.getHeight();
+ }
+ return height;
}
void setUseQuickControls(boolean useQuickControls) {
@@ -234,6 +304,19 @@ public class TitleBarXLarge extends TitleBarBase
mUrlInput.clearFocus();
}
+ private void hideAutoLogin() {
+ Animation anim = AnimationUtils.loadAnimation(
+ getContext(), R.anim.autologin_exit);
+ anim.setAnimationListener(new AnimationListener() {
+ @Override public void onAnimationEnd(Animation a) {
+ mAutoLogin.setVisibility(View.GONE);
+ }
+ @Override public void onAnimationStart(Animation a) {}
+ @Override public void onAnimationRepeat(Animation a) {}
+ });
+ mAutoLogin.startAnimation(anim);
+ }
+
@Override
public void onClick(View v) {
if (mBackButton == v) {
@@ -258,10 +341,41 @@ public class TitleBarXLarge extends TitleBarBase
clearOrClose();
} else if (mVoiceSearch == v) {
mUiController.startVoiceSearch();
+ } else if (mAutoLoginCancel == v) {
+ if (mAutoLoginHandler != null) {
+ mAutoLoginHandler.cancel();
+ mAutoLoginHandler = null;
+ }
+ hideAutoLogin();
+ } else if (mAutoLoginLogin == v) {
+ if (mAutoLoginHandler != null) {
+ mAutoLoginAccount.setEnabled(false);
+ mAutoLoginLogin.setEnabled(false);
+ mAutoLoginProgress.setVisibility(View.VISIBLE);
+ mAutoLoginError.setVisibility(View.GONE);
+ mAutoLoginHandler.login(this);
+ }
+ } else if (mAutoLoginAccount == v) {
+ if (mAutoLoginHandler != null) {
+ mAutoLoginHandler.chooseAccount(this);
+ }
}
}
@Override
+ public void setAccount(String account) {
+ mAutoLoginAccount.setText(account);
+ }
+
+ @Override
+ public void loginFailed() {
+ mAutoLoginAccount.setEnabled(true);
+ mAutoLoginLogin.setEnabled(true);
+ mAutoLoginProgress.setVisibility(View.GONE);
+ mAutoLoginError.setVisibility(View.VISIBLE);
+ }
+
+ @Override
void setFavicon(Bitmap icon) { }
private void clearOrClose() {
diff --git a/src/com/android/browser/UI.java b/src/com/android/browser/UI.java
index 13f8af27d..368c82986 100644
--- a/src/com/android/browser/UI.java
+++ b/src/com/android/browser/UI.java
@@ -124,9 +124,12 @@ public interface UI {
boolean dispatchKey(int code, KeyEvent event);
-
public static interface DropdownChangeListener {
void onNewDropdownDimensions(int height);
}
void registerDropdownChangeListener(DropdownChangeListener d);
+
+ void showAutoLogin(Tab tab);
+
+ void hideAutoLogin(Tab tab);
}
diff --git a/src/com/android/browser/WebViewController.java b/src/com/android/browser/WebViewController.java
index 813b63be3..6b442079b 100644
--- a/src/com/android/browser/WebViewController.java
+++ b/src/com/android/browser/WebViewController.java
@@ -112,4 +112,7 @@ public interface WebViewController {
void bookmarkedStatusHasChanged(Tab tab);
+ void showAutoLogin(Tab tab);
+
+ void hideAutoLogin(Tab tab);
}
diff --git a/src/com/android/browser/XLargeUi.java b/src/com/android/browser/XLargeUi.java
index 9b5a88408..566f7d131 100644
--- a/src/com/android/browser/XLargeUi.java
+++ b/src/com/android/browser/XLargeUi.java
@@ -377,6 +377,11 @@ public class XLargeUi extends BaseUi implements ScrollListener {
}
@Override
+ protected void updateAutoLogin(Tab tab, boolean animate) {
+ mTitleBar.updateAutoLogin(tab, animate);
+ }
+
+ @Override
public void setUrlTitle(Tab tab) {
super.setUrlTitle(tab);
mTabBar.onUrlAndTitle(tab, tab.getUrl(), tab.getTitle());