Skip to content

Commit

Permalink
Merge pull request #34 from SmallPlanetAndroid/master
Browse files Browse the repository at this point in the history
Logs Improvements
  • Loading branch information
AnthonyRonning authored Feb 21, 2019
2 parents 8bb35cb + 040394d commit 1ac0820
Show file tree
Hide file tree
Showing 23 changed files with 366 additions and 30 deletions.
10 changes: 5 additions & 5 deletions LearningMachine/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,20 @@ apply plugin: 'com.android.application'

android {
compileSdkVersion 27
buildToolsVersion '27.0.3'
dexOptions {
javaMaxHeapSize "4g"
}
defaultConfig {
applicationId "com.learningmachine.android.app"
minSdkVersion 19
targetSdkVersion 26
versionName "3.0.4"
versionName "3.1.1"
def buildNumber = System.getenv("BUILD_NUMBER")
if (buildNumber != null) {
versionCode buildNumber.toInteger()
versionNameSuffix "-" + buildNumber
} else {
versionCode 29
versionCode 35
}

testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
Expand Down Expand Up @@ -119,14 +118,15 @@ final SPONGYCASTLE_VERSION = '1.56.0.0'
final PROTOBUF_VERSION = '3.3.1'
final TIMBER_VERSION = '4.5.1'
final JODATIMEANDROID_VERSION = '2.9.9'
final RETROFIT_VERSION = '2.3.0'
final RETROFIT_VERSION = '2.5.0'
final LOGGINGINTERCEPTOR_VERSION = '3.4.1'
final GSON_VERSION = '2.8.1'
final RXJAVA_VERSION = '1.3.0'
final RXANDROID_VERSION = '1.2.1'
final RXLIFECYCLE_VERSION = '1.0'
final RXLINT_VERSION = '1.2'
final PICASSO_VERSION = '2.5.2'
final OKIO_VERSION = '2.2.2'

// android test
final ESPRESSO_VERSION = '3.0.1'
Expand Down Expand Up @@ -174,6 +174,7 @@ dependencies {
implementation "com.squareup.retrofit2:converter-gson:$RETROFIT_VERSION"
implementation "com.squareup.retrofit2:adapter-rxjava:$RETROFIT_VERSION"
implementation "com.squareup.okhttp3:logging-interceptor:$LOGGINGINTERCEPTOR_VERSION"
implementation "com.squareup.okio:okio:$OKIO_VERSION"
implementation "com.google.code.gson:gson:$GSON_VERSION"
implementation "io.reactivex:rxjava:$RXJAVA_VERSION"
implementation "io.reactivex:rxandroid:$RXANDROID_VERSION"
Expand All @@ -182,7 +183,6 @@ dependencies {
implementation "nl.littlerobots.rxlint:rxlint:$RXLINT_VERSION"
implementation "com.squareup.picasso:picasso:$PICASSO_VERSION"
implementation "com.google.guava:guava:$GUAVA_VERSION"
implementation 'com.bugsee:bugsee-android:1.12.3'

implementation 'com.google.android.exoplayer:exoplayer:2.8.4'

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package com.learningmachine.android.app;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.multidex.MultiDexApplication;
import android.webkit.WebView;

import com.bugsee.library.Bugsee;
import com.learningmachine.android.app.data.CertificateManager;
import com.learningmachine.android.app.data.IssuerManager;
import com.learningmachine.android.app.data.inject.Injector;
Expand All @@ -15,9 +17,12 @@
import com.learningmachine.android.app.data.preferences.SharedPreferencesManager;
import com.learningmachine.android.app.util.BitcoinUtils;
import com.learningmachine.android.app.util.FileLoggingTree;
import com.learningmachine.android.app.util.FileUtils;

import net.danlew.android.joda.JodaTimeAndroid;

import java.util.Locale;

import javax.inject.Inject;

import timber.log.Timber;
Expand All @@ -41,6 +46,8 @@ public void onCreate() {
enableWebDebugging();
setupMnemonicCode();
Timber.i("Application was launched!");
logDeviceInfo();
checkLogFileValidity();
}

@Override
Expand All @@ -61,6 +68,62 @@ private void setupTimber() {
Timber.plant(new FileLoggingTree());
}

private void logDeviceInfo() {
ConnectivityManager cm = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo wifiNetwork = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
NetworkInfo mobileNetwork = cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);

String device = Build.DEVICE;
String display = Build.DISPLAY;
String fingerprint = Build.FINGERPRINT;
String hardware = Build.HARDWARE;
String host = Build.HOST;
String id = Build.ID;
String manufacturer = Build.MANUFACTURER;
String model = Build.MODEL;
String product = Build.PRODUCT;
int sdk = Build.VERSION.SDK_INT;
String codename = Build.VERSION.CODENAME;
String release = Build.VERSION.RELEASE;
String versionName = BuildConfig.VERSION_NAME;
int versionCode = BuildConfig.VERSION_CODE;
String displayCountry = Locale.getDefault().getDisplayCountry();
String displayLanguage = Locale.getDefault().getDisplayLanguage();
Timber.d(String.format(Locale.US, "Device Information:\n" +
"device: %s\n" +
"display: %s\n" +
"fingerprint: %s\n" +
"hardware: %s\n" +
"host: %s\n" +
"id: %s\n" +
"manufacturer: %s\n" +
"model: %s\n" +
"product: %s\n" +
"sdk: %d\n" +
"codename: %s\n" +
"release: %s\n" +
"app version name: %s\n" +
"app version code: %d\n" +
"wifi: %s\n" +
"mobile: %s\n" +
"country: %s\n" +
"language %s\n", device, display, fingerprint, hardware, host, id,
model, manufacturer, product, sdk, codename, release, versionName, versionCode,
wifiNetwork, mobileNetwork, displayCountry, displayLanguage));
}

//Delete the logs file after 7 days
private void checkLogFileValidity() {
long sevenDays = 7 * 24 * 60 * 60 * 1000;
long lastLogTimestamp = mPreferencesManager.getLastLogDeletedTimestamp();
if (lastLogTimestamp == 0) {
mPreferencesManager.setLastLogDeletedTimestamp(System.currentTimeMillis());
} else if (System.currentTimeMillis() - lastLogTimestamp > sevenDays) {
FileUtils.deleteLogs(this);
mPreferencesManager.setLastLogDeletedTimestamp(System.currentTimeMillis());
}
}

protected void setupJodaTime() {
JodaTimeAndroid.init(getApplicationContext());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
import com.learningmachine.android.app.data.webservice.CertificateInterceptor;
import com.learningmachine.android.app.data.webservice.CertificateService;
import com.learningmachine.android.app.data.webservice.IssuerService;
import com.learningmachine.android.app.data.webservice.LMGsonConverterFactory;
import com.learningmachine.android.app.data.webservice.VersionService;

import junit.runner.Version;
import java.nio.charset.Charset;

import javax.inject.Named;
import javax.inject.Singleton;
Expand All @@ -16,21 +17,49 @@
import dagger.Provides;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.Buffer;
import okio.BufferedSource;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import rx.schedulers.Schedulers;
import timber.log.Timber;

@Module
public class ApiModule {

@Provides
@Singleton
Interceptor provideLoggingInterceptor(HttpLoggingInterceptor.Level level) {
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
loggingInterceptor.setLevel(level);
return loggingInterceptor;
Interceptor provideLoggingInterceptor() {
return chain -> {
Request request = chain.request();

Timber.d(String.format("Performing Request: %s %s",
request.method(), request.url().toString()));

if (request.body() != null) {
Buffer buffer = new Buffer();
request.body().writeTo(buffer);
String body = buffer.readUtf8();
Timber.d(String.format("body: %s", body));
}

Response response = chain.proceed(request);
Timber.d(String.format("response: %s", response.toString()));
if (response.body() != null && !response.isSuccessful()) {
ResponseBody responseBody = response.body();
BufferedSource source = responseBody.source();
source.request(Long.MAX_VALUE);
Buffer buffer = source.buffer();
String responseBodyString = buffer.clone().readString(Charset.forName("UTF-8"));
Timber.d(String.format("response body: %s", responseBodyString));
}

return response;
};
}

@Provides
Expand All @@ -47,7 +76,7 @@ OkHttpClient provideIssuerOkHttpClient(Interceptor loggingInterceptor) {
Retrofit provideIssuerRetrofit(@Named("issuer") OkHttpClient okHttpClient) {
return new Retrofit.Builder().baseUrl(LMConstants.BASE_URL)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.addConverterFactory(LMGsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.createWithScheduler(Schedulers.io()))
.build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ public class SharedPreferencesManager {

private static final String DELAYED_CERTIFICATE_URL = "SharedPreferencesManager.DelayedCertificate.URL";

private static final String PREF_LAST_LOG_DELETED_TIMESTAMP = "SharedPreferencesManager.Logs.LogsDeletedTimestamp";

private SharedPreferences mPrefs;

public SharedPreferencesManager(Context context) {
Expand Down Expand Up @@ -90,4 +92,14 @@ public void setLegacyReceiveAddress(String receiveAddress) {
.putString(PREF_LEGACY_RECEIVE_ADDRESS, receiveAddress)
.apply();
}

public void setLastLogDeletedTimestamp(long timestamp) {
mPrefs.edit()
.putLong(PREF_LAST_LOG_DELETED_TIMESTAMP, timestamp)
.apply();
}

public long getLastLogDeletedTimestamp() {
return mPrefs.getLong(PREF_LAST_LOG_DELETED_TIMESTAMP, 0);
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
package com.learningmachine.android.app.data.webservice;


import java.io.IOException;
import java.nio.charset.Charset;

import okhttp3.HttpUrl;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.Buffer;
import okio.BufferedSource;
import timber.log.Timber;

public class CertificateInterceptor implements Interceptor {

Expand All @@ -17,6 +23,9 @@ public Response intercept(Chain chain) throws IOException {
HttpUrl url = request.url();
String urlString = url.toString();

Timber.d(String.format("Performing Request: %s %s",
request.method(), urlString));

if (!urlString.endsWith(JSON_EXT)) {
// first try to append json
String urlStringAppended = urlString + JSON_EXT;
Expand All @@ -27,6 +36,19 @@ public Response intercept(Chain chain) throws IOException {
}

Response response = chain.proceed(request);
Timber.d(String.format("response: %s", response.toString()));
if (response.body() != null) {
ResponseBody responseBody = response.body();
BufferedSource source = responseBody.source();
source.request(Long.MAX_VALUE);
Buffer buffer = source.buffer();
String responseBodyString = buffer.clone().readString(Charset.forName("UTF-8"));
if (responseBodyString.length() > 2000) {
responseBodyString = responseBodyString.substring(0, 2000);
}
Timber.d(String.format("response body: %s", responseBodyString));
}

if (!response.isSuccessful()) {
// use query params
url = request.url();
Expand All @@ -39,9 +61,8 @@ public Response intercept(Chain chain) throws IOException {
request = request.newBuilder()
.url(jsonFormatAdded)
.build();
response = chain.proceed(request);
}

return response;
return chain.proceed(request);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.learningmachine.android.app.data.webservice;

import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.reflect.TypeToken;

import java.lang.annotation.Annotation;
import java.lang.reflect.Type;

import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Converter;
import retrofit2.Retrofit;

public class LMGsonConverterFactory extends Converter.Factory {
private static final Gson gson = new Gson();

public static LMGsonConverterFactory create() {
return new LMGsonConverterFactory();
}

@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new LMGsonResponseBodyConverter<>(gson, adapter);
}

@Override
public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations,
Annotation[] methodAnnotations, Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new LMGsonRequestBodyConverter<>(gson, adapter);
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.learningmachine.android.app.data.webservice;

import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonWriter;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.Charset;

import okhttp3.MediaType;
import okhttp3.RequestBody;
import okio.Buffer;
import retrofit2.Converter;

final class LMGsonRequestBodyConverter<T> implements Converter<T, RequestBody> {
private static final MediaType MEDIA_TYPE = MediaType.get("application/json; charset=UTF-8");

private final TypeAdapter<T> adapter;
private final Gson gson;

LMGsonRequestBodyConverter(Gson gson, TypeAdapter<T> adapter) {
this.gson = gson;
this.adapter = adapter;
}

@Override
public RequestBody convert(T value) throws IOException {
Buffer buffer = new Buffer();
Writer writer = new OutputStreamWriter(buffer.outputStream(), Charset.forName("UTF-8"));
JsonWriter jsonWriter = gson.newJsonWriter(writer);
adapter.write(jsonWriter, value);
jsonWriter.close();
return RequestBody.create(MEDIA_TYPE, buffer.readByteString());
}
}
Loading

0 comments on commit 1ac0820

Please sign in to comment.