1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.browser;
18
19import android.accounts.Account;
20import android.accounts.AccountManager;
21import android.accounts.AccountManagerCallback;
22import android.accounts.AccountManagerFuture;
23import android.app.Activity;
24import android.os.Bundle;
25import android.webkit.WebView;
26
27public class DeviceAccountLogin implements
28        AccountManagerCallback<Bundle> {
29
30    private final Activity mActivity;
31    private final WebView mWebView;
32    private final Tab mTab;
33    private final WebViewController mWebViewController;
34    private final AccountManager mAccountManager;
35    Account[] mAccounts;
36    private AutoLoginCallback mCallback;
37    private String mAuthToken;
38
39    // Current state of the login.
40    private int mState = INITIAL;
41
42    public static final int INITIAL = 0;
43    public static final int FAILED = 1;
44    public static final int PROCESSING = 2;
45
46    public interface AutoLoginCallback {
47        public void loginFailed();
48    }
49
50    public DeviceAccountLogin(Activity activity, WebView view, Tab tab,
51            WebViewController controller) {
52        mActivity = activity;
53        mWebView = view;
54        mTab = tab;
55        mWebViewController = controller;
56        mAccountManager = AccountManager.get(activity);
57    }
58
59    public void handleLogin(String realm, String account, String args) {
60        mAccounts = mAccountManager.getAccountsByType(realm);
61        mAuthToken = "weblogin:" + args;
62
63        // No need to display UI if there are no accounts.
64        if (mAccounts.length == 0) {
65            return;
66        }
67
68        // Verify the account before using it.
69        for (Account a : mAccounts) {
70            if (a.name.equals(account)) {
71                // Handle the automatic login case where the service gave us an
72                // account to use.
73                mAccountManager.getAuthToken(a, mAuthToken, null,
74                       mActivity, this, null);
75                return;
76            }
77        }
78
79        displayLoginUi();
80    }
81
82    @Override
83    public void run(AccountManagerFuture<Bundle> value) {
84        try {
85            String result = value.getResult().getString(
86                    AccountManager.KEY_AUTHTOKEN);
87            if (result == null) {
88                loginFailed();
89            } else {
90                mWebView.loadUrl(result);
91                mTab.setDeviceAccountLogin(null);
92                if (mTab.inForeground()) {
93                    mWebViewController.hideAutoLogin(mTab);
94                }
95            }
96        } catch (Exception e) {
97            loginFailed();
98        }
99    }
100
101    public int getState() {
102        return mState;
103    }
104
105    private void loginFailed() {
106        mState = FAILED;
107        if (mTab.getDeviceAccountLogin() == null) {
108            displayLoginUi();
109        } else {
110            if (mCallback != null) {
111                mCallback.loginFailed();
112            }
113        }
114    }
115
116    private void displayLoginUi() {
117        // Display the account picker.
118        mTab.setDeviceAccountLogin(this);
119        if (mTab.inForeground()) {
120            mWebViewController.showAutoLogin(mTab);
121        }
122    }
123
124    public void cancel() {
125        mTab.setDeviceAccountLogin(null);
126    }
127
128    public void login(int accountIndex, AutoLoginCallback cb) {
129        mState = PROCESSING;
130        mCallback = cb;
131        mAccountManager.getAuthToken(
132                mAccounts[accountIndex], mAuthToken, null,
133                mActivity, this, null);
134    }
135
136    public String[] getAccountNames() {
137        String[] names = new String[mAccounts.length];
138        for (int i = 0; i < mAccounts.length; i++) {
139            names[i] = mAccounts[i].name;
140        }
141        return names;
142    }
143}
144