From 9a0a1ab6c97cd155f0b30e3ae3d2092002d769c8 Mon Sep 17 00:00:00 2001 From: Sam Bosley Date: Mon, 5 Nov 2012 15:58:38 -0800 Subject: [PATCH] AB test the social reminders --- api/src/com/todoroo/astrid/data/Task.java | 13 ++++++ .../astrid/reminders/Notifications.java | 1 + .../astrid/reminders/ReminderDialog.java | 40 ++++++++++++------- astrid/res/values/keys.xml | 3 ++ .../todoroo/astrid/adapter/TaskAdapter.java | 7 +--- .../src/com/todoroo/astrid/dao/Database.java | 8 +++- .../astrid/service/StatisticsConstants.java | 2 + .../todoroo/astrid/service/TaskService.java | 21 +++++++++- .../astrid/service/abtesting/ABTests.java | 5 +++ .../astrid/utility/AstridPreferences.java | 3 ++ 10 files changed, 80 insertions(+), 23 deletions(-) diff --git a/api/src/com/todoroo/astrid/data/Task.java b/api/src/com/todoroo/astrid/data/Task.java index cf0e4518d..5f8adc062 100644 --- a/api/src/com/todoroo/astrid/data/Task.java +++ b/api/src/com/todoroo/astrid/data/Task.java @@ -121,6 +121,11 @@ public final class Task extends RemoteModel { public static final LongProperty REMINDER_LAST = new LongProperty( TABLE, "lastNotified"); + /** What kind of reminder the last reminder was: private task, + * social with no faces, social with faces */ + public static final StringProperty SOCIAL_REMINDER = new StringProperty( + TABLE, "socialReminder"); + /** Unixtime snooze is set (0 -> no snooze) */ public static final LongProperty REMINDER_SNOOZE = new LongProperty( TABLE, "snoozeTime"); @@ -208,6 +213,13 @@ public final class Task extends RemoteModel { public static final int IMPORTANCE_SHOULD_DO = 2; public static final int IMPORTANCE_NONE = 3; + // --- social reminder types + + public static final String REMINDER_SOCIAL_UNSEEN = "unseen"; + public static final String REMINDER_SOCIAL_PRIVATE = "private"; + public static final String REMINDER_SOCIAL_NO_FACES = "no_faces"; + public static final String REMINDER_SOCIAL_FACES = "faces"; + /** * @return colors that correspond to importance values */ @@ -244,6 +256,7 @@ public final class Task extends RemoteModel { defaultValues.put(REMINDER_PERIOD.name, 0); defaultValues.put(REMINDER_FLAGS.name, 0); defaultValues.put(REMINDER_LAST.name, 0); + defaultValues.put(SOCIAL_REMINDER.name, REMINDER_SOCIAL_UNSEEN); defaultValues.put(REMINDER_SNOOZE.name, 0); defaultValues.put(ESTIMATED_SECONDS.name, 0); defaultValues.put(ELAPSED_SECONDS.name, 0); diff --git a/astrid/plugin-src/com/todoroo/astrid/reminders/Notifications.java b/astrid/plugin-src/com/todoroo/astrid/reminders/Notifications.java index 8ef5fc7d9..fa4aca6be 100644 --- a/astrid/plugin-src/com/todoroo/astrid/reminders/Notifications.java +++ b/astrid/plugin-src/com/todoroo/astrid/reminders/Notifications.java @@ -186,6 +186,7 @@ public class Notifications extends BroadcastReceiver { // update last reminder time task.setValue(Task.REMINDER_LAST, DateUtilities.now()); + task.setValue(Task.SOCIAL_REMINDER, Task.REMINDER_SOCIAL_UNSEEN); taskDao.saveExisting(task); Context context = ContextManager.getContext(); diff --git a/astrid/plugin-src/com/todoroo/astrid/reminders/ReminderDialog.java b/astrid/plugin-src/com/todoroo/astrid/reminders/ReminderDialog.java index 2b697161f..3ad0b0107 100644 --- a/astrid/plugin-src/com/todoroo/astrid/reminders/ReminderDialog.java +++ b/astrid/plugin-src/com/todoroo/astrid/reminders/ReminderDialog.java @@ -7,6 +7,7 @@ package com.todoroo.astrid.reminders; import java.util.Date; import java.util.LinkedHashSet; +import java.util.concurrent.atomic.AtomicBoolean; import org.json.JSONArray; import org.json.JSONException; @@ -114,9 +115,8 @@ public class ReminderDialog extends Dialog { findViewById(R.id.reminder_complete).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { - Task task = new Task(); - task.setId(taskId); - PluginServices.getTaskService().setComplete(task, true); + Task task = taskService.fetchById(taskId, Task.ID, Task.REMINDER_LAST, Task.SOCIAL_REMINDER); + taskService.setComplete(task, true); activity.sendBroadcast(new Intent(AstridApiConstants.BROADCAST_EVENT_REFRESH)); Toast.makeText(activity, R.string.rmd_NoA_completed_toast, @@ -147,19 +147,22 @@ public class ReminderDialog extends Dialog { private void setupSpeechBubble(Activity activity, long taskId) { ((TextView) findViewById(R.id.reminder_message)).setText( Notifications.getRandomReminder(activity.getResources().getStringArray(R.array.reminder_responses))); - if (true) - addFacesToReminder(activity, taskId); + + Task task = taskService.fetchById(taskId, Task.ID, Task.SHARED_WITH); + addFacesToReminder(activity, task); } - private void addFacesToReminder(Activity activity, long taskId) { + private void addFacesToReminder(Activity activity, Task task) { LinkedHashSet pictureUrls = new LinkedHashSet(); - addSharedWithFaces(taskId, pictureUrls); + AtomicBoolean isSharedTask = new AtomicBoolean(false); + + addSharedWithFaces(task, pictureUrls, isSharedTask); if (pictureUrls.size() < MAX_FACES) { - addTagFaces(taskId, pictureUrls); + addTagFaces(task.getId(), pictureUrls, isSharedTask); } - if (pictureUrls.size() > 0) { + if (pictureUrls.size() > 0 && Preferences.getBoolean(R.string.p_social_reminders, false)) { DisplayMetrics metrics = activity.getResources().getDisplayMetrics(); LinearLayout layout = new LinearLayout(activity); LinearLayout.LayoutParams containerParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); @@ -188,15 +191,23 @@ public class ReminderDialog extends Dialog { ((TextView) findViewById(R.id.reminder_message)).setText( Notifications.getRandomReminder(activity.getResources().getStringArray(R.array.reminders_social))); + + task.setValue(Task.SOCIAL_REMINDER, Task.REMINDER_SOCIAL_FACES); + } else { + if (isSharedTask.get()) + task.setValue(Task.SOCIAL_REMINDER, Task.REMINDER_SOCIAL_NO_FACES); + else + task.setValue(Task.SOCIAL_REMINDER, Task.REMINDER_SOCIAL_PRIVATE); } } - private void addPicturesFromJSONArray(JSONArray array, LinkedHashSet pictureUrls) throws JSONException { + private void addPicturesFromJSONArray(JSONArray array, LinkedHashSet pictureUrls, AtomicBoolean isSharedTask) throws JSONException { for (int i = 0; i < array.length(); i++) { JSONObject person = array.getJSONObject(i); if (person.has("picture")) { //$NON-NLS-1$ if (person.optLong("id") == ActFmPreferenceService.userId()) //$NON-NLS-1$ continue; + isSharedTask.set(true); String pictureUrl = person.getString("picture"); //$NON-NLS-1$ if (!TextUtils.isEmpty(pictureUrl)) { pictureUrls.add(pictureUrl); @@ -205,20 +216,19 @@ public class ReminderDialog extends Dialog { } } - private void addSharedWithFaces(long taskId, LinkedHashSet pictureUrls) { - Task t = taskService.fetchById(taskId, Task.SHARED_WITH); + private void addSharedWithFaces(Task t, LinkedHashSet pictureUrls, AtomicBoolean isSharedTask) { try { JSONObject sharedWith = new JSONObject(t.getValue(Task.SHARED_WITH)); if (sharedWith.has("p")) { //$NON-NLS-1$ JSONArray people = sharedWith.getJSONArray("p"); //$NON-NLS-1$ - addPicturesFromJSONArray(people, pictureUrls); + addPicturesFromJSONArray(people, pictureUrls, isSharedTask); } } catch (JSONException e) { // } } - private void addTagFaces(long taskId, LinkedHashSet pictureUrls) { + private void addTagFaces(long taskId, LinkedHashSet pictureUrls, AtomicBoolean isSharedTask) { TodorooCursor tags = tagService.getTagDataForTask(taskId, TagData.MEMBER_COUNT.gt(0), TagData.MEMBERS); try { TagData td = new TagData(); @@ -226,7 +236,7 @@ public class ReminderDialog extends Dialog { td.readFromCursor(tags); try { JSONArray people = new JSONArray(td.getValue(TagData.MEMBERS)); - addPicturesFromJSONArray(people, pictureUrls); + addPicturesFromJSONArray(people, pictureUrls, isSharedTask); } catch (JSONException e) { // } diff --git a/astrid/res/values/keys.xml b/astrid/res/values/keys.xml index 052077d29..5b7e873c8 100644 --- a/astrid/res/values/keys.xml +++ b/astrid/res/values/keys.xml @@ -67,6 +67,9 @@ show_featured_lists_labs + + social_reminders + account diff --git a/astrid/src/com/todoroo/astrid/adapter/TaskAdapter.java b/astrid/src/com/todoroo/astrid/adapter/TaskAdapter.java index 2cc49dc37..593c00d3f 100644 --- a/astrid/src/com/todoroo/astrid/adapter/TaskAdapter.java +++ b/astrid/src/com/todoroo/astrid/adapter/TaskAdapter.java @@ -88,8 +88,6 @@ import com.todoroo.astrid.helper.AsyncImageView; import com.todoroo.astrid.helper.TaskAdapterAddOnManager; import com.todoroo.astrid.notes.NotesAction; import com.todoroo.astrid.notes.NotesDecorationExposer; -import com.todoroo.astrid.service.StatisticsConstants; -import com.todoroo.astrid.service.StatisticsService; import com.todoroo.astrid.service.TaskService; import com.todoroo.astrid.service.ThemeService; import com.todoroo.astrid.tags.TagService; @@ -139,6 +137,8 @@ public class TaskAdapter extends CursorAdapter implements Filterable { Task.NOTES, Task.USER_ID, Task.USER, + Task.REMINDER_LAST, + Task.SOCIAL_REMINDER, TASK_RABBIT_ID, // Task rabbit metadata id (non-zero means it exists) TAGS // Concatenated list of tags }; @@ -1212,9 +1212,6 @@ public class TaskAdapter extends CursorAdapter implements Filterable { completedItems.put(task.getId(), newState); taskService.setComplete(task, newState); - - if(newState) - StatisticsService.reportEvent(StatisticsConstants.TASK_COMPLETED_V2); } } diff --git a/astrid/src/com/todoroo/astrid/dao/Database.java b/astrid/src/com/todoroo/astrid/dao/Database.java index b14ff418f..f55e66f77 100644 --- a/astrid/src/com/todoroo/astrid/dao/Database.java +++ b/astrid/src/com/todoroo/astrid/dao/Database.java @@ -40,7 +40,7 @@ public class Database extends AbstractDatabase { * Database version number. This variable must be updated when database * tables are updated, as it determines whether a database needs updating. */ - public static final int VERSION = 27; + public static final int VERSION = 28; /** * Database name (must be unique) @@ -345,6 +345,12 @@ public class Database extends AbstractDatabase { } catch (SQLiteException e) { Log.e("astrid", "db-upgrade-" + oldVersion + "-" + newVersion, e); } + case 27: try { + database.execSQL("ALTER TABLE " + Task.TABLE.name + " ADD " + + Task.SOCIAL_REMINDER.accept(visitor, null)); + } catch (SQLiteException e) { + Log.e("astrid", "db-upgrade-" + oldVersion + "-" + newVersion, e); + } return true; } diff --git a/astrid/src/com/todoroo/astrid/service/StatisticsConstants.java b/astrid/src/com/todoroo/astrid/service/StatisticsConstants.java index 989ec1a4d..f22dccb67 100644 --- a/astrid/src/com/todoroo/astrid/service/StatisticsConstants.java +++ b/astrid/src/com/todoroo/astrid/service/StatisticsConstants.java @@ -12,6 +12,8 @@ public class StatisticsConstants { public static final String ACTFM_TASK_COMMENT = "actfm-task-comment"; public static final String ACTFM_NEW_USER = "actfm-new-user"; public static final String TASK_COMPLETED_V2 = "task-completed-v2"; + public static final String TASK_COMPLETED_ONE_DAY = "task-completed-one-day"; + public static final String TASK_COMPLETED_ONE_WEEK = "task-completed-one-week"; public static final String USER_FIRST_TASK = "user-first-task"; public static final String USER_FIRST_LIST = "user-first-list"; public static final String LOST_TASKS_RESTORED = "lost-tasks-restored"; diff --git a/astrid/src/com/todoroo/astrid/service/TaskService.java b/astrid/src/com/todoroo/astrid/service/TaskService.java index 17a983963..57006a251 100644 --- a/astrid/src/com/todoroo/astrid/service/TaskService.java +++ b/astrid/src/com/todoroo/astrid/service/TaskService.java @@ -121,10 +121,27 @@ public class TaskService { * @param item */ public void setComplete(Task item, boolean completed) { - if(completed) + if(completed) { item.setValue(Task.COMPLETION_DATE, DateUtilities.now()); - else + + long reminderLast = item.getValue(Task.REMINDER_LAST); + String socialReminder = item.getValue(Task.SOCIAL_REMINDER); + if (reminderLast > 0) { + long diff = DateUtilities.now() - reminderLast; + if (diff > 0 && diff < DateUtilities.ONE_DAY) { + // within one day of last reminder + StatisticsService.reportEvent(StatisticsConstants.TASK_COMPLETED_ONE_DAY, "social", socialReminder); //$NON-NLS-1$ + } + if (diff > 0 && diff < DateUtilities.ONE_WEEK) { + // within one week of last reminder + StatisticsService.reportEvent(StatisticsConstants.TASK_COMPLETED_ONE_WEEK, "social", socialReminder); //$NON-NLS-1$ + } + } + StatisticsService.reportEvent(StatisticsConstants.TASK_COMPLETED_V2); + } else { item.setValue(Task.COMPLETION_DATE, 0L); + } + taskDao.save(item); } diff --git a/astrid/src/com/todoroo/astrid/service/abtesting/ABTests.java b/astrid/src/com/todoroo/astrid/service/abtesting/ABTests.java index 9ee9d6512..62452ecec 100644 --- a/astrid/src/com/todoroo/astrid/service/abtesting/ABTests.java +++ b/astrid/src/com/todoroo/astrid/service/abtesting/ABTests.java @@ -125,6 +125,8 @@ public class ABTests { public static final String AB_FEATURED_LISTS = "android_featured_lists"; //$NON-NLS-1$ + public static final String AB_SOCIAL_REMINDERS = "android_social_reminders"; //$NON-NLS-1$ + private void initialize() { addTest(AB_FEATURED_LISTS, new int[] { 1, 1 }, @@ -135,5 +137,8 @@ public class ABTests { addTest(AB_CALENDAR_REMINDERS, new int[] { 3, 1 }, new int[] { 3, 1 }, new String[] { "no-cal-reminders", "show-cal-reminders" }); //$NON-NLS-1$ //$NON-NLS-2$ + + addTest(AB_SOCIAL_REMINDERS, new int[] { 1, 1 }, + new int[] { 1, 1 }, new String[] { "no-faces", "show-faces" }); //$NON-NLS-1$ //$NON-NLS-2$ } } diff --git a/astrid/src/com/todoroo/astrid/utility/AstridPreferences.java b/astrid/src/com/todoroo/astrid/utility/AstridPreferences.java index 032111ecf..8a16db21a 100644 --- a/astrid/src/com/todoroo/astrid/utility/AstridPreferences.java +++ b/astrid/src/com/todoroo/astrid/utility/AstridPreferences.java @@ -81,6 +81,9 @@ public class AstridPreferences { Preferences.setIfUnset(prefs, editor, r, R.string.p_calendar_reminders, ABChooser.readChoiceForTest(ABTests.AB_CALENDAR_REMINDERS) != 0); + Preferences.setIfUnset(prefs, editor, r, R.string.p_social_reminders, + ABChooser.readChoiceForTest(ABTests.AB_SOCIAL_REMINDERS) != 0); + if ("white-blue".equals(Preferences.getStringValue(R.string.p_theme))) { //$NON-NLS-1$ migrate from when white-blue wasn't the default Preferences.setString(R.string.p_theme, ThemeService.THEME_WHITE); }