Google Task sync improvements

* Check etag when fetching lists
* Set max results to 100
pull/820/head
Alex Baker 5 years ago
parent 2560465c19
commit db3927a59b

@ -0,0 +1,990 @@
{
"formatVersion": 1,
"database": {
"version": 62,
"identityHash": "968a43df6cf39859b015a60457c28995",
"entities": [
{
"tableName": "notification",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `task` INTEGER NOT NULL, `timestamp` INTEGER NOT NULL, `type` INTEGER NOT NULL, `location` INTEGER)",
"fields": [
{
"fieldPath": "uid",
"columnName": "uid",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "taskId",
"columnName": "task",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "timestamp",
"columnName": "timestamp",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "type",
"columnName": "type",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "location",
"columnName": "location",
"affinity": "INTEGER",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"uid"
],
"autoGenerate": true
},
"indices": [
{
"name": "index_notification_task",
"unique": true,
"columnNames": [
"task"
],
"createSql": "CREATE UNIQUE INDEX `index_notification_task` ON `${TABLE_NAME}` (`task`)"
}
],
"foreignKeys": []
},
{
"tableName": "tagdata",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `remoteId` TEXT, `name` TEXT, `color` INTEGER, `tagOrdering` TEXT)",
"fields": [
{
"fieldPath": "id",
"columnName": "_id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "remoteId",
"columnName": "remoteId",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "color",
"columnName": "color",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "tagOrdering",
"columnName": "tagOrdering",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"_id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "userActivity",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `remoteId` TEXT, `message` TEXT, `picture` TEXT, `target_id` TEXT, `created_at` INTEGER)",
"fields": [
{
"fieldPath": "id",
"columnName": "_id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "remoteId",
"columnName": "remoteId",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "message",
"columnName": "message",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "picture",
"columnName": "picture",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "targetId",
"columnName": "target_id",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "created",
"columnName": "created_at",
"affinity": "INTEGER",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"_id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "task_attachments",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `remoteId` TEXT, `task_id` TEXT, `name` TEXT, `path` TEXT, `content_type` TEXT)",
"fields": [
{
"fieldPath": "id",
"columnName": "_id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "remoteId",
"columnName": "remoteId",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "taskId",
"columnName": "task_id",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "uri",
"columnName": "path",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "contentType",
"columnName": "content_type",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"_id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "task_list_metadata",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `remoteId` TEXT, `tag_uuid` TEXT, `filter` TEXT, `task_ids` TEXT)",
"fields": [
{
"fieldPath": "id",
"columnName": "_id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "remoteId",
"columnName": "remoteId",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "tagUuid",
"columnName": "tag_uuid",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "filter",
"columnName": "filter",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "taskIds",
"columnName": "task_ids",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"_id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "tasks",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `title` TEXT, `importance` INTEGER, `dueDate` INTEGER, `hideUntil` INTEGER, `created` INTEGER, `modified` INTEGER, `completed` INTEGER, `deleted` INTEGER, `notes` TEXT, `estimatedSeconds` INTEGER, `elapsedSeconds` INTEGER, `timerStart` INTEGER, `notificationFlags` INTEGER, `notifications` INTEGER, `lastNotified` INTEGER, `snoozeTime` INTEGER, `recurrence` TEXT, `repeatUntil` INTEGER, `calendarUri` TEXT, `remoteId` TEXT)",
"fields": [
{
"fieldPath": "id",
"columnName": "_id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "title",
"columnName": "title",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "priority",
"columnName": "importance",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "dueDate",
"columnName": "dueDate",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "hideUntil",
"columnName": "hideUntil",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "created",
"columnName": "created",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "modified",
"columnName": "modified",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "completed",
"columnName": "completed",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "deleted",
"columnName": "deleted",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "notes",
"columnName": "notes",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "estimatedSeconds",
"columnName": "estimatedSeconds",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "elapsedSeconds",
"columnName": "elapsedSeconds",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "timerStart",
"columnName": "timerStart",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "notificationFlags",
"columnName": "notificationFlags",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "notifications",
"columnName": "notifications",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "lastNotified",
"columnName": "lastNotified",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "snoozeTime",
"columnName": "snoozeTime",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "recurrence",
"columnName": "recurrence",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "repeatUntil",
"columnName": "repeatUntil",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "calendarUri",
"columnName": "calendarUri",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "remoteId",
"columnName": "remoteId",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"_id"
],
"autoGenerate": true
},
"indices": [
{
"name": "t_rid",
"unique": true,
"columnNames": [
"remoteId"
],
"createSql": "CREATE UNIQUE INDEX `t_rid` ON `${TABLE_NAME}` (`remoteId`)"
}
],
"foreignKeys": []
},
{
"tableName": "alarms",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `task` INTEGER NOT NULL, `time` INTEGER NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "task",
"columnName": "task",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "time",
"columnName": "time",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"_id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "places",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`place_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `uid` TEXT, `name` TEXT, `address` TEXT, `phone` TEXT, `url` TEXT, `latitude` REAL NOT NULL, `longitude` REAL NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "place_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "uid",
"columnName": "uid",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "address",
"columnName": "address",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "phone",
"columnName": "phone",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "url",
"columnName": "url",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "latitude",
"columnName": "latitude",
"affinity": "REAL",
"notNull": true
},
{
"fieldPath": "longitude",
"columnName": "longitude",
"affinity": "REAL",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"place_id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "geofences",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`geofence_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `task` INTEGER NOT NULL, `place` TEXT, `radius` INTEGER NOT NULL, `arrival` INTEGER NOT NULL, `departure` INTEGER NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "geofence_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "task",
"columnName": "task",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "place",
"columnName": "place",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "radius",
"columnName": "radius",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "arrival",
"columnName": "arrival",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "departure",
"columnName": "departure",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"geofence_id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "tags",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `task` INTEGER NOT NULL, `name` TEXT, `tag_uid` TEXT, `task_uid` TEXT)",
"fields": [
{
"fieldPath": "id",
"columnName": "_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "task",
"columnName": "task",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "tagUid",
"columnName": "tag_uid",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "taskUid",
"columnName": "task_uid",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"_id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "google_tasks",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `task` INTEGER NOT NULL, `remote_id` TEXT, `list_id` TEXT, `parent` INTEGER NOT NULL, `indent` INTEGER NOT NULL, `order` INTEGER NOT NULL, `remote_order` INTEGER NOT NULL, `last_sync` INTEGER NOT NULL, `deleted` INTEGER NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "task",
"columnName": "task",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "remoteId",
"columnName": "remote_id",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "listId",
"columnName": "list_id",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "parent",
"columnName": "parent",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "indent",
"columnName": "indent",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "order",
"columnName": "order",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "remoteOrder",
"columnName": "remote_order",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "lastSync",
"columnName": "last_sync",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "deleted",
"columnName": "deleted",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"_id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "filters",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `title` TEXT, `sql` TEXT, `values` TEXT, `criterion` TEXT)",
"fields": [
{
"fieldPath": "id",
"columnName": "_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "title",
"columnName": "title",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "sql",
"columnName": "sql",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "values",
"columnName": "values",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "criterion",
"columnName": "criterion",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"_id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "google_task_lists",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `account` TEXT, `remote_id` TEXT, `title` TEXT, `remote_order` INTEGER NOT NULL, `last_sync` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `color` INTEGER)",
"fields": [
{
"fieldPath": "id",
"columnName": "_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "account",
"columnName": "account",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "remoteId",
"columnName": "remote_id",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "title",
"columnName": "title",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "remoteOrder",
"columnName": "remote_order",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "lastSync",
"columnName": "last_sync",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "deleted",
"columnName": "deleted",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "color",
"columnName": "color",
"affinity": "INTEGER",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"_id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "caldav_calendar",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `account` TEXT, `uuid` TEXT, `name` TEXT, `color` INTEGER NOT NULL, `ctag` TEXT, `url` TEXT)",
"fields": [
{
"fieldPath": "id",
"columnName": "_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "account",
"columnName": "account",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "uuid",
"columnName": "uuid",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "color",
"columnName": "color",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "ctag",
"columnName": "ctag",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "url",
"columnName": "url",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"_id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "caldav_tasks",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `task` INTEGER NOT NULL, `calendar` TEXT, `object` TEXT, `remote_id` TEXT, `etag` TEXT, `last_sync` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `vtodo` TEXT)",
"fields": [
{
"fieldPath": "id",
"columnName": "_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "task",
"columnName": "task",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "calendar",
"columnName": "calendar",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "object",
"columnName": "object",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "remoteId",
"columnName": "remote_id",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "etag",
"columnName": "etag",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "lastSync",
"columnName": "last_sync",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "deleted",
"columnName": "deleted",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "vtodo",
"columnName": "vtodo",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"_id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "caldav_account",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `uuid` TEXT, `name` TEXT, `url` TEXT, `username` TEXT, `password` TEXT, `error` TEXT)",
"fields": [
{
"fieldPath": "id",
"columnName": "_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "uuid",
"columnName": "uuid",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "url",
"columnName": "url",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "username",
"columnName": "username",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "password",
"columnName": "password",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "error",
"columnName": "error",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"_id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "google_task_accounts",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `account` TEXT, `error` TEXT, `etag` TEXT)",
"fields": [
{
"fieldPath": "id",
"columnName": "_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "account",
"columnName": "account",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "error",
"columnName": "error",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "etag",
"columnName": "etag",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"_id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"968a43df6cf39859b015a60457c28995\")"
]
}
}

@ -58,7 +58,7 @@ import org.tasks.notifications.NotificationDao;
CaldavAccount.class,
GoogleTaskAccount.class
},
version = 61)
version = 62)
public abstract class Database extends RoomDatabase {
public static final String NAME = "database";

@ -98,16 +98,15 @@ public class GtasksListService {
List<GoogleTaskList> listsToUpdate = newArrayList();
for (TaskList remoteList : remoteLists) {
GoogleTaskList localList = getList(remoteList.getId());
String listName = localList.getTitle();
Long lastSync = localList.getLastSync();
long lastSync = localList.getLastSync();
long lastUpdate = remoteList.getUpdated().getValue();
if (lastSync < lastUpdate) {
listsToUpdate.add(localList);
Timber.d(
"%s out of date [local=%s] [remote=%s]",
listName, printTimestamp(lastSync), printTimestamp(lastUpdate));
localList.getTitle(), printTimestamp(lastSync), printTimestamp(lastUpdate));
} else {
Timber.d("%s up to date", listName);
Timber.d("%s up to date", localList.getTitle());
}
}
return listsToUpdate;

@ -2,6 +2,7 @@ package com.todoroo.astrid.gtasks.api;
import android.accounts.AccountManager;
import android.os.Bundle;
import androidx.annotation.Nullable;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpResponse;
@ -44,37 +45,31 @@ public class GtasksInvoker {
String token = bundle.getString(AccountManager.KEY_AUTHTOKEN);
credential = new GoogleCredential().setAccessToken(token);
service =
new Tasks.Builder(
new NetHttpTransport(),
new JacksonFactory(),
credential)
new Tasks.Builder(new NetHttpTransport(), new JacksonFactory(), credential)
.setApplicationName(String.format("Tasks/%s", BuildConfig.VERSION_NAME))
.build();
}
public TaskLists allGtaskLists(String pageToken) throws IOException {
return execute(service.tasklists().list().setPageToken(pageToken));
public @Nullable TaskLists allGtaskLists(@Nullable String pageToken) throws IOException {
return execute(service.tasklists().list().setMaxResults(100L).setPageToken(pageToken));
}
public com.google.api.services.tasks.model.Tasks getAllGtasksFromListId(
String listId,
boolean includeDeleted,
boolean includeHidden,
long lastSyncDate,
String pageToken)
public @Nullable com.google.api.services.tasks.model.Tasks getAllGtasksFromListId(
String listId, boolean includeHiddenAndDeleted, long lastSyncDate, @Nullable String pageToken)
throws IOException {
return execute(
service
.tasks()
.list(listId)
.setShowDeleted(includeDeleted)
.setShowHidden(includeHidden)
.setMaxResults(100L)
.setShowDeleted(includeHiddenAndDeleted)
.setShowHidden(includeHiddenAndDeleted)
.setPageToken(pageToken)
.setUpdatedMin(
GtasksApiUtilities.unixTimeToGtasksCompletionTime(lastSyncDate).toStringRfc3339()));
}
public Task createGtask(String listId, Task task, String parent, String priorSiblingId)
public @Nullable Task createGtask(String listId, Task task, String parent, String priorSiblingId)
throws IOException {
Timber.d("createGtask: %s", prettyPrint(task));
return execute(
@ -86,6 +81,7 @@ public class GtasksInvoker {
execute(service.tasks().update(listId, task.getId(), task));
}
@Nullable
Task moveGtask(String listId, String taskId, String parentId, String previousId)
throws IOException {
return execute(
@ -99,11 +95,11 @@ public class GtasksInvoker {
}
}
public TaskList renameGtaskList(String listId, String title) throws IOException {
public @Nullable TaskList renameGtaskList(String listId, String title) throws IOException {
return execute(service.tasklists().patch(listId, new TaskList().setTitle(title)));
}
public TaskList createGtaskList(String title) throws IOException {
public @Nullable TaskList createGtaskList(String title) throws IOException {
return execute(service.tasklists().insert(new TaskList().setTitle(title)));
}
@ -114,11 +110,12 @@ public class GtasksInvoker {
}
}
private synchronized <T> T execute(TasksRequest<T> request) throws IOException {
private synchronized @Nullable <T> T execute(TasksRequest<T> request) throws IOException {
return execute(request, false);
}
private synchronized <T> T execute(TasksRequest<T> request, boolean retry) throws IOException {
private synchronized @Nullable <T> T execute(TasksRequest<T> request, boolean retry)
throws IOException {
String caller = getCaller();
Timber.d("%s request: %s", caller, request);
HttpRequest httpRequest = request.buildHttpRequest();

@ -32,6 +32,9 @@ public class GoogleTaskAccount implements Parcelable {
@ColumnInfo(name = "error")
private transient String error = "";
@ColumnInfo(name = "etag")
private String etag;
public GoogleTaskAccount() {}
@Ignore
@ -39,6 +42,7 @@ public class GoogleTaskAccount implements Parcelable {
id = source.readLong();
account = source.readString();
error = source.readString();
etag = source.readString();
}
@Ignore
@ -70,12 +74,20 @@ public class GoogleTaskAccount implements Parcelable {
this.error = error;
}
public String getEtag() {
return etag;
}
public void setEtag(String etag) {
this.etag = etag;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof GoogleTaskAccount)) {
if (o == null || getClass() != o.getClass()) {
return false;
}
@ -87,7 +99,10 @@ public class GoogleTaskAccount implements Parcelable {
if (account != null ? !account.equals(that.account) : that.account != null) {
return false;
}
return error != null ? error.equals(that.error) : that.error == null;
if (error != null ? !error.equals(that.error) : that.error != null) {
return false;
}
return etag != null ? etag.equals(that.etag) : that.etag == null;
}
@Override
@ -95,6 +110,7 @@ public class GoogleTaskAccount implements Parcelable {
int result = (int) (id ^ (id >>> 32));
result = 31 * result + (account != null ? account.hashCode() : 0);
result = 31 * result + (error != null ? error.hashCode() : 0);
result = 31 * result + (etag != null ? etag.hashCode() : 0);
return result;
}
@ -109,6 +125,9 @@ public class GoogleTaskAccount implements Parcelable {
+ ", error='"
+ error
+ '\''
+ ", etag='"
+ etag
+ '\''
+ '}';
}
@ -122,5 +141,6 @@ public class GoogleTaskAccount implements Parcelable {
dest.writeLong(id);
dest.writeString(account);
dest.writeString(error);
dest.writeString(etag);
}
}

@ -222,14 +222,26 @@ public class Migrations {
new Migration(60, 61) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
database.execSQL("CREATE TABLE IF NOT EXISTS `places` (`place_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `uid` TEXT, `name` TEXT, `address` TEXT, `phone` TEXT, `url` TEXT, `latitude` REAL NOT NULL, `longitude` REAL NOT NULL)");
database.execSQL("CREATE TABLE IF NOT EXISTS `geofences` (`geofence_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `task` INTEGER NOT NULL, `place` TEXT, `radius` INTEGER NOT NULL, `arrival` INTEGER NOT NULL, `departure` INTEGER NOT NULL)");
database.execSQL("INSERT INTO `places` (`place_id`, `uid`, `name`, `address`, `phone`, `url`, `latitude`, `longitude`) SELECT `_id`, hex(randomblob(16)), `name`, `address`, `phone`, `url`, `latitude`, `longitude` FROM `locations`");
database.execSQL("INSERT INTO `geofences` (`geofence_id`, `task`, `place`, `radius`, `arrival`, `departure`) SELECT `_id`, `task`, `uid`, `radius`, `arrival`, `departure` FROM `locations` INNER JOIN `places` ON `_id` = `place_id`");
database.execSQL(
"CREATE TABLE IF NOT EXISTS `places` (`place_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `uid` TEXT, `name` TEXT, `address` TEXT, `phone` TEXT, `url` TEXT, `latitude` REAL NOT NULL, `longitude` REAL NOT NULL)");
database.execSQL(
"CREATE TABLE IF NOT EXISTS `geofences` (`geofence_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `task` INTEGER NOT NULL, `place` TEXT, `radius` INTEGER NOT NULL, `arrival` INTEGER NOT NULL, `departure` INTEGER NOT NULL)");
database.execSQL(
"INSERT INTO `places` (`place_id`, `uid`, `name`, `address`, `phone`, `url`, `latitude`, `longitude`) SELECT `_id`, hex(randomblob(16)), `name`, `address`, `phone`, `url`, `latitude`, `longitude` FROM `locations`");
database.execSQL(
"INSERT INTO `geofences` (`geofence_id`, `task`, `place`, `radius`, `arrival`, `departure`) SELECT `_id`, `task`, `uid`, `radius`, `arrival`, `departure` FROM `locations` INNER JOIN `places` ON `_id` = `place_id`");
database.execSQL("DROP TABLE `locations`");
}
};
private static final Migration MIGRATION_61_62 =
new Migration(61, 62) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
database.execSQL("ALTER TABLE `google_task_accounts` ADD COLUMN `etag` TEXT");
}
};
public static final Migration[] MIGRATIONS =
new Migration[] {
MIGRATION_35_36,
@ -248,7 +260,8 @@ public class Migrations {
MIGRATION_54_58,
MIGRATION_58_59,
MIGRATION_59_60,
MIGRATION_60_61
MIGRATION_60_61,
MIGRATION_61_62
};
private static Migration NOOP(int from, int to) {

@ -132,6 +132,7 @@ public class GoogleTaskSynchronizer {
try {
if (i == 0 || inventory.hasPro()) {
synchronize(account);
account.setError("");
} else {
account.setError(context.getString(R.string.requires_pro_subscription));
}
@ -158,7 +159,8 @@ public class GoogleTaskSynchronizer {
PendingIntent resolve =
PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder =
new NotificationCompat.Builder(context, NotificationManager.NOTIFICATION_CHANNEL_MISCELLANEOUS)
new NotificationCompat.Builder(
context, NotificationManager.NOTIFICATION_CHANNEL_MISCELLANEOUS)
.setAutoCancel(true)
.setContentIntent(resolve)
.setContentTitle(context.getString(R.string.sync_error_permissions))
@ -184,11 +186,16 @@ public class GoogleTaskSynchronizer {
List<TaskList> gtaskLists = new ArrayList<>();
String nextPageToken = null;
String eTag = null;
do {
TaskLists remoteLists = gtasksInvoker.allGtaskLists(nextPageToken);
if (remoteLists == null) {
break;
}
eTag = remoteLists.getEtag();
if (!Strings.isNullOrEmpty(eTag) && eTag.equals(account.getEtag())) {
return;
}
List<TaskList> items = remoteLists.getItems();
if (items != null) {
gtaskLists.addAll(items);
@ -207,7 +214,7 @@ public class GoogleTaskSynchronizer {
for (final GoogleTaskList list : gtasksListService.getListsToUpdate(gtaskLists)) {
fetchAndApplyRemoteChanges(gtasksInvoker, list);
}
account.setError("");
account.setEtag(eTag);
}
private void pushLocalChanges(GoogleTaskAccount account, GtasksInvoker gtasksInvoker)
@ -333,11 +340,7 @@ public class GoogleTaskSynchronizer {
do {
Tasks taskList =
gtasksInvoker.getAllGtasksFromListId(
listId,
includeDeletedAndHidden,
includeDeletedAndHidden,
lastSyncDate + 1000L,
nextPageToken);
listId, includeDeletedAndHidden, lastSyncDate + 1000L, nextPageToken);
if (taskList == null) {
break;
}
@ -348,38 +351,36 @@ public class GoogleTaskSynchronizer {
nextPageToken = taskList.getNextPageToken();
} while (nextPageToken != null);
if (!tasks.isEmpty()) {
for (com.google.api.services.tasks.model.Task gtask : tasks) {
String remoteId = gtask.getId();
GoogleTask googleTask = getMetadataByGtaskId(remoteId);
Task task = null;
if (googleTask == null) {
googleTask = new GoogleTask(0, "");
} else if (googleTask.getTask() > 0) {
task = taskDao.fetch(googleTask.getTask());
}
Boolean isDeleted = gtask.getDeleted();
Boolean isHidden = gtask.getHidden();
if ((isDeleted != null && isDeleted) || (isHidden != null && isHidden)) {
if (task != null) {
taskDeleter.delete(task);
}
continue;
}
if (task == null) {
task = taskCreator.createWithValues("");
for (com.google.api.services.tasks.model.Task gtask : tasks) {
String remoteId = gtask.getId();
GoogleTask googleTask = getMetadataByGtaskId(remoteId);
Task task = null;
if (googleTask == null) {
googleTask = new GoogleTask(0, "");
} else if (googleTask.getTask() > 0) {
task = taskDao.fetch(googleTask.getTask());
}
Boolean isDeleted = gtask.getDeleted();
Boolean isHidden = gtask.getHidden();
if ((isDeleted != null && isDeleted) || (isHidden != null && isHidden)) {
if (task != null) {
taskDeleter.delete(task);
}
GtasksTaskContainer container = new GtasksTaskContainer(gtask, task, listId, googleTask);
container.gtaskMetadata.setRemoteOrder(Long.parseLong(gtask.getPosition()));
container.gtaskMetadata.setParent(localIdForGtasksId(gtask.getParent()));
container.gtaskMetadata.setLastSync(DateUtilities.now() + 1000L);
write(container);
lastSyncDate = Math.max(lastSyncDate, container.getUpdateTime());
continue;
}
if (task == null) {
task = taskCreator.createWithValues("");
}
list.setLastSync(lastSyncDate);
googleTaskListDao.insertOrReplace(list);
gtasksTaskListUpdater.correctOrderAndIndentForList(listId);
GtasksTaskContainer container = new GtasksTaskContainer(gtask, task, listId, googleTask);
container.gtaskMetadata.setRemoteOrder(Long.parseLong(gtask.getPosition()));
container.gtaskMetadata.setParent(localIdForGtasksId(gtask.getParent()));
container.gtaskMetadata.setLastSync(DateUtilities.now() + 1000L);
write(container);
lastSyncDate = Math.max(lastSyncDate, container.getUpdateTime());
}
list.setLastSync(lastSyncDate);
googleTaskListDao.insertOrReplace(list);
gtasksTaskListUpdater.correctOrderAndIndentForList(listId);
} catch (UserRecoverableAuthIOException e) {
throw e;
} catch (IOException e) {

Loading…
Cancel
Save