Move su logs out of magiskdb
This commit is contained in:
parent
a7f0510a3e
commit
576efbdc1b
@ -113,6 +113,7 @@ dependencies {
|
||||
}
|
||||
def vRoom = '2.2.1'
|
||||
implementation "com.github.topjohnwu:room-runtime:${vRoom}"
|
||||
implementation "androidx.room:room-rxjava2:${vRoom}"
|
||||
kapt "androidx.room:room-compiler:${vRoom}"
|
||||
|
||||
def vNav = '2.1.0'
|
||||
|
@ -11,6 +11,8 @@ import androidx.work.impl.WorkDatabase
|
||||
import androidx.work.impl.WorkDatabase_Impl
|
||||
import com.topjohnwu.magisk.data.database.RepoDatabase
|
||||
import com.topjohnwu.magisk.data.database.RepoDatabase_Impl
|
||||
import com.topjohnwu.magisk.data.database.SuLogDatabase
|
||||
import com.topjohnwu.magisk.data.database.SuLogDatabase_Impl
|
||||
import com.topjohnwu.magisk.di.ActivityTracker
|
||||
import com.topjohnwu.magisk.di.koinModules
|
||||
import com.topjohnwu.magisk.extensions.get
|
||||
@ -40,6 +42,7 @@ open class App() : Application() {
|
||||
when (it) {
|
||||
WorkDatabase::class.java -> WorkDatabase_Impl()
|
||||
RepoDatabase::class.java -> RepoDatabase_Impl()
|
||||
SuLogDatabase::class.java -> SuLogDatabase_Impl()
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
@ -1,33 +0,0 @@
|
||||
package com.topjohnwu.magisk.data.database
|
||||
|
||||
import com.topjohnwu.magisk.data.database.magiskdb.*
|
||||
import com.topjohnwu.magisk.model.entity.MagiskLog
|
||||
import com.topjohnwu.magisk.model.entity.toLog
|
||||
import com.topjohnwu.magisk.model.entity.toMap
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
class LogDao : BaseDao() {
|
||||
|
||||
override val table = Table.LOG
|
||||
|
||||
fun deleteOutdated(
|
||||
suTimeout: Long = TimeUnit.DAYS.toMillis(14)
|
||||
) = query<Delete> {
|
||||
condition {
|
||||
lessThan("time", suTimeout.toString())
|
||||
}
|
||||
}.ignoreElement()
|
||||
|
||||
fun deleteAll() = query<Delete>().ignoreElement()
|
||||
|
||||
fun fetchAll() = query<Select> {
|
||||
orderBy("time", Order.DESC)
|
||||
}.flattenAsFlowable { it }
|
||||
.map { it.toLog() }
|
||||
.toList()
|
||||
|
||||
fun put(log: MagiskLog) = query<Insert> {
|
||||
values(log.toMap())
|
||||
}.ignoreElement()
|
||||
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package com.topjohnwu.magisk.data.database
|
||||
|
||||
import androidx.room.*
|
||||
import com.topjohnwu.magisk.model.entity.MagiskLog
|
||||
import io.reactivex.Completable
|
||||
import io.reactivex.Single
|
||||
import java.util.*
|
||||
|
||||
@Database(version = 1, entities = [MagiskLog::class])
|
||||
abstract class SuLogDatabase : RoomDatabase() {
|
||||
|
||||
abstract fun suLogDao(): SuLogDao
|
||||
}
|
||||
|
||||
@Dao
|
||||
abstract class SuLogDao(private val db: SuLogDatabase) {
|
||||
|
||||
private val twoWeeksAgo =
|
||||
Calendar.getInstance().apply { add(Calendar.WEEK_OF_YEAR, -2) }.timeInMillis
|
||||
|
||||
fun deleteAll() = Completable.fromAction { db.clearAllTables() }
|
||||
|
||||
fun fetchAll() = deleteOutdated().andThen(fetch())
|
||||
|
||||
@Query("SELECT * FROM logs ORDER BY time DESC")
|
||||
protected abstract fun fetch(): Single<MutableList<MagiskLog>>
|
||||
|
||||
@Insert
|
||||
abstract fun insert(log: MagiskLog): Completable
|
||||
|
||||
@Query("DELETE FROM logs WHERE time < :timeout")
|
||||
protected abstract fun deleteOutdated(
|
||||
timeout: Long = twoWeeksAgo
|
||||
): Completable
|
||||
|
||||
}
|
@ -1,39 +1,36 @@
|
||||
package com.topjohnwu.magisk.data.repository
|
||||
|
||||
import com.topjohnwu.magisk.Const
|
||||
import com.topjohnwu.magisk.data.database.LogDao
|
||||
import com.topjohnwu.magisk.extensions.toSingle
|
||||
import com.topjohnwu.magisk.data.database.SuLogDao
|
||||
import com.topjohnwu.magisk.model.entity.MagiskLog
|
||||
import com.topjohnwu.magisk.model.entity.WrappedMagiskLog
|
||||
import com.topjohnwu.superuser.Shell
|
||||
import io.reactivex.Completable
|
||||
import io.reactivex.Single
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
|
||||
class LogRepository(
|
||||
private val logDao: LogDao
|
||||
private val logDao: SuLogDao
|
||||
) {
|
||||
|
||||
fun fetchLogs() = logDao.fetchAll()
|
||||
.map { it.sortByDescending { it.date.time }; it }
|
||||
.map { it.wrap() }
|
||||
fun fetchLogs() = logDao.fetchAll().map { it.wrap() }
|
||||
|
||||
fun fetchMagiskLogs() = Single.fromCallable {
|
||||
Shell.su("tail -n 5000 ${Const.MAGISK_LOG}").exec().out
|
||||
}.filter { it.isNotEmpty() }
|
||||
}.flattenAsFlowable { it }.filter { it.isNotEmpty() }
|
||||
|
||||
fun clearLogs() = logDao.deleteAll()
|
||||
fun clearOutdated() = logDao.deleteOutdated()
|
||||
|
||||
fun clearMagiskLogs() = Shell.su("echo -n > " + Const.MAGISK_LOG)
|
||||
.toSingle()
|
||||
.map { it.exec() }
|
||||
fun clearMagiskLogs() = Completable.fromAction {
|
||||
Shell.su("echo -n > ${Const.MAGISK_LOG}").exec()
|
||||
}
|
||||
|
||||
fun put(log: MagiskLog) = logDao.put(log)
|
||||
fun insert(log: MagiskLog) = logDao.insert(log)
|
||||
|
||||
private fun List<MagiskLog>.wrap(): List<WrappedMagiskLog> {
|
||||
val day = TimeUnit.DAYS.toMillis(1)
|
||||
return groupBy { it.date.time / day }
|
||||
return groupBy { it.time / day }
|
||||
.map { WrappedMagiskLog(it.key * day, it.value) }
|
||||
}
|
||||
|
||||
|
@ -8,15 +8,20 @@ import org.koin.dsl.module
|
||||
|
||||
|
||||
val databaseModule = module {
|
||||
single { LogDao() }
|
||||
single { PolicyDao(get()) }
|
||||
single { SettingsDao() }
|
||||
single { StringDao() }
|
||||
single { createRepoDatabase(get()).repoDao() }
|
||||
single { createSuLogDatabase(get(Protected)).suLogDao() }
|
||||
single { RepoUpdater(get(), get()) }
|
||||
}
|
||||
|
||||
fun createRepoDatabase(context: Context) =
|
||||
Room.databaseBuilder(context, RepoDatabase::class.java, "repo.db")
|
||||
.fallbackToDestructiveMigration()
|
||||
.build()
|
||||
Room.databaseBuilder(context, RepoDatabase::class.java, "repo.db")
|
||||
.fallbackToDestructiveMigration()
|
||||
.build()
|
||||
|
||||
fun createSuLogDatabase(context: Context) =
|
||||
Room.databaseBuilder(context, SuLogDatabase::class.java, "sulogs.db")
|
||||
.fallbackToDestructiveMigration()
|
||||
.build()
|
||||
|
@ -1,10 +1,14 @@
|
||||
package com.topjohnwu.magisk.model.entity
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.Ignore
|
||||
import androidx.room.PrimaryKey
|
||||
import com.topjohnwu.magisk.extensions.now
|
||||
import com.topjohnwu.magisk.extensions.timeFormatTime
|
||||
import com.topjohnwu.magisk.extensions.toTime
|
||||
import com.topjohnwu.magisk.model.entity.MagiskPolicy.Companion.ALLOW
|
||||
import java.util.*
|
||||
|
||||
@Entity(tableName = "logs")
|
||||
data class MagiskLog(
|
||||
val fromUid: Int,
|
||||
val toUid: Int,
|
||||
@ -13,9 +17,10 @@ data class MagiskLog(
|
||||
val appName: String,
|
||||
val command: String,
|
||||
val action: Boolean,
|
||||
val date: Date
|
||||
val time: Long = -1
|
||||
) {
|
||||
val timeString = date.time.toTime(timeFormatTime)
|
||||
@PrimaryKey(autoGenerate = true) var id: Int = 0
|
||||
@Ignore val timeString = time.toTime(timeFormatTime)
|
||||
}
|
||||
|
||||
data class WrappedMagiskLog(
|
||||
@ -23,35 +28,8 @@ data class WrappedMagiskLog(
|
||||
val items: List<MagiskLog>
|
||||
)
|
||||
|
||||
fun Map<String, String>.toLog(): MagiskLog {
|
||||
return MagiskLog(
|
||||
fromUid = get("from_uid")?.toIntOrNull() ?: -1,
|
||||
toUid = get("to_uid")?.toIntOrNull() ?: -1,
|
||||
fromPid = get("from_pid")?.toIntOrNull() ?: -1,
|
||||
packageName = get("package_name").orEmpty(),
|
||||
appName = get("app_name").orEmpty(),
|
||||
command = get("command").orEmpty(),
|
||||
action = get("action")?.toIntOrNull() != 0,
|
||||
date = get("time")?.toLongOrNull()?.toDate() ?: Date()
|
||||
)
|
||||
}
|
||||
|
||||
fun Long.toDate() = Date(this)
|
||||
|
||||
fun MagiskLog.toMap() = mapOf(
|
||||
"from_uid" to fromUid,
|
||||
"to_uid" to toUid,
|
||||
"from_pid" to fromPid,
|
||||
"package_name" to packageName,
|
||||
"app_name" to appName,
|
||||
"command" to command,
|
||||
"action" to action,
|
||||
"time" to date.time
|
||||
)
|
||||
|
||||
fun MagiskPolicy.toLog(
|
||||
toUid: Int,
|
||||
fromPid: Int,
|
||||
command: String,
|
||||
date: Date
|
||||
) = MagiskLog(uid, toUid, fromPid, packageName, appName, command, policy == ALLOW, date)
|
||||
command: String
|
||||
) = MagiskLog(uid, toUid, fromPid, packageName, appName, command, policy == ALLOW, now)
|
||||
|
@ -50,13 +50,7 @@ class LogItemEntryRvItem(val item: MagiskLog) : ComparableRvItem<LogItemEntryRvI
|
||||
|
||||
fun toggle() = isExpanded.toggle()
|
||||
|
||||
override fun contentSameAs(other: LogItemEntryRvItem) = item.fromUid == other.item.fromUid &&
|
||||
item.toUid == other.item.toUid &&
|
||||
item.fromPid == other.item.fromPid &&
|
||||
item.packageName == other.item.packageName &&
|
||||
item.command == other.item.command &&
|
||||
item.action == other.item.action &&
|
||||
item.date == other.item.date
|
||||
override fun contentSameAs(other: LogItemEntryRvItem) = item == other.item
|
||||
|
||||
override fun itemSameAs(other: LogItemEntryRvItem) = item.appName == other.item.appName
|
||||
}
|
||||
@ -74,4 +68,4 @@ class MagiskLogRvItem : ComparableRvItem<MagiskLogRvItem>() {
|
||||
override fun contentSameAs(other: MagiskLogRvItem): Boolean = false
|
||||
|
||||
override fun itemSameAs(other: MagiskLogRvItem): Boolean = false
|
||||
}
|
||||
}
|
||||
|
@ -104,7 +104,6 @@ class LogViewModel(
|
||||
.add()
|
||||
|
||||
private fun clearMagiskLogs(callback: () -> Unit) = logRepo.clearMagiskLogs()
|
||||
.ignoreElement()
|
||||
.doOnComplete(callback)
|
||||
.subscribeK { SnackbarEvent(R.string.logs_cleared).publish() }
|
||||
.add()
|
||||
@ -115,8 +114,7 @@ class LogViewModel(
|
||||
.toList()
|
||||
|
||||
private fun fetchMagiskLog() = logRepo.fetchMagiskLogs()
|
||||
.flattenAsFlowable { it }
|
||||
.map { ConsoleRvItem(it) }
|
||||
.toList()
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,6 @@ import com.topjohnwu.magisk.model.entity.toPolicy
|
||||
import com.topjohnwu.magisk.ui.surequest.SuRequestActivity
|
||||
import com.topjohnwu.superuser.Shell
|
||||
import timber.log.Timber
|
||||
import java.util.*
|
||||
|
||||
object SuHandler : ProviderCallHandler {
|
||||
|
||||
@ -101,12 +100,11 @@ object SuHandler : ProviderCallHandler {
|
||||
val log = policy.toLog(
|
||||
toUid = toUid,
|
||||
fromPid = pid,
|
||||
command = command,
|
||||
date = Date()
|
||||
command = command
|
||||
)
|
||||
|
||||
val logRepo = get<LogRepository>()
|
||||
logRepo.put(log).subscribeK(onError = { Timber.e(it) })
|
||||
logRepo.insert(log).subscribeK(onError = { Timber.e(it) })
|
||||
}
|
||||
|
||||
private fun handleNotify(context: Context, data: Bundle) {
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include <daemon.h>
|
||||
#include <utils.h>
|
||||
|
||||
#define DB_VERSION 9
|
||||
#define DB_VERSION 10
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -72,13 +72,6 @@ static char *open_and_init_db(sqlite3 *&db) {
|
||||
"logging INT, notification INT, PRIMARY KEY(uid))",
|
||||
nullptr, nullptr, &err);
|
||||
err_ret(err);
|
||||
// Logs
|
||||
sqlite3_exec(db,
|
||||
"CREATE TABLE IF NOT EXISTS logs "
|
||||
"(from_uid INT, package_name TEXT, app_name TEXT, from_pid INT, "
|
||||
"to_uid INT, action INT, time INT, command TEXT)",
|
||||
nullptr, nullptr, &err);
|
||||
err_ret(err);
|
||||
// Settings
|
||||
sqlite3_exec(db,
|
||||
"CREATE TABLE IF NOT EXISTS settings "
|
||||
@ -144,6 +137,12 @@ static char *open_and_init_db(sqlite3 *&db) {
|
||||
ver = 9;
|
||||
upgrade = true;
|
||||
}
|
||||
if (ver < 10) {
|
||||
sqlite3_exec(db, "DROP TABLE logs", nullptr, nullptr, &err);
|
||||
err_ret(err);
|
||||
ver = 10;
|
||||
upgrade = true;
|
||||
}
|
||||
|
||||
if (upgrade) {
|
||||
// Set version
|
||||
|
Loading…
Reference in New Issue
Block a user