diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 19:31:44 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 19:31:44 -0800 |
commit | 9066cfe9886ac131c34d59ed0e2d287b0e3c0087 (patch) | |
tree | d88beb88001f2482911e3d28e43833b50e4b4e97 /core/java/android/accounts | |
parent | d83a98f4ce9cfa908f5c54bbd70f03eec07e7553 (diff) | |
download | frameworks_base-9066cfe9886ac131c34d59ed0e2d287b0e3c0087.zip frameworks_base-9066cfe9886ac131c34d59ed0e2d287b0e3c0087.tar.gz frameworks_base-9066cfe9886ac131c34d59ed0e2d287b0e3c0087.tar.bz2 |
auto import from //depot/cupcake/@135843
Diffstat (limited to 'core/java/android/accounts')
-rw-r--r-- | core/java/android/accounts/AccountMonitor.java | 174 | ||||
-rw-r--r-- | core/java/android/accounts/AccountMonitorListener.java | 29 | ||||
-rw-r--r-- | core/java/android/accounts/AccountsServiceConstants.java | 78 | ||||
-rw-r--r-- | core/java/android/accounts/IAccountsService.aidl | 54 | ||||
-rwxr-xr-x | core/java/android/accounts/package.html | 5 |
5 files changed, 340 insertions, 0 deletions
diff --git a/core/java/android/accounts/AccountMonitor.java b/core/java/android/accounts/AccountMonitor.java new file mode 100644 index 0000000..f21385e --- /dev/null +++ b/core/java/android/accounts/AccountMonitor.java @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.accounts; + +import android.content.BroadcastReceiver; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.ServiceConnection; +import android.database.SQLException; +import android.os.IBinder; +import android.os.Process; +import android.os.RemoteException; +import android.util.Log; + +/** + * A helper class that calls back on the provided + * AccountMonitorListener with the set of current accounts both when + * it gets created and whenever the set changes. It does this by + * binding to the AccountsService and registering to receive the + * intent broadcast when the set of accounts is changed. The + * connection to the accounts service is only made when it needs to + * fetch the current list of accounts (that is, when the + * AccountMonitor is first created, and when the intent is received). + */ +public class AccountMonitor extends BroadcastReceiver implements ServiceConnection { + private final Context mContext; + private final AccountMonitorListener mListener; + private boolean mClosed = false; + private int pending = 0; + + // This thread runs in the background and runs the code to update accounts + // in the listener. + private class AccountUpdater extends Thread { + private IBinder mService; + + public AccountUpdater(IBinder service) { + mService = service; + } + + @Override + public void run() { + Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); + IAccountsService accountsService = IAccountsService.Stub.asInterface(mService); + String[] accounts = null; + do { + try { + accounts = accountsService.getAccounts(); + } catch (RemoteException e) { + // if the service was killed then the system will restart it and when it does we + // will get another onServiceConnected, at which point we will do a notify. + Log.w("AccountMonitor", "Remote exception when getting accounts", e); + return; + } + + synchronized (AccountMonitor.this) { + --pending; + if (pending == 0) { + break; + } + } + } while (true); + + mContext.unbindService(AccountMonitor.this); + + try { + mListener.onAccountsUpdated(accounts); + } catch (SQLException e) { + // Better luck next time. If the problem was disk-full, + // the STORAGE_OK intent will re-trigger the update. + Log.e("AccountMonitor", "Can't update accounts", e); + } + } + } + + /** + * Initializes the AccountMonitor and initiates a bind to the + * AccountsService to get the initial account list. For 1.0, + * the "list" is always a single account. + * + * @param context the context we are running in + * @param listener the user to notify when the account set changes + */ + public AccountMonitor(Context context, AccountMonitorListener listener) { + if (listener == null) { + throw new IllegalArgumentException("listener is null"); + } + + mContext = context; + mListener = listener; + + // Register a broadcast receiver to monitor account changes + IntentFilter intentFilter = new IntentFilter(); + intentFilter.addAction(AccountsServiceConstants.LOGIN_ACCOUNTS_CHANGED_ACTION); + intentFilter.addAction(Intent.ACTION_DEVICE_STORAGE_OK); // To recover from disk-full. + mContext.registerReceiver(this, intentFilter); + + // Send the listener the initial state now. + notifyListener(); + } + + @Override + public void onReceive(Context context, Intent intent) { + notifyListener(); + } + + public void onServiceConnected(ComponentName className, IBinder service) { + // Create a background thread to update the accounts. + new AccountUpdater(service).start(); + } + + public void onServiceDisconnected(ComponentName className) { + } + + private synchronized void notifyListener() { + if (pending == 0) { + // initiate the bind + if (!mContext.bindService(AccountsServiceConstants.SERVICE_INTENT, + this, Context.BIND_AUTO_CREATE)) { + // This is normal if GLS isn't part of this build. + Log.w("AccountMonitor", + "Couldn't connect to " + + AccountsServiceConstants.SERVICE_INTENT + + " (Missing service?)"); + } + } else { + // already bound. bindService will not trigger another + // call to onServiceConnected, so instead we make sure + // that the existing background thread will call + // getAccounts() after this function returns, by + // incrementing pending. + // + // Yes, this else clause contains only a comment. + } + ++pending; + } + + /** + * calls close() + * @throws Throwable + */ + @Override + protected void finalize() throws Throwable { + close(); + super.finalize(); + } + + /** + * Unregisters the account receiver. Consecutive calls to this + * method are harmless, but also do nothing. Once this call is + * made no more notifications will occur. + */ + public synchronized void close() { + if (!mClosed) { + mContext.unregisterReceiver(this); + mClosed = true; + } + } +} diff --git a/core/java/android/accounts/AccountMonitorListener.java b/core/java/android/accounts/AccountMonitorListener.java new file mode 100644 index 0000000..d0bd9a9 --- /dev/null +++ b/core/java/android/accounts/AccountMonitorListener.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.accounts; + +/** + * An interface that contains the callback used by the AccountMonitor + */ +public interface AccountMonitorListener { + /** + * This invoked when the AccountMonitor starts up and whenever the account + * set changes. + * @param currentAccounts the current accounts + */ + void onAccountsUpdated(String[] currentAccounts); +} diff --git a/core/java/android/accounts/AccountsServiceConstants.java b/core/java/android/accounts/AccountsServiceConstants.java new file mode 100644 index 0000000..b882e7b --- /dev/null +++ b/core/java/android/accounts/AccountsServiceConstants.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.accounts; + +import android.content.Intent; + +/** + * Miscellaneous constants used by the AccountsService and its + * clients. + */ +// TODO: These constants *could* come directly from the +// IAccountsService interface, but that's not possible since the +// aidl compiler doesn't let you define constants (yet.) +public class AccountsServiceConstants { + /** This class is never instantiated. */ + private AccountsServiceConstants() { + } + + /** + * Action sent as a broadcast Intent by the AccountsService + * when accounts are added to and/or removed from the device's + * database, or when the primary account is changed. + */ + public static final String LOGIN_ACCOUNTS_CHANGED_ACTION = + "android.accounts.LOGIN_ACCOUNTS_CHANGED"; + + /** + * Action sent as a broadcast Intent by the AccountsService + * when it starts up and no accounts are available (so some should be added). + */ + public static final String LOGIN_ACCOUNTS_MISSING_ACTION = + "android.accounts.LOGIN_ACCOUNTS_MISSING"; + + /** + * Action on the intent used to bind to the IAccountsService interface. This + * is used for services that have multiple interfaces (allowing + * them to differentiate the interface intended, and return the proper + * Binder.) + */ + private static final String ACCOUNTS_SERVICE_ACTION = "android.accounts.IAccountsService"; + + /* + * The intent uses a component in addition to the action to ensure the actual + * accounts service is bound to (a malicious third-party app could + * theoretically have a service with the same action). + */ + /** The intent used to bind to the accounts service. */ + public static final Intent SERVICE_INTENT = + new Intent() + .setClassName("com.google.android.googleapps", + "com.google.android.googleapps.GoogleLoginService") + .setAction(ACCOUNTS_SERVICE_ACTION); + + /** + * Checks whether the intent is to bind to the accounts service. + * + * @param bindIntent The Intent used to bind to the service. + * @return Whether the intent is to bind to the accounts service. + */ + public static final boolean isForAccountsService(Intent bindIntent) { + String otherAction = bindIntent.getAction(); + return otherAction != null && otherAction.equals(ACCOUNTS_SERVICE_ACTION); + } +} diff --git a/core/java/android/accounts/IAccountsService.aidl b/core/java/android/accounts/IAccountsService.aidl new file mode 100644 index 0000000..dda513c --- /dev/null +++ b/core/java/android/accounts/IAccountsService.aidl @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.accounts; + +/** + * Central application service that allows querying the list of accounts. + */ +interface IAccountsService { + /** + * Gets the list of Accounts the user has previously logged + * in to. Accounts are of the form "username@domain". + * <p> + * This method will return an empty array if the device doesn't + * know about any accounts (yet). + * + * @return The accounts. The array will be zero-length if the + * AccountsService doesn't know about any accounts yet. + */ + String[] getAccounts(); + + /** + * This is an interim solution for bypassing a forgotten gesture on the + * unlock screen (it is hidden, please make sure it stays this way!). This + * will be *removed* when the unlock screen design supports additional + * authenticators. + * <p> + * The user will be presented with username and password fields that are + * called as parameters to this method. If true is returned, the user is + * able to define a new gesture and get back into the system. If false, the + * user can try again. + * + * @param username The username entered. + * @param password The password entered. + * @return Whether to allow the user to bypass the lock screen and define a + * new gesture. + * @hide (The package is already hidden, but just in case someone + * unhides that, this should not be revealed.) + */ + boolean shouldUnlock(String username, String password); +} diff --git a/core/java/android/accounts/package.html b/core/java/android/accounts/package.html new file mode 100755 index 0000000..c9f96a6 --- /dev/null +++ b/core/java/android/accounts/package.html @@ -0,0 +1,5 @@ +<body> + +{@hide} + +</body> |