Started cleaning up and refactoring the AB testing classes to fit with the new analytics framework

pull/14/head
Sam Bosley 13 years ago
parent 6e37a22bf8
commit 02049930c9

@ -29,7 +29,6 @@ import com.timsu.astrid.R;
import com.todoroo.andlib.sql.Functions; import com.todoroo.andlib.sql.Functions;
import com.todoroo.andlib.sql.QueryTemplate; import com.todoroo.andlib.sql.QueryTemplate;
import com.todoroo.andlib.utility.AndroidUtilities; import com.todoroo.andlib.utility.AndroidUtilities;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.andlib.utility.DialogUtilities; import com.todoroo.andlib.utility.DialogUtilities;
import com.todoroo.andlib.utility.Preferences; import com.todoroo.andlib.utility.Preferences;
import com.todoroo.astrid.actfm.TagSettingsActivity; import com.todoroo.astrid.actfm.TagSettingsActivity;
@ -52,7 +51,6 @@ import com.todoroo.astrid.ui.FragmentPopover;
import com.todoroo.astrid.ui.MainMenuPopover; import com.todoroo.astrid.ui.MainMenuPopover;
import com.todoroo.astrid.ui.MainMenuPopover.MainMenuListener; import com.todoroo.astrid.ui.MainMenuPopover.MainMenuListener;
import com.todoroo.astrid.ui.TaskListFragmentPager; import com.todoroo.astrid.ui.TaskListFragmentPager;
import com.todoroo.astrid.utility.AstridPreferences;
import com.todoroo.astrid.utility.Constants; import com.todoroo.astrid.utility.Constants;
import com.todoroo.astrid.utility.Flags; import com.todoroo.astrid.utility.Flags;
@ -200,37 +198,12 @@ public class TaskListActivity extends AstridActivity implements MainMenuListener
if (getIntent().hasExtra(TOKEN_SOURCE)) { if (getIntent().hasExtra(TOKEN_SOURCE)) {
trackActivitySource(); trackActivitySource();
} }
trackUserRetention();
} }
private boolean swipeIsEnabled() { private boolean swipeIsEnabled() {
return fragmentLayout == LAYOUT_SINGLE && swipeEnabled; return fragmentLayout == LAYOUT_SINGLE && swipeEnabled;
} }
private void trackUserRetention() {
long firstLaunchTime = Preferences.getLong(AstridPreferences.P_FIRST_LAUNCH, 0);
long now = DateUtilities.now();
long timeSinceFirst = now - firstLaunchTime;
if (timeSinceFirst > DateUtilities.ONE_DAY * 3 && !Preferences.getBoolean(StatisticsConstants.APP_OPEN_THREE_DAYS, false)) {
StatisticsService.reportEvent(StatisticsConstants.APP_OPEN_THREE_DAYS);
Preferences.setBoolean(StatisticsConstants.APP_OPEN_THREE_DAYS, true);
}
if (timeSinceFirst > DateUtilities.ONE_WEEK && !Preferences.getBoolean(StatisticsConstants.APP_OPEN_ONE_WEEK, false)) {
StatisticsService.reportEvent(StatisticsConstants.APP_OPEN_ONE_WEEK);
Preferences.setBoolean(StatisticsConstants.APP_OPEN_ONE_WEEK, true);
}
if (timeSinceFirst > 2 * DateUtilities.ONE_WEEK && !Preferences.getBoolean(StatisticsConstants.APP_OPEN_TWO_WEEKS, false)) {
StatisticsService.reportEvent(StatisticsConstants.APP_OPEN_TWO_WEEKS);
Preferences.setBoolean(StatisticsConstants.APP_OPEN_TWO_WEEKS, true);
}
if (timeSinceFirst > 3 * DateUtilities.ONE_WEEK && !Preferences.getBoolean(StatisticsConstants.APP_OPEN_THREE_WEEKS, false)) {
StatisticsService.reportEvent(StatisticsConstants.APP_OPEN_THREE_WEEKS);
Preferences.setBoolean(StatisticsConstants.APP_OPEN_THREE_WEEKS, true);
}
}
@Override @Override
public TaskListFragment getTaskListFragment() { public TaskListFragment getTaskListFragment() {
if (swipeIsEnabled()) { if (swipeIsEnabled()) {

@ -25,7 +25,7 @@ import com.todoroo.astrid.gtasks.GtasksPreferenceService;
import com.todoroo.astrid.gtasks.GtasksTaskListUpdater; import com.todoroo.astrid.gtasks.GtasksTaskListUpdater;
import com.todoroo.astrid.gtasks.sync.GtasksSyncService; import com.todoroo.astrid.gtasks.sync.GtasksSyncService;
import com.todoroo.astrid.service.abtesting.ABChooser; import com.todoroo.astrid.service.abtesting.ABChooser;
import com.todoroo.astrid.service.abtesting.ABOptions; import com.todoroo.astrid.service.abtesting.ABTests;
import com.todoroo.astrid.service.abtesting.FeatureFlipper; import com.todoroo.astrid.service.abtesting.FeatureFlipper;
import com.todoroo.astrid.tags.TagService; import com.todoroo.astrid.tags.TagService;
import com.todoroo.astrid.utility.Constants; import com.todoroo.astrid.utility.Constants;
@ -99,7 +99,7 @@ public class AstridDependencyInjector extends AbstractDependencyInjector {
// AB testing // AB testing
injectables.put("abChooser", ABChooser.class); injectables.put("abChooser", ABChooser.class);
injectables.put("abOptions", new ABOptions()); injectables.put("abTests", new ABTests());
injectables.put("featureFlipper", FeatureFlipper.class); injectables.put("featureFlipper", FeatureFlipper.class);
// com.todoroo.astrid.tags // com.todoroo.astrid.tags

@ -42,7 +42,6 @@ import com.todoroo.astrid.opencrx.OpencrxCoreUtils;
import com.todoroo.astrid.producteev.ProducteevUtilities; import com.todoroo.astrid.producteev.ProducteevUtilities;
import com.todoroo.astrid.reminders.ReminderStartupReceiver; import com.todoroo.astrid.reminders.ReminderStartupReceiver;
import com.todoroo.astrid.service.abtesting.ABChooser; import com.todoroo.astrid.service.abtesting.ABChooser;
import com.todoroo.astrid.service.abtesting.ABOptions;
import com.todoroo.astrid.service.abtesting.FeatureFlipper; import com.todoroo.astrid.service.abtesting.FeatureFlipper;
import com.todoroo.astrid.utility.AstridPreferences; import com.todoroo.astrid.utility.AstridPreferences;
import com.todoroo.astrid.utility.Constants; import com.todoroo.astrid.utility.Constants;
@ -213,10 +212,11 @@ public class StartupService {
} }
}).start(); }).start();
abChooser.getChoiceForOption(ABOptions.AB_OPTION_SWIPE_ENABLED_KEY); abChooser.makeChoicesForAllTests();
abChooser.getChoiceForOption(ABOptions.AB_OPTION_CONTACTS_PICKER_ENABLED);
AstridPreferences.setPreferenceDefaults(); AstridPreferences.setPreferenceDefaults();
trackABTestingData();
// check for task killers // check for task killers
if(!Constants.OEM) if(!Constants.OEM)
showTaskKillerHelp(context); showTaskKillerHelp(context);
@ -224,6 +224,28 @@ public class StartupService {
hasStartedUp = true; hasStartedUp = true;
} }
private void trackABTestingData() {
long firstLaunchTime = Preferences.getLong(AstridPreferences.P_FIRST_LAUNCH, 0);
long now = DateUtilities.now();
long timeSinceFirst = now - firstLaunchTime;
if (firstLaunchTime == 0) {
// Event days +0
}
if (timeSinceFirst > DateUtilities.ONE_DAY * 3 /*&& !some condition*/) {
// Event days +3
}
if (timeSinceFirst > DateUtilities.ONE_WEEK /*&& !some condition*/) {
// Event days +7
}
if (timeSinceFirst > 2 * DateUtilities.ONE_WEEK /*&& !some condition*/) {
// Event days +14
}
if (timeSinceFirst > 3 * DateUtilities.ONE_WEEK /*&& !some condition*/) {
// Event days +21
}
}
/** /**
* @param context * @param context
* @param e error that was raised * @param e error that was raised

@ -70,11 +70,4 @@ public class StatisticsConstants {
public static final String TASK_ONE_WEEK = "task-created-one-week"; public static final String TASK_ONE_WEEK = "task-created-one-week";
public static final String TASK_TWO_WEEKS = "task-created-two-weeks"; public static final String TASK_TWO_WEEKS = "task-created-two-weeks";
public static final String TASK_THREE_WEEKS = "task-created-three-weeks"; public static final String TASK_THREE_WEEKS = "task-created-three-weeks";
public static final String APP_OPEN_THREE_DAYS = "app-open-three-days";
public static final String APP_OPEN_ONE_WEEK = "app-open-one-week";
public static final String APP_OPEN_TWO_WEEKS = "app-open-two-weeks";
public static final String APP_OPEN_THREE_WEEKS = "app-open-three-weeks";
} }

@ -11,21 +11,12 @@ import android.content.Context;
import com.localytics.android.LocalyticsSession; import com.localytics.android.LocalyticsSession;
import com.timsu.astrid.R; import com.timsu.astrid.R;
import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.service.DependencyInjectionService;
import com.todoroo.andlib.utility.Preferences; import com.todoroo.andlib.utility.Preferences;
import com.todoroo.astrid.service.abtesting.ABOptions;
import com.todoroo.astrid.utility.Constants; import com.todoroo.astrid.utility.Constants;
public class StatisticsService { public class StatisticsService {
private static LocalyticsSession localyticsSession; private static LocalyticsSession localyticsSession;
private static class StatisticsDependencies {
@Autowired ABOptions abOptions;
public StatisticsDependencies() {
DependencyInjectionService.getInstance().inject(this);
}
}
/** /**
* Indicate session started * Indicate session started
@ -93,15 +84,12 @@ public class StatisticsService {
return; return;
if(localyticsSession != null) { if(localyticsSession != null) {
String[] abAttributes = new StatisticsDependencies().abOptions.getLocalyticsAttributeArrayForEvent(event); if(attributes.length > 0) {
if(attributes.length > 0 || abAttributes.length > 0) {
HashMap<String, String> attrMap = new HashMap<String, String>(); HashMap<String, String> attrMap = new HashMap<String, String>();
for(int i = 1; i < attributes.length; i += 2) { for(int i = 1; i < attributes.length; i += 2) {
if(attributes[i] != null) if(attributes[i] != null)
attrMap.put(attributes[i-1], attributes[i]); attrMap.put(attributes[i-1], attributes[i]);
} }
for (int i = 1; i < abAttributes.length; i += 2)
attrMap.put(abAttributes[i-1], abAttributes[i]);
localyticsSession.tagEvent(event, attrMap); localyticsSession.tagEvent(event, attrMap);
} else } else
localyticsSession.tagEvent(event); localyticsSession.tagEvent(event);

@ -1,6 +1,7 @@
package com.todoroo.astrid.service.abtesting; package com.todoroo.astrid.service.abtesting;
import java.util.Random; import java.util.Random;
import java.util.Set;
import com.todoroo.andlib.service.Autowired; import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.service.DependencyInjectionService; import com.todoroo.andlib.service.DependencyInjectionService;
@ -18,7 +19,7 @@ public class ABChooser {
public static final int NO_OPTION = -1; public static final int NO_OPTION = -1;
@Autowired @Autowired
private ABOptions abOptions; private ABTests abTests;
private final Random random; private final Random random;
@ -27,6 +28,17 @@ public class ABChooser {
random = new Random(); random = new Random();
} }
/**
* Iterates through the list of all available tests and makes sure that a choice
* is made for each of them
*/
public void makeChoicesForAllTests() {
Set<String> tests = abTests.getAllTestKeys();
for (String test : tests) {
getChoiceForTest(test);
}
}
/** /**
* Retrieves the choice for the specified feature if already made, * Retrieves the choice for the specified feature if already made,
* or chooses one randomly from the distribution of feature probabilities * or chooses one randomly from the distribution of feature probabilities
@ -34,42 +46,42 @@ public class ABChooser {
* *
* The statistics session needs to be open here in order to collect statistics * The statistics session needs to be open here in order to collect statistics
* *
* @param optionKey - the preference key string of the option (defined in ABOptions) * @param testKey - the preference key string of the option (defined in ABTests)
* @return * @return
*/ */
public int getChoiceForOption(String optionKey) { private int getChoiceForTest(String testKey) {
int pref = readChoiceForOption(optionKey); int pref = readChoiceForTest(testKey);
if (pref > NO_OPTION) return pref; if (pref > NO_OPTION) return pref;
int chosen = NO_OPTION; int chosen = NO_OPTION;
if (abOptions.isValidKey(optionKey)) { if (abTests.isValidTestKey(testKey)) {
int[] optionProbs = abOptions.getProbsForKey(optionKey); int[] optionProbs = abTests.getProbsForTestKey(testKey);
chosen = chooseOption(optionProbs); chosen = chooseOption(optionProbs);
setChoiceForOption(optionKey, chosen); setChoiceForTest(testKey, chosen);
StatisticsService.reportEvent(abOptions.getDescriptionForOption(optionKey, chosen)); // Session should be open StatisticsService.reportEvent(abTests.getDescriptionForTestOption(testKey, chosen)); // Session should be open
} }
return chosen; return chosen;
} }
/** /**
* Returns the chosen option if set or NO_OPTION if unset * Returns the chosen option if set or NO_OPTION if unset
* @param optionKey * @param testKey
* @return * @return
*/ */
public static int readChoiceForOption(String optionKey) { public static int readChoiceForTest(String testKey) {
return Preferences.getInt(optionKey, NO_OPTION); return Preferences.getInt(testKey, NO_OPTION);
} }
/** /**
* Changes the choice of an A/B feature in the preferences. Useful for * Changes the choice of an A/B feature in the preferences. Useful for
* the feature flipper (can manually override previous choice) * the feature flipper (can manually override previous choice)
* @param optionKey * @param testKey
* @param choiceIndex * @param choiceIndex
*/ */
public void setChoiceForOption(String optionKey, int choiceIndex) { public void setChoiceForTest(String testKey, int choiceIndex) {
if (abOptions.isValidKey(optionKey)) if (abTests.isValidTestKey(testKey))
Preferences.setInt(optionKey, choiceIndex); Preferences.setInt(testKey, choiceIndex);
} }
/* /*

@ -1,194 +0,0 @@
package com.todoroo.astrid.service.abtesting;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import com.todoroo.astrid.service.StatisticsConstants;
/**
* Helper class to define options with their probabilities and descriptions
* @author Sam Bosley <sam@astrid.com>
*
*/
public class ABOptions {
public ABOptions() {
bundles = new HashMap<String, ABOptionBundle>();
events = new HashMap<String, List<String>>();
initialize();
}
/**
* Gets the integer array of weighted probabilities for an option key
* @param key
* @return
*/
public synchronized int[] getProbsForKey(String key) {
if (bundles.containsKey(key)) {
ABOptionBundle bundle = bundles.get(key);
return bundle.weightedProbs;
} else {
return null;
}
}
/**
* Updates the weighted probability array for a given key. Returns true
* on success, false if they key doesn't exist or if the array is the wrong
* length.
* @param key
* @param newProbs
* @return
*/
public synchronized boolean setProbsForKey(String key, int[] newProbs) {
if (bundles.containsKey(newProbs)) {
ABOptionBundle bundle = bundles.get(key);
if (bundle.descriptions == null || newProbs.length == bundle.descriptions.length) {
bundle.weightedProbs = newProbs;
return true;
}
}
return false;
}
/**
* Gets the string array of option descriptions for an option key
* @param key
* @return
*/
public String[] getDescriptionsForKey(String key) {
if (bundles.containsKey(key)) {
ABOptionBundle bundle = bundles.get(key);
return bundle.descriptions;
} else {
return null;
}
}
/**
* Returns the description for a particular choice of the given option
* @param key
* @param optionIndex
* @return
*/
public String getDescriptionForOption(String key, int optionIndex) {
if (bundles.containsKey(key)) {
ABOptionBundle bundle = bundles.get(key);
if (bundle.descriptions != null && optionIndex < bundle.descriptions.length) {
return bundle.descriptions[optionIndex];
}
}
return null;
}
/**
* Maps keys (i.e. preference key identifiers) to feature weights and descriptions
*/
private final HashMap<String, ABOptionBundle> bundles;
private final HashMap<String, List<String>> events; // maps events to lists of interested keys
private static class ABOptionBundle {
public int[] weightedProbs;
public String[] descriptions;
public ABOptionBundle(int[] weightedProbs, String[] descriptions) {
this.weightedProbs = weightedProbs;
this.descriptions = descriptions;
}
}
public boolean isValidKey(String key) {
return bundles.containsKey(key);
}
/**
* Gets a localytics attribute array for the specified event.
* @param event
* @return
*/
public String[] getLocalyticsAttributeArrayForEvent(String event) {
ArrayList<String> attributes = new ArrayList<String>();
List<String> interestedKeys = events.get(event);
if (interestedKeys != null)
for (String key : interestedKeys) {
// Get choice if exists and add to array
if (isValidKey(key)) {
ABOptionBundle bundle = bundles.get(key);
int choice = ABChooser.readChoiceForOption(key);
if (choice != ABChooser.NO_OPTION &&
bundle.descriptions != null && choice < bundle.descriptions.length) {
attributes.add(key);
attributes.add(getDescriptionForOption(key, choice));
}
}
}
return attributes.toArray(new String[attributes.size()]);
}
/**
* A/B testing options are defined below according to the following spec:
*
* @param optionKey = "<key>"
* --This key is used to identify the option in the application and in the preferences
*
* @param probs = { int, int, ... }
* --The different choices in an option correspond to an index in the probability array.
* Probabilities are expressed as integers to easily define relative weights. For example,
* the array { 1, 2 } would mean option 0 would happen one time for every two occurrences of option 1
*
* (optional)
* @param descriptions = { "...", "...", ... }
* --A string description of each option. Useful for tagging events. The index of
* each description should correspond to the events location in the probability array
* (i.e. the arrays should be the same length if this one exists)
*
* (optional)
* @param relevantEvents = { "...", "...", ... }
* --An arbitrary length list of relevant localytics events. When events are
* tagged from StatisticsService, they will be appended with attributes
* that have that event in this array
*/
public void addOption(String optionKey, int[] probs, String[] descriptions, String[] relevantEvents) {
ABOptionBundle bundle = new ABOptionBundle(probs, descriptions);
bundles.put(optionKey, bundle);
if (relevantEvents != null) {
for (String event : relevantEvents) {
List<String> interestedKeys = events.get(event);
if (interestedKeys == null) {
interestedKeys = new ArrayList<String>();
events.put(event, interestedKeys);
}
interestedKeys.add(optionKey);
}
}
}
private void initialize() { // Set up
//Calls to addOption go here
addOption(AB_OPTION_SWIPE_ENABLED_KEY, AB_OPTION_SWIPE_ENABLED_PROBS, AB_OPTION_SWIPE_ENABLED_DESC, AB_OPTION_SWIPE_ENABLED_EVENTS);
addOption(AB_OPTION_CONTACTS_PICKER_ENABLED, AB_OPTION_CONTACTS_ENABLED_PROBS, AB_OPTION_CONTACTS_ENABLED_DESC, AB_OPTION_CONTACTS_ENABLED_EVENTS);
}
public static final String AB_OPTION_SWIPE_ENABLED_KEY = "swipeEnabled"; //$NON-NLS-1$
private static final int[] AB_OPTION_SWIPE_ENABLED_PROBS = { 1, 1 };
private static final String[] AB_OPTION_SWIPE_ENABLED_DESC = { "swipe-lists-disabled", "swipe-lists-enabled" }; //$NON-NLS-1$//$NON-NLS-2$
private static final String[] AB_OPTION_SWIPE_ENABLED_EVENTS = { StatisticsConstants.APP_OPEN_THREE_DAYS,
StatisticsConstants.APP_OPEN_ONE_WEEK,
StatisticsConstants.APP_OPEN_TWO_WEEKS,
StatisticsConstants.APP_OPEN_THREE_WEEKS };
public static final String AB_OPTION_CONTACTS_PICKER_ENABLED = "contactsEnabled"; //$NON-NLS-1$
private static final int[] AB_OPTION_CONTACTS_ENABLED_PROBS = { 1, 1 };
private static final String[] AB_OPTION_CONTACTS_ENABLED_DESC = { "contacts-disabled", "contacts-enabled" }; //$NON-NLS-1$//$NON-NLS-2$
private static final String[] AB_OPTION_CONTACTS_ENABLED_EVENTS = { StatisticsConstants.APP_OPEN_THREE_DAYS,
StatisticsConstants.APP_OPEN_ONE_WEEK,
StatisticsConstants.APP_OPEN_TWO_WEEKS,
StatisticsConstants.APP_OPEN_THREE_WEEKS,
StatisticsConstants.TASK_ASSIGNED_EMAIL,
StatisticsConstants.TASK_ASSIGNED_PICKER };
}

@ -0,0 +1,147 @@
package com.todoroo.astrid.service.abtesting;
import java.util.HashMap;
import java.util.Set;
/**
* Helper class to define options with their probabilities and descriptions
* @author Sam Bosley <sam@astrid.com>
*
*/
public class ABTests {
public ABTests() {
bundles = new HashMap<String, ABTestBundle>();
initialize();
}
/**
* Gets the integer array of weighted probabilities for an option key
* @param key
* @return
*/
public synchronized int[] getProbsForTestKey(String key) {
if (bundles.containsKey(key)) {
ABTestBundle bundle = bundles.get(key);
return bundle.weightedProbs;
} else {
return null;
}
}
/**
* Updates the weighted probability array for a given key. Returns true
* on success, false if they key doesn't exist or if the array is the wrong
* length.
* @param key
* @param newProbs
* @return
*/
public synchronized boolean setProbsForTestKey(String key, int[] newProbs) {
if (bundles.containsKey(newProbs)) {
ABTestBundle bundle = bundles.get(key);
if (bundle.descriptions == null || newProbs.length == bundle.descriptions.length) {
bundle.weightedProbs = newProbs;
return true;
}
}
return false;
}
/**
* Gets the string array of option descriptions for an option key
* @param key
* @return
*/
public String[] getDescriptionsForTestKey(String key) {
if (bundles.containsKey(key)) {
ABTestBundle bundle = bundles.get(key);
return bundle.descriptions;
} else {
return null;
}
}
/**
* Returns the description for a particular choice of the given option
* @param testKey
* @param optionIndex
* @return
*/
public String getDescriptionForTestOption(String testKey, int optionIndex) {
if (bundles.containsKey(testKey)) {
ABTestBundle bundle = bundles.get(testKey);
if (bundle.descriptions != null && optionIndex < bundle.descriptions.length) {
return bundle.descriptions[optionIndex];
}
}
return null;
}
public Set<String> getAllTestKeys() {
return bundles.keySet();
}
/**
* Maps keys (i.e. preference key identifiers) to feature weights and descriptions
*/
private final HashMap<String, ABTestBundle> bundles;
private static class ABTestBundle {
public int[] weightedProbs;
public String[] descriptions;
public ABTestBundle(int[] weightedProbs, String[] descriptions) {
this.weightedProbs = weightedProbs;
this.descriptions = descriptions;
}
}
public boolean isValidTestKey(String key) {
return bundles.containsKey(key);
}
/**
* A/B testing options are defined below according to the following spec:
*
* @param testKey = "<key>"
* --This key is used to identify the option in the application and in the preferences
*
* @param probs = { int, int, ... }
* --The different choices in an option correspond to an index in the probability array.
* Probabilities are expressed as integers to easily define relative weights. For example,
* the array { 1, 2 } would mean option 0 would happen one time for every two occurrences of option 1
*
* (optional)
* @param descriptions = { "...", "...", ... }
* --A string description of each option. Useful for tagging events. The index of
* each description should correspond to the events location in the probability array
* (i.e. the arrays should be the same length if this one exists)
*
* (optional)
* @param relevantEvents = { "...", "...", ... }
* --An arbitrary length list of relevant localytics events. When events are
* tagged from StatisticsService, they will be appended with attributes
* that have that event in this array
*/
public void addTest(String testKey, int[] probs, String[] descriptions) {
ABTestBundle bundle = new ABTestBundle(probs, descriptions);
bundles.put(testKey, bundle);
}
private void initialize() { // Set up
//Calls to addTest go here
addTest(AB_TEST_SWIPE_ENABLED_KEY, AB_TEST_SWIPE_ENABLED_PROBS, AB_TEST_SWIPE_ENABLED_DESC);
addTest(AB_TEST_CONTACTS_PICKER_ENABLED, AB_TEST_CONTACTS_ENABLED_PROBS, AB_TEST_CONTACTS_ENABLED_DESC);
}
public static final String AB_TEST_SWIPE_ENABLED_KEY = "swipeEnabled"; //$NON-NLS-1$
private static final int[] AB_TEST_SWIPE_ENABLED_PROBS = { 1, 1 };
private static final String[] AB_TEST_SWIPE_ENABLED_DESC = { "swipe-lists-disabled", "swipe-lists-enabled" }; //$NON-NLS-1$//$NON-NLS-2$
public static final String AB_TEST_CONTACTS_PICKER_ENABLED = "contactsEnabled"; //$NON-NLS-1$
private static final int[] AB_TEST_CONTACTS_ENABLED_PROBS = { 1, 1 };
private static final String[] AB_TEST_CONTACTS_ENABLED_DESC = { "contacts-disabled", "contacts-enabled" }; //$NON-NLS-1$//$NON-NLS-2$
}

@ -29,7 +29,7 @@ public class FeatureFlipper {
@Autowired private RestClient restClient; @Autowired private RestClient restClient;
@Autowired private ABChooser abChooser; @Autowired private ABChooser abChooser;
@Autowired private ABOptions abOptions; @Autowired private ABTests abTests;
public FeatureFlipper() { public FeatureFlipper() {
DependencyInjectionService.getInstance().inject(this); DependencyInjectionService.getInstance().inject(this);
@ -52,7 +52,7 @@ public class FeatureFlipper {
if (settings.has(KEY_SET_OPTION)) { if (settings.has(KEY_SET_OPTION)) {
int option = settings.getInt(KEY_SET_OPTION); int option = settings.getInt(KEY_SET_OPTION);
abChooser.setChoiceForOption(key, option); abChooser.setChoiceForTest(key, option);
} else if (settings.has(KEY_PROBABILITIES)) { } else if (settings.has(KEY_PROBABILITIES)) {
JSONArray newProbabilities = settings.getJSONArray(KEY_PROBABILITIES); JSONArray newProbabilities = settings.getJSONArray(KEY_PROBABILITIES);
int[] probs = new int[newProbabilities.length()]; int[] probs = new int[newProbabilities.length()];
@ -61,7 +61,7 @@ public class FeatureFlipper {
probs[j] = newProbabilities.getInt(j); probs[j] = newProbabilities.getInt(j);
} }
abOptions.setProbsForKey(key, probs); abTests.setProbsForTestKey(key, probs);
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();

@ -12,7 +12,7 @@ import com.todoroo.astrid.api.AstridApiConstants;
import com.todoroo.astrid.data.Task; import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.service.ThemeService; import com.todoroo.astrid.service.ThemeService;
import com.todoroo.astrid.service.abtesting.ABChooser; import com.todoroo.astrid.service.abtesting.ABChooser;
import com.todoroo.astrid.service.abtesting.ABOptions; import com.todoroo.astrid.service.abtesting.ABTests;
public class AstridPreferences { public class AstridPreferences {
@ -49,10 +49,10 @@ public class AstridPreferences {
Preferences.setIfUnset(prefs, editor, r, R.string.p_fontSize, 18); Preferences.setIfUnset(prefs, editor, r, R.string.p_fontSize, 18);
Preferences.setIfUnset(prefs, editor, r, R.string.p_showNotes, false); Preferences.setIfUnset(prefs, editor, r, R.string.p_showNotes, false);
boolean swipeEnabled = (ABChooser.readChoiceForOption(ABOptions.AB_OPTION_SWIPE_ENABLED_KEY) == 1); boolean swipeEnabled = (ABChooser.readChoiceForTest(ABTests.AB_TEST_SWIPE_ENABLED_KEY) == 1);
Preferences.setIfUnset(prefs, editor, r, R.string.p_swipe_lists_performance_key, swipeEnabled ? 3 : 0); Preferences.setIfUnset(prefs, editor, r, R.string.p_swipe_lists_performance_key, swipeEnabled ? 3 : 0);
boolean contactsPickerEnabled = (ABChooser.readChoiceForOption(ABOptions.AB_OPTION_CONTACTS_PICKER_ENABLED) == 1); boolean contactsPickerEnabled = (ABChooser.readChoiceForTest(ABTests.AB_TEST_CONTACTS_PICKER_ENABLED) == 1);
Preferences.setIfUnset(prefs, editor, r, R.string.p_use_contact_picker, contactsPickerEnabled); Preferences.setIfUnset(prefs, editor, r, R.string.p_use_contact_picker, contactsPickerEnabled);
if ("white-blue".equals(Preferences.getStringValue(R.string.p_theme))) { //$NON-NLS-1$ migrate from when white-blue wasn't the default if ("white-blue".equals(Preferences.getStringValue(R.string.p_theme))) { //$NON-NLS-1$ migrate from when white-blue wasn't the default

Loading…
Cancel
Save