Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(#600) Notification system for settings (for crash logs and apk updates) #656

Merged
merged 15 commits into from
Mar 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions Kuroba/app/src/main/java/com/github/adamantcheese/chan/Chan.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,13 @@
import com.github.adamantcheese.chan.core.manager.BoardManager;
import com.github.adamantcheese.chan.core.manager.FilterWatchManager;
import com.github.adamantcheese.chan.core.manager.ReportManager;
import com.github.adamantcheese.chan.core.manager.SettingsNotificationManager;
import com.github.adamantcheese.chan.core.settings.ChanSettings;
import com.github.adamantcheese.chan.core.site.SiteService;
import com.github.adamantcheese.chan.ui.service.LastPageNotification;
import com.github.adamantcheese.chan.ui.service.SavingNotification;
import com.github.adamantcheese.chan.ui.service.WatchNotification;
import com.github.adamantcheese.chan.ui.settings.SettingNotificationType;
import com.github.adamantcheese.chan.utils.AndroidUtils;
import com.github.adamantcheese.chan.utils.Logger;

Expand Down Expand Up @@ -76,6 +78,9 @@ public class Chan
@Inject
ReportManager reportManager;

@Inject
SettingsNotificationManager settingsNotificationManager;

private static Feather feather;

public static <T> T instance(Class<T> tClass) {
Expand Down Expand Up @@ -200,8 +205,10 @@ public void onCreate() {
System.exit(999);
});

if (ChanSettings.autoCrashLogsUpload.get()) {
reportManager.sendCollectedCrashLogs();
if (ChanSettings.collectCrashLogs.get()) {
if (reportManager.hasCrashLogs()) {
settingsNotificationManager.notify(SettingNotificationType.CrashLog);
}
}
}

Expand Down Expand Up @@ -238,7 +245,7 @@ private void onUnhandledException(Throwable exception, String error) {
return;
}

if (ChanSettings.autoCrashLogsUpload.get()) {
if (ChanSettings.collectCrashLogs.get()) {
reportManager.storeCrashLog(exception.getMessage(), error);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import android.view.KeyEvent;
import android.view.ViewGroup;

import androidx.annotation.CallSuper;

import com.github.adamantcheese.chan.StartActivity;
import com.github.adamantcheese.chan.controller.transition.FadeInTransition;
import com.github.adamantcheese.chan.controller.transition.FadeOutTransition;
Expand Down Expand Up @@ -73,13 +75,15 @@ public Controller(Context context) {
this.context = context;
}

@CallSuper
public void onCreate() {
alive = true;
if (LOG_STATES) {
Logger.test(getClass().getSimpleName() + " onCreate");
}
}

@CallSuper
public void onShow() {
shown = true;
if (LOG_STATES) {
Expand All @@ -95,6 +99,7 @@ public void onShow() {
}
}

@CallSuper
public void onHide() {
shown = false;
if (LOG_STATES) {
Expand All @@ -110,6 +115,7 @@ public void onHide() {
}
}

@CallSuper
public void onDestroy() {
alive = false;
if (LOG_STATES) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import com.github.adamantcheese.chan.core.manager.ReplyManager;
import com.github.adamantcheese.chan.core.manager.ReportManager;
import com.github.adamantcheese.chan.core.manager.SavedThreadLoaderManager;
import com.github.adamantcheese.chan.core.manager.SettingsNotificationManager;
import com.github.adamantcheese.chan.core.manager.ThreadSaveManager;
import com.github.adamantcheese.chan.core.manager.WakeManager;
import com.github.adamantcheese.chan.core.manager.WatchManager;
Expand Down Expand Up @@ -175,16 +176,24 @@ public MockReplyManager provideMockReplyManager() {
public ReportManager provideReportManager(
NetModule.ProxiedOkHttpClient okHttpClient,
Gson gson,
ThreadSaveManager threadSaveManager
ThreadSaveManager threadSaveManager,
SettingsNotificationManager settingsNotificationManager
) {
Logger.d(AppModule.DI_TAG, "Report manager");
File cacheDir = getCacheDir();

return new ReportManager(
okHttpClient.getProxiedClient(),
threadSaveManager,
settingsNotificationManager,
gson,
new File(cacheDir, CRASH_LOGS_DIR_NAME)
);
}

@Provides
@Singleton
public SettingsNotificationManager provideSettingsNotificationManager() {
return new SettingsNotificationManager();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import com.github.adamantcheese.chan.BuildConfig
import com.github.adamantcheese.chan.core.base.ModularResult
import com.github.adamantcheese.chan.core.settings.ChanSettings
import com.github.adamantcheese.chan.ui.controller.LogsController
import com.github.adamantcheese.chan.ui.layout.crashlogs.CrashLog
import com.github.adamantcheese.chan.ui.settings.SettingNotificationType
import com.github.adamantcheese.chan.utils.BackgroundUtils
import com.github.adamantcheese.chan.utils.Logger
import com.github.adamantcheese.chan.utils.TimeUtils.getCurrentDateAndTimeUTC
Expand All @@ -29,6 +31,7 @@ import java.util.concurrent.atomic.AtomicInteger
class ReportManager(
private val okHttpClient: OkHttpClient,
private val threadSaveManager: ThreadSaveManager,
private val settingsNotificationManager: SettingsNotificationManager,
private val gson: Gson,
private val crashLogsDirPath: File
) {
Expand Down Expand Up @@ -74,6 +77,13 @@ class ReportManager(
return@flatMapSingle processSingleRequest(request, crashLogFile)
}
}
.debounce(1, TimeUnit.SECONDS)
.doOnNext {
// If no more crash logs left, remove the notification
if (!hasCrashLogs()) {
settingsNotificationManager.cancel(SettingNotificationType.CrashLog)
}
}
.subscribe({
// Do nothing
}, { error ->
Expand Down Expand Up @@ -126,7 +136,7 @@ class ReportManager(
return
}

val time = System.nanoTime()
val time = System.currentTimeMillis()
val newCrashLog = File(crashLogsDirPath, "${CRASH_LOG_FILE_NAME_PREFIX}_${time}.txt")

if (newCrashLog.exists()) {
Expand Down Expand Up @@ -169,37 +179,96 @@ class ReportManager(
Logger.d(TAG, "Stored new crash log, path = ${newCrashLog.absolutePath}")
}

// Since this is a singleton we don't care about disposing of this thing because nothing may
// leak here
@SuppressLint("CheckResult")
fun sendCollectedCrashLogs() {
fun hasCrashLogs(): Boolean {
if (!createCrashLogsDirIfNotExists()) {
return false
}

val crashLogs = crashLogsDirPath.listFiles()
return crashLogs != null && crashLogs.isNotEmpty()
}

fun countCrashLogs(): Int {
if (!createCrashLogsDirIfNotExists()) {
return 0
}

return crashLogsDirPath.listFiles()?.size ?: 0
}

fun getCrashLogs(): List<File> {
if (!createCrashLogsDirIfNotExists()) {
return emptyList()
}

return crashLogsDirPath.listFiles()
?.sortedByDescending { file -> file.lastModified() }
?.toList() ?: emptyList()
}

fun deleteCrashLogs(crashLogs: List<CrashLog>) {
if (!createCrashLogsDirIfNotExists()) {
settingsNotificationManager.cancel(SettingNotificationType.CrashLog)
return
}

crashLogs.forEach { crashLog -> crashLog.file.delete() }

val remainingCrashLogs = crashLogsDirPath.listFiles()?.size ?: 0
if (remainingCrashLogs == 0) {
settingsNotificationManager.cancel(SettingNotificationType.CrashLog)
return
}

// There are still crash logs left, so show the notifications if they are not shown yet
settingsNotificationManager.notify(SettingNotificationType.CrashLog)
}

fun deleteAllCrashLogs() {
if (!createCrashLogsDirIfNotExists()) {
settingsNotificationManager.cancel(SettingNotificationType.CrashLog)
return
}

val potentialCrashLogs = crashLogsDirPath.listFiles()
if (potentialCrashLogs.isNullOrEmpty()) {
Logger.d(TAG, "No new crash logs")
settingsNotificationManager.cancel(SettingNotificationType.CrashLog)
return
}

potentialCrashLogs.asSequence()
.forEach { crashLogFile -> crashLogFile.delete() }

val remainingCrashLogs = crashLogsDirPath.listFiles()?.size ?: 0
if (remainingCrashLogs == 0) {
settingsNotificationManager.cancel(SettingNotificationType.CrashLog)
return
}

// There are still crash logs left, so show the notifications if they are not shown yet
settingsNotificationManager.notify(SettingNotificationType.CrashLog)
}

fun sendCrashLogs(crashLogs: List<CrashLog>): Completable {
if (!createCrashLogsDirIfNotExists()) {
return Completable.complete()
}

if (crashLogs.isEmpty()) {
return Completable.complete()
}

// Collect and create reports on a background thread because logs may wait quite a lot now
// and it may lag the UI.
Completable.fromAction {
return Completable.fromAction {
BackgroundUtils.ensureBackgroundThread()

val potentialCrashLogs = crashLogsDirPath.listFiles()
if (potentialCrashLogs.isNullOrEmpty()) {
Logger.d(TAG, "No new crash logs")
return@fromAction
}

potentialCrashLogs.asSequence()
.filter { file -> file.name.startsWith(CRASH_LOG_FILE_NAME_PREFIX) }
.map { file -> createReportRequest(file) }
.filterNotNull()
crashLogs
.mapNotNull { crashLog -> createReportRequest(crashLog) }
.forEach { request -> crashLogSenderQueue.onNext(request) }
}
.subscribeOn(senderScheduler)
.subscribe({
// Do nothing
}, { error ->
Logger.e(TAG, "Error while collecting logs: ${error}")
})
.subscribeOn(senderScheduler)
}

fun sendReport(title: String, description: String, logs: String?): Single<ModularResult<Boolean>> {
Expand Down Expand Up @@ -261,11 +330,11 @@ class ReportManager(
"active: $filesLocationActiveDirType"
}

private fun createReportRequest(file: File): ReportRequestWithFile? {
private fun createReportRequest(crashLog: CrashLog): ReportRequestWithFile? {
BackgroundUtils.ensureBackgroundThread()

val log = try {
file.readText()
crashLog.file.readText()
} catch (error: Throwable) {
Logger.e(TAG, "Error reading crash log file", error)
return null
Expand All @@ -282,7 +351,7 @@ class ReportManager(

return ReportRequestWithFile(
reportRequest = request,
crashLogFile = file
crashLogFile = crashLog.file
)
}

Expand Down
Loading