AccountManager.java revision 603073430bbcb1bd29db7afb9b14e2732ad589fb
1/*
2 * Copyright (C) 2009 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 android.accounts;
18
19import android.os.RemoteException;
20import android.os.Bundle;
21import android.app.PendingIntent;
22import android.app.Activity;
23import android.content.Intent;
24import android.content.Context;
25
26import java.util.concurrent.locks.Lock;
27import java.util.concurrent.locks.ReentrantLock;
28import java.util.concurrent.locks.Condition;
29
30/**
31 * A class that helps with interactions with the {@link IAccountManager} interface. It provides
32 * methods to allow for account, password, and authtoken management for all accounts on the
33 * device. Some of these calls are implemented with the help of the corresponding
34 * {@link IAccountAuthenticator} services. One accesses the {@link AccountManager} by calling:
35 *    AccountManager accountManager =
36 *      (AccountManager)context.getSystemService(Context.ACCOUNT_SERVICE)
37 *
38 * <p>
39 * TODO: this interface is still in flux
40 */
41public class AccountManager {
42    private static final String TAG = "AccountManager";
43
44    private final Context mContext;
45    private final IAccountManager mService;
46
47    public AccountManager(Context context, IAccountManager service) {
48        mContext = context;
49        mService = service;
50    }
51
52    public String getPassword(Account account) {
53        try {
54            return mService.getPassword(account);
55        } catch (RemoteException e) {
56            // if this happens the entire runtime will restart
57            throw new RuntimeException(e);
58        }
59    }
60
61    public String getUserData(Account account, String key) {
62        try {
63            return mService.getUserData(account, key);
64        } catch (RemoteException e) {
65            // if this happens the entire runtime will restart
66            throw new RuntimeException(e);
67        }
68    }
69
70    public Account[] blockingGetAccounts() {
71        try {
72            return mService.getAccounts();
73        } catch (RemoteException e) {
74            // if this happens the entire runtime will restart
75            throw new RuntimeException(e);
76        }
77    }
78
79    public void getAccounts(final PendingIntent intent, final int code) {
80        getAccountsByType(null /* all account types */, intent, code);
81    }
82
83    public void getAccountsByType(final String accountType,
84            final PendingIntent intent, final int code) {
85        Thread t = new Thread() {
86            public void run() {
87                try {
88                    Account[] accounts;
89                    if (accountType != null) {
90                        accounts = blockingGetAccountsByType(accountType);
91                    } else {
92                        accounts = blockingGetAccounts();
93                    }
94                    Intent payload = new Intent();
95                    payload.putExtra("accounts", accounts);
96                    intent.send(mContext, code, payload);
97                } catch (PendingIntent.CanceledException e) {
98                    // the pending intent is no longer accepting results, we don't
99                    // need to do anything to handle this
100                }
101            }
102        };
103        t.start();
104    }
105
106    public Account[] blockingGetAccountsByType(String accountType) {
107        try {
108            return mService.getAccountsByType(accountType);
109        } catch (RemoteException e) {
110            // if this happens the entire runtime will restart
111            throw new RuntimeException(e);
112        }
113    }
114
115    public boolean addAccount(Account account, String password, Bundle extras) {
116        try {
117            return mService.addAccount(account, password, extras);
118        } catch (RemoteException e) {
119            // if this happens the entire runtime will restart
120            throw new RuntimeException(e);
121        }
122    }
123
124    public void removeAccount(Account account) {
125        try {
126            mService.removeAccount(account);
127        } catch (RemoteException e) {
128            // if this happens the entire runtime will restart
129        }
130    }
131
132    public void invalidateAuthToken(String accountType, String authToken) {
133        try {
134            mService.invalidateAuthToken(accountType, authToken);
135        } catch (RemoteException e) {
136            // if this happens the entire runtime will restart
137        }
138    }
139
140    public String peekAuthToken(Account account, String authTokenType) {
141        try {
142            return mService.peekAuthToken(account, authTokenType);
143        } catch (RemoteException e) {
144            // if this happens the entire runtime will restart
145            throw new RuntimeException(e);
146        }
147    }
148
149    public void setPassword(Account account, String password) {
150        try {
151            mService.setPassword(account, password);
152        } catch (RemoteException e) {
153            // if this happens the entire runtime will restart
154        }
155    }
156
157    public void clearPassword(Account account) {
158        try {
159            mService.clearPassword(account);
160        } catch (RemoteException e) {
161            // if this happens the entire runtime will restart
162        }
163    }
164
165    public void setUserData(Account account, String key, String value) {
166        try {
167            mService.setUserData(account, key, value);
168        } catch (RemoteException e) {
169            // if this happens the entire runtime will restart
170        }
171    }
172
173    public void getAuthToken(AccountManagerResponse response,
174            Account account, String authTokenType, boolean notifyAuthFailure) {
175        try {
176            mService.getAuthToken(response.getIAccountManagerResponse(), account, authTokenType,
177                    notifyAuthFailure);
178        } catch (RemoteException e) {
179            // if this happens the entire runtime will restart
180        }
181    }
182
183    public void setAuthToken(Account account, String authTokenType, String authToken) {
184        try {
185            mService.setAuthToken(account, authTokenType, authToken);
186        } catch (RemoteException e) {
187            // if this happens the entire runtime will restart
188        }
189    }
190
191    public void addAccountInteractively(AccountManagerResponse response, String accountType) {
192        try {
193            mService.addAccountInteractively(response.getIAccountManagerResponse(), accountType);
194        } catch (RemoteException e) {
195            // if this happens the entire runtime will restart
196        }
197    }
198
199    public class AuthenticateAccountThread extends Thread {
200        public Lock mLock = new ReentrantLock();
201        public Condition mCondition = mLock.newCondition();
202        volatile boolean mSuccess = false;
203        volatile boolean mFailure = false;
204        volatile boolean mResult = false;
205        private final Account mAccount;
206        private final String mPassword;
207        public AuthenticateAccountThread(Account account, String password) {
208            mAccount = account;
209            mPassword = password;
210        }
211        public void run() {
212            try {
213                IAccountManagerResponse response = new IAccountManagerResponse.Stub() {
214                    public void onStringResult(String value) throws RemoteException {
215                    }
216
217                    public void onIntResult(int value) throws RemoteException {
218                    }
219
220                    public void onBooleanResult(boolean value) throws RemoteException {
221                        mLock.lock();
222                        try {
223                            if (!mFailure && !mSuccess) {
224                                mSuccess = true;
225                                mResult = value;
226                                mCondition.signalAll();
227                            }
228                        } finally {
229                            mLock.unlock();
230                        }
231                    }
232
233                    public void onError(int errorCode, String errorMessage) {
234                        mLock.lock();
235                        try {
236                            if (!mFailure && !mSuccess) {
237                                mFailure = true;
238                                mCondition.signalAll();
239                            }
240                        } finally {
241                            mLock.unlock();
242                        }
243                    }
244                };
245
246                mService.authenticateAccount(response, mAccount, mPassword);
247            } catch (RemoteException e) {
248                // if this happens the entire runtime will restart
249            }
250        }
251    }
252
253    public boolean authenticateAccount(Account account, String password) {
254        AuthenticateAccountThread thread = new AuthenticateAccountThread(account, password);
255        thread.mLock.lock();
256        thread.start();
257        try {
258          while (!thread.mSuccess && !thread.mFailure) {
259              try {
260                  thread.mCondition.await();
261              } catch (InterruptedException e) {
262                  // keep waiting
263              }
264          }
265          return thread.mResult;
266        } finally {
267          thread.mLock.unlock();
268        }
269    }
270
271    public void updatePassword(AccountManagerResponse response, Account account) {
272        try {
273            mService.updatePassword(response.getIAccountManagerResponse(), account);
274        } catch (RemoteException e) {
275            // if this happens the entire runtime will restart
276        }
277    }
278
279    public void editProperties(AccountManagerResponse response, String accountType) {
280        try {
281            mService.editProperties(response.getIAccountManagerResponse(), accountType);
282        } catch (RemoteException e) {
283            // if this happens the entire runtime will restart
284        }
285    }
286
287    public void getPasswordStrength(AccountManagerResponse response,
288            String accountType, String password) {
289        try {
290            mService.getPasswordStrength(response.getIAccountManagerResponse(),
291                    accountType, password);
292        } catch (RemoteException e) {
293            // if this happens the entire runtime will restart
294        }
295    }
296
297    public void checkUsernameExistence(AccountManagerResponse response,
298            String accountType, String username) {
299        try {
300            mService.checkUsernameExistence(response.getIAccountManagerResponse(),
301                    accountType, username);
302        } catch (RemoteException e) {
303            // if this happens the entire runtime will restart
304        }
305    }
306}
307