143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani/*
243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani * Copyright (C) 2008 The Android Open Source Project
343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani *
443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani * Licensed under the Apache License, Version 2.0 (the "License");
543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani * you may not use this file except in compliance with the License.
643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani * You may obtain a copy of the License at
743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani *
843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani *      http://www.apache.org/licenses/LICENSE-2.0
943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani *
1043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani * Unless required by applicable law or agreed to in writing, software
1143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani * distributed under the License is distributed on an "AS IS" BASIS,
1243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani * See the License for the specific language governing permissions and
1443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani * limitations under the License.
1543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani */
1643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
1743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasanipackage com.android.settings.accounts;
1843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
1943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.accounts.AccountManager;
2043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.accounts.AccountManagerCallback;
2143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.accounts.AccountManagerFuture;
2243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.accounts.AuthenticatorException;
2343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.accounts.OperationCanceledException;
2443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.app.Activity;
25b22a242e0e87caf214d9a6139df09bbb2975990aCostin Manolacheimport android.app.PendingIntent;
2643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.content.Intent;
2743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.os.Bundle;
2843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.util.Log;
2943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
30eb71f2689785bd43560afb04f8b2281c3f67f695Amith Yamasaniimport com.android.settings.Utils;
31eb71f2689785bd43560afb04f8b2281c3f67f695Amith Yamasani
3243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport java.io.IOException;
3343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
3443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani/**
3543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani * Entry point Actiivty for account setup. Works as follows
3621c2904ba32b33e5a43d33b9c46abc3ce9d6bbb0Amith Yamasani *
3743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani * 1) When the other Activities launch this Activity, it launches {@link ChooseAccountActivity}
3843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani *    without showing anything.
3943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani * 2) After receiving an account type from ChooseAccountActivity, this Activity launches the
4043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani *    account setup specified by AccountManager.
4143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani * 3) After the account setup, this Activity finishes without showing anything.
4243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani *
4343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani * Note:
4443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani * Previously this Activity did what {@link ChooseAccountActivity} does right now, but we
4543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani * currently delegate the work to the other Activity. When we let this Activity do that work, users
4643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani * would see the list of account types when leaving this Activity, since the UI is already ready
4743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani * when returning from each account setup, which doesn't look good.
4843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani */
4943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasanipublic class AddAccountSettings extends Activity {
50b22a242e0e87caf214d9a6139df09bbb2975990aCostin Manolache    /**
5184d04c20531c94a52d20098ee675ad55df9acf8fRussell Brenner     *
52b22a242e0e87caf214d9a6139df09bbb2975990aCostin Manolache     */
53b22a242e0e87caf214d9a6139df09bbb2975990aCostin Manolache    private static final String KEY_ADD_CALLED = "AddAccountCalled";
54b22a242e0e87caf214d9a6139df09bbb2975990aCostin Manolache
55b22a242e0e87caf214d9a6139df09bbb2975990aCostin Manolache    /**
56b22a242e0e87caf214d9a6139df09bbb2975990aCostin Manolache     * Extra parameter to identify the caller. Applications may display a
57b22a242e0e87caf214d9a6139df09bbb2975990aCostin Manolache     * different UI if the calls is made from Settings or from a specific
58b22a242e0e87caf214d9a6139df09bbb2975990aCostin Manolache     * application.
59b22a242e0e87caf214d9a6139df09bbb2975990aCostin Manolache     */
60b22a242e0e87caf214d9a6139df09bbb2975990aCostin Manolache    private static final String KEY_CALLER_IDENTITY = "pendingIntent";
61b22a242e0e87caf214d9a6139df09bbb2975990aCostin Manolache
6243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    private static final String TAG = "AccountSettings";
6343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
6443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    /* package */ static final String EXTRA_SELECTED_ACCOUNT = "selected_account";
6543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
6684d04c20531c94a52d20098ee675ad55df9acf8fRussell Brenner    // show additional info regarding the use of a device with multiple users
6784d04c20531c94a52d20098ee675ad55df9acf8fRussell Brenner    static final String EXTRA_HAS_MULTIPLE_USERS = "hasMultipleUsers";
6884d04c20531c94a52d20098ee675ad55df9acf8fRussell Brenner
6943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    private static final int CHOOSE_ACCOUNT_REQUEST = 1;
70cbabf19cbb85a21da3a4325f5ef925895ac16040Amith Yamasani    private static final int ADD_ACCOUNT_REQUEST = 2;
7143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
72b22a242e0e87caf214d9a6139df09bbb2975990aCostin Manolache    private PendingIntent mPendingIntent;
73b22a242e0e87caf214d9a6139df09bbb2975990aCostin Manolache
7443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    private AccountManagerCallback<Bundle> mCallback = new AccountManagerCallback<Bundle>() {
7543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        public void run(AccountManagerFuture<Bundle> future) {
76cbabf19cbb85a21da3a4325f5ef925895ac16040Amith Yamasani            boolean done = true;
7743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            try {
7843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                Bundle bundle = future.getResult();
79cbabf19cbb85a21da3a4325f5ef925895ac16040Amith Yamasani                //bundle.keySet();
80cbabf19cbb85a21da3a4325f5ef925895ac16040Amith Yamasani                Intent intent = (Intent) bundle.get(AccountManager.KEY_INTENT);
81cbabf19cbb85a21da3a4325f5ef925895ac16040Amith Yamasani                if (intent != null) {
82cbabf19cbb85a21da3a4325f5ef925895ac16040Amith Yamasani                    done = false;
83cbabf19cbb85a21da3a4325f5ef925895ac16040Amith Yamasani                    Bundle addAccountOptions = new Bundle();
84cbabf19cbb85a21da3a4325f5ef925895ac16040Amith Yamasani                    addAccountOptions.putParcelable(KEY_CALLER_IDENTITY, mPendingIntent);
85cbabf19cbb85a21da3a4325f5ef925895ac16040Amith Yamasani                    addAccountOptions.putBoolean(EXTRA_HAS_MULTIPLE_USERS,
86cbabf19cbb85a21da3a4325f5ef925895ac16040Amith Yamasani                            Utils.hasMultipleUsers(AddAccountSettings.this));
87cbabf19cbb85a21da3a4325f5ef925895ac16040Amith Yamasani                    intent.putExtras(addAccountOptions);
88cbabf19cbb85a21da3a4325f5ef925895ac16040Amith Yamasani                    startActivityForResult(intent, ADD_ACCOUNT_REQUEST);
89cbabf19cbb85a21da3a4325f5ef925895ac16040Amith Yamasani                } else {
90cbabf19cbb85a21da3a4325f5ef925895ac16040Amith Yamasani                    setResult(RESULT_OK);
91cbabf19cbb85a21da3a4325f5ef925895ac16040Amith Yamasani                    if (mPendingIntent != null) {
92cbabf19cbb85a21da3a4325f5ef925895ac16040Amith Yamasani                        mPendingIntent.cancel();
93cbabf19cbb85a21da3a4325f5ef925895ac16040Amith Yamasani                        mPendingIntent = null;
94cbabf19cbb85a21da3a4325f5ef925895ac16040Amith Yamasani                    }
95b22a242e0e87caf214d9a6139df09bbb2975990aCostin Manolache                }
96b22a242e0e87caf214d9a6139df09bbb2975990aCostin Manolache
9743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "account added: " + bundle);
9843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            } catch (OperationCanceledException e) {
9943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "addAccount was canceled");
10043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            } catch (IOException e) {
10143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "addAccount failed: " + e);
10243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            } catch (AuthenticatorException e) {
10343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "addAccount failed: " + e);
10443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            } finally {
105cbabf19cbb85a21da3a4325f5ef925895ac16040Amith Yamasani                if (done) {
106cbabf19cbb85a21da3a4325f5ef925895ac16040Amith Yamasani                    finish();
107cbabf19cbb85a21da3a4325f5ef925895ac16040Amith Yamasani                }
10843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            }
10943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        }
11043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    };
11143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
112b22a242e0e87caf214d9a6139df09bbb2975990aCostin Manolache    private boolean mAddAccountCalled = false;
113b22a242e0e87caf214d9a6139df09bbb2975990aCostin Manolache
11443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    @Override
11543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    public void onCreate(Bundle savedInstanceState) {
11643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        super.onCreate(savedInstanceState);
1177bb8f7288eaad7f6cedaea3b5c8dc48e4baa0a7fAmith Yamasani
118b22a242e0e87caf214d9a6139df09bbb2975990aCostin Manolache        if (savedInstanceState != null) {
119b22a242e0e87caf214d9a6139df09bbb2975990aCostin Manolache            mAddAccountCalled = savedInstanceState.getBoolean(KEY_ADD_CALLED);
120b22a242e0e87caf214d9a6139df09bbb2975990aCostin Manolache            if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "restored");
121b22a242e0e87caf214d9a6139df09bbb2975990aCostin Manolache        }
122b22a242e0e87caf214d9a6139df09bbb2975990aCostin Manolache
12321c2904ba32b33e5a43d33b9c46abc3ce9d6bbb0Amith Yamasani        if (mAddAccountCalled) {
12421c2904ba32b33e5a43d33b9c46abc3ce9d6bbb0Amith Yamasani            // We already called add account - maybe the callback was lost.
12521c2904ba32b33e5a43d33b9c46abc3ce9d6bbb0Amith Yamasani            finish();
12621c2904ba32b33e5a43d33b9c46abc3ce9d6bbb0Amith Yamasani            return;
127eb71f2689785bd43560afb04f8b2281c3f67f695Amith Yamasani        }
12843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        final String[] authorities =
12943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                getIntent().getStringArrayExtra(AccountPreferenceBase.AUTHORITIES_FILTER_KEY);
13043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        final String[] accountTypes =
13143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                getIntent().getStringArrayExtra(AccountPreferenceBase.ACCOUNT_TYPES_FILTER_KEY);
13243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        final Intent intent = new Intent(this, ChooseAccountActivity.class);
13343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        if (authorities != null) {
13443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            intent.putExtra(AccountPreferenceBase.AUTHORITIES_FILTER_KEY, authorities);
13543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        }
13643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        if (accountTypes != null) {
13743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            intent.putExtra(AccountPreferenceBase.ACCOUNT_TYPES_FILTER_KEY, accountTypes);
13843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        }
13943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        startActivityForResult(intent, CHOOSE_ACCOUNT_REQUEST);
14043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
14143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
14243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    @Override
14343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    public void onActivityResult(int requestCode, int resultCode, Intent data) {
14443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        switch (requestCode) {
14543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        case CHOOSE_ACCOUNT_REQUEST:
14643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            if (resultCode == RESULT_CANCELED) {
14743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                setResult(resultCode);
14843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                finish();
14943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                return;
15043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            }
15143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            // Go to account setup screen. finish() is called inside mCallback.
15243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            addAccount(data.getStringExtra(EXTRA_SELECTED_ACCOUNT));
15343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            break;
154cbabf19cbb85a21da3a4325f5ef925895ac16040Amith Yamasani        case ADD_ACCOUNT_REQUEST:
155cbabf19cbb85a21da3a4325f5ef925895ac16040Amith Yamasani            setResult(resultCode);
156cbabf19cbb85a21da3a4325f5ef925895ac16040Amith Yamasani            if (mPendingIntent != null) {
157cbabf19cbb85a21da3a4325f5ef925895ac16040Amith Yamasani                mPendingIntent.cancel();
158cbabf19cbb85a21da3a4325f5ef925895ac16040Amith Yamasani                mPendingIntent = null;
159cbabf19cbb85a21da3a4325f5ef925895ac16040Amith Yamasani            }
160cbabf19cbb85a21da3a4325f5ef925895ac16040Amith Yamasani            finish();
161cbabf19cbb85a21da3a4325f5ef925895ac16040Amith Yamasani            break;
16243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        }
16343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
16443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
165b22a242e0e87caf214d9a6139df09bbb2975990aCostin Manolache    protected void onSaveInstanceState(Bundle outState) {
166b22a242e0e87caf214d9a6139df09bbb2975990aCostin Manolache        super.onSaveInstanceState(outState);
167b22a242e0e87caf214d9a6139df09bbb2975990aCostin Manolache        outState.putBoolean(KEY_ADD_CALLED, mAddAccountCalled);
168b22a242e0e87caf214d9a6139df09bbb2975990aCostin Manolache        if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "saved");
169b22a242e0e87caf214d9a6139df09bbb2975990aCostin Manolache    }
170b22a242e0e87caf214d9a6139df09bbb2975990aCostin Manolache
17143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    private void addAccount(String accountType) {
172b22a242e0e87caf214d9a6139df09bbb2975990aCostin Manolache        Bundle addAccountOptions = new Bundle();
173b22a242e0e87caf214d9a6139df09bbb2975990aCostin Manolache        mPendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(), 0);
174b22a242e0e87caf214d9a6139df09bbb2975990aCostin Manolache        addAccountOptions.putParcelable(KEY_CALLER_IDENTITY, mPendingIntent);
17584d04c20531c94a52d20098ee675ad55df9acf8fRussell Brenner        addAccountOptions.putBoolean(EXTRA_HAS_MULTIPLE_USERS, Utils.hasMultipleUsers(this));
17643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        AccountManager.get(this).addAccount(
17743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                accountType,
17843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                null, /* authTokenType */
17943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                null, /* requiredFeatures */
180b22a242e0e87caf214d9a6139df09bbb2975990aCostin Manolache                addAccountOptions,
181cbabf19cbb85a21da3a4325f5ef925895ac16040Amith Yamasani                null,
18243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                mCallback,
18343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                null /* handler */);
184b22a242e0e87caf214d9a6139df09bbb2975990aCostin Manolache        mAddAccountCalled  = true;
18543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
18643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani}
187