diff --git a/app/src/debug/java/org/tasks/BuildSetup.java b/app/src/debug/java/org/tasks/BuildSetup.java deleted file mode 100644 index caa68cae3..000000000 --- a/app/src/debug/java/org/tasks/BuildSetup.java +++ /dev/null @@ -1,66 +0,0 @@ -package org.tasks; - -import android.app.Application; -import android.content.Context; -import android.os.StrictMode; -import com.facebook.flipper.android.AndroidFlipperClient; -import com.facebook.flipper.android.utils.FlipperUtils; -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 javax.inject.Inject; -import leakcanary.AppWatcher; -import org.tasks.injection.ForApplication; -import org.tasks.preferences.Preferences; -import timber.log.Timber; - -class BuildSetup { - - private final Context context; - private final Preferences preferences; - - @Inject - BuildSetup(@ForApplication Context context, Preferences preferences) { - this.context = context; - this.preferences = preferences; - } - - public void setup() { - Timber.plant(new Timber.DebugTree()); - Application application = (Application) context.getApplicationContext(); - SoLoader.init(application, false); - - if (!preferences.getBoolean(R.string.p_leakcanary, false)) { - AppWatcher.setConfig(AppWatcher.getConfig().newBuilder().enabled(false).build()); - } - if (preferences.getBoolean(R.string.p_flipper, false) && FlipperUtils.shouldEnableFlipper(context)) { - FlipperClient client = AndroidFlipperClient.getInstance(application); - client.addPlugin(new InspectorFlipperPlugin(application, DescriptorMapping.withDefaults())); - client.addPlugin(new DatabasesFlipperPlugin(application)); - client.addPlugin(new NetworkFlipperPlugin()); - client.addPlugin(new SharedPreferencesFlipperPlugin(application)); - client.start(); - } - if (preferences.getBoolean(R.string.p_strict_mode_thread, false)) { - StrictMode.setThreadPolicy( - new StrictMode.ThreadPolicy.Builder() - .detectDiskReads() - .detectDiskWrites() - .detectNetwork() - .penaltyLog() - .build()); - } - if (preferences.getBoolean(R.string.p_strict_mode_vm, false)) { - StrictMode.setVmPolicy( - new StrictMode.VmPolicy.Builder() - .detectLeakedSqlLiteObjects() - .detectLeakedClosableObjects() - .penaltyLog() - .build()); - } - } -} diff --git a/app/src/debug/java/org/tasks/BuildSetup.kt b/app/src/debug/java/org/tasks/BuildSetup.kt new file mode 100644 index 000000000..25db2778e --- /dev/null +++ b/app/src/debug/java/org/tasks/BuildSetup.kt @@ -0,0 +1,53 @@ +package org.tasks + +import android.content.Context +import android.os.StrictMode +import android.os.StrictMode.VmPolicy +import com.facebook.flipper.android.AndroidFlipperClient +import com.facebook.flipper.android.utils.FlipperUtils +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 leakcanary.AppWatcher +import org.tasks.injection.ForApplication +import org.tasks.preferences.Preferences +import timber.log.Timber +import timber.log.Timber.DebugTree +import javax.inject.Inject + +internal class BuildSetup @Inject constructor(@ForApplication private val context: Context, private val preferences: Preferences) { + fun setup() { + Timber.plant(DebugTree()) + SoLoader.init(context, false) + val leakCanaryEnabled = preferences.getBoolean(R.string.p_leakcanary, false) + AppWatcher.config = AppWatcher.config.copy(enabled = leakCanaryEnabled) + if (preferences.getBoolean(R.string.p_flipper, false) && FlipperUtils.shouldEnableFlipper(context)) { + val client = AndroidFlipperClient.getInstance(context) + client.addPlugin(InspectorFlipperPlugin(context, DescriptorMapping.withDefaults())) + client.addPlugin(DatabasesFlipperPlugin(context)) + client.addPlugin(NetworkFlipperPlugin()) + client.addPlugin(SharedPreferencesFlipperPlugin(context)) + client.start() + } + if (preferences.getBoolean(R.string.p_strict_mode_thread, false)) { + StrictMode.setThreadPolicy( + StrictMode.ThreadPolicy.Builder() + .detectDiskReads() + .detectDiskWrites() + .detectNetwork() + .penaltyLog() + .build()) + } + if (preferences.getBoolean(R.string.p_strict_mode_vm, false)) { + StrictMode.setVmPolicy( + VmPolicy.Builder() + .detectLeakedSqlLiteObjects() + .detectLeakedClosableObjects() + .penaltyLog() + .build()) + } + } +} \ No newline at end of file diff --git a/app/src/debug/java/org/tasks/DebugNetworkInterceptor.java b/app/src/debug/java/org/tasks/DebugNetworkInterceptor.java deleted file mode 100644 index 959e0c178..000000000 --- a/app/src/debug/java/org/tasks/DebugNetworkInterceptor.java +++ /dev/null @@ -1,48 +0,0 @@ -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 com.google.api.client.http.HttpResponse; -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 execute(HttpRequest request, Class responseClass) throws IOException { - FlipperHttpInterceptor interceptor = - new FlipperHttpInterceptor<>(getNetworkPlugin(context), responseClass); - request - .setInterceptor(interceptor) - .setResponseInterceptor(interceptor) - .execute(); - return interceptor.getResponse(); - } - - public T report(HttpResponse httpResponse, Class responseClass, long start, long finish) - throws IOException { - FlipperHttpInterceptor interceptor = - new FlipperHttpInterceptor<>(getNetworkPlugin(context), responseClass); - interceptor.report(httpResponse, start, finish); - return interceptor.getResponse(); - } -} diff --git a/app/src/debug/java/org/tasks/DebugNetworkInterceptor.kt b/app/src/debug/java/org/tasks/DebugNetworkInterceptor.kt new file mode 100644 index 000000000..0c17cb99a --- /dev/null +++ b/app/src/debug/java/org/tasks/DebugNetworkInterceptor.kt @@ -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 com.google.api.client.http.HttpResponse +import okhttp3.OkHttpClient +import org.tasks.injection.ForApplication +import java.io.IOException +import javax.inject.Inject + +class DebugNetworkInterceptor @Inject constructor(@ForApplication private val context: Context) { + fun add(builder: OkHttpClient.Builder) { + builder.addNetworkInterceptor(FlipperOkhttpInterceptor(getNetworkPlugin(context))) + } + + @Throws(IOException::class) + fun execute(request: HttpRequest, responseClass: Class): T? { + val interceptor = FlipperHttpInterceptor(getNetworkPlugin(context), responseClass) + request + .setInterceptor(interceptor) + .setResponseInterceptor(interceptor) + .execute() + return interceptor.response + } + + @Throws(IOException::class) + fun report(httpResponse: HttpResponse, responseClass: Class, start: Long, finish: Long): T? { + val interceptor = FlipperHttpInterceptor(getNetworkPlugin(context), responseClass) + interceptor.report(httpResponse, start, finish) + return interceptor.response + } + + private fun getNetworkPlugin(context: Context): NetworkFlipperPlugin { + return AndroidFlipperClient.getInstance(context).getPlugin(NetworkFlipperPlugin.ID)!! + } +} \ No newline at end of file diff --git a/app/src/debug/java/org/tasks/FlipperHttpInterceptor.java b/app/src/debug/java/org/tasks/FlipperHttpInterceptor.java deleted file mode 100644 index 2e110bae7..000000000 --- a/app/src/debug/java/org/tasks/FlipperHttpInterceptor.java +++ /dev/null @@ -1,105 +0,0 @@ -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; - -class FlipperHttpInterceptor implements HttpExecuteInterceptor, HttpResponseInterceptor { - - private final Class responseClass; - private final String requestId = UUIDHelper.newUUID(); - private final NetworkFlipperPlugin plugin; - private T body; - - FlipperHttpInterceptor(NetworkFlipperPlugin plugin, Class responseClass) { - this.responseClass = responseClass; - this.plugin = plugin; - } - - @Override - public void intercept(HttpRequest request) { - plugin.reportRequest(toRequestInfo(request, now())); - } - - @Override - public void interceptResponse(HttpResponse response) throws IOException { - plugin.reportResponse(toResponseInfo(response, now())); - } - - void report(HttpResponse response, long start, long end) throws IOException { - plugin.reportRequest(toRequestInfo(response.getRequest(), start)); - plugin.reportResponse(toResponseInfo(response, end)); - } - - public T getResponse() { - return body; - } - - private RequestInfo toRequestInfo(HttpRequest request, long timestamp) { - RequestInfo requestInfo = new RequestInfo(); - requestInfo.method = request.getRequestMethod(); - requestInfo.body = bodyToByteArray(request.getContent()); - requestInfo.headers = getHeaders(request.getHeaders()); - requestInfo.requestId = requestId; - requestInfo.timeStamp = timestamp; - requestInfo.uri = request.getUrl().toString(); - return requestInfo; - } - - private ResponseInfo toResponseInfo(HttpResponse response, long timestamp) throws IOException { - ResponseInfo responseInfo = new ResponseInfo(); - responseInfo.timeStamp = timestamp; - 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); - } - } - return responseInfo; - } - - private List
getHeaders(HttpHeaders headers) { - List
result = new ArrayList<>(); - for (Map.Entry 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(); - } -} diff --git a/app/src/debug/java/org/tasks/FlipperHttpInterceptor.kt b/app/src/debug/java/org/tasks/FlipperHttpInterceptor.kt new file mode 100644 index 000000000..658013072 --- /dev/null +++ b/app/src/debug/java/org/tasks/FlipperHttpInterceptor.kt @@ -0,0 +1,82 @@ +package org.tasks + +import com.facebook.flipper.plugins.network.NetworkFlipperPlugin +import com.facebook.flipper.plugins.network.NetworkReporter +import com.facebook.flipper.plugins.network.NetworkReporter.ResponseInfo +import com.google.api.client.http.* +import com.google.api.client.json.GenericJson +import com.todoroo.andlib.utility.DateUtilities +import com.todoroo.astrid.helper.UUIDHelper +import timber.log.Timber +import java.io.ByteArrayOutputStream +import java.io.IOException + +internal class FlipperHttpInterceptor(private val plugin: NetworkFlipperPlugin, private val responseClass: Class) : HttpExecuteInterceptor, HttpResponseInterceptor { + private val requestId = UUIDHelper.newUUID() + + var response: T? = null + private set + + override fun intercept(request: HttpRequest) { + plugin.reportRequest(toRequestInfo(request, DateUtilities.now())) + } + + @Throws(IOException::class) + override fun interceptResponse(response: HttpResponse) { + plugin.reportResponse(toResponseInfo(response, DateUtilities.now())) + } + + @Throws(IOException::class) + fun report(response: HttpResponse, start: Long, end: Long) { + plugin.reportRequest(toRequestInfo(response.request, start)) + plugin.reportResponse(toResponseInfo(response, end)) + } + + private fun toRequestInfo(request: HttpRequest, timestamp: Long): NetworkReporter.RequestInfo { + val requestInfo = NetworkReporter.RequestInfo() + requestInfo.method = request.requestMethod + requestInfo.body = bodyToByteArray(request.content) + requestInfo.headers = getHeaders(request.headers) + requestInfo.requestId = requestId + requestInfo.timeStamp = timestamp + requestInfo.uri = request.url.toString() + return requestInfo + } + + @Throws(IOException::class) + private fun toResponseInfo(response: HttpResponse, timestamp: Long): ResponseInfo { + val responseInfo = ResponseInfo() + responseInfo.timeStamp = timestamp + responseInfo.headers = getHeaders(response.headers) + responseInfo.requestId = requestId + responseInfo.statusCode = response.statusCode + responseInfo.statusReason = response.statusMessage + this.response = response.parseAs(responseClass) + if (this.response is GenericJson) { + try { + responseInfo.body = (this.response as GenericJson).toPrettyString().toByteArray() + } catch (e: IOException) { + Timber.e(e) + } + } + return responseInfo + } + + private fun getHeaders(headers: HttpHeaders): List { + return headers.map { (name, value) -> NetworkReporter.Header(name, value.toString()) } + } + + private fun bodyToByteArray(content: HttpContent?): ByteArray? { + if (content == null) { + return null + } + val output = ByteArrayOutputStream() + try { + content.writeTo(output) + } catch (e: IOException) { + Timber.e(e) + return null + } + return output.toByteArray() + } +} \ No newline at end of file