Apply google-java-format 1.5.1

pull/699/head
Alex Baker 8 years ago
parent d983167976
commit 02a112e3b3

@ -5,9 +5,7 @@ import javax.inject.Inject;
public class FlavorSetup {
@Inject
public FlavorSetup() {
}
public FlavorSetup() {}
public void setup() {
}
public void setup() {}
}

@ -28,24 +28,23 @@ public class Tracker {
analytics = GoogleAnalytics.getInstance(context);
tracker = analytics.newTracker(R.xml.google_analytics);
tracker.setAppVersion(Integer.toString(BuildConfig.VERSION_CODE));
final StandardExceptionParser standardExceptionParser = new StandardExceptionParser(context,
null);
exceptionParser = (thread, throwable) -> {
StringBuilder stack = new StringBuilder()
.append(standardExceptionParser.getDescription(thread, throwable))
.append("\n")
.append(throwable.getClass().getName())
.append("\n");
for (StackTraceElement element : throwable.getStackTrace()) {
stack.append(element.toString())
.append("\n");
}
return stack.toString();
};
ExceptionReporter reporter = new ExceptionReporter(
tracker,
Thread.getDefaultUncaughtExceptionHandler(),
context);
final StandardExceptionParser standardExceptionParser =
new StandardExceptionParser(context, null);
exceptionParser =
(thread, throwable) -> {
StringBuilder stack =
new StringBuilder()
.append(standardExceptionParser.getDescription(thread, throwable))
.append("\n")
.append(throwable.getClass().getName())
.append("\n");
for (StackTraceElement element : throwable.getStackTrace()) {
stack.append(element.toString()).append("\n");
}
return stack.toString();
};
ExceptionReporter reporter =
new ExceptionReporter(tracker, Thread.getDefaultUncaughtExceptionHandler(), context);
reporter.setExceptionParser(exceptionParser);
Thread.setDefaultUncaughtExceptionHandler(reporter);
}
@ -60,10 +59,11 @@ public class Tracker {
public void reportException(Thread thread, Throwable t) {
Timber.e(t, t.getMessage());
tracker.send(new HitBuilders.ExceptionBuilder()
.setDescription(exceptionParser.getDescription(thread.getName(), t))
.setFatal(false)
.build());
tracker.send(
new HitBuilders.ExceptionBuilder()
.setDescription(exceptionParser.getDescription(thread.getName(), t))
.setFatal(false)
.build());
}
public void reportEvent(Tracking.Events event) {
@ -83,9 +83,8 @@ public class Tracker {
}
private void reportEvent(int category, String action, String label) {
HitBuilders.EventBuilder eventBuilder = new HitBuilders.EventBuilder()
.setCategory(context.getString(category))
.setAction(action);
HitBuilders.EventBuilder eventBuilder =
new HitBuilders.EventBuilder().setCategory(context.getString(category)).setAction(action);
if (!Strings.isNullOrEmpty(label)) {
eventBuilder.setLabel(label);
}

@ -7,26 +7,22 @@ import javax.inject.Inject;
public class PurchaseHelper {
@Inject
public PurchaseHelper() {
}
public boolean purchase(final Activity activity,
final String sku, final String pref,
final int requestCode, final PurchaseHelperCallback callback) {
public PurchaseHelper() {}
public boolean purchase(
final Activity activity,
final String sku,
final String pref,
final int requestCode,
final PurchaseHelperCallback callback) {
callback.purchaseCompleted(false, sku);
return false;
}
public void handleActivityResult(PurchaseHelperCallback callback, int requestCode, int resultCode,
Intent data) {
}
public void disposeIabHelper() {
}
public void handleActivityResult(
PurchaseHelperCallback callback, int requestCode, int resultCode, Intent data) {}
public void consumePurchases() {
public void disposeIabHelper() {}
}
public void consumePurchases() {}
}

@ -8,9 +8,7 @@ import javax.inject.Inject;
public class PlayServices {
@Inject
public PlayServices() {
}
public PlayServices() {}
public boolean isPlayServicesAvailable() {
return false;
@ -20,9 +18,7 @@ public class PlayServices {
return false;
}
public void resolve(Activity activity) {
}
public void resolve(Activity activity) {}
public String getStatus() {
return null;
@ -32,8 +28,8 @@ public class PlayServices {
return false;
}
public void getAuthToken(GtasksLoginActivity gtasksLoginActivity, String a,
GtasksLoginActivity.AuthResultHandler authResultHandler) {
}
public void getAuthToken(
GtasksLoginActivity gtasksLoginActivity,
String a,
GtasksLoginActivity.AuthResultHandler authResultHandler) {}
}

@ -8,19 +8,11 @@ import org.tasks.data.Location;
public class GeofenceApi {
@Inject
public GeofenceApi() {
public GeofenceApi() {}
}
public void register(List<Location> activeGeofences) {}
public void register(List<Location> activeGeofences) {
public void cancel(Location geofence) {}
}
public void cancel(Location geofence) {
}
public void cancel(List<Location> geofences) {
}
public void cancel(List<Location> geofences) {}
}

@ -1,5 +1,3 @@
package org.tasks.location;
public class GeofenceTransitionsIntentService {
}
public class GeofenceTransitionsIntentService {}

@ -1,12 +1,10 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
* <p>See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.andlib.test;
import static android.support.test.InstrumentationRegistry.getTargetContext;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
@ -24,18 +22,15 @@ import org.junit.runner.RunWith;
import org.tasks.R;
/**
* Tests translations for consistency with the default values. You must
* extend this class and create it with your own values for strings
* and arrays.
* Tests translations for consistency with the default values. You must extend this class and create
* it with your own values for strings and arrays.
*
* @author Tim Su <tim@todoroo.com>
*/
@RunWith(AndroidJUnit4.class)
public class TranslationTests {
/**
* Loop through each locale and call runnable
*/
/** Loop through each locale and call runnable */
private void forEachLocale(Callback<Resources> callback) {
Locale[] locales = Locale.getAvailableLocales();
for (Locale locale : locales) {
@ -50,9 +45,7 @@ public class TranslationTests {
return new Resources(resources.getAssets(), resources.getDisplayMetrics(), configuration);
}
/**
* Internal test of format string parser
*/
/** Internal test of format string parser */
@Test
public void testFormatStringParser() {
String s = "abc";
@ -84,8 +77,8 @@ public class TranslationTests {
}
/**
* Test that the format specifiers in translations match exactly the
* translations in the default text
* Test that the format specifiers in translations match exactly the translations in the default
* text
*/
@Test
public void testFormatStringsMatch() {
@ -101,72 +94,68 @@ public class TranslationTests {
formatStrings[i] = new FormatStringData(string);
} catch (Exception e) {
String name = resources.getResourceName(strings[i]);
failures.append(String.format("error opening %s: %s\n",
name, e.getMessage()));
failures.append(String.format("error opening %s: %s\n", name, e.getMessage()));
}
}
forEachLocale(r -> {
Locale locale = r.getConfiguration().locale;
for (int i = 0; i < strings.length; i++) {
try {
switch (strings[i]) {
case R.string.abc_shareactionprovider_share_with_application:
continue;
}
String string = r.getString(strings[i]);
FormatStringData newFS = new FormatStringData(string);
if (!newFS.matches(formatStrings[i])) {
String name = r.getResourceName(strings[i]);
failures.append(String.format("%s (%s): %s != %s\n",
name, locale.toString(), newFS, formatStrings[i]));
forEachLocale(
r -> {
Locale locale = r.getConfiguration().locale;
for (int i = 0; i < strings.length; i++) {
try {
switch (strings[i]) {
case R.string.abc_shareactionprovider_share_with_application:
continue;
}
String string = r.getString(strings[i]);
FormatStringData newFS = new FormatStringData(string);
if (!newFS.matches(formatStrings[i])) {
String name = r.getResourceName(strings[i]);
failures.append(
String.format(
"%s (%s): %s != %s\n", name, locale.toString(), newFS, formatStrings[i]));
}
} catch (Exception e) {
String name = r.getResourceName(strings[i]);
failures.append(
String.format(
"%s: error opening %s: %s\n", locale.toString(), name, e.getMessage()));
}
}
} catch (Exception e) {
String name = r.getResourceName(strings[i]);
failures.append(String.format("%s: error opening %s: %s\n",
locale.toString(), name, e.getMessage()));
}
}
});
});
assertTrue(failures.toString(), errorCount(failures) == 0);
}
/**
* check if string contains contains substrings
*/
/** check if string contains contains substrings */
private void contains(Resources r, int resource, StringBuilder failures, String expected) {
String translation = r.getString(resource);
if (!translation.contains(expected)) {
Locale locale = r.getConfiguration().locale;
String name = r.getResourceName(resource);
failures.append(String.format("%s: %s did not contain: %s\n",
locale.toString(), name, expected));
failures.append(
String.format("%s: %s did not contain: %s\n", locale.toString(), name, expected));
}
}
/**
* Test dollar sign resources
*/
/** Test dollar sign resources */
@Test
public void testSpecialStringsMatch() {
final StringBuilder failures = new StringBuilder();
forEachLocale(r -> {
contains(r, R.string.CFC_tag_text, failures, "?");
contains(r, R.string.CFC_title_contains_text, failures, "?");
contains(r, R.string.CFC_dueBefore_text, failures, "?");
contains(r, R.string.CFC_tag_contains_text, failures, "?");
contains(r, R.string.CFC_gtasks_list_text, failures, "?");
});
forEachLocale(
r -> {
contains(r, R.string.CFC_tag_text, failures, "?");
contains(r, R.string.CFC_title_contains_text, failures, "?");
contains(r, R.string.CFC_dueBefore_text, failures, "?");
contains(r, R.string.CFC_tag_contains_text, failures, "?");
contains(r, R.string.CFC_gtasks_list_text, failures, "?");
});
assertEquals(failures.toString(), 0,
failures.toString().replaceAll("[^\n]", "").length());
assertEquals(failures.toString(), 0, failures.toString().replaceAll("[^\n]", "").length());
}
/**
* Count newlines
*/
/** Count newlines */
private int errorCount(StringBuilder failures) {
int count = 0;
int pos = -1;
@ -179,9 +168,7 @@ public class TranslationTests {
}
}
/**
* @return an array of all string resource id's
*/
/** @return an array of all string resource id's */
private int[] getResourceIds(Class<?> resources) {
Field[] fields = resources.getDeclaredFields();
List<Integer> ids = new ArrayList<>(fields.length);
@ -208,14 +195,10 @@ public class TranslationTests {
private static final char[] scratch = new char[10];
/**
* format characters
*/
/** format characters */
final char[] characters;
/**
* the original string
*/
/** the original string */
final String string;
public FormatStringData(String string) {
@ -240,9 +223,7 @@ public class TranslationTests {
}
}
/**
* test that the characters match
*/
/** test that the characters match */
boolean matches(FormatStringData other) {
if (characters.length != other.characters.length) {
return false;
@ -259,7 +240,6 @@ public class TranslationTests {
} else if (characters[i] != other.characters[i]) {
return false;
}
}
return true;
}

@ -1,9 +1,8 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
* <p>See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.andlib.utility;
import static android.support.test.InstrumentationRegistry.getTargetContext;
@ -66,33 +65,35 @@ public class DateUtilitiesTest {
@Test
public void testTimeString() {
forEachLocale(() -> {
DateTime d = newDateTime();
forEachLocale(
() -> {
DateTime d = newDateTime();
DateUtilities.is24HourOverride = false;
for (int i = 0; i < 24; i++) {
d = d.withHourOfDay(i);
getTimeString(getTargetContext(), d);
}
DateUtilities.is24HourOverride = false;
for (int i = 0; i < 24; i++) {
d = d.withHourOfDay(i);
getTimeString(getTargetContext(), d);
}
DateUtilities.is24HourOverride = true;
for (int i = 0; i < 24; i++) {
d = d.withHourOfDay(i);
getTimeString(getTargetContext(), d);
}
});
DateUtilities.is24HourOverride = true;
for (int i = 0; i < 24; i++) {
d = d.withHourOfDay(i);
getTimeString(getTargetContext(), d);
}
});
}
@Test
public void testDateString() {
forEachLocale(() -> {
DateTime d = newDateTime();
forEachLocale(
() -> {
DateTime d = newDateTime();
for (int i = 0; i < 12; i++) {
d = d.withMonthOfYear(i);
getDateString(d);
}
});
for (int i = 0; i < 12; i++) {
d = d.withMonthOfYear(i);
getDateString(d);
}
});
}
@Test
@ -122,16 +123,24 @@ public class DateUtilitiesTest {
@Test
public void testGetDateStringHidingYear() {
freezeAt(newDate(2014, 1, 1)).thawAfter(new Snippet() {{
assertEquals("Jan 1", getDateString(newDateTime()));
}});
freezeAt(newDate(2014, 1, 1))
.thawAfter(
new Snippet() {
{
assertEquals("Jan 1", getDateString(newDateTime()));
}
});
}
@Test
public void testGetDateStringWithDifferentYear() {
freezeAt(newDate(2013, 12, 31)).thawAfter(new Snippet() {{
assertEquals("Jan 1 '14", getDateString(new DateTime(2014, 1, 1, 0, 0, 0)));
}});
freezeAt(newDate(2013, 12, 31))
.thawAfter(
new Snippet() {
{
assertEquals("Jan 1 '14", getDateString(new DateTime(2014, 1, 1, 0, 0, 0)));
}
});
}
@Test
@ -139,9 +148,13 @@ public class DateUtilitiesTest {
DateTime now = new DateTime(2013, 12, 1, 12, 19, 45, 192);
final long expected = new DateTime(2014, 1, 1, 12, 19, 45, 192).getMillis();
freezeAt(now).thawAfter(new Snippet() {{
assertEquals(expected, oneMonthFromNow());
}});
freezeAt(now)
.thawAfter(
new Snippet() {
{
assertEquals(expected, oneMonthFromNow());
}
});
}
@Test
@ -149,9 +162,13 @@ public class DateUtilitiesTest {
DateTime now = new DateTime(2013, 12, 31, 16, 31, 20, 597);
final long expected = new DateTime(2014, 1, 31, 16, 31, 20, 597).getMillis();
freezeAt(now).thawAfter(new Snippet() {{
assertEquals(expected, oneMonthFromNow());
}});
freezeAt(now)
.thawAfter(
new Snippet() {
{
assertEquals(expected, oneMonthFromNow());
}
});
}
@Test
@ -159,9 +176,13 @@ public class DateUtilitiesTest {
final DateTime now = new DateTime(2013, 12, 31, 17, 17, 32, 900);
final long expected = new DateTime(2014, 7, 1, 17, 17, 32, 900).getMillis();
freezeAt(now).thawAfter(new Snippet() {{
assertEquals(expected, addCalendarMonthsToUnixtime(now.getMillis(), 6));
}});
freezeAt(now)
.thawAfter(
new Snippet() {
{
assertEquals(expected, addCalendarMonthsToUnixtime(now.getMillis(), 6));
}
});
}
@Test
@ -169,9 +190,13 @@ public class DateUtilitiesTest {
DateTime now = new DateTime(2014, 1, 31, 12, 54, 33, 175);
final long expected = new DateTime(2014, 3, 3, 12, 54, 33, 175).getMillis();
freezeAt(now).thawAfter(new Snippet() {{
assertEquals(expected, oneMonthFromNow());
}});
freezeAt(now)
.thawAfter(
new Snippet() {
{
assertEquals(expected, oneMonthFromNow());
}
});
}
@Test
@ -179,17 +204,19 @@ public class DateUtilitiesTest {
DateTime now = new DateTime(2014, 2, 28, 9, 19, 7, 990);
final long expected = new DateTime(2014, 3, 28, 9, 19, 7, 990).getMillis();
freezeAt(now).thawAfter(new Snippet() {{
assertEquals(expected, oneMonthFromNow());
}});
freezeAt(now)
.thawAfter(
new Snippet() {
{
assertEquals(expected, oneMonthFromNow());
}
});
}
@Test
public void testShouldGetStartOfDay() {
DateTime now = new DateTime(2014, 1, 3, 10, 41, 41, 520);
assertEquals(
now.startOfDay().getMillis(),
getStartOfDay(now.getMillis()));
assertEquals(now.startOfDay().getMillis(), getStartOfDay(now.getMillis()));
}
@Test
@ -216,101 +243,145 @@ public class DateUtilitiesTest {
@Test
public void testAddMonthsToTimestamp() {
assertEquals(newDate(2014, 1, 1).getMillis(),
assertEquals(
newDate(2014, 1, 1).getMillis(),
addCalendarMonthsToUnixtime(newDate(2013, 12, 1).getMillis(), 1));
assertEquals(newDate(2014, 12, 31).getMillis(),
assertEquals(
newDate(2014, 12, 31).getMillis(),
addCalendarMonthsToUnixtime(newDate(2013, 12, 31).getMillis(), 12));
}
@Test
public void testAddMonthsWithLessDays() {
assertEquals(newDate(2014, 3, 3).getMillis(),
assertEquals(
newDate(2014, 3, 3).getMillis(),
addCalendarMonthsToUnixtime(newDate(2013, 12, 31).getMillis(), 2));
}
@Test
public void testAddMonthsWithMoreDays() {
assertEquals(newDate(2014, 1, 30).getMillis(),
assertEquals(
newDate(2014, 1, 30).getMillis(),
addCalendarMonthsToUnixtime(newDate(2013, 11, 30).getMillis(), 2));
}
@Test
public void usDateNoYear() {
setLocale(Locale.US);
freezeAt(new DateTime(2018, 1, 1)).thawAfter(() ->
assertEquals("Jan 14", DateUtilities.getRelativeDateStringWithTime(getTargetContext(),
new DateTime(2018, 1, 14).getMillis())));
freezeAt(new DateTime(2018, 1, 1))
.thawAfter(
() ->
assertEquals(
"Jan 14",
DateUtilities.getRelativeDateStringWithTime(
getTargetContext(), new DateTime(2018, 1, 14).getMillis())));
}
@Test
public void usDateWithYear() {
setLocale(Locale.US);
freezeAt(new DateTime(2017, 12, 12)).thawAfter(() ->
assertEquals("Jan 14 '18", DateUtilities.getRelativeDateStringWithTime(getTargetContext(),
new DateTime(2018, 1, 14).getMillis())));
freezeAt(new DateTime(2017, 12, 12))
.thawAfter(
() ->
assertEquals(
"Jan 14 '18",
DateUtilities.getRelativeDateStringWithTime(
getTargetContext(), new DateTime(2018, 1, 14).getMillis())));
}
@Test
public void germanDateNoYear() {
setLocale(Locale.GERMAN);
freezeAt(new DateTime(2018, 1, 1)).thawAfter(() ->
assertEquals("14 Jan.", DateUtilities.getRelativeDateStringWithTime(getTargetContext(),
new DateTime(2018, 1, 14).getMillis())));
freezeAt(new DateTime(2018, 1, 1))
.thawAfter(
() ->
assertEquals(
"14 Jan.",
DateUtilities.getRelativeDateStringWithTime(
getTargetContext(), new DateTime(2018, 1, 14).getMillis())));
}
@Test
public void germanDateWithYear() {
setLocale(Locale.GERMAN);
freezeAt(new DateTime(2017, 12, 12)).thawAfter(() ->
assertEquals("14 Jan. '18", DateUtilities.getRelativeDateStringWithTime(getTargetContext(),
new DateTime(2018, 1, 14).getMillis())));
freezeAt(new DateTime(2017, 12, 12))
.thawAfter(
() ->
assertEquals(
"14 Jan. '18",
DateUtilities.getRelativeDateStringWithTime(
getTargetContext(), new DateTime(2018, 1, 14).getMillis())));
}
@Test
public void koreanDateNoYear() {
setLocale(Locale.KOREAN);
freezeAt(new DateTime(2018, 1, 1)).thawAfter(() ->
assertEquals("1월 14일", DateUtilities.getRelativeDateStringWithTime(getTargetContext(),
new DateTime(2018, 1, 14).getMillis())));
freezeAt(new DateTime(2018, 1, 1))
.thawAfter(
() ->
assertEquals(
"1월 14일",
DateUtilities.getRelativeDateStringWithTime(
getTargetContext(), new DateTime(2018, 1, 14).getMillis())));
}
@Test
public void koreanDateWithYear() {
setLocale(Locale.KOREAN);
freezeAt(new DateTime(2017, 12, 12)).thawAfter(() ->
assertEquals("18년 1월 14일", DateUtilities.getRelativeDateStringWithTime(getTargetContext(),
new DateTime(2018, 1, 14).getMillis())));
freezeAt(new DateTime(2017, 12, 12))
.thawAfter(
() ->
assertEquals(
"18년 1월 14일",
DateUtilities.getRelativeDateStringWithTime(
getTargetContext(), new DateTime(2018, 1, 14).getMillis())));
}
@Test
public void japaneseDateNoYear() {
setLocale(Locale.JAPANESE);
freezeAt(new DateTime(2018, 1, 1)).thawAfter(() ->
assertEquals("1月 14日", DateUtilities.getRelativeDateStringWithTime(getTargetContext(),
new DateTime(2018, 1, 14).getMillis())));
freezeAt(new DateTime(2018, 1, 1))
.thawAfter(
() ->
assertEquals(
"1月 14日",
DateUtilities.getRelativeDateStringWithTime(
getTargetContext(), new DateTime(2018, 1, 14).getMillis())));
}
@Test
public void japaneseDateWithYear() {
setLocale(Locale.JAPANESE);
freezeAt(new DateTime(2017, 12, 12)).thawAfter(() ->
assertEquals("18年 1月 14日", DateUtilities.getRelativeDateStringWithTime(getTargetContext(),
new DateTime(2018, 1, 14).getMillis())));
freezeAt(new DateTime(2017, 12, 12))
.thawAfter(
() ->
assertEquals(
"18年 1月 14日",
DateUtilities.getRelativeDateStringWithTime(
getTargetContext(), new DateTime(2018, 1, 14).getMillis())));
}
@Test
public void chineseDateNoYear() {
setLocale(Locale.CHINESE);
freezeAt(new DateTime(2018, 1, 1)).thawAfter(() ->
assertEquals("1月 14日", DateUtilities.getRelativeDateStringWithTime(getTargetContext(),
new DateTime(2018, 1, 14).getMillis())));
freezeAt(new DateTime(2018, 1, 1))
.thawAfter(
() ->
assertEquals(
"1月 14日",
DateUtilities.getRelativeDateStringWithTime(
getTargetContext(), new DateTime(2018, 1, 14).getMillis())));
}
@Test
public void chineseDateWithYear() {
setLocale(Locale.CHINESE);
freezeAt(new DateTime(2017, 12, 12)).thawAfter(() ->
assertEquals("18年 1月 14日", DateUtilities.getRelativeDateStringWithTime(getTargetContext(),
new DateTime(2018, 1, 14).getMillis())));
freezeAt(new DateTime(2017, 12, 12))
.thawAfter(
() ->
assertEquals(
"18年 1月 14日",
DateUtilities.getRelativeDateStringWithTime(
getTargetContext(), new DateTime(2018, 1, 14).getMillis())));
}
}

@ -1,9 +1,8 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
* <p>See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.dao;
import static junit.framework.Assert.assertEquals;
@ -24,9 +23,7 @@ public class TaskDaoTests extends InjectingTestCase {
@Inject TaskDao taskDao;
/**
* Test basic task creation, fetch, and save
*/
/** Test basic task creation, fetch, and save */
@Test
public void testTaskCreation() {
assertEquals(0, taskDao.getAll().size());
@ -61,9 +58,7 @@ public class TaskDaoTests extends InjectingTestCase {
assertEquals("melancholy", task.getTitle());
}
/**
* Test various task fetch conditions
*/
/** Test various task fetch conditions */
@Test
public void testTaskConditions() {
// create normal task
@ -106,9 +101,7 @@ public class TaskDaoTests extends InjectingTestCase {
assertEquals(5, taskDao.getVisibleTasks().size());
}
/**
* Test task deletion
*/
/** Test task deletion */
@Test
public void testTDeletion() {
assertEquals(0, taskDao.getAll().size());
@ -125,9 +118,7 @@ public class TaskDaoTests extends InjectingTestCase {
assertEquals(0, taskDao.getAll().size());
}
/**
* Test save without prior create doesn't work
*/
/** Test save without prior create doesn't work */
@Test
public void testSaveWithoutCreate() {
// try to save task "happy"
@ -140,9 +131,7 @@ public class TaskDaoTests extends InjectingTestCase {
assertEquals(0, taskDao.getAll().size());
}
/**
* Test passing invalid task indices to various things
*/
/** Test passing invalid task indices to various things */
@Test
public void testInvalidIndex() {
assertEquals(0, taskDao.getAll().size());
@ -162,4 +151,3 @@ public class TaskDaoTests extends InjectingTestCase {
// TODO check eventing
}

@ -88,21 +88,19 @@ public class TaskTest {
@Test
public void testRemoveTimeForSpecificDay() {
long expected = specificDueDate
.withHourOfDay(12)
.withMinuteOfHour(0)
.withSecondOfMinute(0)
.withMillisOfSecond(0)
.getMillis();
long expected =
specificDueDate
.withHourOfDay(12)
.withMinuteOfHour(0)
.withSecondOfMinute(0)
.withMillisOfSecond(0)
.getMillis();
assertEquals(expected, createDueDate(URGENCY_SPECIFIC_DAY, specificDueDate.getMillis()));
}
@Test
public void testRemoveSecondsForSpecificTime() {
long expected = specificDueDate
.withSecondOfMinute(1)
.withMillisOfSecond(0)
.getMillis();
long expected = specificDueDate.withSecondOfMinute(1).withMillisOfSecond(0).getMillis();
assertEquals(expected, createDueDate(URGENCY_SPECIFIC_DAY_TIME, specificDueDate.getMillis()));
}
@ -176,21 +174,29 @@ public class TaskTest {
@Test
public void testTaskIsNotHiddenAtHideUntilTime() {
final long now = currentTimeMillis();
freezeAt(now).thawAfter(new Snippet() {{
Task task = new Task();
task.setHideUntil(now);
assertFalse(task.isHidden());
}});
freezeAt(now)
.thawAfter(
new Snippet() {
{
Task task = new Task();
task.setHideUntil(now);
assertFalse(task.isHidden());
}
});
}
@Test
public void testTaskIsHiddenBeforeHideUntilTime() {
final long now = currentTimeMillis();
freezeAt(now).thawAfter(new Snippet() {{
Task task = new Task();
task.setHideUntil(now + 1);
assertTrue(task.isHidden());
}});
freezeAt(now)
.thawAfter(
new Snippet() {
{
Task task = new Task();
task.setHideUntil(now + 1);
assertTrue(task.isHidden());
}
});
}
@Test
@ -208,54 +214,74 @@ public class TaskTest {
@Test
public void testTaskNotOverdueAtDueTime() {
final long now = currentTimeMillis();
freezeAt(now).thawAfter(new Snippet() {{
Task task = new Task();
task.setDueDate(now);
assertFalse(task.isOverdue());
}});
freezeAt(now)
.thawAfter(
new Snippet() {
{
Task task = new Task();
task.setDueDate(now);
assertFalse(task.isOverdue());
}
});
}
@Test
public void testTaskIsOverduePastDueTime() {
final long dueDate = currentTimeMillis();
freezeAt(dueDate + 1).thawAfter(new Snippet() {{
Task task = new Task();
task.setDueDate(dueDate);
assertTrue(task.isOverdue());
}});
freezeAt(dueDate + 1)
.thawAfter(
new Snippet() {
{
Task task = new Task();
task.setDueDate(dueDate);
assertTrue(task.isOverdue());
}
});
}
@Test
public void testTaskNotOverdueBeforeNoonOnDueDate() {
final DateTime dueDate = new DateTime().startOfDay();
freezeAt(dueDate.plusHours(12).minusMillis(1)).thawAfter(new Snippet() {{
Task task = new Task();
task.setDueDate(dueDate.getMillis());
assertFalse(task.hasDueTime());
assertFalse(task.isOverdue());
}});
freezeAt(dueDate.plusHours(12).minusMillis(1))
.thawAfter(
new Snippet() {
{
Task task = new Task();
task.setDueDate(dueDate.getMillis());
assertFalse(task.hasDueTime());
assertFalse(task.isOverdue());
}
});
}
@Test
public void testTaskOverdueAtNoonOnDueDate() {
final DateTime dueDate = new DateTime().startOfDay();
freezeAt(dueDate.plusHours(12)).thawAfter(new Snippet() {{
Task task = new Task();
task.setDueDate(dueDate.getMillis());
assertFalse(task.hasDueTime());
assertFalse(task.isOverdue());
}});
freezeAt(dueDate.plusHours(12))
.thawAfter(
new Snippet() {
{
Task task = new Task();
task.setDueDate(dueDate.getMillis());
assertFalse(task.hasDueTime());
assertFalse(task.isOverdue());
}
});
}
@Test
public void testTaskWithNoDueTimeIsOverdue() {
final DateTime dueDate = new DateTime().startOfDay();
freezeAt(dueDate.plusDays(1)).thawAfter(new Snippet() {{
Task task = new Task();
task.setDueDate(dueDate.getMillis());
assertFalse(task.hasDueTime());
assertTrue(task.isOverdue());
}});
freezeAt(dueDate.plusDays(1))
.thawAfter(
new Snippet() {
{
Task task = new Task();
task.setDueDate(dueDate.getMillis());
assertFalse(task.hasDueTime());
assertTrue(task.isOverdue());
}
});
}
@Test

@ -21,11 +21,15 @@ public class TaskTest extends InjectingTestCase {
@Test
public void testSavedTaskHasCreationDate() {
freezeClock().thawAfter(new Snippet() {{
Task task = new Task();
taskDao.createNew(task);
assertEquals(currentTimeMillis(), (long) task.getCreationDate());
}});
freezeClock()
.thawAfter(
new Snippet() {
{
Task task = new Task();
taskDao.createNew(task);
assertEquals(currentTimeMillis(), (long) task.getCreationDate());
}
});
}
@Test

@ -89,10 +89,11 @@ public class ReminderServiceTest extends InjectingTestCase {
@Test
public void schedulePastDueDate() {
Task task = newTask(
with(ID, 1L),
with(DUE_TIME, newDateTime().minusDays(1)),
with(REMINDERS, NOTIFY_AT_DEADLINE));
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, newDateTime().minusDays(1)),
with(REMINDERS, NOTIFY_AT_DEADLINE));
service.scheduleAlarm(task);
InOrder order = inOrder(jobs);
@ -102,10 +103,11 @@ public class ReminderServiceTest extends InjectingTestCase {
@Test
public void scheduleFutureDueDate() {
Task task = newTask(
with(ID, 1L),
with(DUE_TIME, newDateTime().plusDays(1)),
with(REMINDERS, NOTIFY_AT_DEADLINE));
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, newDateTime().plusDays(1)),
with(REMINDERS, NOTIFY_AT_DEADLINE));
service.scheduleAlarm(task);
InOrder order = inOrder(jobs);
@ -116,26 +118,27 @@ public class ReminderServiceTest extends InjectingTestCase {
@Test
public void scheduleReminderAtDefaultDueTime() {
DateTime now = newDateTime();
Task task = newTask(
with(ID, 1L),
with(DUE_DATE, now),
with(REMINDERS, NOTIFY_AT_DEADLINE));
Task task = newTask(with(ID, 1L), with(DUE_DATE, now), with(REMINDERS, NOTIFY_AT_DEADLINE));
service.scheduleAlarm(task);
InOrder order = inOrder(jobs);
order.verify(jobs).cancelReminder(1);
order.verify(jobs).add(
new ReminderEntry(1, now.startOfDay().withHourOfDay(18).getMillis(), ReminderService.TYPE_DUE));
order
.verify(jobs)
.add(
new ReminderEntry(
1, now.startOfDay().withHourOfDay(18).getMillis(), ReminderService.TYPE_DUE));
}
@Test
public void dontScheduleReminderForCompletedTask() {
Task task = newTask(
with(ID, 1L),
with(DUE_TIME, newDateTime().plusDays(1)),
with(COMPLETION_TIME, newDateTime()),
with(REMINDERS, NOTIFY_AT_DEADLINE));
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, newDateTime().plusDays(1)),
with(COMPLETION_TIME, newDateTime()),
with(REMINDERS, NOTIFY_AT_DEADLINE));
service.scheduleAlarm(task);
@ -144,11 +147,12 @@ public class ReminderServiceTest extends InjectingTestCase {
@Test
public void dontScheduleReminderForDeletedTask() {
Task task = newTask(
with(ID, 1L),
with(DUE_TIME, newDateTime().plusDays(1)),
with(DELETION_TIME, newDateTime()),
with(REMINDERS, NOTIFY_AT_DEADLINE));
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, newDateTime().plusDays(1)),
with(DELETION_TIME, newDateTime()),
with(REMINDERS, NOTIFY_AT_DEADLINE));
service.scheduleAlarm(task);
@ -158,11 +162,12 @@ public class ReminderServiceTest extends InjectingTestCase {
@Test
public void dontScheduleDueDateReminderWhenAlreadyReminded() {
DateTime now = newDateTime();
Task task = newTask(
with(ID, 1L),
with(DUE_TIME, now),
with(REMINDER_LAST, now.plusSeconds(1)),
with(REMINDERS, NOTIFY_AT_DEADLINE));
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, now),
with(REMINDER_LAST, now.plusSeconds(1)),
with(REMINDERS, NOTIFY_AT_DEADLINE));
service.scheduleAlarm(task);
@ -171,12 +176,13 @@ public class ReminderServiceTest extends InjectingTestCase {
@Test
public void ignoreStaleSnoozeTime() {
Task task = newTask(
with(ID, 1L),
with(DUE_TIME, newDateTime()),
with(SNOOZE_TIME, newDateTime().minusMinutes(5)),
with(REMINDER_LAST, newDateTime().minusMinutes(4)),
with(REMINDERS, NOTIFY_AT_DEADLINE));
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, newDateTime()),
with(SNOOZE_TIME, newDateTime().minusMinutes(5)),
with(REMINDER_LAST, newDateTime().minusMinutes(4)),
with(REMINDERS, NOTIFY_AT_DEADLINE));
service.scheduleAlarm(task);
InOrder order = inOrder(jobs);
@ -187,191 +193,260 @@ public class ReminderServiceTest extends InjectingTestCase {
@Test
public void dontIgnoreMissedSnoozeTime() {
DateTime dueDate = newDateTime();
Task task = newTask(
with(ID, 1L),
with(DUE_TIME, dueDate),
with(SNOOZE_TIME, dueDate.minusMinutes(4)),
with(REMINDER_LAST, dueDate.minusMinutes(5)),
with(REMINDERS, NOTIFY_AT_DEADLINE));
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, dueDate),
with(SNOOZE_TIME, dueDate.minusMinutes(4)),
with(REMINDER_LAST, dueDate.minusMinutes(5)),
with(REMINDERS, NOTIFY_AT_DEADLINE));
service.scheduleAlarm(task);
InOrder order = inOrder(jobs);
order.verify(jobs).cancelReminder(1);
order.verify(jobs).add(new ReminderEntry(1, task.getReminderSnooze(), ReminderService.TYPE_SNOOZE));
order
.verify(jobs)
.add(new ReminderEntry(1, task.getReminderSnooze(), ReminderService.TYPE_SNOOZE));
}
@Test
public void scheduleInitialRandomReminder() {
freezeClock().thawAfter(new Snippet() {{
DateTime now = newDateTime();
when(random.nextFloat()).thenReturn(0.3865f);
Task task = newTask(
with(ID, 1L),
with(REMINDER_LAST, (DateTime) null),
with(CREATION_TIME, now.minusDays(1)),
with(RANDOM_REMINDER_PERIOD, ONE_WEEK));
service.scheduleAlarm(task);
InOrder order = inOrder(jobs);
order.verify(jobs).cancelReminder(1);
order.verify(jobs).add(
new ReminderEntry(1L, now.minusDays(1).getMillis() + 584206592, ReminderService.TYPE_RANDOM));
}});
freezeClock()
.thawAfter(
new Snippet() {
{
DateTime now = newDateTime();
when(random.nextFloat()).thenReturn(0.3865f);
Task task =
newTask(
with(ID, 1L),
with(REMINDER_LAST, (DateTime) null),
with(CREATION_TIME, now.minusDays(1)),
with(RANDOM_REMINDER_PERIOD, ONE_WEEK));
service.scheduleAlarm(task);
InOrder order = inOrder(jobs);
order.verify(jobs).cancelReminder(1);
order
.verify(jobs)
.add(
new ReminderEntry(
1L,
now.minusDays(1).getMillis() + 584206592,
ReminderService.TYPE_RANDOM));
}
});
}
@Test
public void scheduleNextRandomReminder() {
freezeClock().thawAfter(new Snippet() {{
DateTime now = newDateTime();
when(random.nextFloat()).thenReturn(0.3865f);
Task task = newTask(
with(ID, 1L),
with(REMINDER_LAST, now.minusDays(1)),
with(CREATION_TIME, now.minusDays(30)),
with(RANDOM_REMINDER_PERIOD, ONE_WEEK));
service.scheduleAlarm(task);
InOrder order = inOrder(jobs);
order.verify(jobs).cancelReminder(1);
order.verify(jobs).add(
new ReminderEntry(1L, now.minusDays(1).getMillis() + 584206592, ReminderService.TYPE_RANDOM));
}});
freezeClock()
.thawAfter(
new Snippet() {
{
DateTime now = newDateTime();
when(random.nextFloat()).thenReturn(0.3865f);
Task task =
newTask(
with(ID, 1L),
with(REMINDER_LAST, now.minusDays(1)),
with(CREATION_TIME, now.minusDays(30)),
with(RANDOM_REMINDER_PERIOD, ONE_WEEK));
service.scheduleAlarm(task);
InOrder order = inOrder(jobs);
order.verify(jobs).cancelReminder(1);
order
.verify(jobs)
.add(
new ReminderEntry(
1L,
now.minusDays(1).getMillis() + 584206592,
ReminderService.TYPE_RANDOM));
}
});
}
@Test
public void scheduleOverdueRandomReminder() {
freezeClock().thawAfter(new Snippet() {{
DateTime now = newDateTime();
when(random.nextFloat()).thenReturn(0.3865f);
Task task = newTask(
with(ID, 1L),
with(REMINDER_LAST, now.minusDays(14)),
with(CREATION_TIME, now.minusDays(30)),
with(RANDOM_REMINDER_PERIOD, ONE_WEEK));
service.scheduleAlarm(task);
InOrder order = inOrder(jobs);
order.verify(jobs).cancelReminder(1);
order.verify(jobs)
.add(new ReminderEntry(1L, now.getMillis() + 10148400, ReminderService.TYPE_RANDOM));
}});
freezeClock()
.thawAfter(
new Snippet() {
{
DateTime now = newDateTime();
when(random.nextFloat()).thenReturn(0.3865f);
Task task =
newTask(
with(ID, 1L),
with(REMINDER_LAST, now.minusDays(14)),
with(CREATION_TIME, now.minusDays(30)),
with(RANDOM_REMINDER_PERIOD, ONE_WEEK));
service.scheduleAlarm(task);
InOrder order = inOrder(jobs);
order.verify(jobs).cancelReminder(1);
order
.verify(jobs)
.add(
new ReminderEntry(
1L, now.getMillis() + 10148400, ReminderService.TYPE_RANDOM));
}
});
}
@Test
public void scheduleOverdueNoLastReminder() {
Task task = newTask(
with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 9, 22, 15, 30)),
with(REMINDER_LAST, (DateTime) null),
with(REMINDERS, NOTIFY_AFTER_DEADLINE));
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 9, 22, 15, 30)),
with(REMINDER_LAST, (DateTime) null),
with(REMINDERS, NOTIFY_AFTER_DEADLINE));
service.scheduleAlarm(task);
InOrder order = inOrder(jobs);
order.verify(jobs).cancelReminder(1);
order.verify(jobs).add(new ReminderEntry(1L, new DateTime(2017, 9, 23, 15, 30, 1, 0).getMillis(),
ReminderService.TYPE_OVERDUE));
order
.verify(jobs)
.add(
new ReminderEntry(
1L,
new DateTime(2017, 9, 23, 15, 30, 1, 0).getMillis(),
ReminderService.TYPE_OVERDUE));
}
@Test
public void scheduleOverduePastLastReminder() {
Task task = newTask(
with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 9, 22, 15, 30)),
with(REMINDER_LAST, new DateTime(2017, 9, 24, 12, 0)),
with(REMINDERS, NOTIFY_AFTER_DEADLINE));
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 9, 22, 15, 30)),
with(REMINDER_LAST, new DateTime(2017, 9, 24, 12, 0)),
with(REMINDERS, NOTIFY_AFTER_DEADLINE));
service.scheduleAlarm(task);
InOrder order = inOrder(jobs);
order.verify(jobs).cancelReminder(1);
order.verify(jobs).add(new ReminderEntry(1L, new DateTime(2017, 9, 24, 15, 30, 1, 0).getMillis(),
ReminderService.TYPE_OVERDUE));
order
.verify(jobs)
.add(
new ReminderEntry(
1L,
new DateTime(2017, 9, 24, 15, 30, 1, 0).getMillis(),
ReminderService.TYPE_OVERDUE));
}
@Test
public void scheduleOverdueBeforeLastReminder() {
Task task = newTask(
with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 9, 22, 12, 30)),
with(REMINDER_LAST, new DateTime(2017, 9, 24, 15, 0)),
with(REMINDERS, NOTIFY_AFTER_DEADLINE));
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 9, 22, 12, 30)),
with(REMINDER_LAST, new DateTime(2017, 9, 24, 15, 0)),
with(REMINDERS, NOTIFY_AFTER_DEADLINE));
service.scheduleAlarm(task);
InOrder order = inOrder(jobs);
order.verify(jobs).cancelReminder(1);
order.verify(jobs).add(new ReminderEntry(1L, new DateTime(2017, 9, 25, 12, 30, 1, 0).getMillis(),
ReminderService.TYPE_OVERDUE));
order
.verify(jobs)
.add(
new ReminderEntry(
1L,
new DateTime(2017, 9, 25, 12, 30, 1, 0).getMillis(),
ReminderService.TYPE_OVERDUE));
}
@Test
public void scheduleOverdueWithNoDueTime() {
preferences.setInt(R.string.p_rmd_time, (int) TimeUnit.HOURS.toMillis(15));
Task task = newTask(
with(ID, 1L),
with(DUE_DATE, new DateTime(2017, 9, 22)),
with(REMINDER_LAST, new DateTime(2017, 9, 23, 12, 17, 59, 999)),
with(REMINDERS, NOTIFY_AFTER_DEADLINE));
Task task =
newTask(
with(ID, 1L),
with(DUE_DATE, new DateTime(2017, 9, 22)),
with(REMINDER_LAST, new DateTime(2017, 9, 23, 12, 17, 59, 999)),
with(REMINDERS, NOTIFY_AFTER_DEADLINE));
service.scheduleAlarm(task);
InOrder order = inOrder(jobs);
order.verify(jobs).cancelReminder(1);
order.verify(jobs).add(new ReminderEntry(1L, new DateTime(2017, 9, 23, 15, 0, 0, 0).getMillis(),
ReminderService.TYPE_OVERDUE));
order
.verify(jobs)
.add(
new ReminderEntry(
1L,
new DateTime(2017, 9, 23, 15, 0, 0, 0).getMillis(),
ReminderService.TYPE_OVERDUE));
}
@Test
public void scheduleSubsequentOverdueReminder() {
Task task = newTask(
with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 9, 22, 15, 30)),
with(REMINDER_LAST, new DateTime(2017, 9, 23, 15, 30, 59, 999)),
with(REMINDERS, NOTIFY_AFTER_DEADLINE));
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 9, 22, 15, 30)),
with(REMINDER_LAST, new DateTime(2017, 9, 23, 15, 30, 59, 999)),
with(REMINDERS, NOTIFY_AFTER_DEADLINE));
service.scheduleAlarm(task);
InOrder order = inOrder(jobs);
order.verify(jobs).cancelReminder(1);
order.verify(jobs).add(new ReminderEntry(1L, new DateTime(2017, 9, 24, 15, 30, 1, 0).getMillis(),
ReminderService.TYPE_OVERDUE));
order
.verify(jobs)
.add(
new ReminderEntry(
1L,
new DateTime(2017, 9, 24, 15, 30, 1, 0).getMillis(),
ReminderService.TYPE_OVERDUE));
}
@Test
public void scheduleOverdueAfterLastReminder() {
Task task = newTask(
with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 9, 22, 15, 30)),
with(REMINDER_LAST, new DateTime(2017, 9, 23, 12, 17, 59, 999)),
with(REMINDERS, NOTIFY_AFTER_DEADLINE));
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 9, 22, 15, 30)),
with(REMINDER_LAST, new DateTime(2017, 9, 23, 12, 17, 59, 999)),
with(REMINDERS, NOTIFY_AFTER_DEADLINE));
service.scheduleAlarm(task);
InOrder order = inOrder(jobs);
order.verify(jobs).cancelReminder(1);
order.verify(jobs).add(new ReminderEntry(1L, new DateTime(2017, 9, 23, 15, 30, 1, 0).getMillis(),
ReminderService.TYPE_OVERDUE));
order
.verify(jobs)
.add(
new ReminderEntry(
1L,
new DateTime(2017, 9, 23, 15, 30, 1, 0).getMillis(),
ReminderService.TYPE_OVERDUE));
}
@Test
public void snoozeOverridesAll() {
DateTime now = newDateTime();
Task task = newTask(
with(ID, 1L),
with(DUE_TIME, now),
with(SNOOZE_TIME, now.plusMonths(12)),
with(REMINDERS, NOTIFY_AT_DEADLINE | NOTIFY_AFTER_DEADLINE),
with(RANDOM_REMINDER_PERIOD, ONE_HOUR));
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, now),
with(SNOOZE_TIME, now.plusMonths(12)),
with(REMINDERS, NOTIFY_AT_DEADLINE | NOTIFY_AFTER_DEADLINE),
with(RANDOM_REMINDER_PERIOD, ONE_HOUR));
service.scheduleAlarm(task);
InOrder order = inOrder(jobs);
order.verify(jobs).cancelReminder(1);
order.verify(jobs)
order
.verify(jobs)
.add(new ReminderEntry(1, now.plusMonths(12).getMillis(), ReminderService.TYPE_SNOOZE));
}
}

@ -1,9 +1,8 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
* <p>See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.repeats;
import static junit.framework.Assert.assertEquals;
@ -37,8 +36,7 @@ public class AdvancedRepeatTest {
private RRule rrule;
public static void assertDateTimeEquals(long date, long other) {
assertEquals("Expected: " + newDateTime(date) + ", Actual: " + newDateTime(other),
date, other);
assertEquals("Expected: " + newDateTime(date) + ", Actual: " + newDateTime(other), date, other);
}
// --- date with time tests
@ -55,8 +53,9 @@ public class AdvancedRepeatTest {
buildRRule(1, Frequency.DAILY);
// test specific day & time
long dayWithTime = Task.createDueDate(Task.URGENCY_SPECIFIC_DAY_TIME,
new DateTime(2010, 8, 1, 10, 4, 0).getMillis());
long dayWithTime =
Task.createDueDate(
Task.URGENCY_SPECIFIC_DAY_TIME, new DateTime(2010, 8, 1, 10, 4, 0).getMillis());
task.setDueDate(dayWithTime);
long nextDayWithTime = dayWithTime + DateUtilities.ONE_DAY;
@ -71,14 +70,13 @@ public class AdvancedRepeatTest {
buildRRule(1, Frequency.DAILY);
// test specific day & time
long dayWithTime = Task.createDueDate(Task.URGENCY_SPECIFIC_DAY_TIME,
new DateTime(2010, 8, 1, 10, 4, 0).getMillis());
long dayWithTime =
Task.createDueDate(
Task.URGENCY_SPECIFIC_DAY_TIME, new DateTime(2010, 8, 1, 10, 4, 0).getMillis());
task.setDueDate(dayWithTime);
DateTime todayWithTime = newDateTime()
.withHourOfDay(10)
.withMinuteOfHour(4)
.withSecondOfMinute(1);
DateTime todayWithTime =
newDateTime().withHourOfDay(10).withMinuteOfHour(4).withSecondOfMinute(1);
long nextDayWithTimeLong = todayWithTime.getMillis();
nextDayWithTimeLong += DateUtilities.ONE_DAY;
nextDayWithTimeLong = nextDayWithTimeLong / 1000L * 1000;
@ -87,9 +85,7 @@ public class AdvancedRepeatTest {
assertDateTimeEquals(nextDayWithTimeLong, nextDueDate);
}
/**
* test multiple days per week - DUE DATE
*/
/** test multiple days per week - DUE DATE */
@Test
public void testDueDateInPastSingleWeekMultiDay() throws Exception {
buildRRule(1, Frequency.WEEKLY, Weekday.MO, Weekday.WE, Weekday.FR);
@ -107,9 +103,7 @@ public class AdvancedRepeatTest {
assertDueDate(nextDueDate, THIS, Calendar.MONDAY);
}
/**
* test single day repeats - DUE DATE
*/
/** test single day repeats - DUE DATE */
@Test
public void testDueDateSingleDay() throws Exception {
buildRRule(1, Frequency.WEEKLY, Weekday.MO);
@ -139,9 +133,7 @@ public class AdvancedRepeatTest {
assertDueDate(nextDueDate, NEXT, Calendar.MONDAY);
}
/**
* test multiple days per week - DUE DATE
*/
/** test multiple days per week - DUE DATE */
@Test
public void testDueDateSingleWeekMultiDay() throws Exception {
@ -162,9 +154,7 @@ public class AdvancedRepeatTest {
// --- completion tests
/**
* test multiple days per week, multiple intervals - DUE DATE
*/
/** test multiple days per week, multiple intervals - DUE DATE */
@Test
public void testDueDateMultiWeekMultiDay() throws Exception {
buildRRule(2, Frequency.WEEKLY, Weekday.MO, Weekday.WE, Weekday.FR);
@ -182,9 +172,7 @@ public class AdvancedRepeatTest {
assertDueDate(nextDueDate, NEXT, Calendar.MONDAY);
}
/**
* test multiple days per week - COMPLETE DATE
*/
/** test multiple days per week - COMPLETE DATE */
@Test
public void testCompleteDateSingleWeek() throws Exception {
for (Weekday wday : Weekday.values()) {
@ -213,9 +201,7 @@ public class AdvancedRepeatTest {
// --- helpers
/**
* test multiple days per week, multiple intervals - COMPLETE DATE
*/
/** test multiple days per week, multiple intervals - COMPLETE DATE */
@Test
public void testCompleteDateMultiWeek() throws Exception {
for (Weekday wday : Weekday.values()) {

@ -66,10 +66,7 @@ public class NewRepeatTests {
assertEquals(newDayTime(2017, 8, 28, 1, 44), calculateNextDueDate(task));
}
/**
* Tests for repeating from completionDate
*/
/** Tests for repeating from completionDate */
@Test
public void testRepeatMinutelyFromCompleteDateCompleteBefore() throws ParseException {
DateTime dueDateTime = newDayTime(2016, 8, 30, 0, 25);
@ -181,8 +178,9 @@ public class NewRepeatTests {
@Test
public void testAdvancedRepeatWeeklyFromDueDate() throws ParseException {
DateTime dueDateTime = newDayTime(2016, 8, 29, 0, 25);
Task task = newWeeklyFromDue(1, dueDateTime, new WeekdayNum(0, Weekday.MO),
new WeekdayNum(0, Weekday.WE));
Task task =
newWeeklyFromDue(
1, dueDateTime, new WeekdayNum(0, Weekday.MO), new WeekdayNum(0, Weekday.WE));
assertEquals(newDayTime(2016, 8, 31, 0, 25), calculateNextDueDate(task));
}
@ -191,8 +189,13 @@ public class NewRepeatTests {
public void testAdvancedRepeatWeeklyFromCompleteDateCompleteBefore() throws ParseException {
DateTime dueDateTime = newDayTime(2016, 8, 29, 0, 25);
DateTime completionDateTime = newDayTime(2016, 8, 28, 1, 9);
Task task = newWeeklyFromCompleted(1, dueDateTime, completionDateTime,
new WeekdayNum(0, Weekday.MO), new WeekdayNum(0, Weekday.WE));
Task task =
newWeeklyFromCompleted(
1,
dueDateTime,
completionDateTime,
new WeekdayNum(0, Weekday.MO),
new WeekdayNum(0, Weekday.WE));
assertEquals(newDayTime(2016, 8, 29, 0, 25), calculateNextDueDate(task));
}
@ -201,15 +204,22 @@ public class NewRepeatTests {
public void testAdvancedRepeatWeeklyFromCompleteDateCompleteAfter() throws ParseException {
DateTime dueDateTime = newDayTime(2016, 8, 29, 0, 25);
DateTime completionDateTime = newDayTime(2016, 9, 1, 1, 9);
Task task = newWeeklyFromCompleted(1, dueDateTime, completionDateTime,
new WeekdayNum(0, Weekday.MO), new WeekdayNum(0, Weekday.WE));
Task task =
newWeeklyFromCompleted(
1,
dueDateTime,
completionDateTime,
new WeekdayNum(0, Weekday.MO),
new WeekdayNum(0, Weekday.WE));
assertEquals(newDayTime(2016, 9, 5, 0, 25), calculateNextDueDate(task));
}
private DateTime newDayTime(int year, int month, int day, int hour, int minute) {
return new DateTime(Task.createDueDate(Task.URGENCY_SPECIFIC_DAY_TIME,
new DateTime(year, month, day, hour, minute).getMillis()));
return new DateTime(
Task.createDueDate(
Task.URGENCY_SPECIFIC_DAY_TIME,
new DateTime(year, month, day, hour, minute).getMillis()));
}
private DateTime calculateNextDueDate(Task task) throws ParseException {
@ -218,39 +228,47 @@ public class NewRepeatTests {
}
private Task newFromDue(Frequency frequency, int interval, DateTime dueDateTime) {
return new Task() {{
setRecurrence(getRecurrenceRule(frequency, interval, false));
setDueDate(dueDateTime.getMillis());
}};
return new Task() {
{
setRecurrence(getRecurrenceRule(frequency, interval, false));
setDueDate(dueDateTime.getMillis());
}
};
}
private Task newWeeklyFromDue(int interval, DateTime dueDateTime, WeekdayNum... weekdays) {
return new Task() {{
setRecurrence(getRecurrenceRule(Frequency.WEEKLY, interval, false, weekdays));
setDueDate(dueDateTime.getMillis());
}};
return new Task() {
{
setRecurrence(getRecurrenceRule(Frequency.WEEKLY, interval, false, weekdays));
setDueDate(dueDateTime.getMillis());
}
};
}
private Task newFromCompleted(Frequency frequency, int interval, DateTime dueDateTime,
DateTime completionDate) {
return new Task() {{
setRecurrence(getRecurrenceRule(frequency, interval, true));
setDueDate(dueDateTime.getMillis());
setCompletionDate(completionDate.getMillis());
}};
private Task newFromCompleted(
Frequency frequency, int interval, DateTime dueDateTime, DateTime completionDate) {
return new Task() {
{
setRecurrence(getRecurrenceRule(frequency, interval, true));
setDueDate(dueDateTime.getMillis());
setCompletionDate(completionDate.getMillis());
}
};
}
private Task newWeeklyFromCompleted(int interval, DateTime dueDateTime, DateTime completionDate,
WeekdayNum... weekdays) {
return new Task() {{
setRecurrence(getRecurrenceRule(Frequency.WEEKLY, interval, true, weekdays));
setDueDate(dueDateTime.getMillis());
setCompletionDate(completionDate.getMillis());
}};
private Task newWeeklyFromCompleted(
int interval, DateTime dueDateTime, DateTime completionDate, WeekdayNum... weekdays) {
return new Task() {
{
setRecurrence(getRecurrenceRule(Frequency.WEEKLY, interval, true, weekdays));
setDueDate(dueDateTime.getMillis());
setCompletionDate(completionDate.getMillis());
}
};
}
private String getRecurrenceRule(Frequency frequency, int interval, boolean fromCompletion,
WeekdayNum... weekdays) {
private String getRecurrenceRule(
Frequency frequency, int interval, boolean fromCompletion, WeekdayNum... weekdays) {
RRule rrule = new RRule();
rrule.setFreq(frequency);
rrule.setInterval(interval);

@ -64,127 +64,139 @@ public class RepeatTaskHelperTest extends InjectingTestCase {
@Test
public void testMinutelyRepeat() throws ParseException {
Task task = newTask(with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 10, 4, 13, 30)),
with(RRULE, new RRule("RRULE:FREQ=MINUTELY;INTERVAL=30")));
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 10, 4, 13, 30)),
with(RRULE, new RRule("RRULE:FREQ=MINUTELY;INTERVAL=30")));
repeatAndVerify(task,
new DateTime(2017, 10, 4, 13, 30, 1),
new DateTime(2017, 10, 4, 14, 0, 1));
repeatAndVerify(
task, new DateTime(2017, 10, 4, 13, 30, 1), new DateTime(2017, 10, 4, 14, 0, 1));
}
@Test
public void testMinutelyRepeatAfterCompletion() throws ParseException {
Task task = newTask(with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 10, 4, 13, 30)),
with(COMPLETION_TIME, new DateTime(2017, 10, 4, 13, 17, 45, 340)),
with(RRULE, new RRule("RRULE:FREQ=MINUTELY;INTERVAL=30")),
with(AFTER_COMPLETE, true));
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 10, 4, 13, 30)),
with(COMPLETION_TIME, new DateTime(2017, 10, 4, 13, 17, 45, 340)),
with(RRULE, new RRule("RRULE:FREQ=MINUTELY;INTERVAL=30")),
with(AFTER_COMPLETE, true));
repeatAndVerify(task,
new DateTime(2017, 10, 4, 13, 30, 1),
new DateTime(2017, 10, 4, 13, 47, 1));
repeatAndVerify(
task, new DateTime(2017, 10, 4, 13, 30, 1), new DateTime(2017, 10, 4, 13, 47, 1));
}
@Test
public void testMinutelyDecrementCount() throws ParseException {
Task task = newTask(with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 10, 4, 13, 30)),
with(RRULE, new RRule("RRULE:FREQ=MINUTELY;COUNT=2;INTERVAL=30")));
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 10, 4, 13, 30)),
with(RRULE, new RRule("RRULE:FREQ=MINUTELY;COUNT=2;INTERVAL=30")));
repeatAndVerify(task,
new DateTime(2017, 10, 4, 13, 30, 1),
new DateTime(2017, 10, 4, 14, 0, 1));
repeatAndVerify(
task, new DateTime(2017, 10, 4, 13, 30, 1), new DateTime(2017, 10, 4, 14, 0, 1));
assertEquals(1, new RRule(task.getRecurrenceWithoutFrom()).getCount());
}
@Test
public void testMinutelyLastOccurrence() throws ParseException {
Task task = newTask(with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 10, 4, 13, 30)),
with(RRULE, new RRule("RRULE:FREQ=MINUTELY;COUNT=1;INTERVAL=30")));
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 10, 4, 13, 30)),
with(RRULE, new RRule("RRULE:FREQ=MINUTELY;COUNT=1;INTERVAL=30")));
helper.handleRepeat(task);
}
@Test
public void testHourlyRepeat() throws ParseException {
Task task = newTask(with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 10, 4, 13, 30)),
with(RRULE, new RRule("RRULE:FREQ=HOURLY;INTERVAL=6")));
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 10, 4, 13, 30)),
with(RRULE, new RRule("RRULE:FREQ=HOURLY;INTERVAL=6")));
repeatAndVerify(task,
new DateTime(2017, 10, 4, 13, 30, 1),
new DateTime(2017, 10, 4, 19, 30, 1));
repeatAndVerify(
task, new DateTime(2017, 10, 4, 13, 30, 1), new DateTime(2017, 10, 4, 19, 30, 1));
}
@Test
public void testHourlyRepeatAfterCompletion() throws ParseException {
Task task = newTask(with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 10, 4, 13, 30)),
with(COMPLETION_TIME, new DateTime(2017, 10, 4, 13, 17, 45, 340)),
with(RRULE, new RRule("RRULE:FREQ=HOURLY;INTERVAL=6")),
with(AFTER_COMPLETE, true));
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 10, 4, 13, 30)),
with(COMPLETION_TIME, new DateTime(2017, 10, 4, 13, 17, 45, 340)),
with(RRULE, new RRule("RRULE:FREQ=HOURLY;INTERVAL=6")),
with(AFTER_COMPLETE, true));
repeatAndVerify(task,
new DateTime(2017, 10, 4, 13, 30, 1),
new DateTime(2017, 10, 4, 19, 17, 1));
repeatAndVerify(
task, new DateTime(2017, 10, 4, 13, 30, 1), new DateTime(2017, 10, 4, 19, 17, 1));
}
@Test
public void testDailyRepeat() throws ParseException {
Task task = newTask(with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 10, 4, 13, 30)),
with(RRULE, new RRule("RRULE:FREQ=DAILY;INTERVAL=6")));
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 10, 4, 13, 30)),
with(RRULE, new RRule("RRULE:FREQ=DAILY;INTERVAL=6")));
repeatAndVerify(task,
new DateTime(2017, 10, 4, 13, 30, 1),
new DateTime(2017, 10, 10, 13, 30, 1));
repeatAndVerify(
task, new DateTime(2017, 10, 4, 13, 30, 1), new DateTime(2017, 10, 10, 13, 30, 1));
}
@Test
public void testRepeatWeeklyNoDays() throws ParseException {
Task task = newTask(with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 10, 4, 13, 30)),
with(RRULE, new RRule("RRULE:FREQ=WEEKLY;INTERVAL=2")));
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 10, 4, 13, 30)),
with(RRULE, new RRule("RRULE:FREQ=WEEKLY;INTERVAL=2")));
repeatAndVerify(task,
new DateTime(2017, 10, 4, 13, 30, 1),
new DateTime(2017, 10, 18, 13, 30, 1));
repeatAndVerify(
task, new DateTime(2017, 10, 4, 13, 30, 1), new DateTime(2017, 10, 18, 13, 30, 1));
}
@Test
public void testYearly() throws ParseException {
Task task = newTask(with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 10, 4, 13, 30)),
with(RRULE, new RRule("RRULE:FREQ=YEARLY;INTERVAL=3")));
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 10, 4, 13, 30)),
with(RRULE, new RRule("RRULE:FREQ=YEARLY;INTERVAL=3")));
repeatAndVerify(task,
new DateTime(2017, 10, 4, 13, 30, 1),
new DateTime(2020, 10, 4, 13, 30, 1));
repeatAndVerify(
task, new DateTime(2017, 10, 4, 13, 30, 1), new DateTime(2020, 10, 4, 13, 30, 1));
}
@Test
public void testMonthlyRepeat() throws ParseException {
Task task = newTask(with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 10, 4, 13, 30)),
with(RRULE, new RRule("RRULE:FREQ=MONTHLY;INTERVAL=3")));
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 10, 4, 13, 30)),
with(RRULE, new RRule("RRULE:FREQ=MONTHLY;INTERVAL=3")));
repeatAndVerify(task,
new DateTime(2017, 10, 4, 13, 30, 1),
new DateTime(2018, 1, 4, 13, 30, 1));
repeatAndVerify(
task, new DateTime(2017, 10, 4, 13, 30, 1), new DateTime(2018, 1, 4, 13, 30, 1));
}
@Test
public void testMonthlyRepeatAtEndOfMonth() throws ParseException {
Task task = newTask(with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 1, 31, 13, 30)),
with(RRULE, new RRule("RRULE:FREQ=MONTHLY;INTERVAL=1")));
Task task =
newTask(
with(ID, 1L),
with(DUE_TIME, new DateTime(2017, 1, 31, 13, 30)),
with(RRULE, new RRule("RRULE:FREQ=MONTHLY;INTERVAL=1")));
repeatAndVerify(task,
new DateTime(2017, 1, 31, 13, 30, 1),
new DateTime(2017, 2, 28, 13, 30, 1));
repeatAndVerify(
task, new DateTime(2017, 1, 31, 13, 30, 1), new DateTime(2017, 2, 28, 13, 30, 1));
}
private void repeatAndVerify(Task task, DateTime oldDueDate, DateTime newDueDate) {
@ -192,7 +204,8 @@ public class RepeatTaskHelperTest extends InjectingTestCase {
mocks.verify(gCalHelper).rescheduleRepeatingTask(task);
mocks.verify(alarmService).rescheduleAlarms(1, oldDueDate.getMillis(), newDueDate.getMillis());
mocks.verify(localBroadcastManager)
mocks
.verify(localBroadcastManager)
.broadcastRepeat(1, oldDueDate.getMillis(), newDueDate.getMillis());
}

@ -1,9 +1,8 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
* <p>See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.service;
import static junit.framework.Assert.assertEquals;

@ -1,9 +1,8 @@
/**
* Copyright (c) 2012 Todoroo Inc
* <p>
* See the file "LICENSE" for the full license governing this code.
*
* <p>See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.service;
import static junit.framework.Assert.assertEquals;
@ -60,24 +59,22 @@ public class TitleParserTest extends InjectingTestCase {
assertEquals(task.getRecurrence(), nothing.getRecurrence());
}
/**
* Tests correct date is parsed
**/
/** Tests correct date is parsed */
@Test
public void testMonthDate() {
String[] titleMonthStrings = {
"Jan.", "January",
"Feb.", "February",
"Mar.", "March",
"Apr.", "April",
"May", "May",
"Jun.", "June",
"Jul.", "July",
"Aug.", "August",
"Sep.", "September",
"Oct.", "October",
"Nov.", "November",
"Dec.", "December"
"Jan.", "January",
"Feb.", "February",
"Mar.", "March",
"Apr.", "April",
"May", "May",
"Jun.", "June",
"Jul.", "July",
"Aug.", "August",
"Sep.", "September",
"Oct.", "October",
"Nov.", "November",
"Dec.", "December"
};
for (int i = 0; i < 23; i++) {
String testTitle = "Jog on " + titleMonthStrings[i] + " 12.";
@ -138,11 +135,7 @@ public class TitleParserTest extends InjectingTestCase {
@Test
public void test_several_forms_of_eight() {
String[] testTitles = {
"Jog 8 AM",
"Jog 8 o'clock AM",
"at 8:00 AM"
};
String[] testTitles = {"Jog 8 AM", "Jog 8 o'clock AM", "at 8:00 AM"};
for (String testTitle : testTitles) {
Task task = insertTitleAddTask(testTitle);
DateTime date = newDateTime(task.getDueDate());
@ -154,11 +147,7 @@ public class TitleParserTest extends InjectingTestCase {
@Test
public void test_several_forms_of_1230PM() {
String[] testTitles = {
"Jog 12:30 PM",
"at 12:30 PM",
"Do something on 12:30 PM",
"Jog at 12:30 PM Friday"
"Jog 12:30 PM", "at 12:30 PM", "Do something on 12:30 PM", "Jog at 12:30 PM Friday"
};
for (String testTitle : testTitles) {
Task task = insertTitleAddTask(testTitle);
@ -172,7 +161,6 @@ public class TitleParserTest extends InjectingTestCase {
return taskCreator.createWithValues(null, title);
}
// ----------------Days begin----------------//
@Test
public void testDays() {
@ -182,7 +170,7 @@ public class TitleParserTest extends InjectingTestCase {
Task task = taskCreator.createWithValues(null, title);
DateTime date = newDateTime(task.getDueDate());
assertEquals(date.getDayOfWeek(), today.get(Calendar.DAY_OF_WEEK));
//Calendar starts 1-6, date.getDay() starts at 0
// Calendar starts 1-6, date.getDay() starts at 0
title = "Jog tomorrow";
task = taskCreator.createWithValues(null, title);
@ -190,23 +178,9 @@ public class TitleParserTest extends InjectingTestCase {
assertEquals((date.getDayOfWeek()) % 7, (today.get(Calendar.DAY_OF_WEEK) + 1) % 7);
String[] days = {
"sunday",
"monday",
"tuesday",
"wednesday",
"thursday",
"friday",
"saturday",
};
String[] abrevDays = {
"sun.",
"mon.",
"tue.",
"wed.",
"thu.",
"fri.",
"sat."
"sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday",
};
String[] abrevDays = {"sun.", "mon.", "tue.", "wed.", "thu.", "fri.", "sat."};
for (int i = 1; i <= 6; i++) {
title = "Jog " + days[i];
@ -219,24 +193,16 @@ public class TitleParserTest extends InjectingTestCase {
date = newDateTime(task.getDueDate());
assertEquals(date.getDayOfWeek(), i + 1);
}
}
//----------------Days end----------------//
// ----------------Days end----------------//
//----------------Priority begin----------------//
// ----------------Priority begin----------------//
/**
* tests all words using priority 0
*/
/** tests all words using priority 0 */
@Test
public void testPriority0() {
String[] acceptedStrings = {
"priority 0",
"least priority",
"lowest priority",
"bang 0"
};
String[] acceptedStrings = {"priority 0", "least priority", "lowest priority", "bang 0"};
for (String acceptedString : acceptedStrings) {
String title = "Jog " + acceptedString;
Task task = taskCreator.createWithValues(null, title);
@ -251,50 +217,39 @@ public class TitleParserTest extends InjectingTestCase {
@Test
public void testPriority1() {
String[] acceptedStringsAtEnd = {
"priority 1",
"low priority",
"bang",
"bang 1"
};
String[] acceptedStringsAnywhere = {
"!1",
"!"
};
String[] acceptedStringsAtEnd = {"priority 1", "low priority", "bang", "bang 1"};
String[] acceptedStringsAnywhere = {"!1", "!"};
Task task;
for (String acceptedStringAtEnd : acceptedStringsAtEnd) {
task = taskCreator.basicQuickAddTask(
"Jog " + acceptedStringAtEnd); //test at end of task. should set importance.
task =
taskCreator.basicQuickAddTask(
"Jog " + acceptedStringAtEnd); // test at end of task. should set importance.
assertEquals((int) task.getImportance(), Task.IMPORTANCE_SHOULD_DO);
}
for (String acceptedStringAtEnd : acceptedStringsAtEnd) {
task = taskCreator.basicQuickAddTask(
acceptedStringAtEnd + " jog"); //test at beginning of task. should not set importance.
task =
taskCreator.basicQuickAddTask(
acceptedStringAtEnd
+ " jog"); // test at beginning of task. should not set importance.
assertEquals((int) task.getImportance(), Task.IMPORTANCE_SHOULD_DO);
}
for (String acceptedStringAnywhere : acceptedStringsAnywhere) {
task = taskCreator.basicQuickAddTask(
"Jog " + acceptedStringAnywhere); //test at end of task. should set importance.
task =
taskCreator.basicQuickAddTask(
"Jog " + acceptedStringAnywhere); // test at end of task. should set importance.
assertEquals((int) task.getImportance(), Task.IMPORTANCE_SHOULD_DO);
task = taskCreator.basicQuickAddTask(
acceptedStringAnywhere + " jog"); //test at beginning of task. should set importance.
task =
taskCreator.basicQuickAddTask(
acceptedStringAnywhere + " jog"); // test at beginning of task. should set importance.
assertEquals((int) task.getImportance(), Task.IMPORTANCE_SHOULD_DO);
}
}
@Test
public void testPriority2() {
String[] acceptedStringsAtEnd = {
"priority 2",
"high priority",
"bang bang",
"bang 2"
};
String[] acceptedStringsAnywhere = {
"!2",
"!!"
};
String[] acceptedStringsAtEnd = {"priority 2", "high priority", "bang bang", "bang 2"};
String[] acceptedStringsAnywhere = {"!2", "!!"};
for (String acceptedStringAtEnd : acceptedStringsAtEnd) {
String title = "Jog " + acceptedStringAtEnd;
Task task = taskCreator.createWithValues(null, title);
@ -318,18 +273,13 @@ public class TitleParserTest extends InjectingTestCase {
@Test
public void testPriority3() {
String[] acceptedStringsAtEnd = {
"priority 3",
"highest priority",
"bang bang bang",
"bang 3",
"bang bang bang bang bang bang bang"
};
String[] acceptedStringsAnywhere = {
"!3",
"!!!",
"!6",
"!!!!!!!!!!!!!"
"priority 3",
"highest priority",
"bang bang bang",
"bang 3",
"bang bang bang bang bang bang bang"
};
String[] acceptedStringsAnywhere = {"!3", "!!!", "!6", "!!!!!!!!!!!!!"};
for (String acceptedStringAtEnd : acceptedStringsAtEnd) {
String title = "Jog " + acceptedStringAtEnd;
Task task = taskCreator.createWithValues(null, title);
@ -350,13 +300,11 @@ public class TitleParserTest extends InjectingTestCase {
}
}
//----------------Priority end----------------//
// ----------------Priority end----------------//
//----------------Repeats begin----------------//
// ----------------Repeats begin----------------//
/**
* test daily repeat from due date, but with no due date set
*/
/** test daily repeat from due date, but with no due date set */
@Test
public void testDailyWithNoDueDate() {
String title = "Jog daily";
@ -382,12 +330,9 @@ public class TitleParserTest extends InjectingTestCase {
assertFalse(task.hasDueTime());
assertFalse(task.hasDueDate());
}
}
/**
* test weekly repeat from due date, with no due date & time set
*/
/** test weekly repeat from due date, with no due date & time set */
@Test
public void testWeeklyWithNoDueDate() {
String title = "Jog weekly";
@ -415,9 +360,7 @@ public class TitleParserTest extends InjectingTestCase {
}
}
/**
* test hourly repeat from due date, with no due date but no time
*/
/** test hourly repeat from due date, with no due date but no time */
@Test
public void testMonthlyFromNoDueDate() {
String title = "Jog monthly";
@ -493,25 +436,18 @@ public class TitleParserTest extends InjectingTestCase {
}
}
//----------------Repeats end----------------//
// ----------------Repeats end----------------//
//----------------Tags begin----------------//
// ----------------Tags begin----------------//
/**
* tests all words using priority 0
*/
/** tests all words using priority 0 */
@Test
public void testTagsPound() {
String[] acceptedStrings = {
"#tag",
"#a",
"#(a cool tag)",
"#(cool)"
};
String[] acceptedStrings = {"#tag", "#a", "#(a cool tag)", "#(cool)"};
Task task;
for (String acceptedString : acceptedStrings) {
task = new Task();
task.setTitle("Jog " + acceptedString); //test at end of task. should set importance.
task.setTitle("Jog " + acceptedString); // test at end of task. should set importance.
ArrayList<String> tags = new ArrayList<>();
TitleParser.listHelper(tagService, task, tags);
String tag = TitleParser.trimParenthesis(acceptedString);
@ -521,21 +457,14 @@ public class TitleParserTest extends InjectingTestCase {
}
}
/**
* tests all words using priority 0
*/
/** tests all words using priority 0 */
@Test
public void testTagsAt() {
String[] acceptedStrings = {
"@tag",
"@a",
"@(a cool tag)",
"@(cool)"
};
String[] acceptedStrings = {"@tag", "@a", "@(a cool tag)", "@(cool)"};
Task task;
for (String acceptedString : acceptedStrings) {
task = new Task();
task.setTitle("Jog " + acceptedString); //test at end of task. should set importance.
task.setTitle("Jog " + acceptedString); // test at end of task. should set importance.
ArrayList<String> tags = new ArrayList<>();
TitleParser.listHelper(tagService, task, tags);
String tag = TitleParser.trimParenthesis(acceptedString);

@ -15,8 +15,8 @@ import org.tasks.injection.TestComponent;
public class SubtasksHelperTest extends SubtasksTestCase {
private static final String[] EXPECTED_ORDER = {"-1", "1", "2", "3", "4", "5", "6"};
private static final String EXPECTED_REMOTE = "[\"-1\", [\"6\", \"4\", [\"3\", \"1\"]], \"2\", \"5\"]"
.replaceAll("\\s", "");
private static final String EXPECTED_REMOTE =
"[\"-1\", [\"6\", \"4\", [\"3\", \"1\"]], \"2\", \"5\"]".replaceAll("\\s", "");
@Inject TaskDao taskDao;
@Override
@ -25,8 +25,8 @@ public class SubtasksHelperTest extends SubtasksTestCase {
createTasks();
TaskListMetadata m = new TaskListMetadata();
m.setFilter(TaskListMetadata.FILTER_ID_ALL);
updater.initializeFromSerializedTree(m, filter,
SubtasksHelper.convertTreeToRemoteIds(taskDao, DEFAULT_SERIALIZED_TREE));
updater.initializeFromSerializedTree(
m, filter, SubtasksHelper.convertTreeToRemoteIds(taskDao, DEFAULT_SERIALIZED_TREE));
}
private void createTask(String title, String uuid) {
@ -58,8 +58,9 @@ public class SubtasksHelperTest extends SubtasksTestCase {
@Test
public void testLocalToRemoteIdMapping() {
String mapped = SubtasksHelper.convertTreeToRemoteIds(taskDao, DEFAULT_SERIALIZED_TREE)
.replaceAll("\\s", "");
String mapped =
SubtasksHelper.convertTreeToRemoteIds(taskDao, DEFAULT_SERIALIZED_TREE)
.replaceAll("\\s", "");
assertEquals(EXPECTED_REMOTE, mapped);
}

@ -22,8 +22,8 @@ public class SubtasksMovingTest extends SubtasksTestCase {
createTasks();
TaskListMetadata m = new TaskListMetadata();
m.setFilter(TaskListMetadata.FILTER_ID_ALL);
updater.initializeFromSerializedTree(m, filter,
SubtasksHelper.convertTreeToRemoteIds(taskDao, DEFAULT_SERIALIZED_TREE));
updater.initializeFromSerializedTree(
m, filter, SubtasksHelper.convertTreeToRemoteIds(taskDao, DEFAULT_SERIALIZED_TREE));
// Assert initial state is correct
expectParentAndPosition(A, null, 0);

@ -31,8 +31,7 @@ public class SubtasksTestCase extends InjectingTestCase {
* E
* F
*/
static final String DEFAULT_SERIALIZED_TREE = "[-1, [1, 2, [3, 4]], 5, 6]"
.replaceAll("\\s", "");
static final String DEFAULT_SERIALIZED_TREE = "[-1, [1, 2, [3, 4]], 5, 6]".replaceAll("\\s", "");
SubtasksFilterUpdater updater;
Filter filter;
@Inject TaskListMetadataDao taskListMetadataDao;
@ -59,5 +58,4 @@ public class SubtasksTestCase extends InjectingTestCase {
assertEquals("Parent mismatch", parentId, n.parent.uuid);
assertEquals("Position mismatch", positionInParent, n.parent.children.indexOf(n));
}
}

@ -22,5 +22,4 @@ public class SyncModelTest extends NewSyncTestCase {
TagData tag = createTagData();
assertFalse(Task.NO_UUID.equals(tag.getRemoteId()));
}
}

@ -1,5 +1,3 @@
package org.tasks;
public class Snippet {
}
public class Snippet {}

@ -19,16 +19,26 @@ public class DateTimeUtilsTest {
@Test
public void testGetCurrentTime() {
freezeAt(now).thawAfter(new Snippet() {{
assertEquals(now.getMillis(), currentTimeMillis());
}});
freezeAt(now)
.thawAfter(
new Snippet() {
{
assertEquals(now.getMillis(), currentTimeMillis());
}
});
}
@Test
public void testCreateNewUtcDate() {
DateTime utc = now.toUTC();
DateTime actual = newDateUtc(utc.getYear(), utc.getMonthOfYear(), utc.getDayOfMonth(),
utc.getHourOfDay(), utc.getMinuteOfHour(), utc.getSecondOfMinute());
DateTime actual =
newDateUtc(
utc.getYear(),
utc.getMonthOfYear(),
utc.getDayOfMonth(),
utc.getHourOfDay(),
utc.getMinuteOfHour(),
utc.getSecondOfMinute());
assertEquals(utc.getMillis(), actual.getMillis());
}

@ -13,9 +13,8 @@ public abstract class InjectingTestCase {
public void setUp() {
initializeMockito(getTargetContext());
component = DaggerTestComponent.builder()
.testModule(new TestModule(getTargetContext()))
.build();
component =
DaggerTestComponent.builder().testModule(new TestModule(getTargetContext())).build();
inject(component);
}

@ -17,6 +17,12 @@ import org.tasks.time.DateTime;
@RunWith(AndroidJUnit4.class)
public class BackupJobTest {
private static File newFile(DateTime lastModified) {
File result = mock(File.class);
stub(result.lastModified()).toReturn(lastModified.getMillis());
return result;
}
@Test
public void filterExcludesXmlFiles() {
assertFalse(BackupJob.FILE_FILTER.accept(new File("/a/b/c/d/auto.180329-0001.xml")));
@ -33,9 +39,7 @@ public class BackupJobTest {
File file2 = newFile(newDate(2018, 3, 28));
File file3 = newFile(newDate(2018, 3, 29));
assertEquals(
emptyList(),
BackupJob.getDeleteList(new File[] {file2, file1, file3}, 7));
assertEquals(emptyList(), BackupJob.getDeleteList(new File[] {file2, file1, file3}, 7));
}
@Test
@ -50,13 +54,6 @@ public class BackupJobTest {
File file3 = newFile(newDate(2018, 3, 29));
assertEquals(
singletonList(file1),
BackupJob.getDeleteList(new File[] {file2, file1, file3}, 2));
}
private static File newFile(DateTime lastModified) {
File result = mock(File.class);
stub(result.lastModified()).toReturn(lastModified.getMillis());
return result;
singletonList(file1), BackupJob.getDeleteList(new File[] {file2, file1, file3}, 2));
}
}

@ -1,9 +1,8 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
* <p>See the file "LICENSE" for the full license governing this code.
*/
package org.tasks.jobs;
import static android.support.test.InstrumentationRegistry.getTargetContext;
@ -31,12 +30,10 @@ import org.tasks.preferences.Preferences;
public class BackupServiceTests extends InjectingTestCase {
private static final long BACKUP_WAIT_TIME = 500L;
private File temporaryDirectory = null;
@Inject TasksJsonExporter jsonExporter;
@Inject TaskDao taskDao;
@Inject Preferences preferences;
private File temporaryDirectory = null;
@Override
public void setUp() {

@ -59,12 +59,15 @@ public class NotificationQueueTest {
verify(jobManager).scheduleNotification(now);
Freeze.freezeAt(now).thawAfter(new Snippet() {{
assertEquals(
newHashSet(new AlarmEntry(1, 1, now),
new ReminderEntry(1, now, TYPE_DUE)),
newHashSet(queue.getOverdueJobs()));
}});
Freeze.freezeAt(now)
.thawAfter(
new Snippet() {
{
assertEquals(
newHashSet(new AlarmEntry(1, 1, now), new ReminderEntry(1, now, TYPE_DUE)),
newHashSet(queue.getOverdueJobs()));
}
});
}
@Test
@ -78,11 +81,14 @@ public class NotificationQueueTest {
queue.remove(singletonList(new AlarmEntry(1, 1, now)));
Freeze.freezeAt(now).thawAfter(new Snippet() {{
assertEquals(
singletonList(new ReminderEntry(1, now, TYPE_DUE)),
queue.getOverdueJobs());
}});
Freeze.freezeAt(now)
.thawAfter(
new Snippet() {
{
assertEquals(
singletonList(new ReminderEntry(1, now, TYPE_DUE)), queue.getOverdueJobs());
}
});
}
@Test
@ -96,11 +102,13 @@ public class NotificationQueueTest {
queue.remove(singletonList(new ReminderEntry(1, now, TYPE_DUE)));
Freeze.freezeAt(now).thawAfter(new Snippet() {{
assertEquals(
singletonList(new AlarmEntry(1, 1, now)),
queue.getOverdueJobs());
}});
Freeze.freezeAt(now)
.thawAfter(
new Snippet() {
{
assertEquals(singletonList(new AlarmEntry(1, 1, now)), queue.getOverdueJobs());
}
});
}
@Test
@ -194,11 +202,14 @@ public class NotificationQueueTest {
verify(jobManager).scheduleNotification(now);
Freeze.freezeAt(now).thawAfter(new Snippet() {{
assertEquals(
singletonList(new ReminderEntry(1, now, TYPE_DUE)),
queue.getOverdueJobs());
}});
Freeze.freezeAt(now)
.thawAfter(
new Snippet() {
{
assertEquals(
singletonList(new ReminderEntry(1, now, TYPE_DUE)), queue.getOverdueJobs());
}
});
}
@Test
@ -210,11 +221,16 @@ public class NotificationQueueTest {
verify(jobManager).scheduleNotification(now);
Freeze.freezeAt(now).thawAfter(new Snippet() {{
assertEquals(
asList(new ReminderEntry(1, now, TYPE_DUE), new ReminderEntry(2, now, TYPE_DUE)),
queue.getOverdueJobs());
}});
Freeze.freezeAt(now)
.thawAfter(
new Snippet() {
{
assertEquals(
asList(
new ReminderEntry(1, now, TYPE_DUE), new ReminderEntry(2, now, TYPE_DUE)),
queue.getOverdueJobs());
}
});
}
@Test
@ -226,11 +242,17 @@ public class NotificationQueueTest {
verify(jobManager).scheduleNotification(now);
Freeze.freezeAt(now + 2 * ONE_MINUTE).thawAfter(new Snippet() {{
assertEquals(
asList(new ReminderEntry(1, now, TYPE_DUE), new ReminderEntry(2, now + ONE_MINUTE, TYPE_DUE)),
queue.getOverdueJobs());
}});
Freeze.freezeAt(now + 2 * ONE_MINUTE)
.thawAfter(
new Snippet() {
{
assertEquals(
asList(
new ReminderEntry(1, now, TYPE_DUE),
new ReminderEntry(2, now + ONE_MINUTE, TYPE_DUE)),
queue.getOverdueJobs());
}
});
}
@Test
@ -242,13 +264,15 @@ public class NotificationQueueTest {
verify(jobManager).scheduleNotification(now);
Freeze.freezeAt(now).thawAfter(new Snippet() {{
queue.remove(queue.getOverdueJobs());
}});
Freeze.freezeAt(now)
.thawAfter(
new Snippet() {
{
queue.remove(queue.getOverdueJobs());
}
});
assertEquals(
singletonList(new ReminderEntry(2, now + ONE_MINUTE, TYPE_DUE)),
queue.getJobs());
assertEquals(singletonList(new ReminderEntry(2, now + ONE_MINUTE, TYPE_DUE)), queue.getJobs());
}
@Test
@ -261,13 +285,16 @@ public class NotificationQueueTest {
verify(jobManager).scheduleNotification(now);
Freeze.freezeAt(now + ONE_MINUTE).thawAfter(new Snippet() {{
queue.remove(queue.getOverdueJobs());
}});
Freeze.freezeAt(now + ONE_MINUTE)
.thawAfter(
new Snippet() {
{
queue.remove(queue.getOverdueJobs());
}
});
assertEquals(
singletonList(new ReminderEntry(3, now + 2 * ONE_MINUTE, TYPE_DUE)),
queue.getJobs());
singletonList(new ReminderEntry(3, now + 2 * ONE_MINUTE, TYPE_DUE)), queue.getJobs());
}
@Test
@ -304,16 +331,21 @@ public class NotificationQueueTest {
verify(jobManager).scheduleNotification(due.getMillis());
Freeze.freezeAt(now).thawAfter(new Snippet() {{
List<? extends NotificationQueueEntry> overdueJobs = queue.getOverdueJobs();
assertEquals(
asList(new ReminderEntry(1, due.getMillis(), TYPE_DUE),
new ReminderEntry(2, snooze.getMillis(), TYPE_SNOOZE)),
overdueJobs);
queue.remove(overdueJobs);
assertEquals(
singletonList(new ReminderEntry(3, due.plusMinutes(1).getMillis(), TYPE_DUE)),
queue.getJobs());
}});
Freeze.freezeAt(now)
.thawAfter(
new Snippet() {
{
List<? extends NotificationQueueEntry> overdueJobs = queue.getOverdueJobs();
assertEquals(
asList(
new ReminderEntry(1, due.getMillis(), TYPE_DUE),
new ReminderEntry(2, snooze.getMillis(), TYPE_SNOOZE)),
overdueJobs);
queue.remove(overdueJobs);
assertEquals(
singletonList(new ReminderEntry(3, due.plusMinutes(1).getMillis(), TYPE_DUE)),
queue.getJobs());
}
});
}
}

@ -11,20 +11,24 @@ import org.tasks.data.GoogleTaskList;
public class GtaskListMaker {
public static final Property<GoogleTaskList, Long> ID = newProperty();
private static final Property<GoogleTaskList, Integer> ORDER = newProperty();
public static final Property<GoogleTaskList, String> REMOTE_ID = newProperty();
public static final Property<GoogleTaskList, Long> LAST_SYNC = newProperty();
public static final Property<GoogleTaskList, String> NAME = newProperty();
private static final Property<GoogleTaskList, Integer> ORDER = newProperty();
private static final Property<GoogleTaskList, Integer> COLOR = newProperty();
private static final Instantiator<GoogleTaskList> instantiator = lookup -> new GoogleTaskList() {{
setDeleted(0L);
setId(lookup.valueOf(GtaskListMaker.ID, 0L));
setRemoteId(lookup.valueOf(REMOTE_ID, "1"));
setTitle(lookup.valueOf(NAME, "Default"));
setRemoteOrder(lookup.valueOf(ORDER, 0));
setLastSync(lookup.valueOf(LAST_SYNC, 0L));
setColor(lookup.valueOf(COLOR, -1));
}};
private static final Instantiator<GoogleTaskList> instantiator =
lookup ->
new GoogleTaskList() {
{
setDeleted(0L);
setId(lookup.valueOf(GtaskListMaker.ID, 0L));
setRemoteId(lookup.valueOf(REMOTE_ID, "1"));
setTitle(lookup.valueOf(NAME, "Default"));
setRemoteOrder(lookup.valueOf(ORDER, 0));
setLastSync(lookup.valueOf(LAST_SYNC, 0L));
setColor(lookup.valueOf(COLOR, -1));
}
};
public static GoogleTaskList newGtaskList(
PropertyValue<? super GoogleTaskList, ?>... properties) {

@ -8,8 +8,8 @@ import com.natpryce.makeiteasy.PropertyValue;
class Maker {
@SuppressWarnings("unchecked")
public static <T> T make(Instantiator<T> instantiator,
PropertyValue<? super T, ?>... properties) {
public static <T> T make(
Instantiator<T> instantiator, PropertyValue<? super T, ?>... properties) {
return com.natpryce.makeiteasy.MakeItEasy.make(a(instantiator, properties));
}
}

@ -15,10 +15,8 @@ import org.tasks.time.DateTime;
public class TaskMaker {
public static final Property<Task, Long> ID = newProperty();
private static final Property<Task, String> TITLE = newProperty();
public static final Property<Task, DateTime> DUE_DATE = newProperty();
public static final Property<Task, DateTime> DUE_TIME = newProperty();
private static final Property<Task, Integer> PRIORITY = newProperty();
public static final Property<Task, DateTime> REMINDER_LAST = newProperty();
public static final Property<Task, Long> RANDOM_REMINDER_PERIOD = newProperty();
public static final Property<Task, Integer> HIDE_TYPE = newProperty();
@ -29,79 +27,82 @@ public class TaskMaker {
public static final Property<Task, DateTime> SNOOZE_TIME = newProperty();
public static final Property<Task, RRule> RRULE = newProperty();
public static final Property<Task, Boolean> AFTER_COMPLETE = newProperty();
private static final Instantiator<Task> instantiator = lookup -> {
Task task = new Task();
String title = lookup.valueOf(TITLE, (String) null);
if (!Strings.isNullOrEmpty(title)) {
task.setTitle(title);
}
long id = lookup.valueOf(ID, Task.NO_ID);
if (id != Task.NO_ID) {
task.setId(id);
}
int priority = lookup.valueOf(PRIORITY, -1);
if (priority >= 0) {
task.setImportance(priority);
}
DateTime dueDate = lookup.valueOf(DUE_DATE, (DateTime) null);
if (dueDate != null) {
task.setDueDate(Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, dueDate.getMillis()));
}
DateTime dueTime = lookup.valueOf(DUE_TIME, (DateTime) null);
if (dueTime != null) {
task.setDueDate(Task.createDueDate(Task.URGENCY_SPECIFIC_DAY_TIME, dueTime.getMillis()));
}
DateTime completionTime = lookup.valueOf(COMPLETION_TIME, (DateTime) null);
if (completionTime != null) {
task.setCompletionDate(completionTime.getMillis());
}
DateTime deletedTime = lookup.valueOf(DELETION_TIME, (DateTime) null);
if (deletedTime != null) {
task.setDeletionDate(deletedTime.getMillis());
}
DateTime snoozeTime = lookup.valueOf(SNOOZE_TIME, (DateTime) null);
if (snoozeTime != null) {
task.setReminderSnooze(snoozeTime.getMillis());
}
int hideType = lookup.valueOf(HIDE_TYPE, -1);
if (hideType >= 0) {
task.setHideUntil(task.createHideUntil(hideType, 0));
}
int reminderFlags = lookup.valueOf(REMINDERS, -1);
if (reminderFlags >= 0) {
task.setReminderFlags(reminderFlags);
}
DateTime reminderLast = lookup.valueOf(REMINDER_LAST, (DateTime) null);
if (reminderLast != null) {
task.setReminderLast(reminderLast.getMillis());
}
long randomReminderPeriod = lookup.valueOf(RANDOM_REMINDER_PERIOD, 0L);
if (randomReminderPeriod > 0) {
task.setReminderPeriod(randomReminderPeriod);
}
RRule rrule = lookup.valueOf(RRULE, (RRule) null);
if (rrule != null) {
task.setRecurrence(rrule, lookup.valueOf(AFTER_COMPLETE, false));
}
DateTime creationTime = lookup.valueOf(CREATION_TIME, newDateTime());
task.setCreationDate(creationTime.getMillis());
return task;
};
private static final Property<Task, String> TITLE = newProperty();
private static final Property<Task, Integer> PRIORITY = newProperty();
private static final Instantiator<Task> instantiator =
lookup -> {
Task task = new Task();
String title = lookup.valueOf(TITLE, (String) null);
if (!Strings.isNullOrEmpty(title)) {
task.setTitle(title);
}
long id = lookup.valueOf(ID, Task.NO_ID);
if (id != Task.NO_ID) {
task.setId(id);
}
int priority = lookup.valueOf(PRIORITY, -1);
if (priority >= 0) {
task.setImportance(priority);
}
DateTime dueDate = lookup.valueOf(DUE_DATE, (DateTime) null);
if (dueDate != null) {
task.setDueDate(Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, dueDate.getMillis()));
}
DateTime dueTime = lookup.valueOf(DUE_TIME, (DateTime) null);
if (dueTime != null) {
task.setDueDate(Task.createDueDate(Task.URGENCY_SPECIFIC_DAY_TIME, dueTime.getMillis()));
}
DateTime completionTime = lookup.valueOf(COMPLETION_TIME, (DateTime) null);
if (completionTime != null) {
task.setCompletionDate(completionTime.getMillis());
}
DateTime deletedTime = lookup.valueOf(DELETION_TIME, (DateTime) null);
if (deletedTime != null) {
task.setDeletionDate(deletedTime.getMillis());
}
DateTime snoozeTime = lookup.valueOf(SNOOZE_TIME, (DateTime) null);
if (snoozeTime != null) {
task.setReminderSnooze(snoozeTime.getMillis());
}
int hideType = lookup.valueOf(HIDE_TYPE, -1);
if (hideType >= 0) {
task.setHideUntil(task.createHideUntil(hideType, 0));
}
int reminderFlags = lookup.valueOf(REMINDERS, -1);
if (reminderFlags >= 0) {
task.setReminderFlags(reminderFlags);
}
DateTime reminderLast = lookup.valueOf(REMINDER_LAST, (DateTime) null);
if (reminderLast != null) {
task.setReminderLast(reminderLast.getMillis());
}
long randomReminderPeriod = lookup.valueOf(RANDOM_REMINDER_PERIOD, 0L);
if (randomReminderPeriod > 0) {
task.setReminderPeriod(randomReminderPeriod);
}
RRule rrule = lookup.valueOf(RRULE, (RRule) null);
if (rrule != null) {
task.setRecurrence(rrule, lookup.valueOf(AFTER_COMPLETE, false));
}
DateTime creationTime = lookup.valueOf(CREATION_TIME, newDateTime());
task.setCreationDate(creationTime.getMillis());
return task;
};
@SafeVarargs
public static Task newTask(PropertyValue<? super Task, ?>... properties) {

@ -45,8 +45,8 @@ public class PreferenceTests {
long dueDate = new DateTime(2015, 12, 29, 18, 0, 1).getMillis();
assertEquals(new DateTime(2015, 12, 29, 19, 0).getMillis(),
preferences.adjustForQuietHours(dueDate));
assertEquals(
new DateTime(2015, 12, 29, 19, 0).getMillis(), preferences.adjustForQuietHours(dueDate));
}
@Test
@ -56,8 +56,8 @@ public class PreferenceTests {
long dueDate = new DateTime(2015, 12, 29, 22, 0, 1).getMillis();
assertEquals(new DateTime(2015, 12, 30, 10, 0).getMillis(),
preferences.adjustForQuietHours(dueDate));
assertEquals(
new DateTime(2015, 12, 30, 10, 0).getMillis(), preferences.adjustForQuietHours(dueDate));
}
@Test
@ -67,8 +67,8 @@ public class PreferenceTests {
long dueDate = new DateTime(2015, 12, 29, 23, 30).getMillis();
assertEquals(new DateTime(2015, 12, 30, 10, 0).getMillis(),
preferences.adjustForQuietHours(dueDate));
assertEquals(
new DateTime(2015, 12, 30, 10, 0).getMillis(), preferences.adjustForQuietHours(dueDate));
}
@Test
@ -78,8 +78,8 @@ public class PreferenceTests {
long dueDate = new DateTime(2015, 12, 30, 7, 15).getMillis();
assertEquals(new DateTime(2015, 12, 30, 10, 0).getMillis(),
preferences.adjustForQuietHours(dueDate));
assertEquals(
new DateTime(2015, 12, 30, 10, 0).getMillis(), preferences.adjustForQuietHours(dueDate));
}
@Test

@ -25,19 +25,22 @@ public class RepeatRuleToStringTest {
@Test
public void weeklyByDay() {
assertEquals("Repeats weekly on Mon, Tue, Wed, Thu, Fri",
assertEquals(
"Repeats weekly on Mon, Tue, Wed, Thu, Fri",
toString("RRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=MO,TU,WE,TH,FR"));
}
@Test
public void printDaysInRepeatRuleOrder() {
assertEquals("Repeats weekly on Fri, Thu, Wed, Tue, Mon",
assertEquals(
"Repeats weekly on Fri, Thu, Wed, Tue, Mon",
toString("RRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=FR,TH,WE,TU,MO"));
}
@Test
public void useLocaleForDays() {
assertEquals("Wiederhole wöchentlich am Sa., So.",
assertEquals(
"Wiederhole wöchentlich am Sa., So.",
toString("de", "RRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=SA,SU"));
}

@ -32,8 +32,10 @@ public class DateTimeTest {
TimeZone def = TimeZone.getDefault();
try {
TimeZone.setDefault(TimeZone.getTimeZone("America/Chicago"));
assertEquals(2,
new DateTime(2015, 10, 31, 2, 0, 0).withMillisOfDay((int) TimeUnit.HOURS.toMillis(2))
assertEquals(
2,
new DateTime(2015, 10, 31, 2, 0, 0)
.withMillisOfDay((int) TimeUnit.HOURS.toMillis(2))
.getHourOfDay());
} finally {
TimeZone.setDefault(def);
@ -45,8 +47,10 @@ public class DateTimeTest {
TimeZone def = TimeZone.getDefault();
try {
TimeZone.setDefault(TimeZone.getTimeZone("America/Chicago"));
assertEquals(2,
new DateTime(2015, 11, 2, 2, 0, 0).withMillisOfDay((int) TimeUnit.HOURS.toMillis(2))
assertEquals(
2,
new DateTime(2015, 11, 2, 2, 0, 0)
.withMillisOfDay((int) TimeUnit.HOURS.toMillis(2))
.getHourOfDay());
} finally {
TimeZone.setDefault(def);
@ -58,23 +62,33 @@ public class DateTimeTest {
TimeZone def = TimeZone.getDefault();
try {
TimeZone.setDefault(TimeZone.getTimeZone("America/Chicago"));
assertEquals(1,
new DateTime(2015, 3, 8, 0, 0, 0).withMillisOfDay((int) TimeUnit.HOURS.toMillis(1))
assertEquals(
1,
new DateTime(2015, 3, 8, 0, 0, 0)
.withMillisOfDay((int) TimeUnit.HOURS.toMillis(1))
.getHourOfDay());
assertEquals(3,
new DateTime(2015, 3, 8, 0, 0, 0).withMillisOfDay((int) TimeUnit.HOURS.toMillis(2))
assertEquals(
3,
new DateTime(2015, 3, 8, 0, 0, 0)
.withMillisOfDay((int) TimeUnit.HOURS.toMillis(2))
.getHourOfDay());
assertEquals(3,
new DateTime(2015, 3, 8, 0, 0, 0).withMillisOfDay((int) TimeUnit.HOURS.toMillis(3))
assertEquals(
3,
new DateTime(2015, 3, 8, 0, 0, 0)
.withMillisOfDay((int) TimeUnit.HOURS.toMillis(3))
.getHourOfDay());
assertEquals(4,
new DateTime(2015, 3, 8, 0, 0, 0).withMillisOfDay((int) TimeUnit.HOURS.toMillis(4))
assertEquals(
4,
new DateTime(2015, 3, 8, 0, 0, 0)
.withMillisOfDay((int) TimeUnit.HOURS.toMillis(4))
.getHourOfDay());
assertEquals(
new DateTime(2015, 3, 8, 0, 0, 0).withMillisOfDay((int) TimeUnit.HOURS.toMillis(2))
new DateTime(2015, 3, 8, 0, 0, 0)
.withMillisOfDay((int) TimeUnit.HOURS.toMillis(2))
.getMillis(),
new DateTime(2015, 3, 8, 0, 0, 0).withMillisOfDay((int) TimeUnit.HOURS.toMillis(3))
new DateTime(2015, 3, 8, 0, 0, 0)
.withMillisOfDay((int) TimeUnit.HOURS.toMillis(3))
.getMillis());
} finally {
TimeZone.setDefault(def);
@ -86,14 +100,20 @@ public class DateTimeTest {
TimeZone def = TimeZone.getDefault();
try {
TimeZone.setDefault(TimeZone.getTimeZone("America/Chicago"));
assertEquals(1,
new DateTime(2015, 11, 1, 0, 0, 0).withMillisOfDay((int) TimeUnit.HOURS.toMillis(1))
assertEquals(
1,
new DateTime(2015, 11, 1, 0, 0, 0)
.withMillisOfDay((int) TimeUnit.HOURS.toMillis(1))
.getHourOfDay());
assertEquals(2,
new DateTime(2015, 11, 1, 0, 0, 0).withMillisOfDay((int) TimeUnit.HOURS.toMillis(2))
assertEquals(
2,
new DateTime(2015, 11, 1, 0, 0, 0)
.withMillisOfDay((int) TimeUnit.HOURS.toMillis(2))
.getHourOfDay());
assertEquals(3,
new DateTime(2015, 11, 1, 0, 0, 0).withMillisOfDay((int) TimeUnit.HOURS.toMillis(3))
assertEquals(
3,
new DateTime(2015, 11, 1, 0, 0, 0)
.withMillisOfDay((int) TimeUnit.HOURS.toMillis(3))
.getHourOfDay());
} finally {
TimeZone.setDefault(def);
@ -196,8 +216,7 @@ public class DateTimeTest {
@Test
public void testWithHourOfDay() {
assertEquals(
new DateTime(2015, 11, 6, 23, 0, 0),
new DateTime(2015, 11, 6, 1, 0, 0).withHourOfDay(23));
new DateTime(2015, 11, 6, 23, 0, 0), new DateTime(2015, 11, 6, 1, 0, 0).withHourOfDay(23));
}
@Test
@ -222,17 +241,15 @@ public class DateTimeTest {
@Test
public void testMinusMinutes() {
assertEquals(
new DateTime(2015, 11, 4, 23, 59, 0),
new DateTime(2015, 11, 5, 0, 1, 0).minusMinutes(2));
new DateTime(2015, 11, 4, 23, 59, 0), new DateTime(2015, 11, 5, 0, 1, 0).minusMinutes(2));
}
@Test
public void testIsBefore() {
assertTrue(new DateTime(2015, 11, 4, 23, 59, 0)
.isBefore(new DateTime(2015, 11, 4, 23, 59, 1)));
assertTrue(new DateTime(2015, 11, 4, 23, 59, 0).isBefore(new DateTime(2015, 11, 4, 23, 59, 1)));
assertFalse(new DateTime(2015, 11, 4, 23, 59, 0)
.isBefore(new DateTime(2015, 11, 4, 23, 59, 0)));
assertFalse(
new DateTime(2015, 11, 4, 23, 59, 0).isBefore(new DateTime(2015, 11, 4, 23, 59, 0)));
}
@Test
@ -242,25 +259,21 @@ public class DateTimeTest {
@Test
public void testIsAfter() {
assertTrue(new DateTime(2015, 11, 4, 23, 59, 1)
.isAfter(new DateTime(2015, 11, 4, 23, 59, 0)));
assertTrue(new DateTime(2015, 11, 4, 23, 59, 1).isAfter(new DateTime(2015, 11, 4, 23, 59, 0)));
assertFalse(new DateTime(2015, 11, 4, 23, 59, 0)
.isAfter(new DateTime(2015, 11, 4, 23, 59, 0)));
assertFalse(new DateTime(2015, 11, 4, 23, 59, 0).isAfter(new DateTime(2015, 11, 4, 23, 59, 0)));
}
@Test
public void testWithYear() {
assertEquals(
new DateTime(2016, 1, 1, 1, 1, 1),
new DateTime(2015, 1, 1, 1, 1, 1).withYear(2016));
new DateTime(2016, 1, 1, 1, 1, 1), new DateTime(2015, 1, 1, 1, 1, 1).withYear(2016));
}
@Test
public void testWithMonthOfYear() {
assertEquals(
new DateTime(2015, 1, 2, 3, 4, 5),
new DateTime(2015, 2, 2, 3, 4, 5).withMonthOfYear(1));
new DateTime(2015, 1, 2, 3, 4, 5), new DateTime(2015, 2, 2, 3, 4, 5).withMonthOfYear(1));
}
@Test
@ -271,37 +284,37 @@ public class DateTimeTest {
@Test
public void testWithDayOfMonth() {
assertEquals(
new DateTime(2015, 1, 2, 3, 4, 5),
new DateTime(2015, 1, 1, 3, 4, 5).withDayOfMonth(2));
new DateTime(2015, 1, 2, 3, 4, 5), new DateTime(2015, 1, 1, 3, 4, 5).withDayOfMonth(2));
}
@Test
public void testPlusMinutes() {
assertEquals(
new DateTime(2015, 1, 2, 3, 4, 5),
new DateTime(2015, 1, 2, 2, 59, 5).plusMinutes(5));
new DateTime(2015, 1, 2, 3, 4, 5), new DateTime(2015, 1, 2, 2, 59, 5).plusMinutes(5));
}
@Test
public void testPlusHours() {
assertEquals(
new DateTime(2015, 1, 2, 3, 4, 5),
new DateTime(2015, 1, 1, 3, 4, 5).plusHours(24));
new DateTime(2015, 1, 2, 3, 4, 5), new DateTime(2015, 1, 1, 3, 4, 5).plusHours(24));
}
@Test
public void testPlusWeeks() {
assertEquals(
new DateTime(2015, 1, 2, 3, 4, 5),
new DateTime(2014, 12, 12, 3, 4, 5).plusWeeks(3));
new DateTime(2015, 1, 2, 3, 4, 5), new DateTime(2014, 12, 12, 3, 4, 5).plusWeeks(3));
}
@Test
public void testIsBeforeNow() {
Freeze.freezeAt(new DateTime(2015, 10, 6, 16, 15, 27)).thawAfter(new Snippet() {{
assertFalse(new DateTime(2015, 10, 6, 16, 15, 27).isBeforeNow());
assertTrue(new DateTime(2015, 10, 6, 16, 15, 26).isBeforeNow());
}});
Freeze.freezeAt(new DateTime(2015, 10, 6, 16, 15, 27))
.thawAfter(
new Snippet() {
{
assertFalse(new DateTime(2015, 10, 6, 16, 15, 27).isBeforeNow());
assertTrue(new DateTime(2015, 10, 6, 16, 15, 26).isBeforeNow());
}
});
}
@Test
@ -314,12 +327,10 @@ public class DateTimeTest {
@Test
public void testMinusDays() {
assertEquals(
new DateTime(2015, 11, 6, 16, 19, 16),
new DateTime(2015, 12, 4, 16, 19, 16).minusDays(28));
new DateTime(2015, 11, 6, 16, 19, 16), new DateTime(2015, 12, 4, 16, 19, 16).minusDays(28));
assertEquals(
new DateTime(2015, 11, 6, 16, 19, 16),
new DateTime(2015, 11, 7, 16, 19, 16).minusDays(1));
new DateTime(2015, 11, 6, 16, 19, 16), new DateTime(2015, 11, 7, 16, 19, 16).minusDays(1));
}
@Test

@ -1,9 +1,8 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
* <p>See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.gtasks;
import static junit.framework.Assert.assertNotNull;
@ -188,8 +187,7 @@ public class GtasksIndentActionTest extends InjectingTestCase {
GoogleTask metadata = googleTaskDao.getByTaskId(targetTask.getId());
assertNotNull("task has metadata", metadata);
int indentation = metadata.getIndent();
assertTrue("indentation: " + indentation,
indentation == expected);
assertTrue("indentation: " + indentation, indentation == expected);
}
private void givenTask(Task taskToTest) {

@ -43,8 +43,9 @@ public class GtasksListServiceTest extends InjectingTestCase {
@Override
public void setUp() {
super.setUp();
gtasksListService = new GtasksListService(googleTaskListDao, taskDeleter,
localBroadcastManager, googleTaskDao, taskDao);
gtasksListService =
new GtasksListService(
googleTaskListDao, taskDeleter, localBroadcastManager, googleTaskDao, taskDao);
}
@Override
@ -54,15 +55,12 @@ public class GtasksListServiceTest extends InjectingTestCase {
@Test
public void testCreateNewList() {
setLists(newRemoteList(
with(RemoteGtaskListMaker.REMOTE_ID, "1"),
with(RemoteGtaskListMaker.NAME, "Default")));
setLists(
newRemoteList(
with(RemoteGtaskListMaker.REMOTE_ID, "1"), with(RemoteGtaskListMaker.NAME, "Default")));
assertEquals(
newGtaskList(
with(ID, 1L),
with(REMOTE_ID, "1"),
with(NAME, "Default")),
newGtaskList(with(ID, 1L), with(REMOTE_ID, "1"), with(NAME, "Default")),
googleTaskListDao.getById(1L));
}
@ -87,20 +85,19 @@ public class GtasksListServiceTest extends InjectingTestCase {
setLists(taskList);
assertEquals(singletonList(newGtaskList(with(ID, 2L), with(REMOTE_ID, "2"))),
assertEquals(
singletonList(newGtaskList(with(ID, 2L), with(REMOTE_ID, "2"))),
googleTaskListDao.getActiveLists());
}
@Test
public void testUpdateListName() {
googleTaskListDao.insertOrReplace(newGtaskList(
with(ID, 1L),
with(REMOTE_ID, "1"),
with(NAME, "oldName")));
googleTaskListDao.insertOrReplace(
newGtaskList(with(ID, 1L), with(REMOTE_ID, "1"), with(NAME, "oldName")));
setLists(newRemoteList(
with(RemoteGtaskListMaker.REMOTE_ID, "1"),
with(RemoteGtaskListMaker.NAME, "newName")));
setLists(
newRemoteList(
with(RemoteGtaskListMaker.REMOTE_ID, "1"), with(RemoteGtaskListMaker.NAME, "newName")));
assertEquals("newName", googleTaskListDao.getById(1).getTitle());
}
@ -114,8 +111,8 @@ public class GtasksListServiceTest extends InjectingTestCase {
@Test
public void testNewListNeedsUpdate() {
TaskList taskList = new TaskList().setId("1").setTitle("Default")
.setUpdated(new DateTime(currentTimeMillis()));
TaskList taskList =
new TaskList().setId("1").setTitle("Default").setUpdated(new DateTime(currentTimeMillis()));
setLists(taskList);

@ -1,9 +1,8 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
* <p>See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.gtasks;
import static android.support.test.InstrumentationRegistry.getTargetContext;
@ -37,9 +36,7 @@ public class GtasksMetadataServiceTest extends InjectingTestCase {
@Override
protected void inject(TestComponent component) {
component
.plus(new GtasksMetadataServiceTestModule(getTargetContext()))
.inject(this);
component.plus(new GtasksMetadataServiceTestModule(getTargetContext())).inject(this);
}
@Test

@ -1,9 +1,8 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
* <p>See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.gtasks;
import static junit.framework.Assert.assertEquals;
@ -110,8 +109,10 @@ public class GtasksTaskListUpdaterTest extends InjectingTestCase {
if (expectedParent == null) {
assertEquals("Task " + task.getTitle() + " parent none", 0, parent);
} else {
assertEquals("Task " + task.getTitle() + " parent " +
expectedParent.getTitle(), expectedParent.getId(), parent);
assertEquals(
"Task " + task.getTitle() + " parent " + expectedParent.getTitle(),
expectedParent.getId(),
parent);
}
}
@ -120,8 +121,10 @@ public class GtasksTaskListUpdaterTest extends InjectingTestCase {
if (expectedSibling == null) {
assertEquals("Task " + task.getTitle() + " sibling null", 0L, sibling);
} else {
assertEquals("Task " + task.getTitle() + " sibling " +
expectedSibling.getTitle(), expectedSibling.getId(), sibling);
assertEquals(
"Task " + task.getTitle() + " sibling " + expectedSibling.getTitle(),
expectedSibling.getId(),
sibling);
}
}
@ -130,8 +133,10 @@ public class GtasksTaskListUpdaterTest extends InjectingTestCase {
if (expectedParent == null) {
assertEquals("Task " + task.getTitle() + " parent null", 0L, parent);
} else {
assertEquals("Task " + task.getTitle() + " parent " +
expectedParent.getTitle(), expectedParent.getId(), parent);
assertEquals(
"Task " + task.getTitle() + " parent " + expectedParent.getTitle(),
expectedParent.getId(),
parent);
}
}
@ -162,24 +167,21 @@ public class GtasksTaskListUpdaterTest extends InjectingTestCase {
}
}
/**
* A
* B
* C
* D
* E
*/
// A
// B
// C
// D
// E
private Task[] givenTasksABCDE() {
return new Task[]{
createTask("A", 0, 0),
createTask("B", 1, 1),
createTask("C", 2, 1),
createTask("D", 3, 2),
createTask("E", 4, 0),
return new Task[] {
createTask("A", 0, 0),
createTask("B", 1, 1),
createTask("C", 2, 1),
createTask("D", 3, 2),
createTask("E", 4, 0),
};
}
private Task createTask(String title, long order, int indent) {
Task task = new Task();
task.setTitle(title);

@ -1,9 +1,8 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
* <p>See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.gtasks;
import static junit.framework.Assert.assertEquals;
@ -245,9 +244,7 @@ public class GtasksTaskMovingTest extends InjectingTestCase {
// --- helpers
/**
* moveTo = null => move to end
*/
/** moveTo = null => move to end */
private void whenTriggerMove(Task target, Task moveTo) {
gtasksTaskListUpdater.moveTo(list, target.getId(), moveTo == null ? -1 : moveTo.getId());
}
@ -278,14 +275,12 @@ public class GtasksTaskMovingTest extends InjectingTestCase {
component.inject(this);
}
/**
* A
* B
* C
* D
* E
* F
*/
// A
// B
// C
// D
// E
// F
private void givenTasksABCDEF() {
A = createTask("A", 0, 0);
B = createTask("B", 1, 1);

@ -1,9 +1,8 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
* <p>See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.gtasks;
import org.tasks.preferences.Preferences;

@ -65,8 +65,7 @@ public class GtasksApiUtilitiesTest {
TimeZone.getTimeZone("GMT"));
assertEquals(
new DateTime(2014, 1, 8, 6, 0, 0, 0).getMillis(),
gtasksDueTimeToUnixTime(googleDueDate));
new DateTime(2014, 1, 8, 6, 0, 0, 0).getMillis(), gtasksDueTimeToUnixTime(googleDueDate));
}
@Test

@ -25,9 +25,7 @@ public class GoogleTaskSynchronizerTest {
mergeDates(newTask(with(DUE_DATE, new DateTime(2016, 3, 11))).getDueDate(), local);
assertEquals(
new DateTime(2016, 3, 11, 12, 0).getMillis(),
local.getDueDate().longValue());
assertEquals(new DateTime(2016, 3, 11, 12, 0).getMillis(), local.getDueDate().longValue());
}
@Test
@ -36,63 +34,59 @@ public class GoogleTaskSynchronizerTest {
mergeDates(newTask(with(DUE_DATE, new DateTime(2016, 3, 11))).getDueDate(), local);
assertEquals(
new DateTime(2016, 3, 11, 13, 30, 1).getMillis(),
local.getDueDate().longValue());
assertEquals(new DateTime(2016, 3, 11, 13, 30, 1).getMillis(), local.getDueDate().longValue());
}
@Test
public void testDueDateAdjustHideBackwards() {
Task local = newTask(with(DUE_DATE, new DateTime(2016, 3, 12)),
with(HIDE_TYPE, HIDE_UNTIL_DUE));
Task local =
newTask(with(DUE_DATE, new DateTime(2016, 3, 12)), with(HIDE_TYPE, HIDE_UNTIL_DUE));
mergeDates(newTask(with(DUE_DATE, new DateTime(2016, 3, 11))).getDueDate(), local);
assertEquals(
new DateTime(2016, 3, 11).getMillis(),
local.getHideUntil().longValue());
assertEquals(new DateTime(2016, 3, 11).getMillis(), local.getHideUntil().longValue());
}
@Test
public void testDueDateAdjustHideForwards() {
Task local = newTask(with(DUE_DATE, new DateTime(2016, 3, 12)),
with(HIDE_TYPE, HIDE_UNTIL_DUE));
Task local =
newTask(with(DUE_DATE, new DateTime(2016, 3, 12)), with(HIDE_TYPE, HIDE_UNTIL_DUE));
mergeDates(newTask(with(DUE_DATE, new DateTime(2016, 3, 14))).getDueDate(), local);
assertEquals(
new DateTime(2016, 3, 14).getMillis(),
local.getHideUntil().longValue());
assertEquals(new DateTime(2016, 3, 14).getMillis(), local.getHideUntil().longValue());
}
@Test
public void testDueTimeAdjustHideBackwards() {
Task local = newTask(with(DUE_TIME, new DateTime(2016, 3, 12, 13, 30)),
with(HIDE_TYPE, HIDE_UNTIL_DUE_TIME));
Task local =
newTask(
with(DUE_TIME, new DateTime(2016, 3, 12, 13, 30)),
with(HIDE_TYPE, HIDE_UNTIL_DUE_TIME));
mergeDates(newTask(with(DUE_DATE, new DateTime(2016, 3, 11))).getDueDate(), local);
assertEquals(
new DateTime(2016, 3, 11, 13, 30, 1).getMillis(),
local.getHideUntil().longValue());
new DateTime(2016, 3, 11, 13, 30, 1).getMillis(), local.getHideUntil().longValue());
}
@Test
public void testDueTimeAdjustTimeForwards() {
Task local = newTask(with(DUE_TIME, new DateTime(2016, 3, 12, 13, 30)),
with(HIDE_TYPE, HIDE_UNTIL_DUE_TIME));
Task local =
newTask(
with(DUE_TIME, new DateTime(2016, 3, 12, 13, 30)),
with(HIDE_TYPE, HIDE_UNTIL_DUE_TIME));
mergeDates(newTask(with(DUE_DATE, new DateTime(2016, 3, 14))).getDueDate(), local);
assertEquals(
new DateTime(2016, 3, 14, 13, 30, 1).getMillis(),
local.getHideUntil().longValue());
new DateTime(2016, 3, 14, 13, 30, 1).getMillis(), local.getHideUntil().longValue());
}
@Test
public void testDueDateClearHide() {
Task local = newTask(with(DUE_DATE, new DateTime(2016, 3, 12)),
with(HIDE_TYPE, HIDE_UNTIL_DUE));
Task local =
newTask(with(DUE_DATE, new DateTime(2016, 3, 12)), with(HIDE_TYPE, HIDE_UNTIL_DUE));
mergeDates(newTask().getDueDate(), local);
@ -101,8 +95,10 @@ public class GoogleTaskSynchronizerTest {
@Test
public void testDueTimeClearHide() {
Task local = newTask(with(DUE_TIME, new DateTime(2016, 3, 12, 13, 30)),
with(HIDE_TYPE, HIDE_UNTIL_DUE_TIME));
Task local =
newTask(
with(DUE_TIME, new DateTime(2016, 3, 12, 13, 30)),
with(HIDE_TYPE, HIDE_UNTIL_DUE_TIME));
mergeDates(newTask().getDueDate(), local);

@ -14,10 +14,12 @@ public class RemoteGtaskListMaker {
public static final Property<TaskList, String> REMOTE_ID = newProperty();
public static final Property<TaskList, String> NAME = newProperty();
private static final Instantiator<TaskList> instantiator = lookup -> new TaskList()
.setId(lookup.valueOf(REMOTE_ID, "1"))
.setTitle(lookup.valueOf(NAME, "Default"))
.setUpdated(new DateTime(currentTimeMillis()));
private static final Instantiator<TaskList> instantiator =
lookup ->
new TaskList()
.setId(lookup.valueOf(REMOTE_ID, "1"))
.setTitle(lookup.valueOf(NAME, "Default"))
.setUpdated(new DateTime(currentTimeMillis()));
public static TaskList newRemoteList(PropertyValue<? super TaskList, ?>... properties) {
return make(instantiator, properties);

@ -2,6 +2,4 @@ package org.tasks;
import android.support.multidex.MultiDexApplication;
public abstract class BaseApplication extends MultiDexApplication {
}
public abstract class BaseApplication extends MultiDexApplication {}

@ -32,17 +32,19 @@ public class BuildSetup {
}
LeakCanary.install(application);
if (preferences.getBoolean(R.string.p_strict_mode, false)) {
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.detectDiskReads()
.detectDiskWrites()
.detectNetwork()
.penaltyLog()
.build());
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
.detectLeakedSqlLiteObjects()
.detectLeakedClosableObjects()
.penaltyLog()
.build());
StrictMode.setThreadPolicy(
new StrictMode.ThreadPolicy.Builder()
.detectDiskReads()
.detectDiskWrites()
.detectNetwork()
.penaltyLog()
.build());
StrictMode.setVmPolicy(
new StrictMode.VmPolicy.Builder()
.detectLeakedSqlLiteObjects()
.detectLeakedClosableObjects()
.penaltyLog()
.build());
}
return true;
}

@ -5,9 +5,7 @@ import javax.inject.Inject;
public class FlavorSetup {
@Inject
public FlavorSetup() {
}
public FlavorSetup() {}
public void setup() {
}
public void setup() {}
}

@ -6,13 +6,9 @@ import timber.log.Timber;
public class Tracker {
@Inject
public Tracker() {
public Tracker() {}
}
public void setTrackingEnabled(boolean enabled) {
}
public void setTrackingEnabled(boolean enabled) {}
public void reportException(Throwable t) {
Timber.e(t, t.getMessage());
@ -22,19 +18,11 @@ public class Tracker {
Timber.e(t, t.getMessage());
}
public void reportEvent(Tracking.Events event) {
}
public void reportEvent(Tracking.Events event, String string) {
}
public void reportEvent(Tracking.Events setPreference, int resId, String s) {
public void reportEvent(Tracking.Events event) {}
}
public void reportEvent(Tracking.Events event, String string) {}
public void reportEvent(Tracking.Events category, String action, String label) {
public void reportEvent(Tracking.Events setPreference, int resId, String s) {}
}
public void reportEvent(Tracking.Events category, String action, String label) {}
}

@ -14,24 +14,21 @@ public class PurchaseHelper {
this.preferences = preferences;
}
public boolean purchase(final Activity activity,
final String sku, final String pref,
final int requestCode, final PurchaseHelperCallback callback) {
public boolean purchase(
final Activity activity,
final String sku,
final String pref,
final int requestCode,
final PurchaseHelperCallback callback) {
preferences.setBoolean(pref, true);
callback.purchaseCompleted(true, sku);
return true;
}
public void handleActivityResult(PurchaseHelperCallback callback, int requestCode, int resultCode,
Intent data) {
public void handleActivityResult(
PurchaseHelperCallback callback, int requestCode, int resultCode, Intent data) {}
}
public void disposeIabHelper() {
}
public void consumePurchases() {
public void disposeIabHelper() {}
}
public void consumePurchases() {}
}

@ -8,9 +8,7 @@ import javax.inject.Inject;
public class PlayServices {
@Inject
public PlayServices() {
}
public PlayServices() {}
public boolean isPlayServicesAvailable() {
return false;
@ -20,9 +18,7 @@ public class PlayServices {
return false;
}
public void resolve(Activity activity) {
}
public void resolve(Activity activity) {}
public String getStatus() {
return null;
@ -32,8 +28,8 @@ public class PlayServices {
return false;
}
public void getAuthToken(GtasksLoginActivity gtasksLoginActivity, String a,
GtasksLoginActivity.AuthResultHandler authResultHandler) {
}
public void getAuthToken(
GtasksLoginActivity gtasksLoginActivity,
String a,
GtasksLoginActivity.AuthResultHandler authResultHandler) {}
}

@ -8,19 +8,11 @@ import org.tasks.data.Location;
public class GeofenceApi {
@Inject
public GeofenceApi() {
public GeofenceApi() {}
}
public void register(List<Location> activeGeofences) {}
public void register(List<Location> activeGeofences) {
public void cancel(Location geofence) {}
}
public void cancel(Location geofence) {
}
public void cancel(List<Location> geofences) {
}
public void cancel(List<Location> geofences) {}
}

@ -1,5 +1,3 @@
package org.tasks.location;
public class GeofenceTransitionsIntentService {
}
public class GeofenceTransitionsIntentService {}

@ -20,24 +20,20 @@ import android.content.Context;
import android.content.Intent;
/**
* Receiver for the "com.android.vending.billing.PURCHASES_UPDATED" Action
* from the Play Store.
* Receiver for the "com.android.vending.billing.PURCHASES_UPDATED" Action from the Play Store.
*
* <p>It is possible that an in-app item may be acquired without the
* application calling getBuyIntent(), for example if the item can be
* redeemed from inside the Play Store using a promotional code. If this
* application isn't running at the time, then when it is started a call
* to getPurchases() will be sufficient notification. However, if the
* application is already running in the background when the item is acquired,
* a message to this BroadcastReceiver will indicate that the an item
* has been acquired.</p>
* <p>It is possible that an in-app item may be acquired without the application calling
* getBuyIntent(), for example if the item can be redeemed from inside the Play Store using a
* promotional code. If this application isn't running at the time, then when it is started a call
* to getPurchases() will be sufficient notification. However, if the application is already running
* in the background when the item is acquired, a message to this BroadcastReceiver will indicate
* that the an item has been acquired.
*/
public class IabBroadcastReceiver extends BroadcastReceiver {
/**
* The Intent action that this Receiver should filter for.
*/
/** The Intent action that this Receiver should filter for. */
public static final String ACTION = "com.android.vending.billing.PURCHASES_UPDATED";
private final IabBroadcastListener mListener;
public IabBroadcastReceiver(IabBroadcastListener listener) {
@ -51,9 +47,7 @@ public class IabBroadcastReceiver extends BroadcastReceiver {
}
}
/**
* Listener interface for received broadcast messages.
*/
/** Listener interface for received broadcast messages. */
public interface IabBroadcastListener {
void receivedBroadcast();

@ -16,10 +16,9 @@
package com.android.vending.billing;
/**
* Exception thrown when something went wrong with in-app billing.
* An IabException has an associated IabResult (an error).
* To get the IAB result that caused this exception to be thrown,
* call {@link #getResult()}.
* Exception thrown when something went wrong with in-app billing. An IabException has an associated
* IabResult (an error). To get the IAB result that caused this exception to be thrown, call {@link
* #getResult()}.
*/
@SuppressWarnings("ALL")
public class IabException extends Exception {
@ -43,10 +42,8 @@ public class IabException extends Exception {
this(new IabResult(response, message), cause);
}
/**
* Returns the IAB result (error) that this exception signals.
*/
/** Returns the IAB result (error) that this exception signals. */
public IabResult getResult() {
return mResult;
}
}
}

@ -35,35 +35,29 @@ import java.util.List;
import java.util.concurrent.Executor;
import org.json.JSONException;
/**
* Provides convenience methods for in-app billing. You can create one instance of this
* class for your application and use it to process in-app billing operations.
* It provides synchronous (blocking) and asynchronous (non-blocking) methods for
* many common in-app billing operations, as well as automatic signature
* verification.
* Provides convenience methods for in-app billing. You can create one instance of this class for
* your application and use it to process in-app billing operations. It provides synchronous
* (blocking) and asynchronous (non-blocking) methods for many common in-app billing operations, as
* well as automatic signature verification.
*
* After instantiating, you must perform setup in order to start using the object.
* To perform setup, call the {@link #startSetup} method and provide a listener;
* that listener will be notified when setup is complete, after which (and not before)
* you may call other methods.
* <p>After instantiating, you must perform setup in order to start using the object. To perform
* setup, call the {@link #startSetup} method and provide a listener; that listener will be notified
* when setup is complete, after which (and not before) you may call other methods.
*
* After setup is complete, you will typically want to request an inventory of owned
* items and subscriptions. See {@link #queryInventory}, {@link #queryInventoryAsync}
* and related methods.
* <p>After setup is complete, you will typically want to request an inventory of owned items and
* subscriptions. See {@link #queryInventory}, {@link #queryInventoryAsync} and related methods.
*
* When you are done with this object, don't forget to call {@link #dispose}
* to ensure proper cleanup. This object holds a binding to the in-app billing
* service, which will leak unless you dispose of it correctly. If you created
* the object on an Activity's onCreate method, then the recommended
* place to dispose of it is the Activity's onDestroy method.
* <p>When you are done with this object, don't forget to call {@link #dispose} to ensure proper
* cleanup. This object holds a binding to the in-app billing service, which will leak unless you
* dispose of it correctly. If you created the object on an Activity's onCreate method, then the
* recommended place to dispose of it is the Activity's onDestroy method.
*
* A note about threading: When using this object from a background thread, you may
* call the blocking versions of methods; when using from a UI thread, call
* only the asynchronous versions and handle the results via callbacks.
* Also, notice that you can only call one asynchronous operation at a time;
* attempting to start a second asynchronous operation while the first one
* has not yet completed will result in an exception being thrown.
* <p>A note about threading: When using this object from a background thread, you may call the
* blocking versions of methods; when using from a UI thread, call only the asynchronous versions
* and handle the results via callbacks. Also, notice that you can only call one asynchronous
* operation at a time; attempting to start a second asynchronous operation while the first one has
* not yet completed will result in an exception being thrown.
*/
@SuppressWarnings("ALL")
@SuppressLint("all")
@ -142,15 +136,15 @@ public class IabHelper {
OnIabPurchaseFinishedListener mPurchaseListener;
/**
* Creates an instance. After creation, it will not yet be ready to use. You must perform
* setup by calling {@link #startSetup} and wait for setup to complete. This constructor does not
* block and is safe to call from a UI thread.
* Creates an instance. After creation, it will not yet be ready to use. You must perform setup by
* calling {@link #startSetup} and wait for setup to complete. This constructor does not block and
* is safe to call from a UI thread.
*
* @param ctx Your application or Activity context. Needed to bind to the in-app billing service.
* @param base64PublicKey Your application's public key, encoded in base64. This is used for
* verification of purchase signatures. You can find your app's base64-encoded public key in your
* application's page on Google Play Developer Console. Note that this is NOT your "developer
* public key".
* verification of purchase signatures. You can find your app's base64-encoded public key in
* your application's page on Google Play Developer Console. Note that this is NOT your
* "developer public key".
*/
public IabHelper(Context ctx, String base64PublicKey, Executor executor) {
mContext = ctx.getApplicationContext();
@ -164,23 +158,27 @@ public class IabHelper {
*
* @param code The response code
* @return A human-readable string explaining the result code. It also includes the result code
* numerically.
* numerically.
*/
public static String getResponseDesc(int code) {
String[] iab_msgs = ("0:OK/1:User Canceled/2:Unknown/" +
"3:Billing Unavailable/4:Item unavailable/" +
"5:Developer Error/6:Error/7:Item Already Owned/" +
"8:Item not owned").split("/");
String[] iabhelper_msgs = ("0:OK/-1001:Remote exception during initialization/" +
"-1002:Bad response received/" +
"-1003:Purchase signature verification failed/" +
"-1004:Send intent failed/" +
"-1005:User cancelled/" +
"-1006:Unknown purchase response/" +
"-1007:Missing token/" +
"-1008:Unknown error/" +
"-1009:Subscriptions not available/" +
"-1010:Invalid consumption attempt").split("/");
String[] iab_msgs =
("0:OK/1:User Canceled/2:Unknown/"
+ "3:Billing Unavailable/4:Item unavailable/"
+ "5:Developer Error/6:Error/7:Item Already Owned/"
+ "8:Item not owned")
.split("/");
String[] iabhelper_msgs =
("0:OK/-1001:Remote exception during initialization/"
+ "-1002:Bad response received/"
+ "-1003:Purchase signature verification failed/"
+ "-1004:Send intent failed/"
+ "-1005:User cancelled/"
+ "-1006:Unknown purchase response/"
+ "-1007:Missing token/"
+ "-1008:Unknown error/"
+ "-1009:Subscriptions not available/"
+ "-1010:Invalid consumption attempt")
.split("/");
if (code <= IABHELPER_ERROR_BASE) {
int index = IABHELPER_ERROR_BASE - code;
@ -196,9 +194,7 @@ public class IabHelper {
}
}
/**
* Enables or disable debug logging through LogCat.
*/
/** Enables or disable debug logging through LogCat. */
public void enableDebugLogging(boolean enable, String tag) {
checkNotDisposed();
mDebugLog = enable;
@ -211,9 +207,9 @@ public class IabHelper {
}
/**
* Starts the setup process. This will start up the setup process asynchronously.
* You will be notified through the listener when the setup process is complete.
* This method is safe to call from a UI thread.
* Starts the setup process. This will start up the setup process asynchronously. You will be
* notified through the listener when the setup process is complete. This method is safe to call
* from a UI thread.
*
* @param listener The listener to notify when the setup process is complete.
*/
@ -226,87 +222,90 @@ public class IabHelper {
// Connection to IAB service
logDebug("Starting in-app billing setup.");
mServiceConn = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
logDebug("Billing service disconnected.");
mService = null;
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
if (mDisposed) {
return;
}
logDebug("Billing service connected.");
mService = IInAppBillingService.Stub.asInterface(service);
String packageName = mContext.getPackageName();
try {
logDebug("Checking for in-app billing 3 support.");
// check for in-app billing v3 support
int response = mService.isBillingSupported(3, packageName, ITEM_TYPE_INAPP);
if (response != BILLING_RESPONSE_RESULT_OK) {
if (listener != null) {
listener.onIabSetupFinished(new IabResult(response,
"Error checking for billing v3 support."));
}
// if in-app purchases aren't supported, neither are subscriptions
mSubscriptionsSupported = false;
mSubscriptionUpdateSupported = false;
return;
} else {
logDebug("In-app billing version 3 supported for " + packageName);
mServiceConn =
new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
logDebug("Billing service disconnected.");
mService = null;
}
// Check for v5 subscriptions support. This is needed for
// getBuyIntentToReplaceSku which allows for subscription update
response = mService.isBillingSupported(5, packageName, ITEM_TYPE_SUBS);
if (response == BILLING_RESPONSE_RESULT_OK) {
logDebug("Subscription re-signup AVAILABLE.");
mSubscriptionUpdateSupported = true;
} else {
logDebug("Subscription re-signup not available.");
mSubscriptionUpdateSupported = false;
}
if (mSubscriptionUpdateSupported) {
mSubscriptionsSupported = true;
} else {
// check for v3 subscriptions support
response = mService.isBillingSupported(3, packageName, ITEM_TYPE_SUBS);
if (response == BILLING_RESPONSE_RESULT_OK) {
logDebug("Subscriptions AVAILABLE.");
mSubscriptionsSupported = true;
} else {
logDebug("Subscriptions NOT AVAILABLE. Response: " + response);
mSubscriptionsSupported = false;
mSubscriptionUpdateSupported = false;
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
if (mDisposed) {
return;
}
logDebug("Billing service connected.");
mService = IInAppBillingService.Stub.asInterface(service);
String packageName = mContext.getPackageName();
try {
logDebug("Checking for in-app billing 3 support.");
// check for in-app billing v3 support
int response = mService.isBillingSupported(3, packageName, ITEM_TYPE_INAPP);
if (response != BILLING_RESPONSE_RESULT_OK) {
if (listener != null) {
listener.onIabSetupFinished(
new IabResult(response, "Error checking for billing v3 support."));
}
// if in-app purchases aren't supported, neither are subscriptions
mSubscriptionsSupported = false;
mSubscriptionUpdateSupported = false;
return;
} else {
logDebug("In-app billing version 3 supported for " + packageName);
}
// Check for v5 subscriptions support. This is needed for
// getBuyIntentToReplaceSku which allows for subscription update
response = mService.isBillingSupported(5, packageName, ITEM_TYPE_SUBS);
if (response == BILLING_RESPONSE_RESULT_OK) {
logDebug("Subscription re-signup AVAILABLE.");
mSubscriptionUpdateSupported = true;
} else {
logDebug("Subscription re-signup not available.");
mSubscriptionUpdateSupported = false;
}
if (mSubscriptionUpdateSupported) {
mSubscriptionsSupported = true;
} else {
// check for v3 subscriptions support
response = mService.isBillingSupported(3, packageName, ITEM_TYPE_SUBS);
if (response == BILLING_RESPONSE_RESULT_OK) {
logDebug("Subscriptions AVAILABLE.");
mSubscriptionsSupported = true;
} else {
logDebug("Subscriptions NOT AVAILABLE. Response: " + response);
mSubscriptionsSupported = false;
mSubscriptionUpdateSupported = false;
}
}
mSetupDone = true;
} catch (RemoteException e) {
if (listener != null) {
listener.onIabSetupFinished(
new IabResult(
IABHELPER_REMOTE_EXCEPTION,
"RemoteException while setting up in-app billing."));
}
e.printStackTrace();
return;
}
}
mSetupDone = true;
} catch (RemoteException e) {
if (listener != null) {
listener.onIabSetupFinished(new IabResult(IABHELPER_REMOTE_EXCEPTION,
"RemoteException while setting up in-app billing."));
if (listener != null) {
listener.onIabSetupFinished(
new IabResult(BILLING_RESPONSE_RESULT_OK, "Setup successful."));
}
}
e.printStackTrace();
return;
}
if (listener != null) {
listener
.onIabSetupFinished(new IabResult(BILLING_RESPONSE_RESULT_OK, "Setup successful."));
}
}
};
};
Intent serviceIntent = new Intent("com.android.vending.billing.InAppBillingService.BIND");
serviceIntent.setPackage("com.android.vending");
List<ResolveInfo> intentServices = mContext.getPackageManager()
.queryIntentServices(serviceIntent, 0);
List<ResolveInfo> intentServices =
mContext.getPackageManager().queryIntentServices(serviceIntent, 0);
if (intentServices != null && !intentServices.isEmpty()) {
// service available to handle that Intent
mContext.bindService(serviceIntent, mServiceConn, Context.BIND_AUTO_CREATE);
@ -314,17 +313,17 @@ public class IabHelper {
// no service available to handle that Intent
if (listener != null) {
listener.onIabSetupFinished(
new IabResult(BILLING_RESPONSE_RESULT_BILLING_UNAVAILABLE,
new IabResult(
BILLING_RESPONSE_RESULT_BILLING_UNAVAILABLE,
"Billing service unavailable on device."));
}
}
}
/**
* Dispose of object, releasing resources. It's very important to call this
* method when you are done with this object. It will release any resources
* used by it such as service connections. Naturally, once the object is
* disposed of, it can't be used again.
* Dispose of object, releasing resources. It's very important to call this method when you are
* done with this object. It will release any resources used by it such as service connections.
* Naturally, once the object is disposed of, it can't be used again.
*/
public void dispose() {
logDebug("Disposing.");
@ -348,64 +347,76 @@ public class IabHelper {
}
}
/**
* Returns whether subscriptions are supported.
*/
/** Returns whether subscriptions are supported. */
public boolean subscriptionsSupported() {
checkNotDisposed();
return mSubscriptionsSupported;
}
public void launchPurchaseFlow(Activity act, String sku, int requestCode,
OnIabPurchaseFinishedListener listener) {
public void launchPurchaseFlow(
Activity act, String sku, int requestCode, OnIabPurchaseFinishedListener listener) {
launchPurchaseFlow(act, sku, requestCode, listener, "");
}
public void launchPurchaseFlow(Activity act, String sku, int requestCode,
OnIabPurchaseFinishedListener listener, String extraData) {
public void launchPurchaseFlow(
Activity act,
String sku,
int requestCode,
OnIabPurchaseFinishedListener listener,
String extraData) {
launchPurchaseFlow(act, sku, ITEM_TYPE_INAPP, null, requestCode, listener, extraData);
}
public void launchSubscriptionPurchaseFlow(Activity act, String sku, int requestCode,
OnIabPurchaseFinishedListener listener) {
public void launchSubscriptionPurchaseFlow(
Activity act, String sku, int requestCode, OnIabPurchaseFinishedListener listener) {
launchSubscriptionPurchaseFlow(act, sku, requestCode, listener, "");
}
public void launchSubscriptionPurchaseFlow(Activity act, String sku, int requestCode,
OnIabPurchaseFinishedListener listener, String extraData) {
public void launchSubscriptionPurchaseFlow(
Activity act,
String sku,
int requestCode,
OnIabPurchaseFinishedListener listener,
String extraData) {
launchPurchaseFlow(act, sku, ITEM_TYPE_SUBS, null, requestCode, listener, extraData);
}
/**
* Initiate the UI flow for an in-app purchase. Call this method to initiate an in-app purchase,
* which will involve bringing up the Google Play screen. The calling activity will be paused
* while the user interacts with Google Play, and the result will be delivered via the
* activity's {@link android.app.Activity#onActivityResult} method, at which point you must call
* this object's {@link #handleActivityResult} method to continue the purchase flow. This method
* MUST be called from the UI thread of the Activity.
* while the user interacts with Google Play, and the result will be delivered via the activity's
* {@link android.app.Activity#onActivityResult} method, at which point you must call this
* object's {@link #handleActivityResult} method to continue the purchase flow. This method MUST
* be called from the UI thread of the Activity.
*
* @param act The calling activity.
* @param sku The sku of the item to purchase.
* @param itemType indicates if it's a product or a subscription (ITEM_TYPE_INAPP or
* ITEM_TYPE_SUBS)
* ITEM_TYPE_SUBS)
* @param oldSkus A list of SKUs which the new SKU is replacing or null if there are none
* @param requestCode A request code (to differentiate from other responses -- as in {@link
* android.app.Activity#startActivityForResult}).
* android.app.Activity#startActivityForResult}).
* @param listener The listener to notify when the purchase process finishes
* @param extraData Extra data (developer payload), which will be returned with the purchase data
* when the purchase completes. This extra data will be permanently bound to that purchase and
* will always be returned when the purchase is queried.
* when the purchase completes. This extra data will be permanently bound to that purchase and
* will always be returned when the purchase is queried.
*/
public void launchPurchaseFlow(Activity act, String sku, String itemType, List<String> oldSkus,
int requestCode, OnIabPurchaseFinishedListener listener, String extraData) {
public void launchPurchaseFlow(
Activity act,
String sku,
String itemType,
List<String> oldSkus,
int requestCode,
OnIabPurchaseFinishedListener listener,
String extraData) {
checkNotDisposed();
checkSetupDone("launchPurchaseFlow");
flagStartAsync("launchPurchaseFlow");
IabResult result;
if (itemType.equals(ITEM_TYPE_SUBS) && !mSubscriptionsSupported) {
IabResult r = new IabResult(IABHELPER_SUBSCRIPTIONS_NOT_AVAILABLE,
"Subscriptions are not available.");
IabResult r =
new IabResult(IABHELPER_SUBSCRIPTIONS_NOT_AVAILABLE, "Subscriptions are not available.");
flagEndAsync();
if (listener != null) {
listener.onIabPurchaseFinished(r, null);
@ -418,21 +429,24 @@ public class IabHelper {
Bundle buyIntentBundle;
if (oldSkus == null || oldSkus.isEmpty()) {
// Purchasing a new item or subscription re-signup
buyIntentBundle = mService.getBuyIntent(3, mContext.getPackageName(), sku, itemType,
extraData);
buyIntentBundle =
mService.getBuyIntent(3, mContext.getPackageName(), sku, itemType, extraData);
} else {
// Subscription upgrade/downgrade
if (!mSubscriptionUpdateSupported) {
IabResult r = new IabResult(IABHELPER_SUBSCRIPTION_UPDATE_NOT_AVAILABLE,
"Subscription updates are not available.");
IabResult r =
new IabResult(
IABHELPER_SUBSCRIPTION_UPDATE_NOT_AVAILABLE,
"Subscription updates are not available.");
flagEndAsync();
if (listener != null) {
listener.onIabPurchaseFinished(r, null);
}
return;
}
buyIntentBundle = mService.getBuyIntentToReplaceSkus(5, mContext.getPackageName(),
oldSkus, sku, itemType, extraData);
buyIntentBundle =
mService.getBuyIntentToReplaceSkus(
5, mContext.getPackageName(), oldSkus, sku, itemType, extraData);
}
int response = getResponseCodeFromBundle(buyIntentBundle);
if (response != BILLING_RESPONSE_RESULT_OK) {
@ -450,9 +464,12 @@ public class IabHelper {
mRequestCode = requestCode;
mPurchaseListener = listener;
mPurchasingItemType = itemType;
act.startIntentSenderForResult(pendingIntent.getIntentSender(),
requestCode, new Intent(),
Integer.valueOf(0), Integer.valueOf(0),
act.startIntentSenderForResult(
pendingIntent.getIntentSender(),
requestCode,
new Intent(),
Integer.valueOf(0),
Integer.valueOf(0),
Integer.valueOf(0));
} catch (SendIntentException e) {
logError("SendIntentException while launching purchase flow for sku " + sku);
@ -468,8 +485,9 @@ public class IabHelper {
e.printStackTrace();
flagEndAsync();
result = new IabResult(IABHELPER_REMOTE_EXCEPTION,
"Remote exception while starting purchase flow");
result =
new IabResult(
IABHELPER_REMOTE_EXCEPTION, "Remote exception while starting purchase flow");
if (listener != null) {
listener.onIabPurchaseFinished(result, null);
}
@ -477,16 +495,16 @@ public class IabHelper {
}
/**
* Handles an activity result that's part of the purchase flow in in-app billing. If you
* are calling {@link #launchPurchaseFlow}, then you must call this method from your
* Activity's {@link android.app.Activity@onActivityResult} method. This method
* MUST be called from the UI thread of the Activity.
* Handles an activity result that's part of the purchase flow in in-app billing. If you are
* calling {@link #launchPurchaseFlow}, then you must call this method from your Activity's {@link
* android.app.Activity@onActivityResult} method. This method MUST be called from the UI thread of
* the Activity.
*
* @param requestCode The requestCode as you received it.
* @param resultCode The resultCode as you received it.
* @param data The data (Intent) as you received it.
* @return Returns true if the result was related to a purchase flow and was handled; false if the
* result was not related to a purchase, in which case you should handle it normally.
* result was not related to a purchase, in which case you should handle it normally.
*/
public boolean handleActivityResult(int requestCode, int resultCode, Intent data) {
IabResult result;
@ -523,8 +541,9 @@ public class IabHelper {
if (purchaseData == null || dataSignature == null) {
logError("BUG: either purchaseData or dataSignature is null.");
logDebug("Extras: " + data.getExtras().toString());
result = new IabResult(IABHELPER_UNKNOWN_ERROR,
"IAB returned null purchaseData or dataSignature");
result =
new IabResult(
IABHELPER_UNKNOWN_ERROR, "IAB returned null purchaseData or dataSignature");
if (mPurchaseListener != null) {
mPurchaseListener.onIabPurchaseFinished(result, null);
}
@ -539,8 +558,9 @@ public class IabHelper {
// Verify signature
if (!Security.verifyPurchase(mSignatureBase64, purchaseData, dataSignature)) {
logError("Purchase signature verification FAILED for sku " + sku);
result = new IabResult(IABHELPER_VERIFICATION_FAILED,
"Signature verification failed for sku " + sku);
result =
new IabResult(
IABHELPER_VERIFICATION_FAILED, "Signature verification failed for sku " + sku);
if (mPurchaseListener != null) {
mPurchaseListener.onIabPurchaseFinished(result, purchase);
}
@ -558,13 +578,14 @@ public class IabHelper {
}
if (mPurchaseListener != null) {
mPurchaseListener
.onIabPurchaseFinished(new IabResult(BILLING_RESPONSE_RESULT_OK, "Success"), purchase);
mPurchaseListener.onIabPurchaseFinished(
new IabResult(BILLING_RESPONSE_RESULT_OK, "Success"), purchase);
}
} else if (resultCode == Activity.RESULT_OK) {
// result code was OK, but in-app billing response was not OK.
logDebug("Result code was OK but in-app billing response was not OK: " + getResponseDesc(
responseCode));
logDebug(
"Result code was OK but in-app billing response was not OK: "
+ getResponseDesc(responseCode));
if (mPurchaseListener != null) {
result = new IabResult(responseCode, "Problem purchashing item.");
mPurchaseListener.onIabPurchaseFinished(result, null);
@ -576,8 +597,11 @@ public class IabHelper {
mPurchaseListener.onIabPurchaseFinished(result, null);
}
} else {
logError("Purchase failed. Result code: " + Integer.toString(resultCode)
+ ". Response: " + getResponseDesc(responseCode));
logError(
"Purchase failed. Result code: "
+ Integer.toString(resultCode)
+ ". Response: "
+ getResponseDesc(responseCode));
result = new IabResult(IABHELPER_UNKNOWN_PURCHASE_RESPONSE, "Unknown purchase response.");
if (mPurchaseListener != null) {
mPurchaseListener.onIabPurchaseFinished(result, null);
@ -597,15 +621,16 @@ public class IabHelper {
* from a UI thread. For that, use the non-blocking version {@link #queryInventoryAsync}.
*
* @param querySkuDetails if true, SKU details (price, description, etc) will be queried as well
* as purchase information.
* as purchase information.
* @param moreItemSkus additional PRODUCT skus to query information on, regardless of ownership.
* Ignored if null or if querySkuDetails is false.
* Ignored if null or if querySkuDetails is false.
* @param moreSubsSkus additional SUBSCRIPTIONS skus to query information on, regardless of
* ownership. Ignored if null or if querySkuDetails is false.
* ownership. Ignored if null or if querySkuDetails is false.
* @throws IabException if a problem occurs while refreshing the inventory.
*/
public Inventory queryInventory(boolean querySkuDetails, List<String> moreItemSkus,
List<String> moreSubsSkus) throws IabException {
public Inventory queryInventory(
boolean querySkuDetails, List<String> moreItemSkus, List<String> moreSubsSkus)
throws IabException {
checkNotDisposed();
checkSetupDone("queryInventory");
try {
@ -632,71 +657,73 @@ public class IabHelper {
if (querySkuDetails) {
r = querySkuDetails(ITEM_TYPE_SUBS, inv, moreSubsSkus);
if (r != BILLING_RESPONSE_RESULT_OK) {
throw new IabException(r,
"Error refreshing inventory (querying prices of subscriptions).");
throw new IabException(
r, "Error refreshing inventory (querying prices of subscriptions).");
}
}
}
return inv;
} catch (RemoteException e) {
throw new IabException(IABHELPER_REMOTE_EXCEPTION,
"Remote exception while refreshing inventory.", e);
throw new IabException(
IABHELPER_REMOTE_EXCEPTION, "Remote exception while refreshing inventory.", e);
} catch (JSONException e) {
throw new IabException(IABHELPER_BAD_RESPONSE,
"Error parsing JSON response while refreshing inventory.", e);
throw new IabException(
IABHELPER_BAD_RESPONSE, "Error parsing JSON response while refreshing inventory.", e);
}
}
/**
* Asynchronous wrapper for inventory query. This will perform an inventory
* query as described in {@link #queryInventory}, but will do so asynchronously
* and call back the specified listener upon completion. This method is safe to
* call from a UI thread.
* Asynchronous wrapper for inventory query. This will perform an inventory query as described in
* {@link #queryInventory}, but will do so asynchronously and call back the specified listener
* upon completion. This method is safe to call from a UI thread.
*
* @param querySkuDetails as in {@link #queryInventory}
* @param moreSkus as in {@link #queryInventory}
* @param listener The listener to notify when the refresh operation completes.
*/
public void queryInventoryAsync(final boolean querySkuDetails, final List<String> moreSkus,
public void queryInventoryAsync(
final boolean querySkuDetails,
final List<String> moreSkus,
final QueryInventoryFinishedListener listener) {
final Handler handler = new Handler();
checkNotDisposed();
checkSetupDone("queryInventory");
flagStartAsync("refresh inventory");
executor.execute(() -> {
IabResult result = new IabResult(BILLING_RESPONSE_RESULT_OK, "Inventory refresh successful.");
Inventory inv = null;
try {
inv = queryInventory(querySkuDetails, moreSkus);
} catch (IabException ex) {
result = ex.getResult();
}
executor.execute(
() -> {
IabResult result =
new IabResult(BILLING_RESPONSE_RESULT_OK, "Inventory refresh successful.");
Inventory inv = null;
try {
inv = queryInventory(querySkuDetails, moreSkus);
} catch (IabException ex) {
result = ex.getResult();
}
flagEndAsync();
flagEndAsync();
final IabResult result_f = result;
final Inventory inv_f = inv;
if (!mDisposed && listener != null) {
handler.post(() -> listener.onQueryInventoryFinished(result_f, inv_f));
}
});
final IabResult result_f = result;
final Inventory inv_f = inv;
if (!mDisposed && listener != null) {
handler.post(() -> listener.onQueryInventoryFinished(result_f, inv_f));
}
});
}
public void queryInventoryAsync(QueryInventoryFinishedListener listener) {
queryInventoryAsync(true, null, listener);
}
public void queryInventoryAsync(boolean querySkuDetails,
QueryInventoryFinishedListener listener) {
public void queryInventoryAsync(
boolean querySkuDetails, QueryInventoryFinishedListener listener) {
queryInventoryAsync(querySkuDetails, null, listener);
}
/**
* Consumes a given in-app product. Consuming can only be done on an item
* that's owned, and as a result of consumption, the user will no longer own it.
* This method may block or take long to return. Do not call from the UI thread.
* For that, see {@link #consumeAsync}.
* Consumes a given in-app product. Consuming can only be done on an item that's owned, and as a
* result of consumption, the user will no longer own it. This method may block or take long to
* return. Do not call from the UI thread. For that, see {@link #consumeAsync}.
*
* @param itemInfo The PurchaseInfo that represents the item to consume.
* @throws IabException if there is a problem during consumption.
@ -706,7 +733,8 @@ public class IabHelper {
checkSetupDone("consume");
if (!itemInfo.mItemType.equals(ITEM_TYPE_INAPP)) {
throw new IabException(IABHELPER_INVALID_CONSUMPTION,
throw new IabException(
IABHELPER_INVALID_CONSUMPTION,
"Items of type '" + itemInfo.mItemType + "' can't be consumed.");
}
@ -715,8 +743,9 @@ public class IabHelper {
String sku = itemInfo.getSku();
if (token == null || token.equals("")) {
logError("Can't consume " + sku + ". No token.");
throw new IabException(IABHELPER_MISSING_TOKEN, "PurchaseInfo is missing token for sku: "
+ sku + " " + itemInfo);
throw new IabException(
IABHELPER_MISSING_TOKEN,
"PurchaseInfo is missing token for sku: " + sku + " " + itemInfo);
}
logDebug("Consuming sku: " + sku + ", token: " + token);
@ -728,15 +757,17 @@ public class IabHelper {
throw new IabException(response, "Error consuming sku " + sku);
}
} catch (RemoteException e) {
throw new IabException(IABHELPER_REMOTE_EXCEPTION,
"Remote exception while consuming. PurchaseInfo: " + itemInfo, e);
throw new IabException(
IABHELPER_REMOTE_EXCEPTION,
"Remote exception while consuming. PurchaseInfo: " + itemInfo,
e);
}
}
/**
* Asynchronous wrapper to item consumption. Works like {@link #consume}, but
* performs the consumption in the background and notifies completion through
* the provided listener. This method is safe to call from a UI thread.
* Asynchronous wrapper to item consumption. Works like {@link #consume}, but performs the
* consumption in the background and notifies completion through the provided listener. This
* method is safe to call from a UI thread.
*
* @param purchase The purchase to be consumed.
* @param listener The listener to notify when the consumption operation finishes.
@ -808,8 +839,12 @@ public class IabHelper {
void flagStartAsync(String operation) {
if (mAsyncInProgress) {
throw new IllegalStateException("Can't start async operation (" +
operation + ") because another async operation(" + mAsyncOperation + ") is in progress.");
throw new IllegalStateException(
"Can't start async operation ("
+ operation
+ ") because another async operation("
+ mAsyncOperation
+ ") is in progress.");
}
mAsyncOperation = operation;
mAsyncInProgress = true;
@ -831,8 +866,8 @@ public class IabHelper {
do {
logDebug("Calling getPurchases with continuation token: " + continueToken);
Bundle ownedItems = mService.getPurchases(3, mContext.getPackageName(),
itemType, continueToken);
Bundle ownedItems =
mService.getPurchases(3, mContext.getPackageName(), itemType, continueToken);
int response = getResponseCodeFromBundle(ownedItems);
logDebug("Owned items response: " + String.valueOf(response));
@ -847,12 +882,11 @@ public class IabHelper {
return IABHELPER_BAD_RESPONSE;
}
ArrayList<String> ownedSkus = ownedItems.getStringArrayList(
RESPONSE_INAPP_ITEM_LIST);
ArrayList<String> purchaseDataList = ownedItems.getStringArrayList(
RESPONSE_INAPP_PURCHASE_DATA_LIST);
ArrayList<String> signatureList = ownedItems.getStringArrayList(
RESPONSE_INAPP_SIGNATURE_LIST);
ArrayList<String> ownedSkus = ownedItems.getStringArrayList(RESPONSE_INAPP_ITEM_LIST);
ArrayList<String> purchaseDataList =
ownedItems.getStringArrayList(RESPONSE_INAPP_PURCHASE_DATA_LIST);
ArrayList<String> signatureList =
ownedItems.getStringArrayList(RESPONSE_INAPP_SIGNATURE_LIST);
for (int i = 0; i < purchaseDataList.size(); ++i) {
String purchaseData = purchaseDataList.get(i);
@ -925,8 +959,7 @@ public class IabHelper {
for (ArrayList<String> skuPartList : packs) {
Bundle querySkus = new Bundle();
querySkus.putStringArrayList(GET_SKU_DETAILS_ITEM_LIST, skuPartList);
Bundle skuDetails = mService.getSkuDetails(3, mContext.getPackageName(),
itemType, querySkus);
Bundle skuDetails = mService.getSkuDetails(3, mContext.getPackageName(), itemType, querySkus);
if (!skuDetails.containsKey(RESPONSE_GET_SKU_DETAILS_LIST)) {
int response = getResponseCodeFromBundle(skuDetails);
@ -939,8 +972,7 @@ public class IabHelper {
}
}
ArrayList<String> responseList = skuDetails.getStringArrayList(
RESPONSE_GET_SKU_DETAILS_LIST);
ArrayList<String> responseList = skuDetails.getStringArrayList(RESPONSE_GET_SKU_DETAILS_LIST);
for (String thisResponse : responseList) {
SkuDetails d = new SkuDetails(itemType, thisResponse);
@ -952,31 +984,35 @@ public class IabHelper {
return BILLING_RESPONSE_RESULT_OK;
}
void consumeAsyncInternal(final List<Purchase> purchases,
void consumeAsyncInternal(
final List<Purchase> purchases,
final OnConsumeFinishedListener singleListener,
final OnConsumeMultiFinishedListener multiListener) {
final Handler handler = new Handler();
flagStartAsync("consume");
executor.execute(() -> {
final List<IabResult> results = new ArrayList<IabResult>();
for (Purchase purchase : purchases) {
try {
consume(purchase);
results.add(new IabResult(BILLING_RESPONSE_RESULT_OK,
"Successful consume of sku " + purchase.getSku()));
} catch (IabException ex) {
results.add(ex.getResult());
}
}
executor.execute(
() -> {
final List<IabResult> results = new ArrayList<IabResult>();
for (Purchase purchase : purchases) {
try {
consume(purchase);
results.add(
new IabResult(
BILLING_RESPONSE_RESULT_OK,
"Successful consume of sku " + purchase.getSku()));
} catch (IabException ex) {
results.add(ex.getResult());
}
}
flagEndAsync();
if (!mDisposed && singleListener != null) {
handler.post(() -> singleListener.onConsumeFinished(purchases.get(0), results.get(0)));
}
if (!mDisposed && multiListener != null) {
handler.post(() -> multiListener.onConsumeMultiFinished(purchases, results));
}
});
flagEndAsync();
if (!mDisposed && singleListener != null) {
handler.post(() -> singleListener.onConsumeFinished(purchases.get(0), results.get(0)));
}
if (!mDisposed && multiListener != null) {
handler.post(() -> multiListener.onConsumeMultiFinished(purchases, results));
}
});
}
void logDebug(String msg) {
@ -994,8 +1030,8 @@ public class IabHelper {
}
/**
* Callback for setup process. This listener's {@link #onIabSetupFinished} method is called
* when the setup process is complete.
* Callback for setup process. This listener's {@link #onIabSetupFinished} method is called when
* the setup process is complete.
*/
public interface OnIabSetupFinishedListener {
@ -1007,16 +1043,13 @@ public class IabHelper {
void onIabSetupFinished(IabResult result);
}
/**
* Callback that notifies when a purchase is finished.
*/
/** Callback that notifies when a purchase is finished. */
public interface OnIabPurchaseFinishedListener {
/**
* Called to notify that an in-app purchase finished. If the purchase was successful,
* then the sku parameter specifies which item was purchased. If the purchase failed,
* the sku and extraData parameters may or may not be null, depending on how far the purchase
* process went.
* Called to notify that an in-app purchase finished. If the purchase was successful, then the
* sku parameter specifies which item was purchased. If the purchase failed, the sku and
* extraData parameters may or may not be null, depending on how far the purchase process went.
*
* @param result The result of the purchase.
* @param info The purchase information (null if purchase failed)
@ -1024,9 +1057,7 @@ public class IabHelper {
void onIabPurchaseFinished(IabResult result, Purchase info);
}
/**
* Listener that notifies when an inventory query operation completes.
*/
/** Listener that notifies when an inventory query operation completes. */
public interface QueryInventoryFinishedListener {
/**
@ -1038,9 +1069,7 @@ public class IabHelper {
void onQueryInventoryFinished(IabResult result, Inventory inv);
}
/**
* Callback that notifies when a consumption operation finishes.
*/
/** Callback that notifies when a consumption operation finishes. */
public interface OnConsumeFinishedListener {
/**
@ -1052,9 +1081,7 @@ public class IabHelper {
void onConsumeFinished(Purchase purchase, IabResult result);
}
/**
* Callback that notifies when a multi-item consumption operation finishes.
*/
/** Callback that notifies when a multi-item consumption operation finishes. */
public interface OnConsumeMultiFinishedListener {
/**

@ -16,12 +16,10 @@
package com.android.vending.billing;
/**
* Represents the result of an in-app billing operation.
* A result is composed of a response code (an integer) and possibly a
* message (String). You can get those by calling
* {@link #getResponse} and {@link #getMessage()}, respectively. You
* can also inquire whether a result is a success or a failure by
* calling {@link #isSuccess()} and {@link #isFailure()}.
* Represents the result of an in-app billing operation. A result is composed of a response code (an
* integer) and possibly a message (String). You can get those by calling {@link #getResponse} and
* {@link #getMessage()}, respectively. You can also inquire whether a result is a success or a
* failure by calling {@link #isSuccess()} and {@link #isFailure()}.
*/
@SuppressWarnings("ALL")
public class IabResult {
@ -58,4 +56,3 @@ public class IabResult {
return "IabResult: " + getMessage();
}
}

@ -21,8 +21,8 @@ import java.util.List;
import java.util.Map;
/**
* Represents a block of information about in-app items.
* An Inventory is returned by such methods as {@link IabHelper#queryInventory}.
* Represents a block of information about in-app items. An Inventory is returned by such methods as
* {@link IabHelper#queryInventory}.
*/
@SuppressWarnings("ALL")
public class Inventory {
@ -30,44 +30,34 @@ public class Inventory {
Map<String, SkuDetails> mSkuMap = new HashMap<String, SkuDetails>();
Map<String, Purchase> mPurchaseMap = new HashMap<String, Purchase>();
Inventory() {
}
Inventory() {}
/**
* Returns the listing details for an in-app product.
*/
/** Returns the listing details for an in-app product. */
public SkuDetails getSkuDetails(String sku) {
return mSkuMap.get(sku);
}
/**
* Returns purchase information for a given product, or null if there is no purchase.
*/
/** Returns purchase information for a given product, or null if there is no purchase. */
public Purchase getPurchase(String sku) {
return mPurchaseMap.get(sku);
}
/**
* Returns whether or not there exists a purchase of the given product.
*/
/** Returns whether or not there exists a purchase of the given product. */
public boolean hasPurchase(String sku) {
return mPurchaseMap.containsKey(sku);
}
/**
* Return whether or not details about the given product are available.
*/
/** Return whether or not details about the given product are available. */
public boolean hasDetails(String sku) {
return mSkuMap.containsKey(sku);
}
/**
* Erase a purchase (locally) from the inventory, given its product ID. This just
* modifies the Inventory object locally and has no effect on the server! This is
* useful when you have an existing Inventory object which you know to be up to date,
* and you have just consumed an item successfully, which means that erasing its
* purchase data from the Inventory you already have is quicker than querying for
* a new Inventory.
* Erase a purchase (locally) from the inventory, given its product ID. This just modifies the
* Inventory object locally and has no effect on the server! This is useful when you have an
* existing Inventory object which you know to be up to date, and you have just consumed an item
* successfully, which means that erasing its purchase data from the Inventory you already have is
* quicker than querying for a new Inventory.
*/
public void erasePurchase(String sku) {
if (mPurchaseMap.containsKey(sku)) {
@ -75,16 +65,12 @@ public class Inventory {
}
}
/**
* Returns a list of all owned product IDs.
*/
/** Returns a list of all owned product IDs. */
List<String> getAllOwnedSkus() {
return new ArrayList<String>(mPurchaseMap.keySet());
}
/**
* Returns a list of all owned product IDs of a given type
*/
/** Returns a list of all owned product IDs of a given type */
List<String> getAllOwnedSkus(String itemType) {
List<String> result = new ArrayList<String>();
for (Purchase p : mPurchaseMap.values()) {
@ -95,9 +81,7 @@ public class Inventory {
return result;
}
/**
* Returns a list of all purchases.
*/
/** Returns a list of all purchases. */
List<Purchase> getAllPurchases() {
return new ArrayList<Purchase>(mPurchaseMap.values());
}

@ -18,13 +18,11 @@ package com.android.vending.billing;
import org.json.JSONException;
import org.json.JSONObject;
/**
* Represents an in-app billing purchase.
*/
/** Represents an in-app billing purchase. */
@SuppressWarnings("ALL")
public class Purchase {
String mItemType; // ITEM_TYPE_INAPP or ITEM_TYPE_SUBS
String mItemType; // ITEM_TYPE_INAPP or ITEM_TYPE_SUBS
String mOrderId;
String mPackageName;
String mSku;

@ -29,13 +29,11 @@ import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
/**
* Security-related methods. For a secure implementation, all of this code
* should be implemented on a server that communicates with the
* application on the device. For the sake of simplicity and clarity of this
* example, this code is included here and is executed on the device. If you
* must verify the purchases on the phone, you should obfuscate this code to
* make it harder for an attacker to replace the code with stubs that treat all
* purchases as verified.
* Security-related methods. For a secure implementation, all of this code should be implemented on
* a server that communicates with the application on the device. For the sake of simplicity and
* clarity of this example, this code is included here and is executed on the device. If you must
* verify the purchases on the phone, you should obfuscate this code to make it harder for an
* attacker to replace the code with stubs that treat all purchases as verified.
*/
@SuppressWarnings("ALL")
@SuppressLint("all")
@ -47,19 +45,19 @@ public class Security {
private static final String SIGNATURE_ALGORITHM = "SHA1withRSA";
/**
* Verifies that the data was signed with the given signature, and returns
* the verified purchase. The data is in JSON format and signed
* with a private key. The data also contains the {@link PurchaseState}
* and product ID of the purchase.
* Verifies that the data was signed with the given signature, and returns the verified purchase.
* The data is in JSON format and signed with a private key. The data also contains the {@link
* PurchaseState} and product ID of the purchase.
*
* @param base64PublicKey the base64-encoded public key to use for verifying.
* @param signedData the signed JSON string (signed, not encrypted)
* @param signature the signature for the data, signed with the private key
*/
public static boolean verifyPurchase(String base64PublicKey, String signedData,
String signature) {
if (TextUtils.isEmpty(signedData) || TextUtils.isEmpty(base64PublicKey) ||
TextUtils.isEmpty(signature)) {
public static boolean verifyPurchase(
String base64PublicKey, String signedData, String signature) {
if (TextUtils.isEmpty(signedData)
|| TextUtils.isEmpty(base64PublicKey)
|| TextUtils.isEmpty(signature)) {
Log.e(TAG, "Purchase verification failed: missing data.");
return false;
}
@ -69,8 +67,7 @@ public class Security {
}
/**
* Generates a PublicKey instance from a string containing the
* Base64-encoded public key.
* Generates a PublicKey instance from a string containing the Base64-encoded public key.
*
* @param encodedPublicKey Base64-encoded public key
* @throws IllegalArgumentException if encodedPublicKey is invalid
@ -89,8 +86,8 @@ public class Security {
}
/**
* Verifies that the signature from the server matches the computed
* signature on the data. Returns true if the data is correctly signed.
* Verifies that the signature from the server matches the computed signature on the data. Returns
* true if the data is correctly signed.
*
* @param publicKey public key associated with the developer account
* @param signedData signed data from server

@ -18,9 +18,7 @@ package com.android.vending.billing;
import org.json.JSONException;
import org.json.JSONObject;
/**
* Represents an in-app product's listing details.
*/
/** Represents an in-app product's listing details. */
@SuppressWarnings("ALL")
public class SkuDetails {

@ -29,24 +29,23 @@ public class Tracker {
analytics = GoogleAnalytics.getInstance(context);
tracker = analytics.newTracker(R.xml.google_analytics);
tracker.setAppVersion(Integer.toString(BuildConfig.VERSION_CODE));
final StandardExceptionParser standardExceptionParser = new StandardExceptionParser(context,
null);
exceptionParser = (thread, throwable) -> {
StringBuilder stack = new StringBuilder()
.append(standardExceptionParser.getDescription(thread, throwable))
.append("\n")
.append(throwable.getClass().getName())
.append("\n");
for (StackTraceElement element : throwable.getStackTrace()) {
stack.append(element.toString())
.append("\n");
}
return stack.toString();
};
ExceptionReporter reporter = new ExceptionReporter(
tracker,
Thread.getDefaultUncaughtExceptionHandler(),
context);
final StandardExceptionParser standardExceptionParser =
new StandardExceptionParser(context, null);
exceptionParser =
(thread, throwable) -> {
StringBuilder stack =
new StringBuilder()
.append(standardExceptionParser.getDescription(thread, throwable))
.append("\n")
.append(throwable.getClass().getName())
.append("\n");
for (StackTraceElement element : throwable.getStackTrace()) {
stack.append(element.toString()).append("\n");
}
return stack.toString();
};
ExceptionReporter reporter =
new ExceptionReporter(tracker, Thread.getDefaultUncaughtExceptionHandler(), context);
reporter.setExceptionParser(exceptionParser);
Thread.setDefaultUncaughtExceptionHandler(reporter);
}
@ -61,10 +60,11 @@ public class Tracker {
public void reportException(Thread thread, Throwable t) {
Timber.e(t, t.getMessage());
tracker.send(new HitBuilders.ExceptionBuilder()
.setDescription(exceptionParser.getDescription(thread.getName(), t))
.setFatal(false)
.build());
tracker.send(
new HitBuilders.ExceptionBuilder()
.setDescription(exceptionParser.getDescription(thread.getName(), t))
.setFatal(false)
.build());
}
public void reportEvent(Tracking.Events event) {
@ -84,9 +84,8 @@ public class Tracker {
}
private void reportEvent(int category, String action, String label) {
HitBuilders.EventBuilder eventBuilder = new HitBuilders.EventBuilder()
.setCategory(context.getString(category))
.setAction(action);
HitBuilders.EventBuilder eventBuilder =
new HitBuilders.EventBuilder().setCategory(context.getString(category)).setAction(action);
if (!Strings.isNullOrEmpty(label)) {
eventBuilder.setLabel(label);
}
@ -94,10 +93,11 @@ public class Tracker {
}
public void reportIabResult(IabResult result, String sku) {
tracker.send(new HitBuilders.EventBuilder()
.setCategory(context.getString(R.string.tracking_category_iab))
.setAction(sku)
.setLabel(result.getMessage())
.build());
tracker.send(
new HitBuilders.EventBuilder()
.setCategory(context.getString(R.string.tracking_category_iab))
.setAction(sku)
.setLabel(result.getMessage())
.build());
}
}

@ -27,8 +27,11 @@ public class InventoryHelper implements IabBroadcastReceiver.IabBroadcastListene
private Inventory inventory;
@Inject
public InventoryHelper(@ForApplication Context context, Preferences preferences,
LocalBroadcastManager localBroadcastManager, @Named("iab-executor") Executor executor) {
public InventoryHelper(
@ForApplication Context context,
Preferences preferences,
LocalBroadcastManager localBroadcastManager,
@Named("iab-executor") Executor executor) {
this.context = context;
this.preferences = preferences;
this.localBroadcastManager = localBroadcastManager;
@ -36,8 +39,8 @@ public class InventoryHelper implements IabBroadcastReceiver.IabBroadcastListene
}
public void initialize() {
context.registerReceiver(new IabBroadcastReceiver(this),
new IntentFilter(IabBroadcastReceiver.ACTION));
context.registerReceiver(
new IabBroadcastReceiver(this), new IntentFilter(IabBroadcastReceiver.ACTION));
refreshInventory();
}

@ -36,8 +36,12 @@ public class PurchaseHelper implements IabHelper.OnIabSetupFinishedListener {
private IabHelper iabHelper;
@Inject
public PurchaseHelper(@ForApplication Context context, Preferences preferences, Tracker tracker,
InventoryHelper inventory, @Named("iab-executor") Executor executor,
public PurchaseHelper(
@ForApplication Context context,
Preferences preferences,
Tracker tracker,
InventoryHelper inventory,
@Named("iab-executor") Executor executor,
LocalBroadcastManager localBroadcastManager) {
this.context = context;
this.preferences = preferences;
@ -54,8 +58,12 @@ public class PurchaseHelper implements IabHelper.OnIabSetupFinishedListener {
}
}
public boolean purchase(final Activity activity, final String sku, final String pref,
final int requestCode, final PurchaseHelperCallback callback) {
public boolean purchase(
final Activity activity,
final String sku,
final String pref,
final int requestCode,
final PurchaseHelperCallback callback) {
launchPurchaseFlow(activity, sku, pref, requestCode, callback);
return true;
}
@ -75,43 +83,50 @@ public class PurchaseHelper implements IabHelper.OnIabSetupFinishedListener {
if (themes != null) {
purchases.add(themes);
}
final IabHelper iabHelper = new IabHelper(context, context.getString(R.string.gp_key),
executor);
final IabHelper iabHelper =
new IabHelper(context, context.getString(R.string.gp_key), executor);
iabHelper.enableDebugLogging(true);
iabHelper.startSetup(result -> {
if (result.isSuccess()) {
iabHelper.consumeAsync(purchases, (purchases1, results) -> {
for (int i = 0; i < purchases1.size(); i++) {
Purchase purchase = purchases1.get(i);
IabResult iabResult = results.get(i);
if (iabResult.isSuccess()) {
if (purchase.equals(tasker)) {
preferences.setBoolean(R.string.p_purchased_tasker, false);
} else if (purchase.equals(dashclock)) {
preferences.setBoolean(R.string.p_purchased_dashclock, false);
} else if (purchase.equals(themes)) {
preferences.setBoolean(R.string.p_purchased_themes, false);
} else {
Timber.e("Unhandled consumption for purchase: %s", purchase);
}
inventory.erasePurchase(purchase.getSku());
Timber.d("Consumed %s", purchase);
} else {
Timber.e("Consume failed: %s, %s", purchase, iabResult);
}
iabHelper.startSetup(
result -> {
if (result.isSuccess()) {
iabHelper.consumeAsync(
purchases,
(purchases1, results) -> {
for (int i = 0; i < purchases1.size(); i++) {
Purchase purchase = purchases1.get(i);
IabResult iabResult = results.get(i);
if (iabResult.isSuccess()) {
if (purchase.equals(tasker)) {
preferences.setBoolean(R.string.p_purchased_tasker, false);
} else if (purchase.equals(dashclock)) {
preferences.setBoolean(R.string.p_purchased_dashclock, false);
} else if (purchase.equals(themes)) {
preferences.setBoolean(R.string.p_purchased_themes, false);
} else {
Timber.e("Unhandled consumption for purchase: %s", purchase);
}
inventory.erasePurchase(purchase.getSku());
Timber.d("Consumed %s", purchase);
} else {
Timber.e("Consume failed: %s, %s", purchase, iabResult);
}
}
iabHelper.dispose();
});
} else {
Timber.e("setup failed: %s", result.getMessage());
iabHelper.dispose();
}
iabHelper.dispose();
});
} else {
Timber.e("setup failed: %s", result.getMessage());
iabHelper.dispose();
}
});
}
}
private void launchPurchaseFlow(final Activity activity, final String sku, final String pref,
final int requestCode, final PurchaseHelperCallback callback) {
private void launchPurchaseFlow(
final Activity activity,
final String sku,
final String pref,
final int requestCode,
final PurchaseHelperCallback callback) {
if (iabHelper != null) {
Toast.makeText(activity, R.string.billing_service_busy, Toast.LENGTH_LONG).show();
callback.purchaseCompleted(false, sku);
@ -120,41 +135,47 @@ public class PurchaseHelper implements IabHelper.OnIabSetupFinishedListener {
iabHelper = new IabHelper(context, context.getString(R.string.gp_key), executor);
iabHelper.enableDebugLogging(BuildConfig.DEBUG);
Timber.d("%s: startSetup", iabHelper);
iabHelper.startSetup(result -> {
if (result.isSuccess()) {
try {
Timber.d("%s: launchPurchaseFlow for %s", iabHelper, sku);
iabHelper.launchPurchaseFlow(activity, sku, requestCode, (result1, info) -> {
Timber.d(result1.toString());
tracker.reportIabResult(result1, sku);
if (result1.isSuccess()) {
if (!Strings.isNullOrEmpty(pref)) {
preferences.setBoolean(pref, true);
localBroadcastManager.broadcastRefresh();
}
inventory.refreshInventory();
} else if (result1.getResponse() != IabHelper.BILLING_RESPONSE_RESULT_USER_CANCELED &&
result1.getResponse() != IabHelper.IABHELPER_USER_CANCELLED) {
Toast.makeText(activity, result1.getMessage(), Toast.LENGTH_LONG).show();
}
if (activityResultCallback != null) {
activityResultCallback.purchaseCompleted(result1.isSuccess(), sku);
iabHelper.startSetup(
result -> {
if (result.isSuccess()) {
try {
Timber.d("%s: launchPurchaseFlow for %s", iabHelper, sku);
iabHelper.launchPurchaseFlow(
activity,
sku,
requestCode,
(result1, info) -> {
Timber.d(result1.toString());
tracker.reportIabResult(result1, sku);
if (result1.isSuccess()) {
if (!Strings.isNullOrEmpty(pref)) {
preferences.setBoolean(pref, true);
localBroadcastManager.broadcastRefresh();
}
inventory.refreshInventory();
} else if (result1.getResponse()
!= IabHelper.BILLING_RESPONSE_RESULT_USER_CANCELED
&& result1.getResponse() != IabHelper.IABHELPER_USER_CANCELLED) {
Toast.makeText(activity, result1.getMessage(), Toast.LENGTH_LONG).show();
}
if (activityResultCallback != null) {
activityResultCallback.purchaseCompleted(result1.isSuccess(), sku);
}
disposeIabHelper();
});
} catch (IllegalStateException e) {
tracker.reportException(e);
Toast.makeText(activity, R.string.billing_service_busy, Toast.LENGTH_LONG).show();
callback.purchaseCompleted(false, sku);
disposeIabHelper();
}
} else {
Timber.e(result.toString());
Toast.makeText(activity, result.getMessage(), Toast.LENGTH_LONG).show();
callback.purchaseCompleted(false, sku);
disposeIabHelper();
});
} catch (IllegalStateException e) {
tracker.reportException(e);
Toast.makeText(activity, R.string.billing_service_busy, Toast.LENGTH_LONG).show();
callback.purchaseCompleted(false, sku);
disposeIabHelper();
}
} else {
Timber.e(result.toString());
Toast.makeText(activity, result.getMessage(), Toast.LENGTH_LONG).show();
callback.purchaseCompleted(false, sku);
disposeIabHelper();
}
});
}
});
}
public void disposeIabHelper() {
@ -165,8 +186,8 @@ public class PurchaseHelper implements IabHelper.OnIabSetupFinishedListener {
}
}
public void handleActivityResult(PurchaseHelperCallback callback, int requestCode, int resultCode,
Intent data) {
public void handleActivityResult(
PurchaseHelperCallback callback, int requestCode, int resultCode, Intent data) {
this.activityResultCallback = callback;
if (iabHelper != null) {

@ -28,7 +28,9 @@ public class PlayServices {
private final GoogleAccountManager accountManager;
@Inject
public PlayServices(@ForApplication Context context, Preferences preferences,
public PlayServices(
@ForApplication Context context,
Preferences preferences,
GoogleAccountManager googleAccountManager) {
this.context = context;
this.preferences = preferences;
@ -60,8 +62,9 @@ public class PlayServices {
if (googleApiAvailability.isUserResolvableError(error)) {
googleApiAvailability.getErrorDialog(activity, error, REQUEST_RESOLUTION).show();
} else {
Toast.makeText(activity, R.string.common_google_play_services_notification_ticker,
Toast.LENGTH_LONG).show();
Toast.makeText(
activity, R.string.common_google_play_services_notification_ticker, Toast.LENGTH_LONG)
.show();
}
}
@ -78,8 +81,8 @@ public class PlayServices {
String token = credential.getToken();
Timber.d("Invalidating %s", token);
GoogleAuthUtil.clearToken(context, token);
GoogleAuthUtil
.getToken(context, credential.getSelectedAccount(), "oauth2:" + TasksScopes.TASKS, null);
GoogleAuthUtil.getToken(
context, credential.getSelectedAccount(), "oauth2:" + TasksScopes.TASKS, null);
return true;
} catch (GoogleAuthException e) {
Timber.e(e, e.getMessage());
@ -90,25 +93,30 @@ public class PlayServices {
}
}
public void getAuthToken(final Activity activity, final String accountName,
public void getAuthToken(
final Activity activity,
final String accountName,
final GtasksLoginActivity.AuthResultHandler handler) {
final Account account = accountManager.getAccount(accountName);
if (account == null) {
handler.authenticationFailed(
activity.getString(R.string.gtasks_error_accountNotFound, accountName));
} else {
new Thread(() -> {
try {
GoogleAuthUtil.getToken(activity, account, "oauth2:" + TasksScopes.TASKS, null);
handler.authenticationSuccessful(accountName);
} catch (UserRecoverableAuthException e) {
Timber.e(e, e.getMessage());
activity.startActivityForResult(e.getIntent(), GtasksLoginActivity.RC_REQUEST_OAUTH);
} catch (GoogleAuthException | IOException e) {
Timber.e(e, e.getMessage());
handler.authenticationFailed(activity.getString(R.string.gtasks_GLA_errorIOAuth));
}
}).start();
new Thread(
() -> {
try {
GoogleAuthUtil.getToken(activity, account, "oauth2:" + TasksScopes.TASKS, null);
handler.authenticationSuccessful(accountName);
} catch (UserRecoverableAuthException e) {
Timber.e(e, e.getMessage());
activity.startActivityForResult(
e.getIntent(), GtasksLoginActivity.RC_REQUEST_OAUTH);
} catch (GoogleAuthException | IOException e) {
Timber.e(e, e.getMessage());
handler.authenticationFailed(activity.getString(R.string.gtasks_GLA_errorIOAuth));
}
})
.start();
}
}
}

@ -31,7 +31,9 @@ public class GeofenceApi {
private final PermissionChecker permissionChecker;
@Inject
public GeofenceApi(@ForApplication Context context, Preferences preferences,
public GeofenceApi(
@ForApplication Context context,
Preferences preferences,
PermissionChecker permissionChecker) {
this.context = context;
this.preferences = preferences;
@ -43,25 +45,30 @@ public class GeofenceApi {
return;
}
newClient(client -> {
@SuppressWarnings("ResourceType")
@SuppressLint("MissingPermission")
PendingResult<Status> result = LocationServices.GeofencingApi.addGeofences(
client,
getRequests(locations),
PendingIntent.getBroadcast(context, 0,
new Intent(context, GeofenceTransitionsIntentService.Broadcast.class),
PendingIntent.FLAG_UPDATE_CURRENT));
result.setResultCallback(status -> {
if (status.isSuccess()) {
Timber.i("Registered %s", locations);
} else {
Timber.e("Failed to register %s", locations);
}
client.disconnect();
});
});
newClient(
client -> {
@SuppressWarnings("ResourceType")
@SuppressLint("MissingPermission")
PendingResult<Status> result =
LocationServices.GeofencingApi.addGeofences(
client,
getRequests(locations),
PendingIntent.getBroadcast(
context,
0,
new Intent(context, GeofenceTransitionsIntentService.Broadcast.class),
PendingIntent.FLAG_UPDATE_CURRENT));
result.setResultCallback(
status -> {
if (status.isSuccess()) {
Timber.i("Registered %s", locations);
} else {
Timber.e("Failed to register %s", locations);
}
client.disconnect();
});
});
}
public void cancel(final Location location) {
@ -75,16 +82,19 @@ public class GeofenceApi {
List<String> ids = Lists.transform(locations, geofence -> Long.toString(geofence.getId()));
newClient(client -> LocationServices.GeofencingApi.removeGeofences(client, ids)
.setResultCallback(status -> {
if (status.isSuccess()) {
Timber.i("Removed %s", locations);
} else {
Timber.e("Failed to remove %s", locations);
}
client.disconnect();
}));
newClient(
client ->
LocationServices.GeofencingApi.removeGeofences(client, ids)
.setResultCallback(
status -> {
if (status.isSuccess()) {
Timber.i("Removed %s", locations);
} else {
Timber.e("Failed to remove %s", locations);
}
client.disconnect();
}));
}
private void newClient(final GoogleApi.GoogleApiClientConnectionHandler handler) {
@ -97,8 +107,10 @@ public class GeofenceApi {
private com.google.android.gms.location.Geofence toGoogleGeofence(Location location) {
int radius = preferences.getIntegerFromString(R.string.p_geofence_radius, 250);
int responsiveness = (int) TimeUnit.SECONDS
.toMillis(preferences.getIntegerFromString(R.string.p_geofence_responsiveness, 60));
int responsiveness =
(int)
TimeUnit.SECONDS.toMillis(
preferences.getIntegerFromString(R.string.p_geofence_responsiveness, 60));
return new com.google.android.gms.location.Geofence.Builder()
.setCircularRegion(location.getLatitude(), location.getLongitude(), radius)
.setNotificationResponsiveness(responsiveness)

@ -33,8 +33,8 @@ public class GeofenceTransitionsIntentService extends InjectingJobIntentService
int transitionType = geofencingEvent.getGeofenceTransition();
List<com.google.android.gms.location.Geofence> triggeringGeofences = geofencingEvent
.getTriggeringGeofences();
List<com.google.android.gms.location.Geofence> triggeringGeofences =
geofencingEvent.getTriggeringGeofences();
Timber.i("Received geofence transition: %s, %s", transitionType, triggeringGeofences);
if (transitionType == com.google.android.gms.location.Geofence.GEOFENCE_TRANSITION_ENTER) {
for (com.google.android.gms.location.Geofence triggerGeofence : triggeringGeofences) {
@ -64,8 +64,11 @@ public class GeofenceTransitionsIntentService extends InjectingJobIntentService
@Override
public void onReceive(Context context, Intent intent) {
JobIntentService.enqueueWork(context, GeofenceTransitionsIntentService.class,
JobManager.JOB_ID_GEOFENCE_TRANSITION, intent);
JobIntentService.enqueueWork(
context,
GeofenceTransitionsIntentService.class,
JobManager.JOB_ID_GEOFENCE_TRANSITION,
intent);
}
}
}
}

@ -17,23 +17,24 @@ public class GoogleApi implements GoogleApiClient.ConnectionCallbacks {
@Inject
public GoogleApi(@ForApplication Context context) {
builder = new GoogleApiClient.Builder(context)
.addApi(LocationServices.API)
.addApi(Places.GEO_DATA_API)
.addConnectionCallbacks(this);
builder =
new GoogleApiClient.Builder(context)
.addApi(LocationServices.API)
.addApi(Places.GEO_DATA_API)
.addConnectionCallbacks(this);
}
public void connect(final GoogleApiClientConnectionHandler googleApiClientConnectionHandler) {
connect(googleApiClientConnectionHandler,
connect(
googleApiClientConnectionHandler,
connectionResult -> Timber.e("onConnectionFailed(%s)", connectionResult));
}
private void connect(final GoogleApiClientConnectionHandler googleApiClientConnectionHandler,
private void connect(
final GoogleApiClientConnectionHandler googleApiClientConnectionHandler,
GoogleApiClient.OnConnectionFailedListener onConnectionFailedListener) {
this.googleApiClientConnectionHandler = googleApiClientConnectionHandler;
googleApiClient = builder
.addOnConnectionFailedListener(onConnectionFailedListener)
.build();
googleApiClient = builder.addOnConnectionFailedListener(onConnectionFailedListener).build();
googleApiClient.connect();
}

@ -25,8 +25,9 @@ public class PlacePicker {
activity.startActivity(e.getIntent());
} catch (GooglePlayServicesNotAvailableException e) {
Timber.e(e, e.getMessage());
Toast.makeText(activity, R.string.common_google_play_services_notification_ticker,
Toast.LENGTH_LONG).show();
Toast.makeText(
activity, R.string.common_google_play_services_notification_ticker, Toast.LENGTH_LONG)
.show();
}
return null;
}

@ -1,9 +1,8 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
* <p>See the file "LICENSE" for the full license governing this code.
*/
package com.mdimension.jchronic;
import com.mdimension.jchronic.handlers.Handler;
@ -30,47 +29,41 @@ public class AstridChronic {
}
/**
* Parses a string containing a natural language date or time. If the parser
* can find a date or time, either a Time or Chronic::Span will be returned
* (depending on the value of <tt>:guess</tt>). If no date or time can be found,
* +nil+ will be returned.
* Parses a string containing a natural language date or time. If the parser can find a date or
* time, either a Time or Chronic::Span will be returned (depending on the value of
* <tt>:guess</tt>). If no date or time can be found, +nil+ will be returned.
*
* Options are:
* <p>Options are:
*
* [<tt>:context</tt>]
* <tt>:past</tt> or <tt>:future</tt> (defaults to <tt>:future</tt>)
* <p>[<tt>:context</tt>] <tt>:past</tt> or <tt>:future</tt> (defaults to <tt>:future</tt>)
*
* If your string represents a birthday, you can set <tt>:context</tt> to <tt>:past</tt>
* and if an ambiguous string is given, it will assume it is in the
* past. Specify <tt>:future</tt> or omit to set a future context.
* <p>If your string represents a birthday, you can set <tt>:context</tt> to <tt>:past</tt> and if
* an ambiguous string is given, it will assume it is in the past. Specify <tt>:future</tt> or
* omit to set a future context.
*
* [<tt>:now</tt>]
* Time (defaults to Time.now)
* <p>[<tt>:now</tt>] Time (defaults to Time.now)
*
* By setting <tt>:now</tt> to a Time, all computations will be based off
* of that time instead of Time.now
* <p>By setting <tt>:now</tt> to a Time, all computations will be based off of that time instead
* of Time.now
*
* [<tt>:guess</tt>]
* +true+ or +false+ (defaults to +true+)
* <p>[<tt>:guess</tt>] +true+ or +false+ (defaults to +true+)
*
* By default, the parser will guess a single point in time for the
* given date or time. If you'd rather have the entire time span returned,
* set <tt>:guess</tt> to +false+ and a Chronic::Span will be returned.
* <p>By default, the parser will guess a single point in time for the given date or time. If
* you'd rather have the entire time span returned, set <tt>:guess</tt> to +false+ and a
* Chronic::Span will be returned.
*
* [<tt>:ambiguous_time_range</tt>]
* Integer or <tt>:none</tt> (defaults to <tt>6</tt> (6am-6pm))
* <p>[<tt>:ambiguous_time_range</tt>] Integer or <tt>:none</tt> (defaults to <tt>6</tt>
* (6am-6pm))
*
* If an Integer is given, ambiguous times (like 5:00) will be
* assumed to be within the range of that time in the AM to that time
* in the PM. For example, if you set it to <tt>7</tt>, then the parser will
* look for the time between 7am and 7pm. In the case of 5:00, it would
* assume that means 5:00pm. If <tt>:none</tt> is given, no assumption
* will be made, and the first matching instance of that time will
* be used.
* <p>If an Integer is given, ambiguous times (like 5:00) will be assumed to be within the range
* of that time in the AM to that time in the PM. For example, if you set it to <tt>7</tt>, then
* the parser will look for the time between 7am and 7pm. In the case of 5:00, it would assume
* that means 5:00pm. If <tt>:none</tt> is given, no assumption will be made, and the first
* matching instance of that time will be used.
*/
private static Span parse(String text, Options options) {
// store now for later =)
//_now = options.getNow();
// _now = options.getNow();
// put the text into a normal format to ease scanning
String normalizedText = AstridChronic.preNormalize(text);
@ -114,10 +107,9 @@ public class AstridChronic {
}
/**
* Clean up the specified input text by stripping unwanted characters,
* converting idioms to their canonical form, converting number words
* to numbers (three => 3), and converting ordinal words to numeric
* ordinals (third => 3rd)
* Clean up the specified input text by stripping unwanted characters, converting idioms to their
* canonical form, converting number words to numbers (three => 3), and converting ordinal words
* to numeric ordinals (third => 3rd)
*/
private static String preNormalize(String text) {
String normalizedText = text.toLowerCase();
@ -135,8 +127,8 @@ public class AstridChronic {
normalizedText = normalizedText.replaceAll("\\bthis past\\b", "last");
normalizedText = normalizedText.replaceAll("\\bthis last\\b", "last");
normalizedText = normalizedText.replaceAll("\\b(?:in|during) the (morning)\\b", "$1");
normalizedText = normalizedText
.replaceAll("\\b(?:in the|during the|at) (afternoon|evening|night)\\b", "$1");
normalizedText =
normalizedText.replaceAll("\\b(?:in the|during the|at) (afternoon|evening|night)\\b", "$1");
normalizedText = normalizedText.replaceAll("\\btonight\\b", "this night");
normalizedText = normalizedText.replaceAll("(?=\\w)([ap]m|oclock)\\b", " $1");
normalizedText = normalizedText.replaceAll("\\b(hence|after|from)\\b", "future");
@ -144,17 +136,12 @@ public class AstridChronic {
return normalizedText;
}
/**
* Convert ordinal words to numeric ordinals (third => 3rd)
*/
/** Convert ordinal words to numeric ordinals (third => 3rd) */
private static String numericizeOrdinals(String text) {
return text;
}
/**
* Split the text on spaces and convert each word into
* a Token
*/
/** Split the text on spaces and convert each word into a Token */
private static List<Token> baseTokenize(String text) {
String[] words = text.split(" ");
List<Token> tokens = new LinkedList<>();
@ -164,9 +151,7 @@ public class AstridChronic {
return tokens;
}
/**
* Guess a specific time within the given span
*/
/** Guess a specific time within the given span */
// DIFF: We return Span instead of Date
private static Span guess(Span span) {
if (span == null) {

@ -1,9 +1,8 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
* <p>See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.andlib.data;
import android.text.TextUtils;
@ -12,9 +11,9 @@ import com.todoroo.andlib.sql.Field;
/**
* Property represents a typed column in a database.
*
* Within a given database row, the parameter may not exist, in which case the
* value is null, it may be of an incorrect type, in which case an exception is
* thrown, or the correct type, in which case the value is returned.
* <p>Within a given database row, the parameter may not exist, in which case the value is null, it
* may be of an incorrect type, in which case an exception is thrown, or the correct type, in which
* case the value is returned.
*
* @param <TYPE> a database supported type, such as String or Integer
* @author Tim Su <tim@todoroo.com>
@ -23,37 +22,27 @@ public abstract class Property<TYPE> extends Field implements Cloneable {
// --- implementation
/**
* The database table name this property
*/
private final Table table;
/**
* The database column name for this property
*/
/** The database column name for this property */
public final String name;
/** The database table name this property */
private final Table table;
/**
* Create a property by table and column name. Uses the default property
* expression which is derived from default table name
* Create a property by table and column name. Uses the default property expression which is
* derived from default table name
*/
Property(Table table, String columnName) {
this(table, columnName, (table == null) ? (columnName) : (table.name() + "." + columnName));
}
/**
* Create a property by table and column name, manually specifying an
* expression to use in SQL
*/
/** Create a property by table and column name, manually specifying an expression to use in SQL */
Property(Table table, String columnName, String expression) {
super(expression);
this.table = table;
this.name = columnName;
}
/**
* Return a clone of this property
*/
/** Return a clone of this property */
@Override
public Property<TYPE> clone() {
try {
@ -63,9 +52,7 @@ public abstract class Property<TYPE> extends Field implements Cloneable {
}
}
/**
* Return a clone of this property
*/
/** Return a clone of this property */
Property<TYPE> cloneAs(String tableAlias, String columnAlias) {
Table aliasedTable = this.table;
if (!TextUtils.isEmpty(tableAlias)) {
@ -73,8 +60,10 @@ public abstract class Property<TYPE> extends Field implements Cloneable {
}
try {
Property<TYPE> newInstance = this.getClass().getConstructor(Table.class, String.class)
.newInstance(aliasedTable, this.name);
Property<TYPE> newInstance =
this.getClass()
.getConstructor(Table.class, String.class)
.newInstance(aliasedTable, this.name);
if (!TextUtils.isEmpty(columnAlias)) {
return (Property<TYPE>) newInstance.as(columnAlias);
}
@ -136,9 +125,7 @@ public abstract class Property<TYPE> extends Field implements Cloneable {
// --- pseudo-properties
/**
* Runs a SQL function and returns the result as a string
*/
/** Runs a SQL function and returns the result as a string */
public static class CountProperty extends IntegerProperty {
public CountProperty() {

@ -1,16 +1,15 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
* <p>See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.andlib.data;
import com.todoroo.andlib.sql.SqlTable;
/**
* Table class. Most fields are final, so methods such as <code>as</code> will
* clone the table when it returns.
* Table class. Most fields are final, so methods such as <code>as</code> will clone the table when
* it returns.
*
* @author Tim Su <tim@todoroo.com>
*/
@ -28,9 +27,7 @@ public final class Table extends SqlTable {
this.alias = alias;
}
/**
* Create a new join table based on this table, but with an alias
*/
/** Create a new join table based on this table, but with an alias */
@Override
public Table as(String newAlias) {
return new Table(name, newAlias);
@ -39,7 +36,7 @@ public final class Table extends SqlTable {
@Override
public String toString() {
if (hasAlias()) {
return expression + " AS " + alias; //$NON-NLS-1$
return expression + " AS " + alias; // $NON-NLS-1$
}
return expression;
}

@ -1,9 +1,8 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
* <p>See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.andlib.sql;
import static com.todoroo.andlib.sql.SqlConstants.AND;
@ -15,12 +14,13 @@ import static com.todoroo.andlib.sql.SqlConstants.SPACE;
public abstract class Criterion {
public static final Criterion all = new Criterion(Operator.exists) {
@Override
protected void populate(StringBuilder sb) {
sb.append(1);
}
};
public static final Criterion all =
new Criterion(Operator.exists) {
@Override
protected void populate(StringBuilder sb) {
sb.append(1);
}
};
final Operator operator;
public Criterion(Operator operator) {
@ -73,5 +73,4 @@ public abstract class Criterion {
builder.append(RIGHT_PARENTHESIS);
return builder.toString();
}
}

@ -1,9 +1,8 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
* <p>See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.andlib.sql;
import static com.todoroo.andlib.sql.SqlConstants.AS;
@ -46,7 +45,8 @@ public abstract class DBObject<T extends DBObject<?>> implements Cloneable {
if (alias != null ? !alias.equals(dbObject.alias) : dbObject.alias != null) {
return false;
}
if (expression != null ? !expression.equals(dbObject.expression)
if (expression != null
? !expression.equals(dbObject.expression)
: dbObject.expression != null) {
return false;
}

@ -1,9 +1,8 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
* <p>See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.andlib.sql;
import static com.todoroo.andlib.sql.SqlConstants.COMMA;
@ -57,7 +56,11 @@ public class Field extends DBObject<Field> {
@Override
protected void populate(StringBuilder sb) {
sb.append(field).append(SPACE).append(Operator.in).append(SPACE).append(LEFT_PARENTHESIS)
sb.append(field)
.append(SPACE)
.append(Operator.in)
.append(SPACE)
.append(LEFT_PARENTHESIS)
.append(SPACE);
for (T t : value) {
sb.append(t.toString()).append(COMMA);
@ -73,7 +76,11 @@ public class Field extends DBObject<Field> {
@Override
protected void populate(StringBuilder sb) {
sb.append(field).append(SPACE).append(Operator.in).append(SPACE).append(LEFT_PARENTHESIS)
sb.append(field)
.append(SPACE)
.append(Operator.in)
.append(SPACE)
.append(LEFT_PARENTHESIS)
.append(query)
.append(RIGHT_PARENTHESIS);
}

@ -1,9 +1,8 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
* <p>See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.andlib.sql;
public final class Functions {
@ -12,9 +11,7 @@ public final class Functions {
return new Field("UPPER(" + title.toString() + ")");
}
/**
* @return SQL now (in milliseconds)
*/
/** @return SQL now (in milliseconds) */
public static Field now() {
return new Field("(strftime('%s','now')*1000)");
}

@ -1,9 +1,8 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
* <p>See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.andlib.sql;
import static com.todoroo.andlib.sql.SqlConstants.AND;
@ -34,8 +33,15 @@ public class Join {
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(joinType).append(SPACE).append(JOIN).append(SPACE).append(joinTable).append(SPACE)
.append(ON).append(SPACE).append("(");
sb.append(joinType)
.append(SPACE)
.append(JOIN)
.append(SPACE)
.append(joinTable)
.append(SPACE)
.append(ON)
.append(SPACE)
.append("(");
for (int i = 0; i < criterions.length; i++) {
sb.append(criterions[i]);
if (i < criterions.length - 1) {

@ -1,11 +1,11 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
* <p>See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.andlib.sql;
public enum JoinType {
INNER, LEFT
INNER,
LEFT
}

@ -1,9 +1,8 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
* <p>See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.andlib.sql;
public final class Operator {

@ -1,9 +1,8 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
* <p>See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.andlib.sql;
import static com.todoroo.andlib.sql.SqlConstants.SPACE;
@ -42,12 +41,10 @@ public class Order {
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(expression.toString())
.append(SPACE)
.append(orderType.toString());
sb.append(expression.toString()).append(SPACE).append(orderType.toString());
for (Order secondary : secondaryExpressions) {
sb.append(", ").append(secondary.toString()); //$NON-NLS-1$
sb.append(", ").append(secondary.toString()); // $NON-NLS-1$
}
return sb.toString();

@ -1,11 +1,11 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
* <p>See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.andlib.sql;
public enum OrderType {
DESC, ASC
DESC,
ASC
}

@ -1,9 +1,8 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
* <p>See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.andlib.sql;
import static com.todoroo.andlib.sql.SqlConstants.ALL;
@ -49,8 +48,8 @@ public final class Query {
@Override
public boolean equals(Object o) {
return this == o || !(o == null || getClass() != o.getClass()) && this.toString()
.equals(o.toString());
return this == o
|| !(o == null || getClass() != o.getClass()) && this.toString().equals(o.toString());
}
@Override

@ -1,9 +1,8 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
* <p>See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.andlib.sql;
import static com.todoroo.andlib.sql.SqlConstants.COMMA;
@ -16,8 +15,7 @@ import static java.util.Arrays.asList;
import java.util.ArrayList;
/**
* Query Template returns a bunch of criteria that allows a query to be
* constructed
* Query Template returns a bunch of criteria that allows a query to be constructed
*
* @author Tim Su <tim@todoroo.com>
*/

@ -1,9 +1,8 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
* <p>See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.andlib.sql;
final class SqlConstants {

@ -1,9 +1,8 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
* <p>See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.andlib.sql;
public class SqlTable extends DBObject<SqlTable> {

@ -1,9 +1,8 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
* <p>See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.andlib.sql;
import static com.todoroo.andlib.sql.SqlConstants.SPACE;
@ -23,9 +22,7 @@ public class UnaryCriterion extends Criterion {
return new UnaryCriterion(expression, Operator.eq, value);
}
/**
* Sanitize the given input for SQL
*/
/** Sanitize the given input for SQL */
public static String sanitize(String input) {
return input.replace("'", "''");
}

@ -1,9 +1,8 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
* <p>See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.andlib.utility;
import android.app.Activity;
@ -32,29 +31,26 @@ import timber.log.Timber;
*/
public class AndroidUtilities {
public static final String SEPARATOR_ESCAPE = "!PIPE!"; //$NON-NLS-1$
public static final String SERIALIZATION_SEPARATOR = "|"; //$NON-NLS-1$
public static final String SEPARATOR_ESCAPE = "!PIPE!"; // $NON-NLS-1$
public static final String SERIALIZATION_SEPARATOR = "|"; // $NON-NLS-1$
// --- utility methods
/**
* Suppress virtual keyboard until user's first tap
*/
/** Suppress virtual keyboard until user's first tap */
public static void suppressVirtualKeyboard(final TextView editor) {
final int inputType = editor.getInputType();
editor.setInputType(InputType.TYPE_NULL);
editor.setOnTouchListener((v, event) -> {
editor.setInputType(inputType);
editor.setOnTouchListener(null);
return false;
});
editor.setOnTouchListener(
(v, event) -> {
editor.setInputType(inputType);
editor.setOnTouchListener(null);
return false;
});
}
// --- serialization
/**
* Serializes a content value into a string
*/
/** Serializes a content value into a string */
public static String mapToSerializedString(Map<String, Object> source) {
StringBuilder result = new StringBuilder();
for (Entry<String, Object> entry : source.entrySet()) {
@ -63,13 +59,11 @@ public class AndroidUtilities {
return result.toString();
}
/**
* add serialized helper
*/
private static void addSerialized(StringBuilder result,
String key, Object value) {
result.append(key.replace(SERIALIZATION_SEPARATOR, SEPARATOR_ESCAPE)).append(
SERIALIZATION_SEPARATOR);
/** add serialized helper */
private static void addSerialized(StringBuilder result, String key, Object value) {
result
.append(key.replace(SERIALIZATION_SEPARATOR, SEPARATOR_ESCAPE))
.append(SERIALIZATION_SEPARATOR);
if (value instanceof Integer) {
result.append('i').append(value);
} else if (value instanceof Double) {
@ -77,7 +71,8 @@ public class AndroidUtilities {
} else if (value instanceof Long) {
result.append('l').append(value);
} else if (value instanceof String) {
result.append('s')
result
.append('s')
.append(value.toString().replace(SERIALIZATION_SEPARATOR, SEPARATOR_ESCAPE));
} else if (value instanceof Boolean) {
result.append('b').append(value);
@ -93,30 +88,33 @@ public class AndroidUtilities {
}
Map<String, Object> result = new HashMap<>();
fromSerialized(string, result, (object, key, type, value) -> {
switch (type) {
case 'i':
object.put(key, Integer.parseInt(value));
break;
case 'd':
object.put(key, Double.parseDouble(value));
break;
case 'l':
object.put(key, Long.parseLong(value));
break;
case 's':
object.put(key, value.replace(SEPARATOR_ESCAPE, SERIALIZATION_SEPARATOR));
break;
case 'b':
object.put(key, Boolean.parseBoolean(value));
break;
}
});
fromSerialized(
string,
result,
(object, key, type, value) -> {
switch (type) {
case 'i':
object.put(key, Integer.parseInt(value));
break;
case 'd':
object.put(key, Double.parseDouble(value));
break;
case 'l':
object.put(key, Long.parseLong(value));
break;
case 's':
object.put(key, value.replace(SEPARATOR_ESCAPE, SERIALIZATION_SEPARATOR));
break;
case 'b':
object.put(key, Boolean.parseBoolean(value));
break;
}
});
return result;
}
private static <T> void fromSerialized(String string, T object, SerializedPut<T> putter) {
String[] pairs = string.split("\\" + SERIALIZATION_SEPARATOR); //$NON-NLS-1$
String[] pairs = string.split("\\" + SERIALIZATION_SEPARATOR); // $NON-NLS-1$
for (int i = 0; i < pairs.length; i += 2) {
try {
String key = pairs[i].replaceAll(SEPARATOR_ESCAPE, SERIALIZATION_SEPARATOR);
@ -134,9 +132,7 @@ public class AndroidUtilities {
}
}
/**
* Copy a file from one place to another
*/
/** Copy a file from one place to another */
public static void copyFile(File in, File out) throws Exception {
FileInputStream fis = new FileInputStream(in);
FileOutputStream fos = new FileOutputStream(out);
@ -148,9 +144,7 @@ public class AndroidUtilities {
}
}
/**
* Copy stream from source to destination
*/
/** Copy stream from source to destination */
private static void copyStream(InputStream source, OutputStream dest) throws IOException {
int bytes;
byte[] buffer;
@ -218,8 +212,8 @@ public class AndroidUtilities {
}
/**
* Sleep, ignoring interruption. Before using this method, think carefully
* about why you are ignoring interruptions.
* Sleep, ignoring interruption. Before using this method, think carefully about why you are
* ignoring interruptions.
*/
public static void sleepDeep(long l) {
try {
@ -229,9 +223,7 @@ public class AndroidUtilities {
}
}
/**
* Capitalize the first character
*/
/** Capitalize the first character */
public static String capitalize(String string) {
return string.substring(0, 1).toUpperCase() + string.substring(1);
}
@ -240,8 +232,8 @@ public class AndroidUtilities {
try {
View currentFocus = activity.getCurrentFocus();
if (currentFocus != null) {
InputMethodManager inputMethodManager = (InputMethodManager) activity
.getSystemService(Context.INPUT_METHOD_SERVICE);
InputMethodManager inputMethodManager =
(InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(currentFocus.getWindowToken(), 0);
}
} catch (Exception e) {
@ -255,16 +247,14 @@ public class AndroidUtilities {
* @param views - a list of views that might potentially be displaying the keyboard
*/
public static void hideSoftInputForViews(Context context, View... views) {
InputMethodManager imm = (InputMethodManager) context
.getSystemService(Context.INPUT_METHOD_SERVICE);
InputMethodManager imm =
(InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
for (View v : views) {
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
}
}
/**
* Returns the final word characters after the last '.'
*/
/** Returns the final word characters after the last '.' */
public static String getFileExtension(String file) {
int index = file.lastIndexOf('.');
String extension = "";

@ -1,9 +1,8 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
* <p>See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.andlib.utility;
import static org.tasks.date.DateTimeUtils.newDateTime;
@ -16,25 +15,17 @@ import org.tasks.R;
import org.tasks.locale.Locale;
import org.tasks.time.DateTime;
public class DateUtilities {
/**
* Represents a single hour
*/
/** Represents a single hour */
public static final long ONE_HOUR = 3600000L;
/**
* Represents a single day
*/
/** Represents a single day */
public static final long ONE_DAY = 24 * ONE_HOUR;
/**
* Represents a single week
*/
/** Represents a single week */
public static final long ONE_WEEK = 7 * ONE_DAY;
/**
* Represents a single minute
*/
/** Represents a single minute */
public static final long ONE_MINUTE = 60000L;
private static final long abbreviationLimit = DateUtilities.ONE_DAY * 6;
private static final String JA = "MMM d\u65E5";
private static final String JA_YEAR = "yy\u5E74 " + JA;
@ -45,8 +36,8 @@ public class DateUtilities {
static Boolean is24HourOverride = null;
/**
* Add the specified amount of months to the given time.<br/>
* The day of month will stay the same.<br/>
* Add the specified amount of months to the given time.<br>
* The day of month will stay the same.<br>
*
* @param time the base-time (in milliseconds) to which the amount of months is added
* @param interval the amount of months to be added
@ -63,9 +54,7 @@ public class DateUtilities {
return result.getMillis();
}
/**
* Returns unixtime for current time
*/
/** Returns unixtime for current time */
public static long now() {
return currentTimeMillis();
}
@ -74,9 +63,7 @@ public class DateUtilities {
* =========================================================== formatters
* ====================================================================== */
/**
* Returns unixtime one month from now
*/
/** Returns unixtime one month from now */
public static long oneMonthFromNow() {
return addCalendarMonthsToUnixtime(currentTimeMillis(), 1);
}
@ -138,26 +125,18 @@ public class DateUtilities {
case "KE":
case "MN":
case "US":
return includeYear
? monthFormat + " d ''yy"
: monthFormat + " d";
return includeYear ? monthFormat + " d ''yy" : monthFormat + " d";
default:
return includeYear
? "d " + monthFormat + " ''yy"
: "d " + monthFormat;
return includeYear ? "d " + monthFormat + " ''yy" : "d " + monthFormat;
}
}
/**
* @return weekday
*/
/** @return weekday */
public static String getWeekday(DateTime date) {
return date.toString("EEEE");
}
/**
* @return weekday
*/
/** @return weekday */
public static String getWeekdayShort(DateTime date) {
return date.toString("EEE");
}
@ -175,15 +154,16 @@ public class DateUtilities {
public static String getRelativeDateStringWithTime(Context context, long timestamp) {
String string = DateUtilities.getRelativeDay(context, timestamp, false);
if (Task.hasDueTime(timestamp)) {
string = String.format("%s %s", string, //$NON-NLS-1$
DateUtilities.getTimeString(context, timestamp));
string =
String.format(
"%s %s",
string, // $NON-NLS-1$
DateUtilities.getTimeString(context, timestamp));
}
return string;
}
/**
* @return yesterday, today, tomorrow, or null
*/
/** @return yesterday, today, tomorrow, or null */
public static String getRelativeDay(Context context, long date, boolean abbreviated) {
long today = getStartOfDay(currentTimeMillis());
long input = getStartOfDay(date);
@ -201,7 +181,8 @@ public class DateUtilities {
}
if (today + abbreviationLimit >= input && today - abbreviationLimit <= input) {
return abbreviated ? DateUtilities.getWeekdayShort(newDateTime(date))
return abbreviated
? DateUtilities.getWeekdayShort(newDateTime(date))
: DateUtilities.getWeekday(newDateTime(date));
}

@ -1,32 +1,29 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
* <p>See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.andlib.utility;
import android.app.Activity;
import android.app.Dialog;
import timber.log.Timber;
public class DialogUtilities {
/**
* Dismiss a dialog off the UI thread
*/
/** Dismiss a dialog off the UI thread */
@Deprecated
public static void dismissDialog(Activity activity, final Dialog dialog) {
if (dialog == null) {
return;
}
activity.runOnUiThread(() -> {
try {
dialog.dismiss();
} catch (Exception e) {
Timber.e(e, e.getMessage());
}
});
activity.runOnUiThread(
() -> {
try {
dialog.dismiss();
} catch (Exception e) {
Timber.e(e, e.getMessage());
}
});
}
}

@ -1,9 +1,8 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
* <p>See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.activity;
import static java.util.Arrays.asList;
@ -29,13 +28,18 @@ import org.tasks.preferences.Preferences;
import org.tasks.preferences.beast.BeastModeRecyclerAdapter;
import org.tasks.ui.MenuColorizer;
public class BeastModePreferences extends ThemedInjectingAppCompatActivity implements
Toolbar.OnMenuItemClickListener {
public class BeastModePreferences extends ThemedInjectingAppCompatActivity
implements Toolbar.OnMenuItemClickListener {
private static final String BEAST_MODE_ORDER_PREF = "beast_mode_order_v3"; //$NON-NLS-1$
private static final String BEAST_MODE_ORDER_PREF = "beast_mode_order_v3"; // $NON-NLS-1$
private static final String BEAST_MODE_PREF_ITEM_SEPARATOR = ";";
@BindView(R.id.toolbar) Toolbar toolbar;
@BindView(R.id.recycler_view) RecyclerView recyclerView;
@BindView(R.id.toolbar)
Toolbar toolbar;
@BindView(R.id.recycler_view)
RecyclerView recyclerView;
@Inject Preferences preferences;
private BeastModeRecyclerAdapter adapter;
@ -53,8 +57,8 @@ public class BeastModePreferences extends ThemedInjectingAppCompatActivity imple
preferences.setString(BEAST_MODE_ORDER_PREF, newSetting.toString());
}
public static ArrayList<String> constructOrderedControlList(Preferences preferences,
Context context) {
public static ArrayList<String> constructOrderedControlList(
Preferences preferences, Context context) {
String order = preferences.getStringValue(BEAST_MODE_ORDER_PREF);
ArrayList<String> list = new ArrayList<>();
String[] itemsArray;

@ -1,7 +1,4 @@
/**
* TODO: make this lightweight, don't extend the entire TaskListActivity
*/
/** TODO: make this lightweight, don't extend the entire TaskListActivity */
package com.todoroo.astrid.activity;
import static org.tasks.intents.TaskIntents.getEditTaskStack;
@ -17,8 +14,7 @@ import org.tasks.injection.InjectingAppCompatActivity;
/**
* @author joshuagross
*
* Create a new task based on incoming links from the "share" menu
* <p>Create a new task based on incoming links from the "share" menu
*/
public final class ShareLinkActivity extends InjectingAppCompatActivity {

@ -1,9 +1,8 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
* <p>See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.activity;
import static org.tasks.date.DateTimeUtils.newDateTime;
@ -53,8 +52,8 @@ import org.tasks.ui.MenuColorizer;
import org.tasks.ui.RemoteListFragment;
import org.tasks.ui.TaskEditControlFragment;
public final class TaskEditFragment extends InjectingFragment implements
Toolbar.OnMenuItemClickListener {
public final class TaskEditFragment extends InjectingFragment
implements Toolbar.OnMenuItemClickListener {
public static final String TAG_TASKEDIT_FRAGMENT = "taskedit_fragment";
private static final String EXTRA_TASK = "extra_task";
@ -70,9 +69,16 @@ public final class TaskEditFragment extends InjectingFragment implements
@Inject Tracker tracker;
@Inject TimerPlugin timerPlugin;
@Inject LocalBroadcastManager localBroadcastManager;
@BindView(R.id.toolbar) Toolbar toolbar;
@BindView(R.id.comments) LinearLayout comments;
@BindView(R.id.control_sets) LinearLayout controlSets;
@BindView(R.id.toolbar)
Toolbar toolbar;
@BindView(R.id.comments)
LinearLayout comments;
@BindView(R.id.control_sets)
LinearLayout controlSets;
Task model = null;
private TaskEditFragmentCallbackHandler callback;
@ -97,8 +103,8 @@ public final class TaskEditFragment extends InjectingFragment implements
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_task_edit, container, false);
ButterKnife.bind(this, view);
@ -106,15 +112,17 @@ public final class TaskEditFragment extends InjectingFragment implements
model = arguments.getParcelable(EXTRA_TASK);
final boolean backButtonSavesTask = preferences.backButtonSavesTask();
toolbar.setNavigationIcon(ContextCompat.getDrawable(context,
backButtonSavesTask ? R.drawable.ic_close_24dp : R.drawable.ic_save_24dp));
toolbar.setNavigationOnClickListener(v -> {
if (backButtonSavesTask) {
discardButtonClick();
} else {
save();
}
});
toolbar.setNavigationIcon(
ContextCompat.getDrawable(
context, backButtonSavesTask ? R.drawable.ic_close_24dp : R.drawable.ic_save_24dp));
toolbar.setNavigationOnClickListener(
v -> {
if (backButtonSavesTask) {
discardButtonClick();
} else {
save();
}
});
toolbar.inflateMenu(R.menu.menu_task_edit_fragment);
toolbar.setOnMenuItemClickListener(this);
MenuColorizer.colorToolbar(context, toolbar);
@ -127,16 +135,17 @@ public final class TaskEditFragment extends InjectingFragment implements
commentsController.reloadView();
FragmentManager fragmentManager = getChildFragmentManager();
List<TaskEditControlFragment> taskEditControlFragments = taskEditControlSetFragmentManager
.getOrCreateFragments(fragmentManager, model);
List<TaskEditControlFragment> taskEditControlFragments =
taskEditControlSetFragmentManager.getOrCreateFragments(fragmentManager, model);
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
for (int i = 0; i < taskEditControlFragments.size(); i++) {
TaskEditControlFragment taskEditControlFragment = taskEditControlFragments.get(i);
String tag = getString(taskEditControlFragment.controlId());
fragmentTransaction
.replace(TaskEditControlSetFragmentManager.TASK_EDIT_CONTROL_FRAGMENT_ROWS[i],
taskEditControlFragment, tag);
fragmentTransaction.replace(
TaskEditControlSetFragmentManager.TASK_EDIT_CONTROL_FRAGMENT_ROWS[i],
taskEditControlFragment,
tag);
}
fragmentTransaction.commit();
@ -163,29 +172,32 @@ public final class TaskEditFragment extends InjectingFragment implements
public Task stopTimer() {
timerPlugin.stopTimer(model);
String elapsedTime = DateUtils.formatElapsedTime(model.getElapsedSeconds());
addComment(String.format("%s %s\n%s %s", //$NON-NLS-1$
getString(R.string.TEA_timer_comment_stopped),
DateUtilities.getTimeString(getActivity(), newDateTime()),
getString(R.string.TEA_timer_comment_spent),
elapsedTime), null);
addComment(
String.format(
"%s %s\n%s %s", // $NON-NLS-1$
getString(R.string.TEA_timer_comment_stopped),
DateUtilities.getTimeString(getActivity(), newDateTime()),
getString(R.string.TEA_timer_comment_spent),
elapsedTime),
null);
return model;
}
public Task startTimer() {
timerPlugin.startTimer(model);
addComment(String.format("%s %s",
getString(R.string.TEA_timer_comment_started),
DateUtilities.getTimeString(getActivity(), newDateTime())),
addComment(
String.format(
"%s %s",
getString(R.string.TEA_timer_comment_started),
DateUtilities.getTimeString(getActivity(), newDateTime())),
null);
return model;
}
/**
* Save task model from values in UI components
*/
/** Save task model from values in UI components */
public void save() {
List<TaskEditControlFragment> fragments = taskEditControlSetFragmentManager
.getFragmentsInPersistOrder(getChildFragmentManager());
List<TaskEditControlFragment> fragments =
taskEditControlSetFragmentManager.getFragmentsInPersistOrder(getChildFragmentManager());
if (hasChanges(fragments)) {
boolean isNewTask = model.isNew();
if (isNewTask) {
@ -201,9 +213,7 @@ public final class TaskEditFragment extends InjectingFragment implements
}
if (isNewTask) {
((TaskListActivity) getActivity())
.getTaskListFragment()
.onTaskCreated(model.getUuid());
((TaskListActivity) getActivity()).getTaskListFragment().onTaskCreated(model.getUuid());
}
callback.taskEditFinished();
} else {
@ -260,7 +270,8 @@ public final class TaskEditFragment extends InjectingFragment implements
public void discardButtonClick() {
if (hasChanges(
taskEditControlSetFragmentManager.getFragmentsInPersistOrder(getChildFragmentManager()))) {
dialogBuilder.newMessageDialog(R.string.discard_confirmation)
dialogBuilder
.newMessageDialog(R.string.discard_confirmation)
.setPositiveButton(R.string.keep_editing, null)
.setNegativeButton(R.string.discard, (dialog, which) -> discard())
.show();
@ -278,12 +289,15 @@ public final class TaskEditFragment extends InjectingFragment implements
}
private void deleteButtonClick() {
dialogBuilder.newMessageDialog(R.string.DLG_delete_this_task_question)
.setPositiveButton(android.R.string.ok, (dialog, which) -> {
timerPlugin.stopTimer(model);
taskDeleter.markDeleted(model);
callback.taskEditFinished();
})
dialogBuilder
.newMessageDialog(R.string.DLG_delete_this_task_question)
.setPositiveButton(
android.R.string.ok,
(dialog, which) -> {
timerPlugin.stopTimer(model);
taskDeleter.markDeleted(model);
callback.taskEditFinished();
})
.setNegativeButton(android.R.string.cancel, null)
.show();
}

@ -1,9 +1,8 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
* <p>See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.activity;
import static com.todoroo.andlib.utility.AndroidUtilities.atLeastLollipop;
@ -73,26 +72,25 @@ import org.tasks.ui.PriorityControlSet;
import org.tasks.ui.TaskListViewModel;
import timber.log.Timber;
public class TaskListActivity extends InjectingAppCompatActivity implements
OnFilterItemClickedListener,
TaskListFragment.TaskListFragmentCallbackHandler,
PriorityControlSet.OnPriorityChanged,
TimerControlSet.TimerControlSetCallback,
RepeatControlSet.RepeatChangedListener,
DeadlineControlSet.DueDateChangeListener,
TaskEditFragment.TaskEditFragmentCallbackHandler,
CommentBarFragment.CommentBarFragmentCallback,
SortDialog.SortDialogCallback,
RemoteListSelectionHandler {
/**
* For indicating the new list screen should be launched at fragment setup time
*/
public static final String TOKEN_CREATE_NEW_LIST_NAME = "newListName"; //$NON-NLS-1$
public static final String OPEN_FILTER = "open_filter"; //$NON-NLS-1$
public class TaskListActivity extends InjectingAppCompatActivity
implements OnFilterItemClickedListener,
TaskListFragment.TaskListFragmentCallbackHandler,
PriorityControlSet.OnPriorityChanged,
TimerControlSet.TimerControlSetCallback,
RepeatControlSet.RepeatChangedListener,
DeadlineControlSet.DueDateChangeListener,
TaskEditFragment.TaskEditFragmentCallbackHandler,
CommentBarFragment.CommentBarFragmentCallback,
SortDialog.SortDialogCallback,
RemoteListSelectionHandler {
/** For indicating the new list screen should be launched at fragment setup time */
public static final String TOKEN_CREATE_NEW_LIST_NAME = "newListName"; // $NON-NLS-1$
public static final String OPEN_FILTER = "open_filter"; // $NON-NLS-1$
public static final String LOAD_FILTER = "load_filter";
public static final String OPEN_TASK = "open_task"; //$NON-NLS-1$
public static final String OPEN_NEW_TASK = "open_new_task"; //$NON-NLS-1$
public static final String OPEN_TASK = "open_task"; // $NON-NLS-1$
public static final String OPEN_NEW_TASK = "open_new_task"; // $NON-NLS-1$
private static final String FRAG_TAG_TASK_LIST = "frag_tag_task_list";
@Inject Preferences preferences;
@Inject SubtasksHelper subtasksHelper;
@ -107,9 +105,16 @@ public class TaskListActivity extends InjectingAppCompatActivity implements
@Inject TaskDao taskDao;
@Inject CaldavDao caldavDao;
@Inject LocalBroadcastManager localBroadcastManager;
@BindView(R.id.drawer_layout) DrawerLayout drawerLayout;
@BindView(R.id.master) FrameLayout master;
@BindView(R.id.detail) FrameLayout detail;
@BindView(R.id.drawer_layout)
DrawerLayout drawerLayout;
@BindView(R.id.master)
FrameLayout master;
@BindView(R.id.detail)
FrameLayout detail;
private NavigationDrawerFragment navigationDrawer;
private TaskListViewModel viewModel;
private int currentNightMode;
@ -117,9 +122,7 @@ public class TaskListActivity extends InjectingAppCompatActivity implements
private Filter filter;
private ActionMode actionMode = null;
/**
* @see android.app.Activity#onCreate(Bundle)
*/
/** @see android.app.Activity#onCreate(Bundle) */
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -137,12 +140,13 @@ public class TaskListActivity extends InjectingAppCompatActivity implements
navigationDrawer = getNavigationDrawerFragment();
navigationDrawer.setUp(drawerLayout);
drawerLayout.addDrawerListener(new DrawerLayout.SimpleDrawerListener() {
@Override
public void onDrawerStateChanged(int newState) {
finishActionMode();
}
});
drawerLayout.addDrawerListener(
new DrawerLayout.SimpleDrawerListener() {
@Override
public void onDrawerStateChanged(int newState) {
finishActionMode();
}
});
handleIntent();
}
@ -162,8 +166,10 @@ public class TaskListActivity extends InjectingAppCompatActivity implements
TaskEditFragment taskEditFragment = getTaskEditFragment();
if (taskEditFragment == null) {
hideDetailFragment();
} else if (intent.hasExtra(OPEN_FILTER) || intent.hasExtra(LOAD_FILTER) || intent
.hasExtra(OPEN_TASK) || intent.hasExtra(OPEN_NEW_TASK)) {
} else if (intent.hasExtra(OPEN_FILTER)
|| intent.hasExtra(LOAD_FILTER)
|| intent.hasExtra(OPEN_TASK)
|| intent.hasExtra(OPEN_NEW_TASK)) {
taskEditFragment.save();
taskEditFinished();
} else {
@ -176,8 +182,8 @@ public class TaskListActivity extends InjectingAppCompatActivity implements
intent.removeExtra(OPEN_FILTER);
loadTaskListFragment(filter);
} else if (intent.hasExtra(LOAD_FILTER)) {
Filter filter = defaultFilterProvider
.getFilterFromPreference(intent.getStringExtra(LOAD_FILTER));
Filter filter =
defaultFilterProvider.getFilterFromPreference(intent.getStringExtra(LOAD_FILTER));
intent.removeExtra(LOAD_FILTER);
loadTaskListFragment(filter);
} else if (taskListFragment == null) {
@ -196,7 +202,8 @@ public class TaskListActivity extends InjectingAppCompatActivity implements
private void hideDetailFragment() {
if (isDoublePaneLayout()) {
getSupportFragmentManager().beginTransaction()
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.detail, new EmptyTaskEditFragment())
.commit();
} else {
@ -218,7 +225,8 @@ public class TaskListActivity extends InjectingAppCompatActivity implements
navigationDrawer.setSelected(filter);
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
fragmentManager
.beginTransaction()
.replace(R.id.master, taskListFragment, FRAG_TAG_TASK_LIST)
.commit();
}
@ -253,8 +261,9 @@ public class TaskListActivity extends InjectingAppCompatActivity implements
}
private NavigationDrawerFragment getNavigationDrawerFragment() {
return (NavigationDrawerFragment) getSupportFragmentManager()
.findFragmentById(NavigationDrawerFragment.FRAGMENT_NAVIGATION_DRAWER);
return (NavigationDrawerFragment)
getSupportFragmentManager()
.findFragmentById(NavigationDrawerFragment.FRAGMENT_NAVIGATION_DRAWER);
}
@Override
@ -422,13 +431,12 @@ public class TaskListActivity extends InjectingAppCompatActivity implements
}
public TaskListFragment getTaskListFragment() {
return (TaskListFragment) getSupportFragmentManager()
.findFragmentByTag(FRAG_TAG_TASK_LIST);
return (TaskListFragment) getSupportFragmentManager().findFragmentByTag(FRAG_TAG_TASK_LIST);
}
public TaskEditFragment getTaskEditFragment() {
return (TaskEditFragment) getSupportFragmentManager()
.findFragmentByTag(TaskEditFragment.TAG_TASKEDIT_FRAGMENT);
return (TaskEditFragment)
getSupportFragmentManager().findFragmentByTag(TaskEditFragment.TAG_TASKEDIT_FRAGMENT);
}
@Override
@ -457,8 +465,9 @@ public class TaskListActivity extends InjectingAppCompatActivity implements
@Override
public void taskEditFinished() {
getSupportFragmentManager().popBackStackImmediate(TaskEditFragment.TAG_TASKEDIT_FRAGMENT,
FragmentManager.POP_BACK_STACK_INCLUSIVE);
getSupportFragmentManager()
.popBackStackImmediate(
TaskEditFragment.TAG_TASKEDIT_FRAGMENT, FragmentManager.POP_BACK_STACK_INCLUSIVE);
hideDetailFragment();
hideKeyboard();
getTaskListFragment().loadTaskListContent();
@ -467,8 +476,8 @@ public class TaskListActivity extends InjectingAppCompatActivity implements
private void hideKeyboard() {
View view = getCurrentFocus();
if (view != null) {
InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(
INPUT_METHOD_SERVICE);
InputMethodManager inputMethodManager =
(InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
}

@ -1,9 +1,8 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
* <p>See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.activity;
import static android.support.v4.content.ContextCompat.getColor;
@ -70,17 +69,16 @@ import org.tasks.ui.ProgressDialogAsyncTask;
import org.tasks.ui.TaskListViewModel;
/**
* Primary activity for the Bente application. Shows a list of upcoming tasks
* and a user's coaches.
* Primary activity for the Bente application. Shows a list of upcoming tasks and a user's coaches.
*
* @author Tim Su <tim@todoroo.com>
*/
public class TaskListFragment extends InjectingFragment implements
SwipeRefreshLayout.OnRefreshListener, Toolbar.OnMenuItemClickListener {
public class TaskListFragment extends InjectingFragment
implements SwipeRefreshLayout.OnRefreshListener, Toolbar.OnMenuItemClickListener {
public static final String TAGS_METADATA_JOIN = "for_tags"; // $NON-NLS-1$
public static final String FILE_METADATA_JOIN = "for_actions"; // $NON-NLS-1$
private static final int VOICE_RECOGNITION_REQUEST_CODE = 1234;
public static final String TAGS_METADATA_JOIN = "for_tags"; //$NON-NLS-1$
public static final String FILE_METADATA_JOIN = "for_actions"; //$NON-NLS-1$
private static final String EXTRA_FILTER = "extra_filter";
private static final String FRAG_TAG_SORT_DIALOG = "frag_tag_sort_dialog";
@ -102,11 +100,22 @@ public class TaskListFragment extends InjectingFragment implements
@Inject ViewHolderFactory viewHolderFactory;
@Inject LocalBroadcastManager localBroadcastManager;
@Inject Device device;
@BindView(R.id.swipe_layout) SwipeRefreshLayout swipeRefreshLayout;
@BindView(R.id.swipe_layout_empty) SwipeRefreshLayout emptyRefreshLayout;
@BindView(R.id.toolbar) Toolbar toolbar;
@BindView(R.id.task_list_coordinator) CoordinatorLayout coordinatorLayout;
@BindView(R.id.recycler_view) RecyclerView recyclerView;
@BindView(R.id.swipe_layout)
SwipeRefreshLayout swipeRefreshLayout;
@BindView(R.id.swipe_layout_empty)
SwipeRefreshLayout emptyRefreshLayout;
@BindView(R.id.toolbar)
Toolbar toolbar;
@BindView(R.id.task_list_coordinator)
CoordinatorLayout coordinatorLayout;
@BindView(R.id.recycler_view)
RecyclerView recyclerView;
private TaskListViewModel taskListViewModel;
private TaskAdapter taskAdapter = null;
private TaskListRecyclerAdapter recyclerAdapter;
@ -134,10 +143,11 @@ public class TaskListFragment extends InjectingFragment implements
protected void setSyncOngoing(final boolean ongoing) {
Activity activity = getActivity();
if (activity != null) {
activity.runOnUiThread(() -> {
swipeRefreshLayout.setRefreshing(ongoing);
emptyRefreshLayout.setRefreshing(ongoing);
});
activity.runOnUiThread(
() -> {
swipeRefreshLayout.setRefreshing(ongoing);
emptyRefreshLayout.setRefreshing(ongoing);
});
}
}
@ -164,9 +174,7 @@ public class TaskListFragment extends InjectingFragment implements
component.inject(this);
}
/**
* Called when loading up the activity
*/
/** Called when loading up the activity */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -193,8 +201,8 @@ public class TaskListFragment extends InjectingFragment implements
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View parent = inflater.inflate(R.layout.fragment_task_list, container, false);
ButterKnife.bind(this, parent);
setupRefresh(swipeRefreshLayout);
@ -237,27 +245,32 @@ public class TaskListFragment extends InjectingFragment implements
menu.findItem(R.id.menu_voice_add).setVisible(device.voiceInputAvailable());
final MenuItem item = menu.findItem(R.id.menu_search);
final SearchView actionView = (SearchView) MenuItemCompat.getActionView(item);
actionView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
query = query.trim();
String title = getString(R.string.FLA_search_filter, query);
Filter savedFilter = new Filter(title,
new QueryTemplate().where(Criterion.and(
Task.DELETION_DATE.eq(0),
Criterion.or(
Task.NOTES.like("%" + query + "%"),
Task.TITLE.like("%" + query + "%")))));
((TaskListActivity) getActivity()).onFilterItemClicked(savedFilter);
MenuItemCompat.collapseActionView(item);
return true;
}
@Override
public boolean onQueryTextChange(String query) {
return false;
}
});
actionView.setOnQueryTextListener(
new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
query = query.trim();
String title = getString(R.string.FLA_search_filter, query);
Filter savedFilter =
new Filter(
title,
new QueryTemplate()
.where(
Criterion.and(
Task.DELETION_DATE.eq(0),
Criterion.or(
Task.NOTES.like("%" + query + "%"),
Task.TITLE.like("%" + query + "%")))));
((TaskListActivity) getActivity()).onFilterItemClicked(savedFilter);
MenuItemCompat.collapseActionView(item);
return true;
}
@Override
public boolean onQueryTextChange(String query) {
return false;
}
});
}
@Override
@ -265,11 +278,11 @@ public class TaskListFragment extends InjectingFragment implements
switch (item.getItemId()) {
case R.id.menu_voice_add:
Intent recognition = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
recognition.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
recognition.putExtra(
RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
recognition.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 1);
recognition
.putExtra(RecognizerIntent.EXTRA_PROMPT, getString(R.string.voice_create_prompt));
recognition.putExtra(
RecognizerIntent.EXTRA_PROMPT, getString(R.string.voice_create_prompt));
startActivityForResult(recognition, TaskListFragment.VOICE_RECOGNITION_REQUEST_CODE);
return true;
case R.id.menu_sort:
@ -294,7 +307,8 @@ public class TaskListFragment extends InjectingFragment implements
startActivityForResult(intent, REQUEST_EDIT_FILTER);
return true;
case R.id.menu_clear_completed:
dialogBuilder.newMessageDialog(R.string.clear_completed_tasks_confirmation)
dialogBuilder
.newMessageDialog(R.string.clear_completed_tasks_confirmation)
.setPositiveButton(android.R.string.ok, (dialog, which) -> clearCompleted())
.setNegativeButton(android.R.string.cancel, null)
.show();
@ -337,22 +351,26 @@ public class TaskListFragment extends InjectingFragment implements
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
taskListViewModel.getTasks(filter, taskProperties()).observe(getActivity(), list -> {
if (list.isEmpty()) {
swipeRefreshLayout.setVisibility(View.GONE);
emptyRefreshLayout.setVisibility(View.VISIBLE);
} else {
swipeRefreshLayout.setVisibility(View.VISIBLE);
emptyRefreshLayout.setVisibility(View.GONE);
}
taskListViewModel
.getTasks(filter, taskProperties())
.observe(
getActivity(),
list -> {
if (list.isEmpty()) {
swipeRefreshLayout.setVisibility(View.GONE);
emptyRefreshLayout.setVisibility(View.VISIBLE);
} else {
swipeRefreshLayout.setVisibility(View.VISIBLE);
emptyRefreshLayout.setVisibility(View.GONE);
}
// stash selected items
Bundle saveState = recyclerAdapter.getSaveState();
// stash selected items
Bundle saveState = recyclerAdapter.getSaveState();
recyclerAdapter.setList(list);
recyclerAdapter.setList(list);
recyclerAdapter.restoreSaveState(saveState);
});
recyclerAdapter.restoreSaveState(saveState);
});
((DefaultItemAnimator) recyclerView.getItemAnimator()).setSupportsChangeAnimations(false);
recyclerAdapter.applyToRecyclerView(recyclerView);
@ -369,8 +387,9 @@ public class TaskListFragment extends InjectingFragment implements
}
public Snackbar makeSnackbar(String text) {
Snackbar snackbar = Snackbar.make(coordinatorLayout, text, 8000)
.setActionTextColor(getColor(context, R.color.snackbar_text_color));
Snackbar snackbar =
Snackbar.make(coordinatorLayout, text, 8000)
.setActionTextColor(getColor(context, R.color.snackbar_text_color));
snackbar.getView().setBackgroundColor(getColor(context, R.color.snackbar_background));
return snackbar;
}
@ -383,8 +402,8 @@ public class TaskListFragment extends InjectingFragment implements
}
/**
* Called by the RefreshReceiver when the task list receives a refresh
* broadcast. Subclasses should override this.
* Called by the RefreshReceiver when the task list receives a refresh broadcast. Subclasses
* should override this.
*/
private void refresh() {
// TODO: compare indents in diff callback, then animate this
@ -413,9 +432,7 @@ public class TaskListFragment extends InjectingFragment implements
return new TaskAdapter();
}
/**
* Fill in the Task List with current items
*/
/** Fill in the Task List with current items */
protected void setTaskAdapter() {
if (filter == null) {
return;
@ -423,8 +440,16 @@ public class TaskListFragment extends InjectingFragment implements
// set up list adapters
taskAdapter = createTaskAdapter();
recyclerAdapter = new TaskListRecyclerAdapter(getActivity(), taskAdapter, viewHolderFactory,
this, taskDeleter, taskDuplicator, tracker, dialogBuilder);
recyclerAdapter =
new TaskListRecyclerAdapter(
getActivity(),
taskAdapter,
viewHolderFactory,
this,
taskDeleter,
taskDuplicator,
tracker,
dialogBuilder);
taskAdapter.setHelper(recyclerAdapter.getHelper());
}
@ -443,8 +468,7 @@ public class TaskListFragment extends InjectingFragment implements
syncAdapters.syncNow();
}
public void onTaskCreated(String uuid) {
}
public void onTaskCreated(String uuid) {}
/*
* ======================================================================
@ -476,8 +500,9 @@ public class TaskListFragment extends InjectingFragment implements
List<String> match = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
if (match != null && match.size() > 0 && match.get(0).length() > 0) {
String recognizedSpeech = match.get(0);
recognizedSpeech = recognizedSpeech.substring(0, 1).toUpperCase() +
recognizedSpeech.substring(1).toLowerCase();
recognizedSpeech =
recognizedSpeech.substring(0, 1).toUpperCase()
+ recognizedSpeech.substring(1).toLowerCase();
onTaskListItemClicked(addTask(recognizedSpeech));
}
@ -489,8 +514,11 @@ public class TaskListFragment extends InjectingFragment implements
if (FilterSettingsActivity.ACTION_FILTER_DELETED.equals(action)) {
activity.onFilterItemClicked(null);
} else if (FilterSettingsActivity.ACTION_FILTER_RENAMED.equals(action)) {
activity.getIntent().putExtra(TaskListActivity.OPEN_FILTER,
(Filter) data.getParcelableExtra(FilterSettingsActivity.TOKEN_FILTER));
activity
.getIntent()
.putExtra(
TaskListActivity.OPEN_FILTER,
(Filter) data.getParcelableExtra(FilterSettingsActivity.TOKEN_FILTER));
activity.recreate();
}
}
@ -509,13 +537,13 @@ public class TaskListFragment extends InjectingFragment implements
}
protected boolean hasDraggableOption() {
return BuiltInFilterExposer.isInbox(context, filter) || BuiltInFilterExposer
.isTodayFilter(context, filter);
return BuiltInFilterExposer.isInbox(context, filter)
|| BuiltInFilterExposer.isTodayFilter(context, filter);
}
/**
* Container Activity must implement this interface and we ensure that it
* does during the onAttach() callback
* Container Activity must implement this interface and we ensure that it does during the
* onAttach() callback
*/
public interface TaskListFragmentCallbackHandler {

@ -1,9 +1,8 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
* <p>See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.adapter;
import static android.support.v4.content.ContextCompat.getColor;
@ -71,9 +70,14 @@ public class FilterAdapter extends ArrayAdapter<FilterListItem> {
private Filter selected;
@Inject
public FilterAdapter(FilterProvider filterProvider, FilterCounter filterCounter,
public FilterAdapter(
FilterProvider filterProvider,
FilterCounter filterCounter,
Activity activity,
Theme theme, ThemeCache themeCache, Locale locale, Preferences preferences) {
Theme theme,
ThemeCache themeCache,
Locale locale,
Preferences preferences) {
super(activity, 0);
this.filterProvider = filterProvider;
this.filterCounter = filterCounter;
@ -118,9 +122,7 @@ public class FilterAdapter extends ArrayAdapter<FilterListItem> {
filterCounter.refreshFilterCounts(this::notifyDataSetChanged);
}
/**
* Create or reuse a view
*/
/** Create or reuse a view */
private View newView(View convertView, ViewGroup parent, FilterListItem.Type viewType) {
if (convertView == null) {
ViewHolder viewHolder = new ViewHolder();
@ -131,11 +133,17 @@ public class FilterAdapter extends ArrayAdapter<FilterListItem> {
if (navigationDrawer) {
viewHolder.name.setCheckMarkDrawable(null);
} else if (preLollipop()) {
ColorStateList tintList = new ColorStateList(new int[][]{
new int[]{-android.R.attr.state_checked}, new int[]{android.R.attr.state_checked}},
new int[]{
ResourcesCompat.getColor(activity.getResources(), android.R.color.transparent,
null), theme.getThemeAccent().getAccentColor()});
ColorStateList tintList =
new ColorStateList(
new int[][] {
new int[] {-android.R.attr.state_checked},
new int[] {android.R.attr.state_checked}
},
new int[] {
ResourcesCompat.getColor(
activity.getResources(), android.R.color.transparent, null),
theme.getThemeAccent().getAccentColor()
});
Drawable original = ContextCompat.getDrawable(activity, R.drawable.ic_check_black_24dp);
Drawable wrapped = DrawableCompat.wrap(original.mutate());
DrawableCompat.setTintList(wrapped, tintList);
@ -264,21 +272,23 @@ public class FilterAdapter extends ArrayAdapter<FilterListItem> {
addSubMenu(R.string.filters, filterProvider.getFilters(), false);
if (navigationDrawer) {
add(new NavigationDrawerAction(
activity.getResources().getString(R.string.FLA_new_filter),
R.drawable.ic_add_24dp,
new Intent(activity, CustomFilterActivity.class),
NavigationDrawerFragment.ACTIVITY_REQUEST_NEW_FILTER));
add(
new NavigationDrawerAction(
activity.getResources().getString(R.string.FLA_new_filter),
R.drawable.ic_add_24dp,
new Intent(activity, CustomFilterActivity.class),
NavigationDrawerFragment.ACTIVITY_REQUEST_NEW_FILTER));
}
addSubMenu(R.string.tags, filterProvider.getTags(), false);
if (navigationDrawer) {
add(new NavigationDrawerAction(
activity.getResources().getString(R.string.new_tag),
R.drawable.ic_add_24dp,
new Intent(activity, TagSettingsActivity.class),
NavigationDrawerFragment.REQUEST_NEW_LIST));
add(
new NavigationDrawerAction(
activity.getResources().getString(R.string.new_tag),
R.drawable.ic_add_24dp,
new Intent(activity, TagSettingsActivity.class),
NavigationDrawerFragment.REQUEST_NEW_LIST));
}
List<Filter> googleTaskFilters = filterProvider.getGoogleTaskFilters();
@ -290,39 +300,43 @@ public class FilterAdapter extends ArrayAdapter<FilterListItem> {
addSubMenu(title, googleTaskFilters, true);
if (navigationDrawer) {
add(new NavigationDrawerAction(
activity.getResources().getString(R.string.new_list),
R.drawable.ic_add_24dp,
new Intent(activity, GoogleTaskListSettingsActivity.class),
NavigationDrawerFragment.REQUEST_NEW_GTASK_LIST));
add(
new NavigationDrawerAction(
activity.getResources().getString(R.string.new_list),
R.drawable.ic_add_24dp,
new Intent(activity, GoogleTaskListSettingsActivity.class),
NavigationDrawerFragment.REQUEST_NEW_GTASK_LIST));
}
}
if (preferences.getBoolean(R.string.p_sync_caldav, false)) {
addSubMenu(R.string.CalDAV, filterProvider.getCaldavFilters(), false);
if (navigationDrawer) {
add(new NavigationDrawerAction(
activity.getResources().getString(R.string.add_account),
R.drawable.ic_add_24dp,
new Intent(activity, CaldavSettingsActivity.class),
NavigationDrawerFragment.REQUEST_NEW_CALDAV_ACCOUNT));
add(
new NavigationDrawerAction(
activity.getResources().getString(R.string.add_account),
R.drawable.ic_add_24dp,
new Intent(activity, CaldavSettingsActivity.class),
NavigationDrawerFragment.REQUEST_NEW_CALDAV_ACCOUNT));
}
}
if (navigationDrawer) {
add(new NavigationDrawerSeparator());
add(new NavigationDrawerAction(
activity.getResources().getString(R.string.TLA_menu_settings),
R.drawable.ic_settings_24dp,
new Intent(activity, BasicPreferences.class),
REQUEST_SETTINGS));
add(new NavigationDrawerAction(
activity.getResources().getString(R.string.help_and_feedback),
R.drawable.ic_help_24dp,
new Intent(activity, HelpAndFeedbackActivity.class),
0));
add(
new NavigationDrawerAction(
activity.getResources().getString(R.string.TLA_menu_settings),
R.drawable.ic_settings_24dp,
new Intent(activity, BasicPreferences.class),
REQUEST_SETTINGS));
add(
new NavigationDrawerAction(
activity.getResources().getString(R.string.help_and_feedback),
R.drawable.ic_help_24dp,
new Intent(activity, HelpAndFeedbackActivity.class),
0));
}
notifyDataSetChanged();
@ -343,9 +357,10 @@ public class FilterAdapter extends ArrayAdapter<FilterListItem> {
}
viewHolder.icon.setImageResource(filter.icon);
viewHolder.icon.setColorFilter(filter.tint >= 0
? themeCache.getThemeColor(filter.tint).getPrimaryColor()
: getColor(activity, R.color.text_primary));
viewHolder.icon.setColorFilter(
filter.tint >= 0
? themeCache.getThemeColor(filter.tint).getPrimaryColor()
: getColor(activity, R.color.text_primary));
String title = filter.listingTitle;
if (!title.equals(viewHolder.name.getText())) {

@ -1,9 +1,8 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
* <p>See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.adapter;
import static com.google.common.collect.Lists.newArrayList;
@ -28,19 +27,26 @@ import org.tasks.data.TaskAttachment;
*/
public class TaskAdapter {
private static final StringProperty TAGS = new StringProperty(null,
"group_concat(nullif(" + TaskListFragment.TAGS_METADATA_JOIN + ".tag_uid, '')" + ", ',')")
.as("tags");
private static final LongProperty FILE_ID_PROPERTY = TaskAttachment.ID
.cloneAs(TaskListFragment.FILE_METADATA_JOIN, "fileId");
public static final Property<?>[] PROPERTIES = ObjectArrays.concat(
Task.PROPERTIES,
new Property<?>[]{
TAGS, // Concatenated list of tags
FILE_ID_PROPERTY // File id
}, Property.class);
private AsyncPagedListDiffer<Task> helper;
private static final StringProperty TAGS =
new StringProperty(
null,
"group_concat(nullif("
+ TaskListFragment.TAGS_METADATA_JOIN
+ ".tag_uid, '')"
+ ", ',')")
.as("tags");
private static final LongProperty FILE_ID_PROPERTY =
TaskAttachment.ID.cloneAs(TaskListFragment.FILE_METADATA_JOIN, "fileId");
public static final Property<?>[] PROPERTIES =
ObjectArrays.concat(
Task.PROPERTIES,
new Property<?>[] {
TAGS, // Concatenated list of tags
FILE_ID_PROPERTY // File id
},
Property.class);
private final Set<Long> selected = new HashSet<>();
private AsyncPagedListDiffer<Task> helper;
private OnCompletedTaskListener onCompletedTaskListener = null;
public int getCount() {
@ -89,13 +95,9 @@ public class TaskAdapter {
return false;
}
public void moved(int from, int to) {
public void moved(int from, int to) {}
}
public void indented(int position, int delta) {
}
public void indented(int position, int delta) {}
public long getTaskId(int position) {
return getTask(position).getId();

@ -1,9 +1,8 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
* <p>See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.alarms;
import java.util.LinkedHashSet;
@ -91,27 +90,21 @@ public class AlarmService {
return alarmDao.getActiveAlarms(taskId);
}
/**
* Schedules all alarms
*/
/** Schedules all alarms */
public void scheduleAllAlarms() {
for (Alarm alarm : getActiveAlarms()) {
scheduleAlarm(alarm);
}
}
/**
* Schedules alarms for a single task
*/
/** Schedules alarms for a single task */
private void scheduleAlarms(long taskId) {
for (Alarm alarm : getActiveAlarmsForTask(taskId)) {
scheduleAlarm(alarm);
}
}
/**
* Schedules alarms for a single task
*/
/** Schedules alarms for a single task */
private void scheduleAlarm(Alarm alarm) {
if (alarm == null) {
return;

@ -1,9 +1,8 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
* <p>See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.api;
/**
@ -13,23 +12,15 @@ package com.todoroo.astrid.api;
*/
public class AstridApiConstants {
/**
* Name of Astrid's publicly readable preference store
*/
/** Name of Astrid's publicly readable preference store */
public static final String PUBLIC_PREFS = "public";
/**
* Extras name for task id
*/
/** Extras name for task id */
public static final String EXTRAS_TASK_ID = "task_id";
/**
* Extras name for old task due date
*/
/** Extras name for old task due date */
public static final String EXTRAS_OLD_DUE_DATE = "oldDueDate";
/**
* Extras name for new task due date
*/
/** Extras name for new task due date */
public static final String EXTRAS_NEW_DUE_DATE = "newDueDate";
}

@ -15,30 +15,25 @@ import org.tasks.data.CaldavTask;
public class CaldavFilter extends Filter {
/**
* Parcelable Creator Object
*/
public static final Creator<CaldavFilter> CREATOR = new Creator<CaldavFilter>() {
/** Parcelable Creator Object */
public static final Creator<CaldavFilter> CREATOR =
new Creator<CaldavFilter>() {
/**
* {@inheritDoc}
*/
@Override
public CaldavFilter createFromParcel(Parcel source) {
CaldavFilter item = new CaldavFilter();
item.readFromParcel(source);
return item;
}
/** {@inheritDoc} */
@Override
public CaldavFilter createFromParcel(Parcel source) {
CaldavFilter item = new CaldavFilter();
item.readFromParcel(source);
return item;
}
/**
* {@inheritDoc}
*/
@Override
public CaldavFilter[] newArray(int size) {
return new CaldavFilter[size];
}
/** {@inheritDoc} */
@Override
public CaldavFilter[] newArray(int size) {
return new CaldavFilter[size];
}
};
};
private static final int TAG = R.drawable.ic_cloud_black_24dp;
private CaldavAccount account;
@ -56,9 +51,10 @@ public class CaldavFilter extends Filter {
private static QueryTemplate queryTemplate(CaldavAccount caldavAccount) {
return new QueryTemplate()
.join(Join.left(CaldavTask.TABLE, Task.ID.eq(Field.field("caldav_tasks.task"))))
.where(Criterion.and(
TaskDao.TaskCriteria.activeAndVisible(),
Field.field("account").eq(caldavAccount.getUuid())));
.where(
Criterion.and(
TaskDao.TaskCriteria.activeAndVisible(),
Field.field("account").eq(caldavAccount.getUuid())));
}
private static Map<String, Object> getValuesForNewTask(CaldavAccount caldavAccount) {
@ -71,9 +67,7 @@ public class CaldavFilter extends Filter {
return account.getUuid();
}
/**
* {@inheritDoc}
*/
/** {@inheritDoc} */
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);

@ -8,32 +8,28 @@ import java.util.Map;
public class CustomFilter extends Filter {
/**
* Parcelable Creator Object
*/
public static final Parcelable.Creator<CustomFilter> CREATOR = new Parcelable.Creator<CustomFilter>() {
/** Parcelable Creator Object */
public static final Parcelable.Creator<CustomFilter> CREATOR =
new Parcelable.Creator<CustomFilter>() {
/**
* {@inheritDoc}
*/
@Override
public CustomFilter createFromParcel(Parcel source) {
return new CustomFilter(source);
}
/** {@inheritDoc} */
@Override
public CustomFilter createFromParcel(Parcel source) {
return new CustomFilter(source);
}
/** {@inheritDoc} */
@Override
public CustomFilter[] newArray(int size) {
return new CustomFilter[size];
}
};
/**
* {@inheritDoc}
*/
@Override
public CustomFilter[] newArray(int size) {
return new CustomFilter[size];
}
};
private long id;
private String criterion;
public CustomFilter(String listingTitle, String sql, Map<String, Object> values, long id,
String criterion) {
public CustomFilter(
String listingTitle, String sql, Map<String, Object> values, long id, String criterion) {
super(listingTitle, sql, values);
this.id = id;
this.criterion = criterion;
@ -59,9 +55,7 @@ public class CustomFilter extends Filter {
return id;
}
/**
* {@inheritDoc}
*/
/** {@inheritDoc} */
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);

@ -1,9 +1,8 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
* <p>See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.api;
import android.graphics.Bitmap;
@ -13,59 +12,51 @@ import java.util.HashMap;
import java.util.Map;
/**
* CustomFilterCriteria allow users to build a custom filter by chaining
* together criteria
* CustomFilterCriteria allow users to build a custom filter by chaining together criteria
*
* @author Tim Su <tim@todoroo.com>
*/
abstract public class CustomFilterCriterion implements Parcelable {
public abstract class CustomFilterCriterion implements Parcelable {
/**
* Values to apply to a task when quick-adding a task from a filter
* created from this criterion. ? will be replaced with the entry value.
* For example, when a user views tasks tagged 'ABC', the
* tasks they create should also be tagged 'ABC'. If set to null, no
* additional values will be stored for a task.
* Values to apply to a task when quick-adding a task from a filter created from this criterion. ?
* will be replaced with the entry value. For example, when a user views tasks tagged 'ABC', the
* tasks they create should also be tagged 'ABC'. If set to null, no additional values will be
* stored for a task.
*/
public final Map<String, Object> valuesForNewTasks = new HashMap<>();
/**
* Criteria Identifier. This identifier allows saved filters to be reloaded.
* <p>
* e.g "duedate"
*
* <p>e.g "duedate"
*/
public String identifier;
/**
* Criteria Title. If the title contains ?, this is replaced by the entry
* label string selected.
* <p>
* e.g "Due: ?"
* Criteria Title. If the title contains ?, this is replaced by the entry label string selected.
*
* <p>e.g "Due: ?"
*/
public String text;
/**
* Criterion SQL. This query should return task id's. If this contains
* ?, it will be replaced by the entry value
* <p>
* Examples:
* Criterion SQL. This query should return task id's. If this contains ?, it will be replaced by
* the entry value
*
* <p>Examples:
*
* <ul>
* <li><code>SELECT _id FROM tasks WHERE dueDate <= ?</code>
* <li><code>SELECT task FROM metadata WHERE value = '?'</code>
* <li><code>SELECT _id FROM tasks WHERE dueDate <= ?</code>
* <li><code>SELECT task FROM metadata WHERE value = '?'</code>
* </ul>
*/
public String sql;
/**
* Criteria name. This is displayed when users are selecting a criteria
*/
/** Criteria name. This is displayed when users are selecting a criteria */
public String name;
/**
* Icon for this criteria. Can be null for no bitmap
*/
/** Icon for this criteria. Can be null for no bitmap */
Bitmap icon;
// --- parcelable utilities
/**
* Utility method to write to parcel
*/
/** Utility method to write to parcel */
void writeToParcel(Parcel dest) {
dest.writeString(identifier);
dest.writeString(text);
@ -75,9 +66,7 @@ abstract public class CustomFilterCriterion implements Parcelable {
dest.writeString(name);
}
/**
* Utility method to read from parcel
*/
/** Utility method to read from parcel */
void readFromParcel(Parcel source) {
identifier = source.readString();
text = source.readString();

@ -1,9 +1,8 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
* <p>See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.api;
import android.os.Parcel;
@ -14,57 +13,49 @@ import java.util.HashMap;
import java.util.Map;
/**
* A <code>FilterListFilter</code> allows users to display tasks that have
* something in common.
* <p>
* A plug-in can expose new <code>FilterListFilter</code>s to the system by
* responding to the <code>com.todoroo.astrid.GET_FILTERS</code> broadcast
* intent.
* A <code>FilterListFilter</code> allows users to display tasks that have something in common.
*
* <p>A plug-in can expose new <code>FilterListFilter</code>s to the system by responding to the
* <code>com.todoroo.astrid.GET_FILTERS</code> broadcast intent.
*
* @author Tim Su <tim@todoroo.com>
*/
public class Filter extends FilterListItem {
/** Parcelable Creator Object */
public static final Parcelable.Creator<Filter> CREATOR =
new Parcelable.Creator<Filter>() {
/** {@inheritDoc} */
@Override
public Filter createFromParcel(Parcel source) {
Filter item = new Filter();
item.readFromParcel(source);
return item;
}
/** {@inheritDoc} */
@Override
public Filter[] newArray(int size) {
return new Filter[size];
}
};
/**
* Parcelable Creator Object
*/
public static final Parcelable.Creator<Filter> CREATOR = new Parcelable.Creator<Filter>() {
/**
* {@inheritDoc}
*/
@Override
public Filter createFromParcel(Parcel source) {
Filter item = new Filter();
item.readFromParcel(source);
return item;
}
/**
* {@inheritDoc}
*/
@Override
public Filter[] newArray(int size) {
return new Filter[size];
}
};
/**
* Values to apply to a task when quick-adding a task from this filter.
* For example, when a user views tasks tagged 'ABC', the
* tasks they create should also be tagged 'ABC'. If set to null, no
* Values to apply to a task when quick-adding a task from this filter. For example, when a user
* views tasks tagged 'ABC', the tasks they create should also be tagged 'ABC'. If set to null, no
* additional values will be stored for a task. Can use {@link PermaSql}
*/
final public Map<String, Object> valuesForNewTasks = new HashMap<>();
public final Map<String, Object> valuesForNewTasks = new HashMap<>();
/**
* {@link PermaSql} query for this filter. The query will be appended to the select
* statement after "<code>SELECT fields FROM table %s</code>". It is
* recommended that you use a {@link QueryTemplate} to construct your
* query.
* <p>
* Examples:
* {@link PermaSql} query for this filter. The query will be appended to the select statement
* after "<code>SELECT fields FROM table %s</code>". It is recommended that you use a {@link
* QueryTemplate} to construct your query.
*
* <p>Examples:
*
* <ul>
* <li><code>"WHERE completionDate = 0"</code>
* <li><code>"INNER JOIN " +
* <li><code>"WHERE completionDate = 0"</code>
* <li><code>"INNER JOIN " +
* Constants.TABLE_METADATA + " ON metadata.task = tasks.id WHERE
* metadata.namespace = " + NAMESPACE + " AND metadata.key = 'a' AND
* metadata.value = 'b' GROUP BY tasks.id ORDER BY tasks.title"</code>
@ -72,8 +63,8 @@ public class Filter extends FilterListItem {
*/
String sqlQuery;
/**
* Field for holding a modified sqlQuery based on sqlQuery. Useful for adjusting
* query for sort/subtasks without breaking the equality checking based on sqlQuery.
* Field for holding a modified sqlQuery based on sqlQuery. Useful for adjusting query for
* sort/subtasks without breaking the equality checking based on sqlQuery.
*/
private String filterOverride;
@ -87,10 +78,9 @@ public class Filter extends FilterListItem {
* @param listingTitle Title of this item as displayed on the lists page, e.g. Inbox
* @param sqlQuery SQL query for this list (see {@link #sqlQuery} for examples).
*/
public Filter(String listingTitle, QueryTemplate sqlQuery,
Map<String, Object> valuesForNewTasks) {
this(listingTitle, sqlQuery == null ? null : sqlQuery.toString(),
valuesForNewTasks);
public Filter(
String listingTitle, QueryTemplate sqlQuery, Map<String, Object> valuesForNewTasks) {
this(listingTitle, sqlQuery == null ? null : sqlQuery.toString(), valuesForNewTasks);
}
/**
@ -108,9 +98,7 @@ public class Filter extends FilterListItem {
}
}
/**
* Utility constructor
*/
/** Utility constructor */
Filter() {
// do nothing
}
@ -132,8 +120,7 @@ public class Filter extends FilterListItem {
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((sqlQuery == null) ? 0 : sqlQuery.hashCode());
result = prime * result + ((sqlQuery == null) ? 0 : sqlQuery.hashCode());
result = prime * result + ((listingTitle == null) ? 0 : listingTitle.hashCode());
return result;
}
@ -172,9 +159,7 @@ public class Filter extends FilterListItem {
return Type.ITEM;
}
/**
* {@inheritDoc}
*/
/** {@inheritDoc} */
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
@ -197,10 +182,15 @@ public class Filter extends FilterListItem {
@Override
public String toString() {
return "Filter{" +
"sqlQuery='" + sqlQuery + '\'' +
", filterOverride='" + filterOverride + '\'' +
", valuesForNewTasks=" + valuesForNewTasks +
'}';
return "Filter{"
+ "sqlQuery='"
+ sqlQuery
+ '\''
+ ", filterOverride='"
+ filterOverride
+ '\''
+ ", valuesForNewTasks="
+ valuesForNewTasks
+ '}';
}
}

@ -1,9 +1,8 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
* <p>See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.api;
import android.content.Intent;
@ -15,12 +14,11 @@ import android.os.Parcelable;
*
* @author Tim Su <tim@todoroo.com>
*/
abstract public class FilterListItem implements Parcelable {
public abstract class FilterListItem implements Parcelable {
/**
* Title of this item displayed on the Filters page
*/
/** Title of this item displayed on the Filters page */
public String listingTitle = null;
public int icon = 0;
public int tint = -1;
@ -31,9 +29,7 @@ abstract public class FilterListItem implements Parcelable {
return 0;
}
/**
* {@inheritDoc}
*/
/** {@inheritDoc} */
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(listingTitle);
@ -45,9 +41,7 @@ abstract public class FilterListItem implements Parcelable {
// --- parcelable helpers
/**
* Utility method to read FilterListItem properties from a parcel.
*/
/** Utility method to read FilterListItem properties from a parcel. */
protected void readFromParcel(Parcel source) {
listingTitle = source.readString();
icon = source.readInt();
@ -58,9 +52,7 @@ abstract public class FilterListItem implements Parcelable {
@Override
public String toString() {
return "FilterListItem{" +
"listingTitle='" + listingTitle + '\'' +
'}';
return "FilterListItem{" + "listingTitle='" + listingTitle + '\'' + '}';
}
public enum Type {

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save