A mobile app for thmmy.gr
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

286 lines
11 KiB

package gr.thmmy.mthmmy.base;
import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.widget.ImageView;
import androidx.core.content.ContextCompat;
import androidx.preference.PreferenceManager;
import com.bumptech.glide.Glide;
import com.franmontiel.persistentcookiejar.PersistentCookieJar;
import com.franmontiel.persistentcookiejar.cache.SetCookieCache;
import com.franmontiel.persistentcookiejar.persistence.SharedPrefsCookiePersistor;
import com.google.firebase.FirebaseApp;
import com.google.firebase.analytics.FirebaseAnalytics;
import com.google.firebase.crashlytics.FirebaseCrashlytics;
import com.google.firebase.remoteconfig.FirebaseRemoteConfig;
import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings;
import com.localebro.okhttpprofiler.OkHttpProfilerInterceptor;
import com.mikepenz.materialdrawer.util.AbstractDrawerImageLoader;
import com.mikepenz.materialdrawer.util.DrawerImageLoader;
import net.gotev.uploadservice.UploadService;
import net.gotev.uploadservice.okhttp.OkHttpStack;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import gr.thmmy.mthmmy.BuildConfig;
import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.session.SessionManager;
import gr.thmmy.mthmmy.utils.crashreporting.CrashReportingTree;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import timber.log.Timber;
import static gr.thmmy.mthmmy.activities.settings.SettingsActivity.DISPLAY_COMPACT_TABS;
import static gr.thmmy.mthmmy.activities.settings.SettingsActivity.DISPLAY_RELATIVE_TIME;
import static gr.thmmy.mthmmy.activities.upload.UploadActivity.firebaseConfigUploadsCoursesKey;
import static gr.thmmy.mthmmy.utils.io.ResourceUtils.readJSONResourceToString;
public class BaseApplication extends Application implements Executor{
private static BaseApplication baseApplication; //BaseApplication singleton
private CrashReportingTree crashReportingTree;
//Firebase
private static String firebaseProjectId;
private FirebaseAnalytics firebaseAnalytics;
private FirebaseRemoteConfig firebaseRemoteConfig;
//Client & SessionManager
private OkHttpClient client;
private SessionManager sessionManager;
private boolean displayRelativeTime;
private boolean displayCompactTabs;
//Display Metrics
private static float widthDp;
private static int widthPxl, heightPxl;
public static BaseApplication getInstance() {
return baseApplication;
}
@Override
public void onCreate() {
super.onCreate();
baseApplication = this; //init singleton
// Initialize Timber
if (BuildConfig.DEBUG)
Timber.plant(new Timber.DebugTree());
//Shared Preferences
SharedPreferences sessionSharedPrefs = getSharedPreferences(getString(R.string.session_shared_prefs), MODE_PRIVATE);
SharedPreferences settingsSharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences draftsPrefs = getSharedPreferences(getString(R.string.pref_topic_drafts_key), MODE_PRIVATE);
initFirebase(settingsSharedPrefs);
SharedPrefsCookiePersistor sharedPrefsCookiePersistor = new SharedPrefsCookiePersistor(getApplicationContext());
PersistentCookieJar cookieJar = new PersistentCookieJar(new SetCookieCache(), sharedPrefsCookiePersistor);
initOkHttp(cookieJar);
sessionManager = new SessionManager(client, cookieJar, sharedPrefsCookiePersistor, sessionSharedPrefs, draftsPrefs);
//Sets up upload service
UploadService.NAMESPACE = BuildConfig.APPLICATION_ID;
UploadService.HTTP_STACK = new OkHttpStack(client);
//Initialize and create the image loader logic for the drawer
initDrawerImageLoader();
setDisplayMetrics();
displayRelativeTime = settingsSharedPrefs.getBoolean(DISPLAY_RELATIVE_TIME, true);
displayCompactTabs = settingsSharedPrefs.getBoolean(DISPLAY_COMPACT_TABS, true);
}
private void initFirebase(SharedPreferences settingsSharedPrefs) {
if (settingsSharedPrefs.getBoolean(getString(R.string.pref_privacy_crashlytics_enable_key), false)) {
Timber.i("Starting app with Firebase Crashlytics enabled.");
setFirebaseCrashlyticsEnabled(true);
}
else {
Timber.i("Starting app with Firebase Crashlytics disabled.");
setFirebaseCrashlyticsEnabled(false);
}
firebaseProjectId = FirebaseApp.getInstance().getOptions().getProjectId();
firebaseAnalytics = FirebaseAnalytics.getInstance(this);
boolean enableAnalytics = settingsSharedPrefs.getBoolean(getString(R.string.pref_privacy_analytics_enable_key), false);
firebaseAnalytics.setAnalyticsCollectionEnabled(enableAnalytics);
if (enableAnalytics)
Timber.i("Starting app with Firebase Analytics enabled.");
else
Timber.i("Starting app with Firebase Analytics disabled.");
// Firebase Remote Config (uploads courses)
InputStream inputStream = getApplicationContext().getResources().openRawResource(R.raw.uploads_courses);
String uploadsCourses = readJSONResourceToString(inputStream);
Map<String, Object> uploadsCoursesMap = new HashMap<>();
uploadsCoursesMap.put(firebaseConfigUploadsCoursesKey, uploadsCourses);
firebaseRemoteConfig = FirebaseRemoteConfig.getInstance();
FirebaseRemoteConfigSettings configSettings = new FirebaseRemoteConfigSettings.Builder()
.setMinimumFetchIntervalInSeconds(3600)
.build();
firebaseRemoteConfig.setConfigSettingsAsync(configSettings);
firebaseRemoteConfig.setDefaultsAsync(uploadsCoursesMap);
firebaseRemoteConfig.fetchAndActivate()
.addOnCompleteListener(this, task -> {
if (task.isSuccessful()) {
boolean updated = task.getResult();
Timber.i("Firebase remote config params updated: %s", updated);
} else
Timber.e("Fetching Firebase remote config params failed!");
});
}
private void initOkHttp(PersistentCookieJar cookieJar) {
OkHttpClient.Builder builder = new OkHttpClient.Builder()
.cookieJar(cookieJar)
.addInterceptor(chain -> {
Request request = chain.request();
HttpUrl oldUrl = chain.request().url();
if (Objects.equals(chain.request().url().host(), "www.thmmy.gr")
&& !oldUrl.toString().contains("theme=4")) {
//Probably works but needs more testing:
HttpUrl newUrl = oldUrl.newBuilder().addQueryParameter("theme", "4").build();
request = request.newBuilder().url(newUrl).build();
}
return chain.proceed(request);
})
.connectTimeout(40, TimeUnit.SECONDS)
.writeTimeout(40, TimeUnit.SECONDS)
.readTimeout(40, TimeUnit.SECONDS);
if (BuildConfig.DEBUG)
builder.addInterceptor(new OkHttpProfilerInterceptor());
client = builder.build();
}
private void initDrawerImageLoader() {
DrawerImageLoader.init(new AbstractDrawerImageLoader() {
@Override
public void set(ImageView imageView, Uri uri, Drawable placeholder, String tag) {
Glide.with(imageView.getContext()).load(uri).circleCrop().error(placeholder).placeholder(placeholder).into(imageView);
}
@Override
public void cancel(ImageView imageView) {
Glide.with(imageView.getContext()).clear(imageView);
}
@Override
public Drawable placeholder(Context ctx, String tag) {
if (DrawerImageLoader.Tags.PROFILE.name().equals(tag)) {
return ContextCompat.getDrawable(BaseApplication.getInstance(), R.drawable.ic_default_user_avatar);
}
return super.placeholder(ctx, tag);
}
});
}
private void setDisplayMetrics() {
DisplayMetrics displayMetrics = getApplicationContext().getResources().getDisplayMetrics();
widthPxl = displayMetrics.widthPixels;
widthDp = widthPxl / displayMetrics.density;
heightPxl = displayMetrics.heightPixels;
}
//-------------------- Getters --------------------
public Context getContext() {
return getApplicationContext();
}
public OkHttpClient getClient() {
return client;
}
public SessionManager getSessionManager() {
return sessionManager;
}
public float getWidthInDp() {
return widthDp;
}
public int getWidthInPixels() {
return widthPxl;
}
public int getHeightInPixels() {
return heightPxl;
}
public boolean isDisplayRelativeTimeEnabled() {
return displayRelativeTime;
}
public boolean isDisplayCompactTabsEnabled() {
return displayCompactTabs;
}
//-------------------- Firebase --------------------
public void logFirebaseAnalyticsEvent(String event, Bundle params) {
firebaseAnalytics.logEvent(event, params);
}
public void setFirebaseAnalyticsEnabled(boolean enabled) {
firebaseAnalytics.setAnalyticsCollectionEnabled(enabled);
if (!enabled)
firebaseAnalytics.resetAnalyticsData();
if (enabled)
Timber.i("Firebase Analytics enabled.");
else
Timber.i("Firebase Analytics disabled.");
}
public void setFirebaseCrashlyticsEnabled(boolean enable) {
FirebaseCrashlytics.getInstance().setCrashlyticsCollectionEnabled(enable);
if (enable) {
crashReportingTree = new CrashReportingTree();
Timber.plant(crashReportingTree);
Timber.i("CrashReporting tree planted.");
Timber.i("Firebase Crashlytics enabled.");
}
else {
if (crashReportingTree != null) {
Timber.uproot(crashReportingTree);
Timber.i("CrashReporting tree uprooted.");
}
Timber.i("Firebase Crashlytics disabled.");
}
}
public static String getFirebaseProjectId() {
return firebaseProjectId;
}
// Implement Executor (for Firebase remote config)
@Override
public void execute(Runnable runnable) {
runnable.run();
}
}