19206677e461328f15854c5fcb1366d0e261534c6Patrick Scott/*
29206677e461328f15854c5fcb1366d0e261534c6Patrick Scott * Copyright (C) 2011 The Android Open Source Project
39206677e461328f15854c5fcb1366d0e261534c6Patrick Scott *
49206677e461328f15854c5fcb1366d0e261534c6Patrick Scott * Licensed under the Apache License, Version 2.0 (the "License");
59206677e461328f15854c5fcb1366d0e261534c6Patrick Scott * you may not use this file except in compliance with the License.
69206677e461328f15854c5fcb1366d0e261534c6Patrick Scott * You may obtain a copy of the License at
79206677e461328f15854c5fcb1366d0e261534c6Patrick Scott *
89206677e461328f15854c5fcb1366d0e261534c6Patrick Scott *      http://www.apache.org/licenses/LICENSE-2.0
99206677e461328f15854c5fcb1366d0e261534c6Patrick Scott *
109206677e461328f15854c5fcb1366d0e261534c6Patrick Scott * Unless required by applicable law or agreed to in writing, software
119206677e461328f15854c5fcb1366d0e261534c6Patrick Scott * distributed under the License is distributed on an "AS IS" BASIS,
129206677e461328f15854c5fcb1366d0e261534c6Patrick Scott * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139206677e461328f15854c5fcb1366d0e261534c6Patrick Scott * See the License for the specific language governing permissions and
149206677e461328f15854c5fcb1366d0e261534c6Patrick Scott * limitations under the License.
159206677e461328f15854c5fcb1366d0e261534c6Patrick Scott */
169206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
179206677e461328f15854c5fcb1366d0e261534c6Patrick Scottpackage com.android.browser;
189206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
199206677e461328f15854c5fcb1366d0e261534c6Patrick Scottimport android.accounts.Account;
209206677e461328f15854c5fcb1366d0e261534c6Patrick Scottimport android.accounts.AccountManager;
219206677e461328f15854c5fcb1366d0e261534c6Patrick Scottimport android.accounts.AccountManagerCallback;
229206677e461328f15854c5fcb1366d0e261534c6Patrick Scottimport android.accounts.AccountManagerFuture;
239206677e461328f15854c5fcb1366d0e261534c6Patrick Scottimport android.app.Activity;
249206677e461328f15854c5fcb1366d0e261534c6Patrick Scottimport android.os.Bundle;
259206677e461328f15854c5fcb1366d0e261534c6Patrick Scottimport android.webkit.WebView;
269206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
279206677e461328f15854c5fcb1366d0e261534c6Patrick Scottpublic class DeviceAccountLogin implements
28f94df7eb15fcbca9e47d5163f087fa1425c4511dJohn Reck        AccountManagerCallback<Bundle> {
299206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
309206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    private final Activity mActivity;
319206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    private final WebView mWebView;
329206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    private final Tab mTab;
339206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    private final WebViewController mWebViewController;
349206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    private final AccountManager mAccountManager;
35f94df7eb15fcbca9e47d5163f087fa1425c4511dJohn Reck    Account[] mAccounts;
369206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    private AutoLoginCallback mCallback;
379206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    private String mAuthToken;
389206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
399206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    // Current state of the login.
409206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    private int mState = INITIAL;
419206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
429206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    public static final int INITIAL = 0;
439206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    public static final int FAILED = 1;
449206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    public static final int PROCESSING = 2;
459206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
469206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    public interface AutoLoginCallback {
479206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        public void loginFailed();
489206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    }
499206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
509206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    public DeviceAccountLogin(Activity activity, WebView view, Tab tab,
519206677e461328f15854c5fcb1366d0e261534c6Patrick Scott            WebViewController controller) {
529206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        mActivity = activity;
539206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        mWebView = view;
549206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        mTab = tab;
559206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        mWebViewController = controller;
569206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        mAccountManager = AccountManager.get(activity);
579206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    }
589206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
599206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    public void handleLogin(String realm, String account, String args) {
609206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        mAccounts = mAccountManager.getAccountsByType(realm);
619206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        mAuthToken = "weblogin:" + args;
629206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
639206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        // No need to display UI if there are no accounts.
649206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        if (mAccounts.length == 0) {
659206677e461328f15854c5fcb1366d0e261534c6Patrick Scott            return;
669206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        }
679206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
689206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        // Verify the account before using it.
699206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        for (Account a : mAccounts) {
709206677e461328f15854c5fcb1366d0e261534c6Patrick Scott            if (a.name.equals(account)) {
719206677e461328f15854c5fcb1366d0e261534c6Patrick Scott                // Handle the automatic login case where the service gave us an
729206677e461328f15854c5fcb1366d0e261534c6Patrick Scott                // account to use.
739206677e461328f15854c5fcb1366d0e261534c6Patrick Scott                mAccountManager.getAuthToken(a, mAuthToken, null,
749206677e461328f15854c5fcb1366d0e261534c6Patrick Scott                       mActivity, this, null);
759206677e461328f15854c5fcb1366d0e261534c6Patrick Scott                return;
769206677e461328f15854c5fcb1366d0e261534c6Patrick Scott            }
779206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        }
789206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
799206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        displayLoginUi();
809206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    }
819206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
829206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    @Override
839206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    public void run(AccountManagerFuture<Bundle> value) {
849206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        try {
859206677e461328f15854c5fcb1366d0e261534c6Patrick Scott            String result = value.getResult().getString(
869206677e461328f15854c5fcb1366d0e261534c6Patrick Scott                    AccountManager.KEY_AUTHTOKEN);
879206677e461328f15854c5fcb1366d0e261534c6Patrick Scott            if (result == null) {
889206677e461328f15854c5fcb1366d0e261534c6Patrick Scott                loginFailed();
899206677e461328f15854c5fcb1366d0e261534c6Patrick Scott            } else {
909206677e461328f15854c5fcb1366d0e261534c6Patrick Scott                mWebView.loadUrl(result);
919206677e461328f15854c5fcb1366d0e261534c6Patrick Scott                mTab.setDeviceAccountLogin(null);
929206677e461328f15854c5fcb1366d0e261534c6Patrick Scott                if (mTab.inForeground()) {
939206677e461328f15854c5fcb1366d0e261534c6Patrick Scott                    mWebViewController.hideAutoLogin(mTab);
949206677e461328f15854c5fcb1366d0e261534c6Patrick Scott                }
959206677e461328f15854c5fcb1366d0e261534c6Patrick Scott            }
969206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        } catch (Exception e) {
979206677e461328f15854c5fcb1366d0e261534c6Patrick Scott            loginFailed();
989206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        }
999206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    }
1009206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
1019206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    public int getState() {
1029206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        return mState;
1039206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    }
1049206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
1059206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    private void loginFailed() {
1069206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        mState = FAILED;
1079206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        if (mTab.getDeviceAccountLogin() == null) {
1089206677e461328f15854c5fcb1366d0e261534c6Patrick Scott            displayLoginUi();
1099206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        } else {
110b38f88126b7ea255a884d06018d3d1c64e25bdffPatrick Scott            if (mCallback != null) {
111b38f88126b7ea255a884d06018d3d1c64e25bdffPatrick Scott                mCallback.loginFailed();
112b38f88126b7ea255a884d06018d3d1c64e25bdffPatrick Scott            }
1139206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        }
1149206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    }
1159206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
1169206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    private void displayLoginUi() {
1179206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        // Display the account picker.
1189206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        mTab.setDeviceAccountLogin(this);
1199206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        if (mTab.inForeground()) {
1209206677e461328f15854c5fcb1366d0e261534c6Patrick Scott            mWebViewController.showAutoLogin(mTab);
1219206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        }
1229206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    }
1239206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
1249206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    public void cancel() {
1259206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        mTab.setDeviceAccountLogin(null);
1269206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    }
1279206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
128f94df7eb15fcbca9e47d5163f087fa1425c4511dJohn Reck    public void login(int accountIndex, AutoLoginCallback cb) {
1299206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        mState = PROCESSING;
1309206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        mCallback = cb;
1319206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        mAccountManager.getAuthToken(
132f94df7eb15fcbca9e47d5163f087fa1425c4511dJohn Reck                mAccounts[accountIndex], mAuthToken, null,
1339206677e461328f15854c5fcb1366d0e261534c6Patrick Scott                mActivity, this, null);
1349206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    }
1359206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
136f94df7eb15fcbca9e47d5163f087fa1425c4511dJohn Reck    public String[] getAccountNames() {
137f94df7eb15fcbca9e47d5163f087fa1425c4511dJohn Reck        String[] names = new String[mAccounts.length];
138f94df7eb15fcbca9e47d5163f087fa1425c4511dJohn Reck        for (int i = 0; i < mAccounts.length; i++) {
139f94df7eb15fcbca9e47d5163f087fa1425c4511dJohn Reck            names[i] = mAccounts[i].name;
1409206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        }
141f94df7eb15fcbca9e47d5163f087fa1425c4511dJohn Reck        return names;
1429206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    }
1439206677e461328f15854c5fcb1366d0e261534c6Patrick Scott}
144