1/* 2 * Copyright (C) 2008 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.settings.accounts; 18 19import android.accounts.AccountManager; 20import android.accounts.AccountManagerCallback; 21import android.accounts.AccountManagerFuture; 22import android.accounts.AuthenticatorException; 23import android.accounts.OperationCanceledException; 24import android.app.Activity; 25import android.app.PendingIntent; 26import android.content.Intent; 27import android.os.Bundle; 28import android.util.Log; 29 30import java.io.IOException; 31 32/** 33 * Entry point Actiivty for account setup. Works as follows 34 * 35 * 1) When the other Activities launch this Activity, it launches {@link ChooseAccountActivity} 36 * without showing anything. 37 * 2) After receiving an account type from ChooseAccountActivity, this Activity launches the 38 * account setup specified by AccountManager. 39 * 3) After the account setup, this Activity finishes without showing anything. 40 * 41 * Note: 42 * Previously this Activity did what {@link ChooseAccountActivity} does right now, but we 43 * currently delegate the work to the other Activity. When we let this Activity do that work, users 44 * would see the list of account types when leaving this Activity, since the UI is already ready 45 * when returning from each account setup, which doesn't look good. 46 */ 47public class AddAccountSettings extends Activity { 48 /** 49 * 50 */ 51 private static final String KEY_ADD_CALLED = "AddAccountCalled"; 52 53 /** 54 * Extra parameter to identify the caller. Applications may display a 55 * different UI if the calls is made from Settings or from a specific 56 * application. 57 */ 58 private static final String KEY_CALLER_IDENTITY = "pendingIntent"; 59 60 private static final String TAG = "AccountSettings"; 61 62 /* package */ static final String EXTRA_SELECTED_ACCOUNT = "selected_account"; 63 64 private static final int CHOOSE_ACCOUNT_REQUEST = 1; 65 66 private PendingIntent mPendingIntent; 67 68 private AccountManagerCallback<Bundle> mCallback = new AccountManagerCallback<Bundle>() { 69 public void run(AccountManagerFuture<Bundle> future) { 70 try { 71 Bundle bundle = future.getResult(); 72 bundle.keySet(); 73 setResult(RESULT_OK); 74 75 if (mPendingIntent != null) { 76 mPendingIntent.cancel(); 77 } 78 79 if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "account added: " + bundle); 80 } catch (OperationCanceledException e) { 81 if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "addAccount was canceled"); 82 } catch (IOException e) { 83 if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "addAccount failed: " + e); 84 } catch (AuthenticatorException e) { 85 if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "addAccount failed: " + e); 86 } finally { 87 finish(); 88 } 89 } 90 }; 91 92 private boolean mAddAccountCalled = false; 93 94 @Override 95 public void onCreate(Bundle savedInstanceState) { 96 super.onCreate(savedInstanceState); 97 98 if (savedInstanceState != null) { 99 mAddAccountCalled = savedInstanceState.getBoolean(KEY_ADD_CALLED); 100 if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "restored"); 101 } 102 103 if (mAddAccountCalled) { 104 // We already called add account - maybe the callback was lost. 105 finish(); 106 return; 107 } 108 final String[] authorities = 109 getIntent().getStringArrayExtra(AccountPreferenceBase.AUTHORITIES_FILTER_KEY); 110 final String[] accountTypes = 111 getIntent().getStringArrayExtra(AccountPreferenceBase.ACCOUNT_TYPES_FILTER_KEY); 112 final Intent intent = new Intent(this, ChooseAccountActivity.class); 113 if (authorities != null) { 114 intent.putExtra(AccountPreferenceBase.AUTHORITIES_FILTER_KEY, authorities); 115 } 116 if (accountTypes != null) { 117 intent.putExtra(AccountPreferenceBase.ACCOUNT_TYPES_FILTER_KEY, accountTypes); 118 } 119 startActivityForResult(intent, CHOOSE_ACCOUNT_REQUEST); 120 } 121 122 @Override 123 public void onActivityResult(int requestCode, int resultCode, Intent data) { 124 switch (requestCode) { 125 case CHOOSE_ACCOUNT_REQUEST: 126 if (resultCode == RESULT_CANCELED) { 127 setResult(resultCode); 128 finish(); 129 return; 130 } 131 // Go to account setup screen. finish() is called inside mCallback. 132 addAccount(data.getStringExtra(EXTRA_SELECTED_ACCOUNT)); 133 break; 134 } 135 } 136 137 protected void onSaveInstanceState(Bundle outState) { 138 super.onSaveInstanceState(outState); 139 outState.putBoolean(KEY_ADD_CALLED, mAddAccountCalled); 140 if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "saved"); 141 } 142 143 private void addAccount(String accountType) { 144 Bundle addAccountOptions = new Bundle(); 145 mPendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(), 0); 146 addAccountOptions.putParcelable(KEY_CALLER_IDENTITY, mPendingIntent); 147 AccountManager.get(this).addAccount( 148 accountType, 149 null, /* authTokenType */ 150 null, /* requiredFeatures */ 151 addAccountOptions, 152 this, 153 mCallback, 154 null /* handler */); 155 mAddAccountCalled = true; 156 } 157} 158