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