Add Flipper network interceptors

pull/820/head
Alex Baker 5 years ago
parent 4997ec3f0e
commit 31bb7b1abd

@ -9,6 +9,7 @@ import com.facebook.flipper.core.FlipperClient;
import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin;
import com.facebook.flipper.plugins.inspector.DescriptorMapping;
import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin;
import com.facebook.flipper.plugins.network.NetworkFlipperPlugin;
import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin;
import com.facebook.soloader.SoLoader;
import com.squareup.leakcanary.LeakCanary;
@ -35,6 +36,7 @@ public class BuildSetup {
FlipperClient client = AndroidFlipperClient.getInstance(context);
client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults()));
client.addPlugin(new DatabasesFlipperPlugin(context));
client.addPlugin(new NetworkFlipperPlugin());
client.addPlugin(new SharedPreferencesFlipperPlugin(context));
client.start();
}

@ -0,0 +1,21 @@
package org.tasks;
import com.google.api.client.http.HttpExecuteInterceptor;
import com.google.api.client.http.HttpRequest;
import java.io.IOException;
public class ChainedHttpExecuteInterceptor implements HttpExecuteInterceptor {
private final HttpExecuteInterceptor[] interceptors;
ChainedHttpExecuteInterceptor(HttpExecuteInterceptor... interceptors) {
this.interceptors = interceptors;
}
@Override
public void intercept(HttpRequest request) throws IOException {
for (HttpExecuteInterceptor interceptor : interceptors) {
interceptor.intercept(request);
}
}
}

@ -0,0 +1,39 @@
package org.tasks;
import android.content.Context;
import com.facebook.flipper.android.AndroidFlipperClient;
import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor;
import com.facebook.flipper.plugins.network.NetworkFlipperPlugin;
import com.google.api.client.http.HttpRequest;
import java.io.IOException;
import javax.inject.Inject;
import okhttp3.OkHttpClient;
import org.tasks.injection.ForApplication;
public class DebugNetworkInterceptor {
private final Context context;
@Inject
public DebugNetworkInterceptor(@ForApplication Context context) {
this.context = context;
}
private static NetworkFlipperPlugin getNetworkPlugin(Context context) {
return AndroidFlipperClient.getInstance(context).getPlugin(NetworkFlipperPlugin.ID);
}
public void add(OkHttpClient.Builder builder) {
builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(getNetworkPlugin(context)));
}
public <T> T execute(HttpRequest request, Class<T> responseClass) throws IOException {
FlipperHttpInterceptor<T> interceptor =
new FlipperHttpInterceptor<>(getNetworkPlugin(context), responseClass);
request
.setInterceptor(new ChainedHttpExecuteInterceptor(request.getInterceptor(), interceptor))
.setResponseInterceptor(interceptor)
.execute();
return interceptor.getResponse();
}
}

@ -0,0 +1,92 @@
package org.tasks;
import static com.todoroo.andlib.utility.DateUtilities.now;
import com.facebook.flipper.plugins.network.NetworkFlipperPlugin;
import com.facebook.flipper.plugins.network.NetworkReporter.Header;
import com.facebook.flipper.plugins.network.NetworkReporter.RequestInfo;
import com.facebook.flipper.plugins.network.NetworkReporter.ResponseInfo;
import com.google.api.client.http.HttpContent;
import com.google.api.client.http.HttpExecuteInterceptor;
import com.google.api.client.http.HttpHeaders;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpResponse;
import com.google.api.client.http.HttpResponseInterceptor;
import com.google.api.client.json.GenericJson;
import com.todoroo.astrid.helper.UUIDHelper;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import timber.log.Timber;
public class FlipperHttpInterceptor<T> implements HttpExecuteInterceptor, HttpResponseInterceptor {
private final Class<T> responseClass;
private final String requestId = UUIDHelper.newUUID();
private final NetworkFlipperPlugin plugin;
private T body;
FlipperHttpInterceptor(NetworkFlipperPlugin plugin, Class<T> responseClass) {
this.responseClass = responseClass;
this.plugin = plugin;
}
@Override
public void intercept(HttpRequest request) {
RequestInfo requestInfo = new RequestInfo();
requestInfo.method = request.getRequestMethod();
requestInfo.body = bodyToByteArray(request.getContent());
requestInfo.headers = getHeaders(request.getHeaders());
requestInfo.requestId = requestId;
requestInfo.timeStamp = now();
requestInfo.uri = request.getUrl().toString();
plugin.reportRequest(requestInfo);
}
@Override
public void interceptResponse(HttpResponse response) throws IOException {
ResponseInfo responseInfo = new ResponseInfo();
responseInfo.timeStamp = now();
responseInfo.headers = getHeaders(response.getHeaders());
responseInfo.requestId = requestId;
responseInfo.statusCode = response.getStatusCode();
responseInfo.statusReason = response.getStatusMessage();
body = response.parseAs(responseClass);
if (body instanceof GenericJson) {
try {
responseInfo.body = ((GenericJson) body).toPrettyString().getBytes();
} catch (IOException e) {
Timber.e(e);
}
}
plugin.reportResponse(responseInfo);
}
public T getResponse() {
return body;
}
private List<Header> getHeaders(HttpHeaders headers) {
List<Header> result = new ArrayList<>();
for (Map.Entry<String, Object> entry : headers.entrySet()) {
result.add(new Header(entry.getKey(), entry.getValue().toString()));
}
return result;
}
private byte[] bodyToByteArray(HttpContent content) {
if (content == null) {
return null;
}
ByteArrayOutputStream output = new ByteArrayOutputStream();
try {
content.writeTo(output);
} catch (IOException e) {
Timber.e(e);
return null;
}
return output.toByteArray();
}
}

@ -1,10 +1,11 @@
package com.todoroo.astrid.gtasks.api;
import android.accounts.AccountManager;
import android.content.Context;
import android.os.Bundle;
import androidx.annotation.Nullable;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.services.AbstractGoogleClientRequest;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpResponseException;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.GenericJson;
@ -16,10 +17,13 @@ import com.google.api.services.tasks.model.Task;
import com.google.api.services.tasks.model.TaskList;
import com.google.api.services.tasks.model.TaskLists;
import com.google.common.base.Strings;
import com.google.gson.GsonBuilder;
import java.io.IOException;
import javax.inject.Inject;
import org.tasks.BuildConfig;
import org.tasks.DebugNetworkInterceptor;
import org.tasks.gtasks.GoogleAccountManager;
import org.tasks.injection.ForApplication;
import org.tasks.preferences.Preferences;
import timber.log.Timber;
/**
@ -30,20 +34,50 @@ import timber.log.Timber;
*/
public class GtasksInvoker {
private final String account;
private final Context context;
private final GoogleAccountManager googleAccountManager;
private final Tasks service;
private final Preferences preferences;
private final DebugNetworkInterceptor interceptor;
private final GoogleCredential credential = new GoogleCredential();
private final String account;
private final Tasks service;
public GtasksInvoker(String account, GoogleAccountManager googleAccountManager) {
this.account = account;
@Inject
public GtasksInvoker(
@ForApplication Context context,
GoogleAccountManager googleAccountManager,
Preferences preferences,
DebugNetworkInterceptor interceptor) {
this.context = context;
this.googleAccountManager = googleAccountManager;
this.preferences = preferences;
this.interceptor = interceptor;
account = null;
service = null;
}
private GtasksInvoker(
Context context,
GoogleAccountManager googleAccountManager,
Preferences preferences,
DebugNetworkInterceptor interceptor,
String account) {
this.context = context;
this.googleAccountManager = googleAccountManager;
this.preferences = preferences;
this.interceptor = interceptor;
this.account = account;
service =
new Tasks.Builder(new NetHttpTransport(), new JacksonFactory(), credential)
.setApplicationName(String.format("Tasks/%s", BuildConfig.VERSION_NAME))
.build();
}
public GtasksInvoker forAccount(String account) {
return new GtasksInvoker(context, googleAccountManager, preferences, interceptor, account);
}
private void checkToken() {
if (Strings.isNullOrEmpty(credential.getAccessToken())) {
Bundle bundle = googleAccountManager.getAccessToken(account, TasksScopes.TASKS);
@ -115,10 +149,15 @@ public class GtasksInvoker {
private synchronized @Nullable <T> T execute(TasksRequest<T> request, boolean retry)
throws IOException {
checkToken();
Timber.d("%s request: %s", getCaller(retry), prettyPrint(request));
T response;
try {
response = request.execute();
HttpRequest httpRequest = request.buildHttpRequest();
Timber.d("%s", httpRequest.getUrl());
if (preferences.isFlipperEnabled()) {
response = interceptor.execute(httpRequest, request.getResponseClass());
} else {
response = httpRequest.execute().parseAs(request.getResponseClass());
}
} catch (HttpResponseException e) {
if (e.getStatusCode() == 401 && !retry) {
googleAccountManager.invalidateToken(credential.getAccessToken());
@ -136,8 +175,6 @@ public class GtasksInvoker {
if (BuildConfig.DEBUG) {
if (object instanceof GenericJson) {
return ((GenericJson) object).toPrettyString();
} else if (object instanceof AbstractGoogleClientRequest) {
return new GsonBuilder().setPrettyPrinting().create().toJson(object);
}
}
return object;

@ -4,7 +4,7 @@ import org.tasks.caldav.CaldavClient;
import org.tasks.ui.CompletableViewModel;
public class AddCaldavAccountViewModel extends CompletableViewModel<String> {
public void addAccount(String url, String username, String password) {
run(() -> new CaldavClient(url, username, password).getHomeSet());
public void addAccount(CaldavClient client, String url, String username, String password) {
run(() -> client.forUrl(url, username, password).getHomeSet());
}
}

@ -2,11 +2,10 @@ package org.tasks.activities;
import org.tasks.caldav.CaldavClient;
import org.tasks.data.CaldavAccount;
import org.tasks.security.Encryption;
import org.tasks.ui.CompletableViewModel;
public class CreateCalendarViewModel extends CompletableViewModel<String> {
public void createCalendar(CaldavAccount caldavAccount, Encryption encryption, String name) {
run(() -> new CaldavClient(caldavAccount, encryption).makeCollection(name));
public void createCalendar(CaldavClient client, CaldavAccount account, String name) {
run(() -> client.forAccount(account).makeCollection(name));
}
}

@ -2,12 +2,11 @@ package org.tasks.activities;
import com.google.api.services.tasks.model.TaskList;
import com.todoroo.astrid.gtasks.api.GtasksInvoker;
import org.tasks.gtasks.GoogleAccountManager;
import org.tasks.ui.CompletableViewModel;
@SuppressWarnings("WeakerAccess")
public class CreateListViewModel extends CompletableViewModel<TaskList> {
void createList(GoogleAccountManager googleAccountManager, String account, String name) {
run(() -> new GtasksInvoker(account, googleAccountManager).createGtaskList(name));
void createList(GtasksInvoker invoker, String account, String name) {
run(() -> invoker.forAccount(account).createGtaskList(name));
}
}

@ -3,12 +3,10 @@ package org.tasks.activities;
import org.tasks.caldav.CaldavClient;
import org.tasks.data.CaldavAccount;
import org.tasks.data.CaldavCalendar;
import org.tasks.security.Encryption;
import org.tasks.ui.ActionViewModel;
public class DeleteCalendarViewModel extends ActionViewModel {
public void deleteCalendar(
CaldavAccount caldavAccount, Encryption encryption, CaldavCalendar calendar) {
run(() -> new CaldavClient(caldavAccount, calendar, encryption).deleteCollection());
public void deleteCalendar(CaldavClient client, CaldavAccount account, CaldavCalendar calendar) {
run(() -> client.forCalendar(account, calendar).deleteCollection());
}
}

@ -2,12 +2,11 @@ package org.tasks.activities;
import com.todoroo.astrid.gtasks.api.GtasksInvoker;
import org.tasks.data.GoogleTaskList;
import org.tasks.gtasks.GoogleAccountManager;
import org.tasks.ui.ActionViewModel;
@SuppressWarnings("WeakerAccess")
public class DeleteListViewModel extends ActionViewModel {
void deleteList(GoogleAccountManager googleAccountManager, GoogleTaskList list) {
run(() -> new GtasksInvoker(list.getAccount(), googleAccountManager).deleteGtaskList(list.getRemoteId()));
void deleteList(GtasksInvoker invoker, GoogleTaskList list) {
run(() -> invoker.forAccount(list.getAccount()).deleteGtaskList(list.getRemoteId()));
}
}

@ -24,6 +24,7 @@ import com.todoroo.astrid.activity.MainActivity;
import com.todoroo.astrid.activity.TaskListFragment;
import com.todoroo.astrid.api.GtasksFilter;
import com.todoroo.astrid.gtasks.GtasksListService;
import com.todoroo.astrid.gtasks.api.GtasksInvoker;
import com.todoroo.astrid.service.TaskDeleter;
import javax.inject.Inject;
import org.tasks.R;
@ -59,7 +60,7 @@ public class GoogleTaskListSettingsActivity extends ThemedInjectingAppCompatActi
@Inject ThemeCache themeCache;
@Inject ThemeColor themeColor;
@Inject TaskDeleter taskDeleter;
@Inject GoogleAccountManager googleAccountManager;
@Inject GtasksInvoker gtasksInvoker;
@BindView(R.id.name)
TextInputEditText name;
@ -206,10 +207,10 @@ public class GoogleTaskListSettingsActivity extends ThemedInjectingAppCompatActi
if (isNewList) {
showProgressIndicator();
createListViewModel.createList(googleAccountManager, gtasksList.getAccount(), newName);
createListViewModel.createList(gtasksInvoker, gtasksList.getAccount(), newName);
} else if (nameChanged()) {
showProgressIndicator();
renameListViewModel.renameList(googleAccountManager, gtasksList, newName);
renameListViewModel.renameList(gtasksInvoker, gtasksList, newName);
} else {
if (colorChanged()) {
gtasksList.setColor(selectedTheme);
@ -250,7 +251,7 @@ public class GoogleTaskListSettingsActivity extends ThemedInjectingAppCompatActi
R.string.delete,
(dialog, which) -> {
showProgressIndicator();
deleteListViewModel.deleteList(googleAccountManager, gtasksList);
deleteListViewModel.deleteList(gtasksInvoker, gtasksList);
})
.setNegativeButton(android.R.string.cancel, null)
.show();

@ -3,15 +3,11 @@ package org.tasks.activities;
import com.google.api.services.tasks.model.TaskList;
import com.todoroo.astrid.gtasks.api.GtasksInvoker;
import org.tasks.data.GoogleTaskList;
import org.tasks.gtasks.GoogleAccountManager;
import org.tasks.ui.CompletableViewModel;
@SuppressWarnings("WeakerAccess")
public class RenameListViewModel extends CompletableViewModel<TaskList> {
void renameList(GoogleAccountManager googleAccountManager, GoogleTaskList list, String name) {
run(
() ->
new GtasksInvoker(list.getAccount(), googleAccountManager)
.renameGtaskList(list.getRemoteId(), name));
void renameList(GtasksInvoker invoker, GoogleTaskList list, String name) {
run(() -> invoker.forAccount(list.getAccount()).renameGtaskList(list.getRemoteId(), name));
}
}

@ -4,7 +4,8 @@ import org.tasks.caldav.CaldavClient;
import org.tasks.ui.CompletableViewModel;
public class UpdateCaldavAccountViewModel extends CompletableViewModel<String> {
public void updateCaldavAccount(String url, String username, String password) {
run(() -> new CaldavClient(url, username, password).getHomeSet());
public void updateCaldavAccount(
CaldavClient client, String url, String username, String password) {
run(() -> client.forUrl(url, username, password).getHomeSet());
}
}

@ -38,6 +38,7 @@ import org.tasks.data.CaldavAccount;
import org.tasks.data.CaldavDao;
import org.tasks.dialogs.DialogBuilder;
import org.tasks.injection.ActivityComponent;
import org.tasks.injection.ForApplication;
import org.tasks.injection.ThemedInjectingAppCompatActivity;
import org.tasks.preferences.Preferences;
import org.tasks.security.Encryption;
@ -51,6 +52,7 @@ public class CaldavAccountSettingsActivity extends ThemedInjectingAppCompatActiv
public static final String EXTRA_CALDAV_DATA = "caldavData"; // $NON-NLS-1$
private static final String PASSWORD_MASK = "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022";
@Inject @ForApplication Context context;
@Inject DialogBuilder dialogBuilder;
@Inject Preferences preferences;
@Inject Tracker tracker;
@ -58,6 +60,7 @@ public class CaldavAccountSettingsActivity extends ThemedInjectingAppCompatActiv
@Inject SyncAdapters syncAdapters;
@Inject TaskDeleter taskDeleter;
@Inject Encryption encryption;
@Inject CaldavClient client;
@BindView(R.id.root_layout)
LinearLayout root;
@ -296,10 +299,10 @@ public class CaldavAccountSettingsActivity extends ThemedInjectingAppCompatActiv
if (caldavAccount == null) {
showProgressIndicator();
addCaldavAccountViewModel.addAccount(url, username, password);
addCaldavAccountViewModel.addAccount(client, url, username, password);
} else if (needsValidation()) {
showProgressIndicator();
updateCaldavAccountViewModel.updateCaldavAccount(url, username, password);
updateCaldavAccountViewModel.updateCaldavAccount(client, url, username, password);
} else if (hasChanges()) {
updateAccount(caldavAccount.getUrl());
} else {

@ -43,9 +43,9 @@ import org.tasks.data.CaldavCalendar;
import org.tasks.data.CaldavDao;
import org.tasks.dialogs.DialogBuilder;
import org.tasks.injection.ActivityComponent;
import org.tasks.injection.ForApplication;
import org.tasks.injection.ThemedInjectingAppCompatActivity;
import org.tasks.preferences.Preferences;
import org.tasks.security.Encryption;
import org.tasks.sync.SyncAdapters;
import org.tasks.themes.ThemeCache;
import org.tasks.themes.ThemeColor;
@ -59,6 +59,7 @@ public class CaldavCalendarSettingsActivity extends ThemedInjectingAppCompatActi
public static final String EXTRA_CALDAV_ACCOUNT = "extra_caldav_account";
private static final String EXTRA_SELECTED_THEME = "extra_selected_theme";
private static final int REQUEST_COLOR_PICKER = 10109;
@Inject @ForApplication Context context;
@Inject DialogBuilder dialogBuilder;
@Inject Preferences preferences;
@Inject ThemeCache themeCache;
@ -66,8 +67,8 @@ public class CaldavCalendarSettingsActivity extends ThemedInjectingAppCompatActi
@Inject Tracker tracker;
@Inject CaldavDao caldavDao;
@Inject SyncAdapters syncAdapters;
@Inject Encryption encryption;
@Inject TaskDeleter taskDeleter;
@Inject CaldavClient client;
@BindView(R.id.root_layout)
LinearLayout root;
@ -223,7 +224,7 @@ public class CaldavCalendarSettingsActivity extends ThemedInjectingAppCompatActi
if (caldavCalendar == null) {
showProgressIndicator();
createCalendarViewModel.createCalendar(caldavAccount, encryption, name);
createCalendarViewModel.createCalendar(client, caldavAccount, name);
} else if (hasChanges()) {
updateAccount();
} else {
@ -393,7 +394,7 @@ public class CaldavCalendarSettingsActivity extends ThemedInjectingAppCompatActi
R.string.delete,
(dialog, which) -> {
showProgressIndicator();
deleteCalendarViewModel.deleteCalendar(caldavAccount, encryption, caldavCalendar);
deleteCalendarViewModel.deleteCalendar(client, caldavAccount, caldavCalendar);
})
.setNegativeButton(android.R.string.cancel, null)
.show();

@ -6,6 +6,7 @@ import static at.bitfire.dav4android.XmlUtils.NS_CARDDAV;
import static at.bitfire.dav4android.XmlUtils.NS_WEBDAV;
import static java.util.Arrays.asList;
import android.content.Context;
import at.bitfire.dav4android.BasicDigestAuthHandler;
import at.bitfire.dav4android.DavResource;
import at.bitfire.dav4android.DavResponse;
@ -24,11 +25,16 @@ import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.OkHttpClient.Builder;
import org.tasks.DebugNetworkInterceptor;
import org.tasks.R;
import org.tasks.data.CaldavAccount;
import org.tasks.data.CaldavCalendar;
import org.tasks.injection.ForApplication;
import org.tasks.preferences.Preferences;
import org.tasks.security.Encryption;
import org.tasks.ui.DisplayableException;
import org.xmlpull.v1.XmlPullParserException;
@ -38,28 +44,43 @@ import timber.log.Timber;
public class CaldavClient {
private final Context context;
private final Encryption encryption;
private final Preferences preferences;
private final DebugNetworkInterceptor interceptor;
private final OkHttpClient httpClient;
private final HttpUrl httpUrl;
public CaldavClient(CaldavAccount caldavAccount, Encryption encryption) {
this(
caldavAccount.getUrl(),
caldavAccount.getUsername(),
encryption.decrypt(caldavAccount.getPassword()));
}
@Inject
public CaldavClient(
CaldavAccount caldavAccount, CaldavCalendar caldavCalendar, Encryption encryption) {
this(
caldavCalendar.getUrl(),
caldavAccount.getUsername(),
encryption.decrypt(caldavAccount.getPassword()));
@ForApplication Context context,
Encryption encryption,
Preferences preferences,
DebugNetworkInterceptor interceptor) {
this.context = context;
this.encryption = encryption;
this.preferences = preferences;
this.interceptor = interceptor;
httpClient = null;
httpUrl = null;
}
public CaldavClient(String url, String username, String password) {
private CaldavClient(
Context context,
Encryption encryption,
Preferences preferences,
DebugNetworkInterceptor interceptor,
String url,
String username,
String password) {
this.context = context;
this.encryption = encryption;
this.preferences = preferences;
this.interceptor = interceptor;
BasicDigestAuthHandler basicDigestAuthHandler =
new BasicDigestAuthHandler(null, username, password);
httpClient =
Builder builder =
new OkHttpClient()
.newBuilder()
.addNetworkInterceptor(basicDigestAuthHandler)
@ -67,11 +88,26 @@ public class CaldavClient {
.cookieJar(new MemoryCookieStore())
.followRedirects(false)
.followSslRedirects(true)
.readTimeout(30, TimeUnit.SECONDS)
.build();
.readTimeout(30, TimeUnit.SECONDS);
if (preferences.isFlipperEnabled()) {
interceptor.add(builder);
}
httpClient = builder.build();
httpUrl = HttpUrl.parse(url);
}
public CaldavClient forAccount(CaldavAccount account) {
return forUrl(account.getUrl(), account.getUsername(), account.getPassword(encryption));
}
public CaldavClient forCalendar(CaldavAccount account, CaldavCalendar calendar) {
return forUrl(calendar.getUrl(), account.getUsername(), account.getPassword(encryption));
}
public CaldavClient forUrl(String url, String username, String password) {
return new CaldavClient(context, encryption, preferences, interceptor, url, username, password);
}
private String tryFindPrincipal() throws DavException, IOException {
for (String link : asList("", "/.well-known/caldav")) {
HttpUrl url = httpUrl.resolve(link);

@ -54,7 +54,6 @@ import org.tasks.data.CaldavCalendar;
import org.tasks.data.CaldavDao;
import org.tasks.data.CaldavTask;
import org.tasks.injection.ForApplication;
import org.tasks.security.Encryption;
import timber.log.Timber;
public class CaldavSynchronizer {
@ -69,9 +68,9 @@ public class CaldavSynchronizer {
private final LocalBroadcastManager localBroadcastManager;
private final TaskCreator taskCreator;
private final TaskDeleter taskDeleter;
private final Encryption encryption;
private final Inventory inventory;
private final Tracker tracker;
private final CaldavClient client;
private final Context context;
@Inject
@ -82,18 +81,18 @@ public class CaldavSynchronizer {
LocalBroadcastManager localBroadcastManager,
TaskCreator taskCreator,
TaskDeleter taskDeleter,
Encryption encryption,
Inventory inventory,
Tracker tracker) {
Tracker tracker,
CaldavClient client) {
this.context = context;
this.caldavDao = caldavDao;
this.taskDao = taskDao;
this.localBroadcastManager = localBroadcastManager;
this.taskCreator = taskCreator;
this.taskDeleter = taskDeleter;
this.encryption = encryption;
this.inventory = inventory;
this.tracker = tracker;
this.client = client;
}
public void sync() {
@ -108,7 +107,7 @@ public class CaldavSynchronizer {
setError(account, context.getString(R.string.password_required));
continue;
}
CaldavClient caldavClient = new CaldavClient(account, encryption);
CaldavClient caldavClient = client.forAccount(account);
List<DavResponse> resources;
try {
resources = caldavClient.getCalendars();

@ -8,6 +8,7 @@ import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.Ignore;
import androidx.room.PrimaryKey;
import org.tasks.security.Encryption;
@Entity(tableName = "caldav_account")
public class CaldavAccount implements Parcelable {
@ -109,6 +110,10 @@ public class CaldavAccount implements Parcelable {
this.password = password;
}
public String getPassword(Encryption encryption) {
return encryption.decrypt(password);
}
public String getError() {
return error;
}

@ -78,6 +78,7 @@ public class GoogleTaskSynchronizer {
private final LocalBroadcastManager localBroadcastManager;
private final Inventory inventory;
private final TaskDeleter taskDeleter;
private final GtasksInvoker gtasksInvoker;
@Inject
public GoogleTaskSynchronizer(
@ -95,7 +96,8 @@ public class GoogleTaskSynchronizer {
GoogleAccountManager googleAccountManager,
LocalBroadcastManager localBroadcastManager,
Inventory inventory,
TaskDeleter taskDeleter) {
TaskDeleter taskDeleter,
GtasksInvoker gtasksInvoker) {
this.context = context;
this.googleTaskListDao = googleTaskListDao;
this.gtasksListService = gtasksListService;
@ -111,6 +113,7 @@ public class GoogleTaskSynchronizer {
this.localBroadcastManager = localBroadcastManager;
this.inventory = inventory;
this.taskDeleter = taskDeleter;
this.gtasksInvoker = gtasksInvoker;
}
public static void mergeDates(long remoteDueDate, Task local) {
@ -182,7 +185,7 @@ public class GoogleTaskSynchronizer {
return;
}
GtasksInvoker gtasksInvoker = new GtasksInvoker(account.getAccount(), googleAccountManager);
GtasksInvoker gtasksInvoker = this.gtasksInvoker.forAccount(account.getAccount());
pushLocalChanges(account, gtasksInvoker);
List<TaskList> gtaskLists = new ArrayList<>();

@ -32,6 +32,7 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;
import org.tasks.BuildConfig;
import org.tasks.R;
import org.tasks.billing.Purchase;
import org.tasks.data.TaskAttachment;
@ -506,4 +507,8 @@ public class Preferences {
}
return result;
}
public boolean isFlipperEnabled() {
return BuildConfig.DEBUG && getBoolean(R.string.p_flipper, false);
}
}

@ -0,0 +1,16 @@
package org.tasks;
import com.google.api.client.http.HttpRequest;
import javax.inject.Inject;
import okhttp3.OkHttpClient;
public class DebugNetworkInterceptor {
@Inject
public DebugNetworkInterceptor() {}
public void add(OkHttpClient.Builder builder) {}
public <T> T execute(HttpRequest request, Class<T> responseClass) {
return null;
}
}
Loading…
Cancel
Save