AddAccountSettings.java revision 263bcc8b732dbb47d3ce63904e0e05191fabbad6
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.Context; 27import android.content.Intent; 28import android.os.Bundle; 29import android.os.UserManager; 30import android.util.Log; 31import android.widget.Toast; 32 33import com.android.settings.R; 34import com.android.settings.Settings; 35import com.android.settings.Utils; 36 37import java.io.IOException; 38 39/** 40 * Entry point Actiivty for account setup. Works as follows 41 * 42 * 1) When the other Activities launch this Activity, it launches {@link ChooseAccountActivity} 43 * without showing anything. 44 * 2) After receiving an account type from ChooseAccountActivity, this Activity launches the 45 * account setup specified by AccountManager. 46 * 3) After the account setup, this Activity finishes without showing anything. 47 * 48 * Note: 49 * Previously this Activity did what {@link ChooseAccountActivity} does right now, but we 50 * currently delegate the work to the other Activity. When we let this Activity do that work, users 51 * would see the list of account types when leaving this Activity, since the UI is already ready 52 * when returning from each account setup, which doesn't look good. 53 */ 54public class AddAccountSettings extends Activity { 55 /** 56 * 57 */ 58 private static final String KEY_ADD_CALLED = "AddAccountCalled"; 59 60 /** 61 * Extra parameter to identify the caller. Applications may display a 62 * different UI if the calls is made from Settings or from a specific 63 * application. 64 */ 65 private static final String KEY_CALLER_IDENTITY = "pendingIntent"; 66 67 private static final String TAG = "AccountSettings"; 68 69 /* package */ static final String EXTRA_SELECTED_ACCOUNT = "selected_account"; 70 71 // show additional info regarding the use of a device with multiple users 72 static final String EXTRA_HAS_MULTIPLE_USERS = "hasMultipleUsers"; 73 74 private static final int CHOOSE_ACCOUNT_REQUEST = 1; 75 private static final int ADD_ACCOUNT_REQUEST = 2; 76 77 private PendingIntent mPendingIntent; 78 79 private final AccountManagerCallback<Bundle> mCallback = new AccountManagerCallback<Bundle>() { 80 @Override 81 public void run(AccountManagerFuture<Bundle> future) { 82 boolean done = true; 83 try { 84 Bundle bundle = future.getResult(); 85 //bundle.keySet(); 86 Intent intent = (Intent) bundle.get(AccountManager.KEY_INTENT); 87 if (intent != null) { 88 done = false; 89 Bundle addAccountOptions = new Bundle(); 90 addAccountOptions.putParcelable(KEY_CALLER_IDENTITY, mPendingIntent); 91 addAccountOptions.putBoolean(EXTRA_HAS_MULTIPLE_USERS, 92 Utils.hasMultipleUsers(AddAccountSettings.this)); 93 intent.putExtras(addAccountOptions); 94 startActivityForResult(intent, ADD_ACCOUNT_REQUEST); 95 } else { 96 setResult(RESULT_OK); 97 if (mPendingIntent != null) { 98 mPendingIntent.cancel(); 99 mPendingIntent = null; 100 } 101 } 102 103 if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "account added: " + bundle); 104 } catch (OperationCanceledException e) { 105 if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "addAccount was canceled"); 106 } catch (IOException e) { 107 if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "addAccount failed: " + e); 108 } catch (AuthenticatorException e) { 109 if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "addAccount failed: " + e); 110 } finally { 111 if (done) { 112 finish(); 113 } 114 } 115 } 116 }; 117 118 private boolean mAddAccountCalled = false; 119 120 @Override 121 public void onCreate(Bundle savedInstanceState) { 122 super.onCreate(savedInstanceState); 123 124 if (savedInstanceState != null) { 125 mAddAccountCalled = savedInstanceState.getBoolean(KEY_ADD_CALLED); 126 if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "restored"); 127 } 128 129 final UserManager um = (UserManager) getSystemService(Context.USER_SERVICE); 130 if (um.hasUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS)) { 131 // We aren't allowed to add an account. 132 Toast.makeText(this, R.string.user_cannot_add_accounts_message, Toast.LENGTH_LONG) 133 .show(); 134 finish(); 135 return; 136 } 137 if (mAddAccountCalled) { 138 // We already called add account - maybe the callback was lost. 139 finish(); 140 return; 141 } 142 final String[] authorities = 143 getIntent().getStringArrayExtra(AccountPreferenceBase.AUTHORITIES_FILTER_KEY); 144 final String[] accountTypes = 145 getIntent().getStringArrayExtra(AccountPreferenceBase.ACCOUNT_TYPES_FILTER_KEY); 146 final Intent intent = new Intent(this, Settings.ChooseAccountActivity.class); 147 if (authorities != null) { 148 intent.putExtra(AccountPreferenceBase.AUTHORITIES_FILTER_KEY, authorities); 149 } 150 if (accountTypes != null) { 151 intent.putExtra(AccountPreferenceBase.ACCOUNT_TYPES_FILTER_KEY, accountTypes); 152 } 153 startActivityForResult(intent, CHOOSE_ACCOUNT_REQUEST); 154 } 155 156 @Override 157 public void onActivityResult(int requestCode, int resultCode, Intent data) { 158 switch (requestCode) { 159 case CHOOSE_ACCOUNT_REQUEST: 160 if (resultCode == RESULT_CANCELED) { 161 setResult(resultCode); 162 finish(); 163 return; 164 } 165 // Go to account setup screen. finish() is called inside mCallback. 166 addAccount(data.getStringExtra(EXTRA_SELECTED_ACCOUNT)); 167 break; 168 case ADD_ACCOUNT_REQUEST: 169 setResult(resultCode); 170 if (mPendingIntent != null) { 171 mPendingIntent.cancel(); 172 mPendingIntent = null; 173 } 174 finish(); 175 break; 176 } 177 } 178 179 @Override 180 protected void onSaveInstanceState(Bundle outState) { 181 super.onSaveInstanceState(outState); 182 outState.putBoolean(KEY_ADD_CALLED, mAddAccountCalled); 183 if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "saved"); 184 } 185 186 private void addAccount(String accountType) { 187 Bundle addAccountOptions = new Bundle(); 188 mPendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(), 0); 189 addAccountOptions.putParcelable(KEY_CALLER_IDENTITY, mPendingIntent); 190 addAccountOptions.putBoolean(EXTRA_HAS_MULTIPLE_USERS, Utils.hasMultipleUsers(this)); 191 AccountManager.get(this).addAccount( 192 accountType, 193 null, /* authTokenType */ 194 null, /* requiredFeatures */ 195 addAccountOptions, 196 null, 197 mCallback, 198 null /* handler */); 199 mAddAccountCalled = true; 200 } 201} 202