From d2d4f8150b21fe37500a6f26df31ee4fb99f5058 Mon Sep 17 00:00:00 2001 From: Tim Su Date: Fri, 1 Oct 2010 02:35:40 -0700 Subject: [PATCH] Imported auth manager and account chooser code from Google MyTracks (Apache License). Wired up gtasks to use auth manager. Modern seems to work but Old does not. --- astrid/.classpath | 1 + astrid/AndroidManifest.xml | 7 + astrid/libs/googleloginclient-helper.jar | Bin 0 -> 19759 bytes .../astrid/gtasks/auth/AccountChooser.java | 125 +++++++++++ .../astrid/gtasks/auth/AuthManager.java | 77 +++++++ .../gtasks/auth/AuthManagerFactory.java | 53 +++++ .../astrid/gtasks/auth/AuthManagerOld.java | 198 +++++++++++++++++ .../astrid/gtasks/auth/ModernAuthManager.java | 210 ++++++++++++++++++ .../gtasks/sync/GtasksSyncProvider.java | 45 ++-- .../producteev/ProducteevPreferences.java | 1 + astrid/res/values/strings-gtasks.xml | 9 + .../weloveastrid/rmilk/MilkPreferences.java | 1 + 12 files changed, 707 insertions(+), 20 deletions(-) create mode 100644 astrid/libs/googleloginclient-helper.jar create mode 100644 astrid/plugin-src/com/todoroo/astrid/gtasks/auth/AccountChooser.java create mode 100644 astrid/plugin-src/com/todoroo/astrid/gtasks/auth/AuthManager.java create mode 100644 astrid/plugin-src/com/todoroo/astrid/gtasks/auth/AuthManagerFactory.java create mode 100644 astrid/plugin-src/com/todoroo/astrid/gtasks/auth/AuthManagerOld.java create mode 100644 astrid/plugin-src/com/todoroo/astrid/gtasks/auth/ModernAuthManager.java diff --git a/astrid/.classpath b/astrid/.classpath index 9cf65cc65..e0db125e4 100644 --- a/astrid/.classpath +++ b/astrid/.classpath @@ -15,5 +15,6 @@ + diff --git a/astrid/AndroidManifest.xml b/astrid/AndroidManifest.xml index 01ff5b68c..b6727a190 100644 --- a/astrid/AndroidManifest.xml +++ b/astrid/AndroidManifest.xml @@ -22,6 +22,13 @@ + + + + + + + diff --git a/astrid/libs/googleloginclient-helper.jar b/astrid/libs/googleloginclient-helper.jar new file mode 100644 index 0000000000000000000000000000000000000000..6e610e991f742e189b4fa76fc76841feedb064ea GIT binary patch literal 19759 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 R%^wB^At3w*WJ$Y$cmR= 7; + } + + /** + * Get a right {@link AuthManager} for the platform. + * @return A new AuthManager + */ + public static AuthManager getAuthManager(Activity activity, int code, + Bundle extras, boolean requireGoogle, String service) { + if (useModernAuthManager()) { + return new ModernAuthManager(activity, code, extras, requireGoogle, service); + } else { + return new AuthManagerOld(activity, code, extras, requireGoogle, service); + } + } + +} diff --git a/astrid/plugin-src/com/todoroo/astrid/gtasks/auth/AuthManagerOld.java b/astrid/plugin-src/com/todoroo/astrid/gtasks/auth/AuthManagerOld.java new file mode 100644 index 000000000..eda7413e2 --- /dev/null +++ b/astrid/plugin-src/com/todoroo/astrid/gtasks/auth/AuthManagerOld.java @@ -0,0 +1,198 @@ +/* + * Copyright 2009 Google Inc. + * + * 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 com.todoroo.astrid.gtasks.auth; + +import java.util.Iterator; +import java.util.Vector; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; + +import com.google.android.googlelogindist.GoogleLoginServiceConstants; +import com.google.android.googlelogindist.GoogleLoginServiceHelper; + +/** + * AuthManager keeps track of the current auth token for a user. The advantage + * over just passing around a String is that this class can renew the auth + * token if necessary, and it will change for all classes using this + * AuthManager. + */ +public class AuthManagerOld implements AuthManager { + /** The activity that will handle auth result callbacks. */ + private final Activity activity; + + /** The code used to tell the activity that it is an auth result. */ + private final int code; + + /** Extras to pass into the getCredentials function. */ + private final Bundle extras; + + /** True if the account must be a Google account (not a domain account). */ + private final boolean requireGoogle; + + /** The name of the service to authorize for. */ + private final String service; + + /** A list of handlers to call when a new auth token is fetched. */ + private final Vector newTokenListeners = new Vector(); + + /** The most recently fetched auth token or null if none is available. */ + private String authToken; + + /** + * The number of handlers at the beginning of the above list that shouldn't + * be removed after they are called. + */ + private int stickyNewTokenListenerCount; + + /** + * AuthManager requires many of the same parameters as + * {@link GoogleLoginServiceHelper#getCredentials(Activity, int, Bundle, + * boolean, String, boolean)}. The activity must have + * a handler in {@link Activity#onActivityResult} that calls + * {@link #authResult(int, Intent)} if the request code is the code given + * here. + * + * @param activity An activity with a handler in + * {@link Activity#onActivityResult} that calls + * {@link #authResult(int, Intent)} when {@literal code} is the request + * code + * @param code The request code to pass to + * {@link Activity#onActivityResult} when + * {@link #authResult(int, Intent)} should be called + * @param extras A {@link Bundle} of extras for + * {@link GoogleLoginServiceHelper} + * @param requireGoogle True if the account must be a Google account + * @param service The name of the service to authenticate as + */ + public AuthManagerOld(Activity activity, int code, Bundle extras, + boolean requireGoogle, String service) { + this.activity = activity; + this.code = code; + this.extras = extras; + this.requireGoogle = requireGoogle; + this.service = service; + } + + /* (non-Javadoc) + * @see com.google.android.apps.mytracks.io.AuthManager#doLogin(java.lang.Runnable) + */ + public void doLogin(Runnable whenFinished, Object o) { + synchronized (newTokenListeners) { + if (whenFinished != null) { + newTokenListeners.add(whenFinished); + } + } + activity.runOnUiThread(new LoginRunnable()); + } + + /** + * Runnable which actually gets login credentials. + */ + private class LoginRunnable implements Runnable { + @Override + public void run() { + GoogleLoginServiceHelper.getCredentials( + activity, code, extras, requireGoogle, service, true); + } + } + + /* (non-Javadoc) + * @see com.google.android.apps.mytracks.io.AuthManager#authResult(int, android.content.Intent) + */ + public boolean authResult(int resultCode, Intent results) { + if (resultCode == Activity.RESULT_OK) { + authToken = results.getStringExtra( + GoogleLoginServiceConstants.AUTHTOKEN_KEY); + if (authToken == null) { + GoogleLoginServiceHelper.getCredentials( + activity, code, extras, requireGoogle, service, false); + return true; + } else { + // Notify all active listeners that we have a new auth token. + synchronized (newTokenListeners) { + Iterator iter = newTokenListeners.iterator(); + while (iter.hasNext()) { + iter.next().run(); + } + iter = null; + // Remove anything not in the sticky part of the list. + newTokenListeners.setSize(stickyNewTokenListenerCount); + } + return true; + } + } + return false; + } + + /* (non-Javadoc) + * @see com.google.android.apps.mytracks.io.AuthManager#getAuthToken() + */ + public String getAuthToken() { + return authToken; + } + + /* (non-Javadoc) + * @see com.google.android.apps.mytracks.io.AuthManager#invalidateAndRefresh(java.lang.Runnable) + */ + public void invalidateAndRefresh(Runnable whenFinished) { + synchronized (newTokenListeners) { + if (whenFinished != null) { + newTokenListeners.add(whenFinished); + } + } + activity.runOnUiThread(new Runnable() { + public void run() { + GoogleLoginServiceHelper.invalidateAuthToken(activity, code, authToken); + } + }); + } + + /** + * Adds a {@link Runnable} to be executed every time the auth token is + * updated. The {@link Runnable} will not be removed until manually removed + * with {@link #removeStickyNewTokenListener(Runnable)}. + * + * @param listener The {@link Runnable} to execute every time a new auth + * token is fetched + */ + public void addStickyNewTokenListener(Runnable listener) { + synchronized (newTokenListeners) { + newTokenListeners.add(0, listener); + stickyNewTokenListenerCount++; + } + } + + /** + * Stops executing the given {@link Runnable} every time the auth token is + * updated. This {@link Runnable} must have been added with + * {@link #addStickyNewTokenListener(Runnable)} above. If the + * {@link Runnable} was added more than once, only the first occurrence + * will be removed. + * + * @param listener The {@link Runnable} to stop executing every time a new + * auth token is fetched + */ + public void removeStickyNewTokenListener(Runnable listener) { + synchronized (newTokenListeners) { + if (stickyNewTokenListenerCount > 0 + && newTokenListeners.remove(listener)) { + stickyNewTokenListenerCount--; + } + } + } +} diff --git a/astrid/plugin-src/com/todoroo/astrid/gtasks/auth/ModernAuthManager.java b/astrid/plugin-src/com/todoroo/astrid/gtasks/auth/ModernAuthManager.java new file mode 100644 index 000000000..0df1b4812 --- /dev/null +++ b/astrid/plugin-src/com/todoroo/astrid/gtasks/auth/ModernAuthManager.java @@ -0,0 +1,210 @@ +/* + * Copyright 2010 Google Inc. + * + * 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 com.todoroo.astrid.gtasks.auth; + +import java.io.IOException; + +import android.accounts.Account; +import android.accounts.AccountManager; +import android.accounts.AccountManagerCallback; +import android.accounts.AccountManagerFuture; +import android.accounts.AuthenticatorException; +import android.accounts.OperationCanceledException; +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.util.Log; + +/** + * AuthManager keeps track of the current auth token for a user. The advantage + * over just passing around a String is that this class can renew the auth + * token if necessary, and it will change for all classes using this + * AuthManager. + */ +public class ModernAuthManager implements AuthManager { + protected static final int GET_LOGIN_REQUEST = 1; + +/** The activity that will handle auth result callbacks. */ + private final Activity activity; + + /** The name of the service to authorize for. */ + private final String service; + + /** The most recently fetched auth token or null if none is available. */ + private String authToken; + + private final AccountManager accountManager; + + private Runnable whenFinished; + + /** + * AuthManager requires many of the same parameters as + * {@link com.google.android.googlelogindist.GoogleLoginServiceHelper + * #getCredentials(Activity, int, Bundle, boolean, String, boolean)}. + * The activity must have a handler in {@link Activity#onActivityResult} that + * calls {@link #authResult(int, Intent)} if the request code is the code + * given here. + * + * @param activity An activity with a handler in + * {@link Activity#onActivityResult} that calls + * {@link #authResult(int, Intent)} when {@literal code} is the request + * code + * @param code The request code to pass to + * {@link Activity#onActivityResult} when + * {@link #authResult(int, Intent)} should be called + * @param extras A {@link Bundle} of extras for + * {@link com.google.android.googlelogindist.GoogleLoginServiceHelper} + * @param requireGoogle True if the account must be a Google account + * @param service The name of the service to authenticate as + */ + public ModernAuthManager(Activity activity, int code, Bundle extras, + boolean requireGoogle, String service) { + this.activity = activity; + this.service = service; + this.accountManager = AccountManager.get(activity); + } + + /** + * Call this to do the initial login. The user will be asked to login if + * they haven't already. The {@link Runnable} provided will be executed + * when the auth token is successfully fetched. + * + * @param runnable A {@link Runnable} to execute when the auth token + * has been successfully fetched and is available via + * {@link #getAuthToken()} + */ + @SuppressWarnings("nls") + public void doLogin(final Runnable runnable, Object o) { + this.whenFinished = runnable; + if (!(o instanceof Account)) { + throw new IllegalArgumentException("FroyoAuthManager requires an account."); + } + Account account = (Account) o; + accountManager.getAuthToken(account, service, true, + new AccountManagerCallback() { + public void run(AccountManagerFuture future) { + try { + Bundle result = future.getResult(); + + // AccountManager needs user to grant permission + if (result.containsKey(AccountManager.KEY_INTENT)) { + Intent intent = (Intent) result.get(AccountManager.KEY_INTENT); + clearNewTaskFlag(intent); + activity.startActivityForResult(intent, GET_LOGIN_REQUEST); + return; + } + + authToken = result.getString( + AccountManager.KEY_AUTHTOKEN); + Log.e("gtasks-auth", "Got auth token."); + runWhenFinished(); + } catch (OperationCanceledException e) { + Log.e("gtasks-auth", "Operation Canceled", e); + } catch (IOException e) { + Log.e("gtasks-auth", "IOException", e); + } catch (AuthenticatorException e) { + Log.e("gtasks-auth", "Authentication Failed", e); + } + } + }, null /* handler */); + } + + private static void clearNewTaskFlag(Intent intent) { + int flags = intent.getFlags(); + flags &= ~Intent.FLAG_ACTIVITY_NEW_TASK; + intent.setFlags(flags); + } + + /** + * The {@link Activity} passed into the constructor should call this + * function when it gets {@link Activity#onActivityResult} with the request + * code passed into the constructor. The resultCode and results should + * come directly from the {@link Activity#onActivityResult} function. This + * function will return true if an auth token was successfully fetched or + * the process is not finished. + * + * @param resultCode The result code passed in to the {@link Activity}'s + * {@link Activity#onActivityResult} function + * @param results The data passed in to the {@link Activity}'s + * {@link Activity#onActivityResult} function + * @return True if the auth token was fetched or we aren't done fetching + * the auth token, or False if there was an error or the request was + * canceled + */ + @SuppressWarnings("nls") + public boolean authResult(int resultCode, Intent results) { + if (results != null) { + authToken = results.getStringExtra( + AccountManager.KEY_AUTHTOKEN); + Log.w("google-auth", "authResult: " + authToken); + } else { + Log.e("google-auth", "No auth result results!!"); + } + runWhenFinished(); + return authToken != null; + } + + /** + * Returns the current auth token. Response may be null if no valid auth + * token has been fetched. + * + * @return The current auth token or null if no auth token has been + * fetched + */ + public String getAuthToken() { + return authToken; + } + + /** + * Invalidates the existing auth token and request a new one. The + * {@link Runnable} provided will be executed when the new auth token is + * successfully fetched. + * + * @param runnable A {@link Runnable} to execute when a new auth token + * is successfully fetched + */ + public void invalidateAndRefresh(final Runnable runnable) { + this.whenFinished = runnable; + + activity.runOnUiThread(new Runnable() { + public void run() { + accountManager.invalidateAuthToken("com.google", authToken); //$NON-NLS-1$ + new AccountChooser().chooseAccount(activity, + new AccountChooser.AccountHandler() { + @Override + public void handleAccountSelected(Account account) { + if (account != null) { + doLogin(whenFinished, account); + } else { + runWhenFinished(); + } + } + }); + } + }); + } + + private void runWhenFinished() { + if (whenFinished != null) { + (new Thread() { + @Override + public void run() { + whenFinished.run(); + } + }).start(); + } + } +} diff --git a/astrid/plugin-src/com/todoroo/astrid/gtasks/sync/GtasksSyncProvider.java b/astrid/plugin-src/com/todoroo/astrid/gtasks/sync/GtasksSyncProvider.java index b3da92157..83aa673e7 100644 --- a/astrid/plugin-src/com/todoroo/astrid/gtasks/sync/GtasksSyncProvider.java +++ b/astrid/plugin-src/com/todoroo/astrid/gtasks/sync/GtasksSyncProvider.java @@ -16,6 +16,8 @@ import android.app.PendingIntent; import android.app.Service; import android.content.Context; import android.content.Intent; +import android.os.Bundle; +import android.util.Log; import com.flurry.android.FlurryAgent; import com.timsu.astrid.R; @@ -41,6 +43,8 @@ import com.todoroo.astrid.gtasks.GtasksMetadataService; import com.todoroo.astrid.gtasks.GtasksPreferenceService; import com.todoroo.astrid.gtasks.GtasksPreferences; import com.todoroo.astrid.gtasks.GtasksTaskListUpdater; +import com.todoroo.astrid.gtasks.auth.AuthManager; +import com.todoroo.astrid.gtasks.auth.AuthManagerFactory; import com.todoroo.astrid.producteev.api.ApiServiceException; import com.todoroo.astrid.service.AstridDependencyInjector; import com.todoroo.astrid.sync.SyncBackgroundService; @@ -48,7 +52,6 @@ import com.todoroo.astrid.sync.SyncContainer; import com.todoroo.astrid.sync.SyncProvider; import com.todoroo.astrid.utility.Constants; import com.todoroo.gtasks.GoogleConnectionManager; -import com.todoroo.gtasks.GoogleLoginException; import com.todoroo.gtasks.GoogleTaskService; import com.todoroo.gtasks.GoogleTaskTask; import com.todoroo.gtasks.GoogleTaskView; @@ -83,8 +86,6 @@ public class GtasksSyncProvider extends SyncProvider { public GtasksSyncProvider() { super(); DependencyInjectionService.getInstance().inject(this); - // TODO? - gtasksPreferenceService.stopOngoing(); } // ---------------------------------------------------------------------- @@ -152,7 +153,8 @@ public class GtasksSyncProvider extends SyncProvider { final GoogleConnectionManager connectionManager; if(authToken == null) { - connectionManager = logInHelper(); + Log.e("astrid-sync", "No token, unable to sync"); + return; } else { connectionManager = new GoogleConnectionManager(authToken); } @@ -168,36 +170,39 @@ public class GtasksSyncProvider extends SyncProvider { } } - private GoogleConnectionManager logInHelper() throws GoogleLoginException, - IOException { - // TODO get email and password or something? - String email = "tasktest@todoroo.com"; - String password = "tasktest0000"; - GoogleConnectionManager connectionManager = new GoogleConnectionManager(email, password); - connectionManager.authenticate(true); - gtasksPreferenceService.setToken(connectionManager.getToken()); - return connectionManager; - } - /** * If user isn't already signed in, show sign in dialog. Else perform sync. */ @Override - protected void initiateManual(Activity activity) { + protected void initiateManual(final Activity activity) { String authToken = gtasksPreferenceService.getToken(); gtasksPreferenceService.stopOngoing(); // check if we have a token & it works if(authToken == null) { try { - logInHelper(); + final AuthManager authManager = AuthManagerFactory.getAuthManager(activity, 0, new Bundle(), true, "goanna_mobile"); + authManager.invalidateAndRefresh(new Runnable() { + @Override + public void run() { + String token = authManager.getAuthToken(); + if(token != null) { + gtasksPreferenceService.setToken(token); + //activity.startService(new Intent(SyncBackgroundService.SYNC_ACTION, null, + // activity, GtasksBackgroundService.class)); + System.err.println("yay! " + token); + activity.finish(); + } + } + }); } catch (Exception e) { handleException("auth", e, true); } - } - - activity.startService(new Intent(SyncBackgroundService.SYNC_ACTION, null, + } else { + activity.startService(new Intent(SyncBackgroundService.SYNC_ACTION, null, activity, GtasksBackgroundService.class)); + activity.finish(); + } } diff --git a/astrid/plugin-src/com/todoroo/astrid/producteev/ProducteevPreferences.java b/astrid/plugin-src/com/todoroo/astrid/producteev/ProducteevPreferences.java index 3d51b53ae..d62fa6e86 100644 --- a/astrid/plugin-src/com/todoroo/astrid/producteev/ProducteevPreferences.java +++ b/astrid/plugin-src/com/todoroo/astrid/producteev/ProducteevPreferences.java @@ -31,6 +31,7 @@ public class ProducteevPreferences extends SyncProviderPreferences { @Override public void startSync() { new ProducteevSyncProvider().synchronize(this); + finish(); } @Override diff --git a/astrid/res/values/strings-gtasks.xml b/astrid/res/values/strings-gtasks.xml index febd2d61a..912031eb3 100644 --- a/astrid/res/values/strings-gtasks.xml +++ b/astrid/res/values/strings-gtasks.xml @@ -35,5 +35,14 @@ Astrid: Google Tasks + + Choose Account + + + No Accounts Found + + + We were unable to find a Google account on this phone. You will not be able to synchronize to Google Tasks without one! + diff --git a/astrid/rmilk-src/org/weloveastrid/rmilk/MilkPreferences.java b/astrid/rmilk-src/org/weloveastrid/rmilk/MilkPreferences.java index 613486a18..89b3ab780 100644 --- a/astrid/rmilk-src/org/weloveastrid/rmilk/MilkPreferences.java +++ b/astrid/rmilk-src/org/weloveastrid/rmilk/MilkPreferences.java @@ -23,6 +23,7 @@ public class MilkPreferences extends SyncProviderPreferences { @Override public void startSync() { new MilkSyncProvider().synchronize(this); + finish(); } @Override