summaryrefslogtreecommitdiffstats
path: root/core/java/android/accounts
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-03 19:31:44 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-03 19:31:44 -0800
commit9066cfe9886ac131c34d59ed0e2d287b0e3c0087 (patch)
treed88beb88001f2482911e3d28e43833b50e4b4e97 /core/java/android/accounts
parentd83a98f4ce9cfa908f5c54bbd70f03eec07e7553 (diff)
downloadframeworks_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.java174
-rw-r--r--core/java/android/accounts/AccountMonitorListener.java29
-rw-r--r--core/java/android/accounts/AccountsServiceConstants.java78
-rw-r--r--core/java/android/accounts/IAccountsService.aidl54
-rwxr-xr-xcore/java/android/accounts/package.html5
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>