selectedPacks = getPref(SELECTED_PACKS);
-
- for (String packName : selectedPacks) {
- output.append("Pack: ").append(packName).append("\n");
-
- ModulePack pack = FrameworkManager.getModulePack(packName);
- if (pack != null)
- output.append("\tVersion: ").append(pack.getPackVersion()).append("\n");
- }
- }
- }
-
- output.append("[")
- .append(StringUtils.HHmmssSSS.format(new Date(System.currentTimeMillis())))
- .append("]");
-
- return output.toString();
- } catch (Throwable t) {
- Timber.d(t, "Error");
- }
-
- return "";
- }
-
- private void stop() {
- isAlive = false;
- LOCK.notify();
- }
-
- void addError(int logLevel, Throwable error) {
- Timber.d("Error added");
-
- checkInit();
-
- synchronized (LOCK) {
- errorHolders.add(new ErrorHolder(logLevel, error));
- LOCK.notifyAll();
- }
- }
-
- private static class ErrorHolder {
- private final int logLevel;
- private final Throwable throwable;
- private final String errorMessage;
-
- ErrorHolder(int logLevel, Throwable throwable) {
- this(logLevel, throwable, null);
- }
-
- ErrorHolder(int logLevel, Throwable throwable, String errorMessage) {
- this.logLevel = logLevel;
- this.throwable = throwable;
- this.errorMessage = errorMessage;
- }
-
- ErrorHolder(int logLevel, String errorMessage) {
- this(logLevel, null, errorMessage);
- }
-
- public int getLogLevel() {
- return logLevel;
- }
-
- public Throwable getThrowable() {
- return throwable;
- }
-
- public String getErrorMessage() {
- return errorMessage;
- }
-
- String convertToOutput() {
- if (errorMessage == null && throwable == null)
- return null;
-
- StringBuilder builder = new StringBuilder();
-
- switch (logLevel) {
- case Log.ASSERT:
- builder.append(" [ASSERT] ");
- break;
- case Log.ERROR:
- builder.append(" [ERROR] ");
- break;
- case Log.WARN:
- builder.append(" [WARN] ");
- break;
- default:
- break;
- }
-
- if (errorMessage != null)
- builder.append(errorMessage);
-
- if (throwable != null) {
- if (errorMessage != null)
- builder.append("\n");
-
- builder.append(Log.getStackTraceString(throwable));
- }
-
- builder.append("\n\n");
-
- return builder.toString();
- }
- }
-}
diff --git a/app/src/main/java/com/ljmu/andre/GsonPreferences/DeadlockItemModel.java b/app/src/main/java/com/ljmu/andre/GsonPreferences/DeadlockItemModel.java
deleted file mode 100644
index a3e74fe..0000000
--- a/app/src/main/java/com/ljmu/andre/GsonPreferences/DeadlockItemModel.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package com.ljmu.andre.GsonPreferences;
-
-import androidx.annotation.Nullable;
-
-/**
- * This class was created by Andre R M (SID: 701439)
- * It and its contents are free to use by all
- */
-
-class DeadlockItemModel {
- private String name;
- private StackTraceElement[] traceElements;
-
- private DeadlockItemModel(String name, StackTraceElement[] traceElements) {
- this.name = name;
- this.traceElements = traceElements;
- }
-
- static DeadlockItem generate(String name, StackTraceElement[] traceElements,
- @Nullable Throwable previousNode) {
- return new DeadlockItemModel(name, traceElements).new DeadlockItem(previousNode);
- }
-
- @SuppressWarnings("SerializableInnerClassWithNonSerializableOuterClass")
- class DeadlockItem extends Throwable {
- private static final long serialVersionUID = -2891934505164278935L;
-
- private DeadlockItem(Throwable previousNode) {
- super(name, previousNode);
- }
-
- /**
- * ===========================================================================
- * Overridden toString() to remove the original class names from the stack.
- * If not overridden each stack trace will be prepended with:
- * "com.ljmu.andre.GsonPreference.DeadlockItemModel$DeadlockItem"
- * followed by the full classname of the stacktrace item.
- *
- * This function will only prepend the stacktrace with "Deadlock Item"
- * ===========================================================================
- */
- @Override
- public String toString() {
- String s = "Deadlock Item";
- String message = getLocalizedMessage();
- return (message != null) ? (s + ": " + message) : s;
- }
-
- @Override
- public synchronized Throwable fillInStackTrace() {
- setStackTrace(traceElements);
- return this;
- }
- }
-}
diff --git a/app/src/main/java/com/ljmu/andre/GsonPreferences/DeadlockMonitor.java b/app/src/main/java/com/ljmu/andre/GsonPreferences/DeadlockMonitor.java
deleted file mode 100644
index 72479a5..0000000
--- a/app/src/main/java/com/ljmu/andre/GsonPreferences/DeadlockMonitor.java
+++ /dev/null
@@ -1,122 +0,0 @@
-package com.ljmu.andre.GsonPreferences;
-
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-
-import com.ljmu.andre.GsonPreferences.DeadlockItemModel.DeadlockItem;
-
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.TreeMap;
-import java.util.concurrent.TimeUnit;
-
-import timber.log.Timber;
-
-/**
- * This class was created by Andre R M (SID: 701439)
- * It and its contents are free to use by all
- */
-
-class DeadlockMonitor extends Thread {
- private static final int MONITOR_WAIT_TIME = 5;
- private static final TimeUnit MONITOR_TIME_UNIT = TimeUnit.SECONDS;
- private static DeadlockMonitor instance;
- private static int tick = 0;
- private static Runnable ticker = () -> {
- synchronized (Preferences.LOCK) {
- tick = (tick + 1) % Integer.MAX_VALUE;
- }
- };
-
- private DeadlockMonitor(String name) {
- super(name);
- Timber.d("Created deadlock monitor");
- }
-
- @Override
- public void run() {
- HandlerThread lockHandlerThread = new HandlerThread("Pref Lock Handler");
- lockHandlerThread.start();
- Handler lockHandler = new Handler(lockHandlerThread.getLooper());
-
- while (!isInterrupted()) {
-// Timber.d("Scanning deadlock monitor");
- int lastTick = tick;
-// Timber.d("LastTick: " + lastTick);
- lockHandler.post(ticker);
-
- try {
- MONITOR_TIME_UNIT.sleep(MONITOR_WAIT_TIME);
- } catch (InterruptedException e) {
- Timber.e(e);
- }
-
- Timber.d("Tick after monitor: " + tick);
-
- if (lastTick == tick) {
- logAllThreadsStacks();
- }
- }
-
- lockHandler.removeCallbacks(ticker);
- lockHandlerThread.quit();
-
- Timber.e("DEADLOCK MONITOR EXITED");
- }
-
- private static void logAllThreadsStacks() {
- Thread mainThread = Looper.getMainLooper().getThread();
-
- Map stackTraces = new TreeMap<>((left, right) -> {
- if (left == right)
- return 0;
- if (left == mainThread)
- return 1;
- if (right == mainThread)
- return -1;
- return right.getName().compareTo(left.getName());
- });
-
- stackTraces.putAll(Thread.getAllStackTraces());
-
- if (!stackTraces.containsKey(mainThread)) {
- stackTraces.put(mainThread, mainThread.getStackTrace());
- }
-
- DeadlockItem threadReplica = null;
- for (Entry entry : stackTraces.entrySet()) {
- String threadTitle = getThreadTitle(entry.getKey());
-
- threadReplica = DeadlockItemModel.generate(threadTitle, entry.getValue(), threadReplica);
- }
-
- Timber.e(new DeadlockException("Preference Deadlock", threadReplica));
- }
-
- private static String getThreadTitle(Thread thread) {
- return thread.getName() + " (state = " + thread.getState() + ")";
- }
-
- public synchronized static void init() {
- boolean wasDead = false;
-
- if (instance != null && !instance.isAlive()) {
- instance.interrupt();
- wasDead = true;
- }
-
- if (instance == null || wasDead) {
- instance = new DeadlockMonitor("Preference Deadlock Monitor");
- instance.start();
- }
- }
-
- private static class DeadlockException extends Exception {
- private static final long serialVersionUID = 6021707890871456237L;
-
- DeadlockException(String message, Throwable cause) {
- super(message, cause);
- }
- }
-}
diff --git a/app/src/main/java/com/ljmu/andre/GsonPreferences/PreferenceMap.java b/app/src/main/java/com/ljmu/andre/GsonPreferences/PreferenceMap.java
deleted file mode 100644
index e4a6d61..0000000
--- a/app/src/main/java/com/ljmu/andre/GsonPreferences/PreferenceMap.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.ljmu.andre.GsonPreferences;
-
-import com.ljmu.andre.GsonPreferences.Preferences.Preference;
-
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * ===========================================================================
- * Map capable of being de/serialised without losing the generics
- * ===========================================================================
- */
-class PreferenceMap extends ConcurrentHashMap {
- private static final long serialVersionUID = 2162788535918724249L;
-
- PreferenceMap() {
- }
-
- PreferenceMap(Map extends String, ? extends Preference> m) {
- super(m);
- }
-}
diff --git a/app/src/main/java/com/ljmu/andre/GsonPreferences/PreferenceObserver.java b/app/src/main/java/com/ljmu/andre/GsonPreferences/PreferenceObserver.java
deleted file mode 100644
index dba1dd6..0000000
--- a/app/src/main/java/com/ljmu/andre/GsonPreferences/PreferenceObserver.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package com.ljmu.andre.GsonPreferences;
-
-import android.os.FileObserver;
-import androidx.annotation.Nullable;
-
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import timber.log.Timber;
-
-/**
- * This class was created by Andre R M (SID: 701439)
- * It and its contents are free to use by all
- */
-
-class PreferenceObserver extends FileObserver {
- private static AtomicBoolean isLocalChange = new AtomicBoolean(false);
-
- PreferenceObserver(String path) {
- super(path);
- }
-
- @Override
- public void onEvent(int event, @Nullable String path) {
- Timber.d("Preference Observer Event: " + event);
-
- if (isLocalChange.get()) {
- Timber.d("Local event occurred... Skipping reload");
-
- if (event == FileObserver.CLOSE_NOWRITE || event == FileObserver.CLOSE_WRITE) {
- Timber.d("Finished local events");
- isLocalChange.set(false);
- }
-
- return;
- }
-
- switch (event) {
- case FileObserver.CLOSE_WRITE:
- Timber.d("Preference closed with potential changes");
- Preferences.loadPreferenceMap();
- break;
- case FileObserver.CLOSE_NOWRITE:
- Timber.d("Preference closed with no changes");
- break;
- }
- }
-
- void notifyLocalChange() {
- isLocalChange.set(true);
- }
-}
diff --git a/app/src/main/java/com/ljmu/andre/GsonPreferences/PreferenceUtils.java b/app/src/main/java/com/ljmu/andre/GsonPreferences/PreferenceUtils.java
deleted file mode 100644
index 8297de6..0000000
--- a/app/src/main/java/com/ljmu/andre/GsonPreferences/PreferenceUtils.java
+++ /dev/null
@@ -1,190 +0,0 @@
-package com.ljmu.andre.GsonPreferences;
-
-import androidx.annotation.Nullable;
-
-import com.google.common.io.Closer;
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-import com.google.gson.JsonArray;
-import com.google.gson.JsonDeserializationContext;
-import com.google.gson.JsonDeserializer;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParseException;
-import com.google.gson.JsonSerializationContext;
-import com.google.gson.JsonSerializer;
-import com.ljmu.andre.GsonPreferences.Preferences.Preference;
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.lang.reflect.Type;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import io.reactivex.Observable;
-import io.reactivex.annotations.NonNull;
-import io.reactivex.observers.DisposableObserver;
-import io.reactivex.schedulers.Schedulers;
-import timber.log.Timber;
-
-/**
- * This class was created by Andre R M (SID: 701439)
- * It and its contents are free to use by all
- */
-
-class PreferenceUtils {
- private static final Object WRITE_LOCK = new Object();
-
- static void saveMap(File preferenceFile, PreferenceMap preferenceMap, Gson gson) {
- Closer closer = Closer.create();
- PreferenceMap copiedPrefs = new PreferenceMap(preferenceMap);
-
- Observable.fromCallable(
- () -> {
- Timber.d("Entering write lock");
- synchronized (WRITE_LOCK) {
- Timber.d("Entered write lock");
- BufferedWriter writer = closer.register(
- new BufferedWriter(
- new FileWriter(preferenceFile)
- )
- );
-
- gson.toJson(copiedPrefs, writer);
- writer.flush();
- Timber.d("Exiting write lock");
- }
- Timber.d("Exited write lock");
-
- return new Object();
- })
- .subscribeOn(Schedulers.io())
- .subscribe(new DisposableObserver