diff --git a/astrid/AndroidManifest.xml b/astrid/AndroidManifest.xml index 34d3c956a..feb0ae011 100644 --- a/astrid/AndroidManifest.xml +++ b/astrid/AndroidManifest.xml @@ -308,6 +308,8 @@ + diff --git a/astrid/plugin-src/com/todoroo/astrid/actfm/ActFmGoogleAuthActivity.java b/astrid/plugin-src/com/todoroo/astrid/actfm/ActFmGoogleAuthActivity.java new file mode 100644 index 000000000..59ec6765e --- /dev/null +++ b/astrid/plugin-src/com/todoroo/astrid/actfm/ActFmGoogleAuthActivity.java @@ -0,0 +1,178 @@ +/* + * ASTRID: Android's Simple Task Recording Dashboard + * + * Copyright (c) 2009 Tim Su + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +package com.todoroo.astrid.actfm; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.concurrent.TimeUnit; + +import android.accounts.Account; +import android.accounts.AccountManager; +import android.accounts.AccountManagerCallback; +import android.accounts.AccountManagerFuture; +import android.app.ListActivity; +import android.app.ProgressDialog; +import android.content.Intent; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.ArrayAdapter; +import android.widget.ListView; +import android.widget.Toast; + +import com.google.api.client.googleapis.extensions.android2.auth.GoogleAccountManager; +import com.timsu.astrid.R; +import com.todoroo.andlib.service.ContextManager; +import com.todoroo.andlib.utility.DialogUtilities; +import com.todoroo.astrid.service.StatisticsService; + +/** + * This activity allows users to sign in or log in to Google Tasks + * through the Android account manager + * + * @author Sam Bosley + * + */ +public class ActFmGoogleAuthActivity extends ListActivity { + + private static final String AUTH_TOKEN_TYPE = "oauth2:https://www.googleapis.com/auth/userinfo.profile"; //$NON-NLS-1$ + + public static final String RESULT_EMAIL = "email"; //$NON-NLS-1$ + public static final String RESULT_TOKEN = "token"; //$NON-NLS-1$ + + // --- ui initialization + + private GoogleAccountManager accountManager; + private String[] nameArray; + + private String authToken; + private String accountName; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + ContextManager.setContext(this); + + setContentView(R.layout.gtasks_login_activity); + setTitle(R.string.actfm_GAA_title); + + accountManager = new GoogleAccountManager(this); + Account[] accounts = accountManager.getAccounts(); + ArrayList accountNames = new ArrayList(); + for (Account a : accounts) { + accountNames.add(a.name); + } + + nameArray = accountNames.toArray(new String[accountNames.size()]); + setListAdapter(new ArrayAdapter(this, android.R.layout.simple_list_item_1, nameArray)); + } + + @Override + protected void onListItemClick(ListView l, View v, int position, long id) { + super.onListItemClick(l, v, position, id); + final ProgressDialog pd = DialogUtilities.progressDialog(this, this.getString(R.string.gtasks_GLA_authenticating)); + pd.show(); + final Account a = accountManager.getAccountByName(nameArray[position]); + accountName = a.name; + getAuthToken(a, pd); + } + + private void getAuthToken(Account a, final ProgressDialog pd) { + AccountManagerCallback callback = new AccountManagerCallback() { + public void run(final AccountManagerFuture future) { + new Thread() { + @Override + public void run() { + try { + Bundle bundle = future.getResult(30, TimeUnit.SECONDS); + if (bundle.containsKey(AccountManager.KEY_AUTHTOKEN)) { + authToken = bundle.getString(AccountManager.KEY_AUTHTOKEN); + onAuthTokenSuccess(); + } + } catch (final Exception e) { + Log.e("actfm-google-auth", "Login Error", e); //$NON-NLS-1$ //$NON-NLS-2$ + runOnUiThread(new Runnable() { + @Override + public void run() { + int error = e instanceof IOException ? R.string.gtasks_GLA_errorIOAuth : + R.string.gtasks_GLA_errorAuth; + Toast.makeText(ActFmGoogleAuthActivity.this, + error, + Toast.LENGTH_LONG).show(); + } + }); + } finally { + DialogUtilities.dismissDialog(ActFmGoogleAuthActivity.this, pd); + } + } + }.start(); + } + }; + accountManager.manager.getAuthToken(a, AUTH_TOKEN_TYPE, null, this, callback, null); + } + + private void onAuthCancel() { + setResult(RESULT_CANCELED); + finish(); + } + + private void onAuthTokenSuccess() { + Intent data = new Intent(); + data.putExtra(RESULT_EMAIL, accountName); + data.putExtra(RESULT_TOKEN, authToken); + setResult(RESULT_OK, data); + finish(); + } + + + @Override + protected void onResume() { + super.onResume(); + StatisticsService.sessionStart(this); + } + + @Override + protected void onPause() { + super.onPause(); + StatisticsService.sessionPause(); + } + + @Override + protected void onStop() { + super.onStop(); + StatisticsService.sessionStop(this); + } + + private static final int REQUEST_AUTHENTICATE = 0; + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if(requestCode == REQUEST_AUTHENTICATE && resultCode == RESULT_OK){ + final ProgressDialog pd = DialogUtilities.progressDialog(this, this.getString(R.string.gtasks_GLA_authenticating)); + pd.show(); + final Account a = accountManager.getAccountByName(accountName); + getAuthToken(a, pd); + } else { + onAuthCancel(); + } + } + +} \ No newline at end of file diff --git a/astrid/plugin-src/com/todoroo/astrid/actfm/ActFmLoginActivity.java b/astrid/plugin-src/com/todoroo/astrid/actfm/ActFmLoginActivity.java index 8f79a9a53..a0cdcff9e 100644 --- a/astrid/plugin-src/com/todoroo/astrid/actfm/ActFmLoginActivity.java +++ b/astrid/plugin-src/com/todoroo/astrid/actfm/ActFmLoginActivity.java @@ -21,9 +21,7 @@ package com.todoroo.astrid.actfm; import java.io.FileNotFoundException; import java.io.IOException; -import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; -import java.security.NoSuchAlgorithmException; import java.util.Random; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; @@ -79,9 +77,9 @@ import com.todoroo.astrid.service.StatisticsService; import com.todoroo.astrid.service.TaskService; /** - * This activity allows users to sign in or log in to Producteev + * This activity allows users to sign in or log in to Astrid.com * - * @author arne.jans + * @author Tim Su * */ public class ActFmLoginActivity extends FragmentActivity implements AuthListener { @@ -102,13 +100,14 @@ public class ActFmLoginActivity extends FragmentActivity implements AuthListener private TextView errors; protected boolean noSync = false; - public static final String SHOW_TOAST = "show_toast"; + public static final String SHOW_TOAST = "show_toast"; //$NON-NLS-1$ + private boolean showToast; // --- ui initialization private static final int REQUEST_CODE_GOOGLE_ACCOUNTS = 1; - private static final int REQUEST_CODE_OAUTH = 2; + private static final int REQUEST_CODE_GOOGLE = 2; static { AstridDependencyInjector.initialize(); @@ -129,7 +128,6 @@ public class ActFmLoginActivity extends FragmentActivity implements AuthListener DependencyInjectionService.getInstance().inject(this); } - @SuppressWarnings("nls") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -189,6 +187,7 @@ public class ActFmLoginActivity extends FragmentActivity implements AuthListener StatisticsService.reportEvent(StatisticsConstants.ACTFM_LOGIN_SHOW); } + @SuppressWarnings("nls") protected void initializeUI() { facebook = new Facebook(APP_ID); facebookRunner = new AsyncFacebookRunner(facebook); @@ -207,21 +206,11 @@ public class ActFmLoginActivity extends FragmentActivity implements AuthListener protected final OnClickListener googleListener = new OnClickListener() { @Override - @SuppressWarnings("nls") public void onClick(View arg0) { Intent intent = new Intent(ActFmLoginActivity.this, - OAuthLoginActivity.class); - try { - String url = actFmInvoker.createFetchUrl("user_oauth", - "provider", "google"); - intent.putExtra(OAuthLoginActivity.URL_TOKEN, url); - startActivityForResult(intent, REQUEST_CODE_OAUTH); - StatisticsService.reportEvent(StatisticsConstants.ACTFM_LOGIN_GL_START); - } catch (UnsupportedEncodingException e) { - handleError(e); - } catch (NoSuchAlgorithmException e) { - handleError(e); - } + ActFmGoogleAuthActivity.class); + startActivityForResult(intent, REQUEST_CODE_GOOGLE); + StatisticsService.reportEvent(StatisticsConstants.ACTFM_LOGIN_GL_START); } }; @@ -541,15 +530,10 @@ public class ActFmLoginActivity extends FragmentActivity implements AuthListener onFBAuthSucceed(); } errors.setVisibility(View.GONE); - } else if (requestCode == REQUEST_CODE_OAUTH) { - String result = data.getStringExtra(OAuthLoginActivity.DATA_RESPONSE); - try { - JSONObject json = new JSONObject(result); - postAuthenticate(json, json.getString("token")); - StatisticsService.reportEvent(StatisticsConstants.ACTFM_LOGIN_GL_SUCCESS); - } catch (JSONException e) { - handleError(e); - } + } else if (requestCode == REQUEST_CODE_GOOGLE) { + String email= data.getStringExtra(ActFmGoogleAuthActivity.RESULT_EMAIL); + String token = data.getStringExtra(ActFmGoogleAuthActivity.RESULT_TOKEN); + authenticate(email, email, "google", token); } } @@ -568,4 +552,4 @@ public class ActFmLoginActivity extends FragmentActivity implements AuthListener REQUEST_CODE_GOOGLE_ACCOUNTS, false); } -} \ No newline at end of file +} diff --git a/astrid/plugin-src/com/todoroo/astrid/actfm/sync/ActFmPreferenceService.java b/astrid/plugin-src/com/todoroo/astrid/actfm/sync/ActFmPreferenceService.java index 3be21794c..3cb407732 100644 --- a/astrid/plugin-src/com/todoroo/astrid/actfm/sync/ActFmPreferenceService.java +++ b/astrid/plugin-src/com/todoroo/astrid/actfm/sync/ActFmPreferenceService.java @@ -41,7 +41,7 @@ public class ActFmPreferenceService extends SyncProviderUtilities { @Override public boolean shouldShowToast() { - if(Preferences.getBoolean(AstridPreferences.P_FIRST_ACTION, false)) + if(Preferences.getBoolean(AstridPreferences.P_FIRST_TASK, true)) return false; return super.shouldShowToast(); } diff --git a/astrid/plugin-src/com/todoroo/astrid/gtasks/auth/GtasksLoginActivity.java b/astrid/plugin-src/com/todoroo/astrid/gtasks/auth/GtasksLoginActivity.java index 814b340dd..17ed289df 100644 --- a/astrid/plugin-src/com/todoroo/astrid/gtasks/auth/GtasksLoginActivity.java +++ b/astrid/plugin-src/com/todoroo/astrid/gtasks/auth/GtasksLoginActivity.java @@ -19,6 +19,7 @@ */ package com.todoroo.astrid.gtasks.auth; +import java.io.IOException; import java.util.ArrayList; import java.util.concurrent.TimeUnit; @@ -30,6 +31,7 @@ import android.app.ListActivity; import android.app.ProgressDialog; import android.content.Intent; import android.os.Bundle; +import android.util.Log; import android.view.View; import android.widget.ArrayAdapter; import android.widget.ListView; @@ -81,8 +83,9 @@ public class GtasksLoginActivity extends ListActivity { super.onCreate(savedInstanceState); ContextManager.setContext(this); + setContentView(R.layout.gtasks_login_activity); setTitle(R.string.gtasks_GLA_title); - getListView().setBackgroundColor(getResources().getColor(android.R.color.background_dark)); + accountManager = new GoogleAccountManager(this); Account[] accounts = accountManager.getAccounts(); ArrayList accountNames = new ArrayList(); @@ -117,12 +120,16 @@ public class GtasksLoginActivity extends ListActivity { authToken = bundle.getString(AccountManager.KEY_AUTHTOKEN); onAuthTokenSuccess(); } - } catch (Exception e) { - e.printStackTrace(); - GtasksLoginActivity.this.runOnUiThread(new Runnable() { + } catch (final Exception e) { + Log.e("gtasks-login", "Login Error", e); //$NON-NLS-1$ //$NON-NLS-2$ + runOnUiThread(new Runnable() { @Override public void run() { - Toast.makeText(GtasksLoginActivity.this, R.string.gtasks_GLA_errorAuth, Toast.LENGTH_LONG).show(); + int error = e instanceof IOException ? R.string.gtasks_GLA_errorIOAuth : + R.string.gtasks_GLA_errorAuth; + Toast.makeText(GtasksLoginActivity.this, + error, + Toast.LENGTH_LONG).show(); } }); } finally { diff --git a/astrid/proguard.cfg b/astrid/proguard.cfg index 81129cde9..beb734a14 100644 --- a/astrid/proguard.cfg +++ b/astrid/proguard.cfg @@ -13,6 +13,9 @@ -keep class com.google.common.base.Preconditions -keep class * extends com.todoroo.andlib.data.AbstractModel -keep class android.support.v4.** +-keep class com.google.gson.stream.JsonReader { + public void setLenient(boolean); +} # ignore reflection-based access from google libraries -dontwarn com.google.** diff --git a/astrid/res/layout/gtasks_login_activity.xml b/astrid/res/layout/gtasks_login_activity.xml index 7e1fd031f..c573b861e 100644 --- a/astrid/res/layout/gtasks_login_activity.xml +++ b/astrid/res/layout/gtasks_login_activity.xml @@ -1,14 +1,18 @@ - + + android:layout_width="fill_parent" + android:layout_height="fill_parent"/> + + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:text="@string/gtasks_GLA_noaccounts" + android:gravity="center" + style="@style/TextAppearance.TLA_NoItems" /> - \ No newline at end of file + \ No newline at end of file diff --git a/astrid/res/values/strings-actfm.xml b/astrid/res/values/strings-actfm.xml index c7082ab02..c7db8beb3 100644 --- a/astrid/res/values/strings-actfm.xml +++ b/astrid/res/values/strings-actfm.xml @@ -220,11 +220,8 @@ Login to Astrid.com - - Please connect to Google: - - - Astrid won\'t send messages e-mails without permission. + + Select a Google account: diff --git a/astrid/res/values/strings-gtasks.xml b/astrid/res/values/strings-gtasks.xml index b764607fd..190c3a478 100644 --- a/astrid/res/values/strings-gtasks.xml +++ b/astrid/res/values/strings-gtasks.xml @@ -75,6 +75,9 @@ Error authenticating! Please check your username and password in your phone\'s account manager + + + Sorry, we had trouble communicating with Google servers. Please try again later. You may have encountered a captcha. diff --git a/astrid/res/values/strings-welcome.xml b/astrid/res/values/strings-welcome.xml index 38c36c9eb..44d83370a 100644 --- a/astrid/res/values/strings-welcome.xml +++ b/astrid/res/values/strings-welcome.xml @@ -15,9 +15,9 @@ That\'s it! - The perfect personal\nto-do list that works great\nwith friends - Perfect for any list:\nto read, to watch, to buy,\nto visit, to do! - Share lists\nwith friends, housemates,\nor your sweetheart! + The perfect to-do list that \nworks great with friends + Perfect for any list:\nread, watch, buy, visit! + Share lists with \nfriends, housemates,\nor your sweetheart! Never wonder who\'s\nbringing dessert! Tap to add notes,\nset reminders,\nand much more! Additional features,\nproductivity tips, and\nsuggestions from friends diff --git a/astrid/src/com/todoroo/astrid/dao/MetadataDao.java b/astrid/src/com/todoroo/astrid/dao/MetadataDao.java index bd0bd301c..778187966 100644 --- a/astrid/src/com/todoroo/astrid/dao/MetadataDao.java +++ b/astrid/src/com/todoroo/astrid/dao/MetadataDao.java @@ -73,7 +73,7 @@ public class MetadataDao extends DatabaseDao { item.setValue(Metadata.CREATION_DATE, DateUtilities.now()); boolean state = super.persist(item); - if(Preferences.getBoolean(AstridPreferences.P_FIRST_LIST, false)) { + if(Preferences.getBoolean(AstridPreferences.P_FIRST_LIST, true)) { if (state && item.getValue(Metadata.KEY).equals(TagService.KEY)) { StatisticsService.reportEvent(StatisticsConstants.USER_FIRST_LIST); Preferences.setBoolean(AstridPreferences.P_FIRST_LIST, false); diff --git a/astrid/src/com/todoroo/astrid/dao/TaskDao.java b/astrid/src/com/todoroo/astrid/dao/TaskDao.java index b6faa8b43..efe51afc3 100644 --- a/astrid/src/com/todoroo/astrid/dao/TaskDao.java +++ b/astrid/src/com/todoroo/astrid/dao/TaskDao.java @@ -207,9 +207,9 @@ public class TaskDao extends DatabaseDao { } private void userRetentionMetrics() { - if(Preferences.getBoolean(AstridPreferences.P_FIRST_ACTION, false)) { + if(Preferences.getBoolean(AstridPreferences.P_FIRST_TASK, true)) { StatisticsService.reportEvent(StatisticsConstants.USER_FIRST_TASK); - Preferences.setBoolean(AstridPreferences.P_FIRST_ACTION, false); + Preferences.setBoolean(AstridPreferences.P_FIRST_TASK, false); } long firstLaunchTime = Preferences.getLong(AstridPreferences.P_FIRST_LAUNCH, 0); diff --git a/astrid/src/com/todoroo/astrid/service/UpgradeService.java b/astrid/src/com/todoroo/astrid/service/UpgradeService.java index 7695b263d..549ca19e5 100644 --- a/astrid/src/com/todoroo/astrid/service/UpgradeService.java +++ b/astrid/src/com/todoroo/astrid/service/UpgradeService.java @@ -41,6 +41,7 @@ import com.todoroo.astrid.utility.AstridPreferences; public final class UpgradeService { + public static final int V3_9_2_3 = 210; public static final int V3_9_2_2 = 209; public static final int V3_9_2_1 = 208; public static final int V3_9_2 = 207; @@ -174,6 +175,14 @@ public final class UpgradeService { Preferences.clear(AstridPreferences.P_UPGRADE_FROM); StringBuilder changeLog = new StringBuilder(); + if (from >= V3_9_2 && from < V3_9_2_3) { + newVersionString(changeLog, "3.9.2.3 (1/20/12)", new String[] { + "Fixed a bug with displaying update messages", + "Fixed an occasional crash in Gtasks Sync", + "Other minor bugfixes" + }); + } + if (from >= V3_9_2 && from < V3_9_2_2) { newVersionString(changeLog, "3.9.2.2 (1/19/12)", new String[] { "Astrid now recognizes words like 'tomorrow', 'monday', '!!!' and '2 pm' to set date and importance", diff --git a/astrid/src/com/todoroo/astrid/utility/AstridPreferences.java b/astrid/src/com/todoroo/astrid/utility/AstridPreferences.java index d5f8c533b..b2631ae79 100644 --- a/astrid/src/com/todoroo/astrid/utility/AstridPreferences.java +++ b/astrid/src/com/todoroo/astrid/utility/AstridPreferences.java @@ -15,7 +15,7 @@ public class AstridPreferences { private static final String P_CURRENT_VERSION = "cv"; //$NON-NLS-1$ - public static final String P_FIRST_ACTION = "fa"; //$NON-NLS-1$ + public static final String P_FIRST_TASK = "ft"; //$NON-NLS-1$ public static final String P_FIRST_LIST = "fl"; //$NON-NLS-1$