diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 6eb2e60c..79ada8ae 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -3,9 +3,9 @@
xmlns:tools="http://schemas.android.com/tools">
-
-
-
+
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/java/eu/darken/octi/common/debug/recording/core/RecorderModule.kt b/app/src/main/java/eu/darken/octi/common/debug/recording/core/RecorderModule.kt
index 1291eef3..9ab7463f 100644
--- a/app/src/main/java/eu/darken/octi/common/debug/recording/core/RecorderModule.kt
+++ b/app/src/main/java/eu/darken/octi/common/debug/recording/core/RecorderModule.kt
@@ -12,7 +12,6 @@ import eu.darken.octi.common.debug.logging.log
import eu.darken.octi.common.debug.logging.logTag
import eu.darken.octi.common.debug.recording.ui.RecorderActivity
import eu.darken.octi.common.flow.DynamicStateFlow
-import eu.darken.octi.common.startServiceCompat
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.filter
@@ -57,11 +56,7 @@ class RecorderModule @Inject constructor(
newRecorder.start(createRecordingFilePath())
triggerFile.createNewFile()
- context.startServiceCompat(Intent(context, RecorderService::class.java))
-
- copy(
- recorder = newRecorder
- )
+ copy(recorder = newRecorder)
} else if (!shouldRecord && isRecording) {
val currentLog = recorder!!.path!!
recorder.stop()
diff --git a/app/src/main/java/eu/darken/octi/common/debug/recording/core/RecorderService.kt b/app/src/main/java/eu/darken/octi/common/debug/recording/core/RecorderService.kt
deleted file mode 100644
index d4e697f7..00000000
--- a/app/src/main/java/eu/darken/octi/common/debug/recording/core/RecorderService.kt
+++ /dev/null
@@ -1,112 +0,0 @@
-package eu.darken.octi.common.debug.recording.core
-
-import android.app.NotificationManager
-import android.app.PendingIntent
-import android.content.Intent
-import android.os.IBinder
-import androidx.core.app.NotificationChannelCompat
-import androidx.core.app.NotificationCompat
-import androidx.core.app.NotificationManagerCompat
-import dagger.hilt.android.AndroidEntryPoint
-import eu.darken.octi.R
-import eu.darken.octi.common.BuildConfigWrap
-import eu.darken.octi.common.coroutine.DispatcherProvider
-import eu.darken.octi.common.debug.logging.log
-import eu.darken.octi.common.debug.logging.logTag
-import eu.darken.octi.common.notifications.PendingIntentCompat
-import eu.darken.octi.common.uix.Service2
-import eu.darken.octi.main.ui.MainActivity
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.SupervisorJob
-import kotlinx.coroutines.cancel
-import kotlinx.coroutines.flow.launchIn
-import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.launch
-import javax.inject.Inject
-
-
-@AndroidEntryPoint
-class RecorderService : Service2() {
- private lateinit var builder: NotificationCompat.Builder
-
- @Inject lateinit var recorderModule: RecorderModule
- @Inject lateinit var notificationManager: NotificationManager
- @Inject lateinit var dispatcherProvider: DispatcherProvider
- private val recorderScope by lazy {
- CoroutineScope(SupervisorJob() + dispatcherProvider.IO)
- }
-
- override fun onBind(intent: Intent?): IBinder? = null
-
- override fun onCreate() {
- super.onCreate()
- val compatChannel = NotificationChannelCompat
- .Builder(NOTIF_CHANID_DEBUG, NotificationManagerCompat.IMPORTANCE_MAX)
- .setName(getString(R.string.debug_notification_channel_label))
- .build()
- NotificationManagerCompat.from(this).createNotificationChannel(compatChannel)
-
- val openIntent = Intent(this, MainActivity::class.java)
- val openPi = PendingIntent.getActivity(
- this,
- 0,
- openIntent,
- PendingIntentCompat.FLAG_IMMUTABLE
- )
-
- val stopIntent = Intent(this, RecorderService::class.java)
- stopIntent.action = STOP_ACTION
- val stopPi = PendingIntent.getService(
- this,
- 0,
- stopIntent,
- PendingIntentCompat.FLAG_IMMUTABLE
- )
-
- builder = NotificationCompat.Builder(this, NOTIF_CHANID_DEBUG)
- .setChannelId(NOTIF_CHANID_DEBUG)
- .setContentIntent(openPi)
- .setPriority(NotificationCompat.PRIORITY_MAX)
- .setSmallIcon(R.drawable.ic_baseline_bug_report_24)
- .setContentText("Idle")
- .setContentTitle(getString(R.string.app_name))
- .addAction(NotificationCompat.Action.Builder(0, getString(R.string.general_done_action), stopPi).build())
-
- startForeground(NOTIFICATION_ID, builder.build())
-
- recorderModule.state
- .onEach {
- if (it.isRecording) {
- builder.setContentText("Recording debug log: ${it.currentLogPath?.path}")
- notificationManager.notify(NOTIFICATION_ID, builder.build())
- } else {
- stopForeground(true)
- stopSelf()
- }
- }
- .launchIn(recorderScope)
- }
-
- override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
- log(TAG) { "onStartCommand(intent=$intent, flags=$flags, startId=$startId" }
- if (intent?.action == STOP_ACTION) {
- recorderScope.launch {
- recorderModule.stopRecorder()
- }
- }
- return START_STICKY
- }
-
- override fun onDestroy() {
- recorderScope.coroutineContext.cancel()
- super.onDestroy()
- }
-
- companion object {
- private val TAG =
- logTag("Debug", "Log", "eu.darken.octi.common.debug.recording.core.Recorder", "Service")
- private val NOTIF_CHANID_DEBUG = "${BuildConfigWrap.APPLICATION_ID}.notification.channel.debug"
- private const val STOP_ACTION = "STOP_SERVICE"
- private const val NOTIFICATION_ID = 53
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/eu/darken/octi/main/ui/settings/support/SupportEvent.kt b/app/src/main/java/eu/darken/octi/main/ui/settings/support/SupportEvent.kt
new file mode 100644
index 00000000..95ae9615
--- /dev/null
+++ b/app/src/main/java/eu/darken/octi/main/ui/settings/support/SupportEvent.kt
@@ -0,0 +1,5 @@
+package eu.darken.octi.main.ui.settings.support
+
+sealed interface SupportEvent {
+ data object DebugLogInfo : SupportEvent
+}
\ No newline at end of file
diff --git a/app/src/main/java/eu/darken/octi/main/ui/settings/support/SupportFragment.kt b/app/src/main/java/eu/darken/octi/main/ui/settings/support/SupportFragment.kt
index 78460b2e..74c8757f 100644
--- a/app/src/main/java/eu/darken/octi/main/ui/settings/support/SupportFragment.kt
+++ b/app/src/main/java/eu/darken/octi/main/ui/settings/support/SupportFragment.kt
@@ -6,7 +6,6 @@ import androidx.annotation.Keep
import androidx.fragment.app.viewModels
import androidx.preference.Preference
import com.google.android.material.dialog.MaterialAlertDialogBuilder
-import com.google.android.material.snackbar.Snackbar
import dagger.hilt.android.AndroidEntryPoint
import eu.darken.octi.R
import eu.darken.octi.common.ClipboardHelper
@@ -35,31 +34,37 @@ class SupportFragment : PreferenceFragment2() {
override fun onPreferencesCreated() {
debugLogPref.setOnPreferenceClickListener {
- MaterialAlertDialogBuilder(requireContext()).apply {
- setTitle(R.string.support_debuglog_label)
- setMessage(R.string.settings_debuglog_explanation)
- setPositiveButton(R.string.general_continue) { _, _ -> vm.startDebugLog() }
- setNegativeButton(R.string.general_cancel_action) { _, _ -> }
- setNeutralButton(R.string.settings_privacy_policy_label) { _, _ -> webpageTool.open(PrivacyPolicy.URL) }
- }.show()
+ vm.toggleDebugLog()
true
}
super.onPreferencesCreated()
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- vm.clipboardEvent.observe2(this) { installId ->
- Snackbar.make(requireView(), installId, Snackbar.LENGTH_INDEFINITE)
- .setAction(R.string.general_copy_action) {
- clipboardHelper.copyToClipboard(installId)
+ vm.isRecording.observe2(this) {
+ debugLogPref.apply {
+ if (it != null) {
+ setIcon(R.drawable.ic_bug_stop_24)
+ setTitle(R.string.support_debuglog_inprogress_label)
+ summary = it.path
+ } else {
+ setIcon(R.drawable.ic_baseline_bug_report_24)
+ setTitle(R.string.support_debuglog_label)
+ setSummary(R.string.support_debuglog_desc)
}
- .show()
+ }
}
- vm.emailEvent.observe2(this) { startActivity(it) }
-
- vm.isRecording.observe2(this) {
- debugLogPref.isEnabled = !it
+ vm.events.observe2(this) {
+ when (it) {
+ SupportEvent.DebugLogInfo -> MaterialAlertDialogBuilder(requireContext()).apply {
+ setTitle(R.string.support_debuglog_label)
+ setMessage(R.string.settings_debuglog_explanation)
+ setPositiveButton(R.string.general_continue) { _, _ -> vm.toggleDebugLog(consent = true) }
+ setNegativeButton(R.string.general_cancel_action) { _, _ -> }
+ setNeutralButton(R.string.settings_privacy_policy_label) { _, _ -> webpageTool.open(PrivacyPolicy.URL) }
+ }.show()
+ }
}
super.onViewCreated(view, savedInstanceState)
diff --git a/app/src/main/java/eu/darken/octi/main/ui/settings/support/SupportFragmentVM.kt b/app/src/main/java/eu/darken/octi/main/ui/settings/support/SupportFragmentVM.kt
index 1e384052..97d3b431 100644
--- a/app/src/main/java/eu/darken/octi/main/ui/settings/support/SupportFragmentVM.kt
+++ b/app/src/main/java/eu/darken/octi/main/ui/settings/support/SupportFragmentVM.kt
@@ -1,12 +1,12 @@
package eu.darken.octi.main.ui.settings.support
-import android.content.Intent
import dagger.hilt.android.lifecycle.HiltViewModel
import eu.darken.octi.common.coroutine.DispatcherProvider
import eu.darken.octi.common.debug.logging.log
import eu.darken.octi.common.debug.recording.core.RecorderModule
import eu.darken.octi.common.livedata.SingleLiveEvent
import eu.darken.octi.common.uix.ViewModel3
+import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import javax.inject.Inject
@@ -16,13 +16,22 @@ class SupportFragmentVM @Inject constructor(
private val recorderModule: RecorderModule,
) : ViewModel3(dispatcherProvider) {
- val emailEvent = SingleLiveEvent()
- val clipboardEvent = SingleLiveEvent()
+ val isRecording = recorderModule.state.map { it.currentLogPath }.asLiveData2()
- val isRecording = recorderModule.state.map { it.isRecording }.asLiveData2()
+ val events = SingleLiveEvent()
- fun startDebugLog() = launch {
- log { "startDebugLog()" }
- recorderModule.startRecorder()
+ fun toggleDebugLog(consent: Boolean = false) = launch {
+ log { "toggleDebugLog()" }
+ recorderModule.apply {
+ if (state.first().isRecording) {
+ stopRecorder()
+ } else {
+ if (consent) {
+ startRecorder()
+ } else {
+ events.postValue(SupportEvent.DebugLogInfo)
+ }
+ }
+ }
}
}
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_bug_stop_24.xml b/app/src/main/res/drawable/ic_bug_stop_24.xml
new file mode 100644
index 00000000..83f9224c
--- /dev/null
+++ b/app/src/main/res/drawable/ic_bug_stop_24.xml
@@ -0,0 +1,10 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index bcc7d9ac..adc593b4 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -56,7 +56,8 @@
Discord
A place to hang out in and ask questions.
- Debug log
+ Record debug log
+ Stop debug log
Record everything the app is doing into a text file that you can share.
Support
This file contains sensitive information (e.g. your installed applications). Only share it with trusted parties.