Skip to content

Commit

Permalink
fix: notification/toast on RimeMessage will be popped up repeatedly
Browse files Browse the repository at this point in the history
- Implements logcat command DSL and Flow extensions to simplify codes
  • Loading branch information
WhiredPlanck committed Jan 4, 2025
1 parent 46916af commit 00560f3
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 41 deletions.
40 changes: 19 additions & 21 deletions app/src/main/java/com/osfans/trime/daemon/RimeDaemon.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package com.osfans.trime.daemon
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.os.Build
import androidx.core.app.NotificationCompat
Expand All @@ -21,11 +22,10 @@ import com.osfans.trime.core.lifecycleScope
import com.osfans.trime.core.whenReady
import com.osfans.trime.ui.main.LogActivity
import com.osfans.trime.util.appContext
import com.osfans.trime.util.logcat
import com.osfans.trime.util.toast
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
Expand Down Expand Up @@ -151,9 +151,6 @@ object RimeDaemon {
.let { notificationManager.notify(id, it) }
realRime.finalize()
realRime.startup(fullCheck)
realRime.messageFlow
.onEach(::handleRimeMessage)
.launchIn(TrimeApplication.getInstance().coroutineScope)
TrimeApplication.getInstance().coroutineScope.launch {
// cancel notification on ready
realRime.lifecycle.whenReady {
Expand All @@ -162,44 +159,45 @@ object RimeDaemon {
}
}

private suspend fun handleRimeMessage(it: RimeMessage<*>) {
suspend fun onRimeMessage(
ctx: Context,
it: RimeMessage<*>,
) {
if (it is RimeMessage.DeployMessage) {
when (it.data) {
RimeMessage.DeployMessage.State.Start -> {
withContext(Dispatchers.IO) {
Runtime.getRuntime().exec(arrayOf("logcat", "-c"))
logcat { clear() }
}
}
RimeMessage.DeployMessage.State.Success -> {
ContextCompat.getMainExecutor(appContext).execute {
appContext.toast(R.string.deploy_finish)
ContextCompat.getMainExecutor(ctx).execute {
ctx.toast(R.string.deploy_finish)
}
}
RimeMessage.DeployMessage.State.Failure -> {
val intent =
Intent(appContext, LogActivity::class.java).apply {
Intent(ctx, LogActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
val log =
withContext(Dispatchers.IO) {
Runtime
.getRuntime()
.exec(
arrayOf("logcat", "-d", "-v", "brief", "-s", "rime.trime:W"),
).inputStream
.bufferedReader()
.readText()
logcat {
format("brief")
filterspec("rime.trime", "W")
dump()
}.inputStream.bufferedReader().readText()
}
putExtra(LogActivity.FROM_DEPLOY, true)
putExtra(LogActivity.DEPLOY_FAILURE_TRACE, log)
}
NotificationCompat
.Builder(appContext, CHANNEL_ID)
.Builder(ctx, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_baseline_warning_24)
.setContentTitle(appContext.getString(R.string.rime_daemon))
.setContentText(appContext.getString(R.string.view_deploy_failure_log))
.setContentTitle(ctx.getString(R.string.rime_daemon))
.setContentText(ctx.getString(R.string.view_deploy_failure_log))
.setContentIntent(
PendingIntent.getActivity(
appContext,
ctx,
0,
intent,
PendingIntent.FLAG_ONE_SHOT or
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,10 @@ open class TrimeInputMethodService : LifecycleInputMethodService() {
}
}
}
else -> {}
else ->
lifecycleScope.launch {
RimeDaemon.onRimeMessage(this@TrimeInputMethodService, it)
}
}
}

Expand Down
20 changes: 20 additions & 0 deletions app/src/main/java/com/osfans/trime/util/Flow.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* SPDX-FileCopyrightText: 2015 - 2025 Rime community
* SPDX-License-Identifier: GPL-3.0-or-later
*/

package com.osfans.trime.util

import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.asFlow
import kotlinx.coroutines.flow.cancellable
import kotlinx.coroutines.flow.flowOn

fun Process.asFlow(): Flow<String> =
inputStream
.bufferedReader()
.lineSequence()
.asFlow()
.flowOn(Dispatchers.IO)
.cancellable()
60 changes: 41 additions & 19 deletions app/src/main/java/com/osfans/trime/util/Logcat.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,7 @@ import kotlinx.coroutines.Job
import kotlinx.coroutines.async
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.asFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.cancellable
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.launch

class Logcat(
Expand All @@ -42,12 +39,10 @@ class Logcat(
fun getLogAsync(): Deferred<Result<List<String>>> =
async {
runCatching {
Runtime
.getRuntime()
.exec(arrayOf("logcat", pid?.let { "--pid=$it" } ?: "", "-d"))
.inputStream
.bufferedReader()
.readLines()
logcat {
pid?.let { pid(it) }
dump()
}.inputStream.bufferedReader().readLines()
}
}

Expand All @@ -56,7 +51,7 @@ class Logcat(
*/
fun clearLog(): Job =
launch {
runCatching { Runtime.getRuntime().exec(arrayOf("logcat", "-c")) }
runCatching { logcat { clear() } }
}

/**
Expand All @@ -68,16 +63,11 @@ class Logcat(
} else {
launch {
runCatching {
Runtime
.getRuntime()
.exec(arrayOf("logcat", pid?.let { "--pid=$it" } ?: "", "-v", "time"))
.also { process = it }
.inputStream
.bufferedReader()
.lineSequence()
logcat {
pid?.let { pid(it) }
format("time")
}.also { process = it }
.asFlow()
.flowOn(Dispatchers.IO)
.cancellable()
.collect { flow.emit(it) }
}
}.also { emittingJob = it }
Expand All @@ -95,3 +85,35 @@ class Logcat(
val default by lazy { Logcat() }
}
}

// DSL
inline fun logcat(builderAction: LogcatCommandBuilder.() -> Unit): java.lang.Process =
LogcatCommandBuilder().apply(builderAction).toProcess()

class LogcatCommandBuilder {
private val cmdList = arrayListOf("logcat")

fun clear() = apply { cmdList.add("--clear") }

fun dump() = apply { cmdList.add("-d") }

fun pid(pid: Int) = apply { cmdList.add("--pid=$pid") }

fun format(format: String) = apply { cmdList.add("--format=$format") }

fun filterspec(
tag: String,
priority: String,
) = apply {
cmdList.add("-s")
cmdList.add("$tag:$priority")
}

fun filterspec(spec: String) =
apply {
cmdList.add("-s")
cmdList.add(spec)
}

fun toProcess(): java.lang.Process = Runtime.getRuntime().exec(cmdList.toTypedArray())
}

0 comments on commit 00560f3

Please sign in to comment.