Commit 576efbdc authored by topjohnwu's avatar topjohnwu

Move su logs out of magiskdb

parent a7f0510a
...@@ -113,6 +113,7 @@ dependencies { ...@@ -113,6 +113,7 @@ dependencies {
} }
def vRoom = '2.2.1' def vRoom = '2.2.1'
implementation "com.github.topjohnwu:room-runtime:${vRoom}" implementation "com.github.topjohnwu:room-runtime:${vRoom}"
implementation "androidx.room:room-rxjava2:${vRoom}"
kapt "androidx.room:room-compiler:${vRoom}" kapt "androidx.room:room-compiler:${vRoom}"
def vNav = '2.1.0' def vNav = '2.1.0'
......
...@@ -11,6 +11,8 @@ import androidx.work.impl.WorkDatabase ...@@ -11,6 +11,8 @@ import androidx.work.impl.WorkDatabase
import androidx.work.impl.WorkDatabase_Impl import androidx.work.impl.WorkDatabase_Impl
import com.topjohnwu.magisk.data.database.RepoDatabase import com.topjohnwu.magisk.data.database.RepoDatabase
import com.topjohnwu.magisk.data.database.RepoDatabase_Impl 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.ActivityTracker
import com.topjohnwu.magisk.di.koinModules import com.topjohnwu.magisk.di.koinModules
import com.topjohnwu.magisk.extensions.get import com.topjohnwu.magisk.extensions.get
...@@ -40,6 +42,7 @@ open class App() : Application() { ...@@ -40,6 +42,7 @@ open class App() : Application() {
when (it) { when (it) {
WorkDatabase::class.java -> WorkDatabase_Impl() WorkDatabase::class.java -> WorkDatabase_Impl()
RepoDatabase::class.java -> RepoDatabase_Impl() RepoDatabase::class.java -> RepoDatabase_Impl()
SuLogDatabase::class.java -> SuLogDatabase_Impl()
else -> null else -> null
} }
} }
......
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()
}
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
}
package com.topjohnwu.magisk.data.repository package com.topjohnwu.magisk.data.repository
import com.topjohnwu.magisk.Const import com.topjohnwu.magisk.Const
import com.topjohnwu.magisk.data.database.LogDao import com.topjohnwu.magisk.data.database.SuLogDao
import com.topjohnwu.magisk.extensions.toSingle
import com.topjohnwu.magisk.model.entity.MagiskLog import com.topjohnwu.magisk.model.entity.MagiskLog
import com.topjohnwu.magisk.model.entity.WrappedMagiskLog import com.topjohnwu.magisk.model.entity.WrappedMagiskLog
import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.Shell
import io.reactivex.Completable
import io.reactivex.Single import io.reactivex.Single
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
class LogRepository( class LogRepository(
private val logDao: LogDao private val logDao: SuLogDao
) { ) {
fun fetchLogs() = logDao.fetchAll() fun fetchLogs() = logDao.fetchAll().map { it.wrap() }
.map { it.sortByDescending { it.date.time }; it }
.map { it.wrap() }
fun fetchMagiskLogs() = Single.fromCallable { fun fetchMagiskLogs() = Single.fromCallable {
Shell.su("tail -n 5000 ${Const.MAGISK_LOG}").exec().out Shell.su("tail -n 5000 ${Const.MAGISK_LOG}").exec().out
}.filter { it.isNotEmpty() } }.flattenAsFlowable { it }.filter { it.isNotEmpty() }
fun clearLogs() = logDao.deleteAll() fun clearLogs() = logDao.deleteAll()
fun clearOutdated() = logDao.deleteOutdated()
fun clearMagiskLogs() = Shell.su("echo -n > " + Const.MAGISK_LOG) fun clearMagiskLogs() = Completable.fromAction {
.toSingle() Shell.su("echo -n > ${Const.MAGISK_LOG}").exec()
.map { it.exec() } }
fun put(log: MagiskLog) = logDao.put(log) fun insert(log: MagiskLog) = logDao.insert(log)
private fun List<MagiskLog>.wrap(): List<WrappedMagiskLog> { private fun List<MagiskLog>.wrap(): List<WrappedMagiskLog> {
val day = TimeUnit.DAYS.toMillis(1) val day = TimeUnit.DAYS.toMillis(1)
return groupBy { it.date.time / day } return groupBy { it.time / day }
.map { WrappedMagiskLog(it.key * day, it.value) } .map { WrappedMagiskLog(it.key * day, it.value) }
} }
......
...@@ -8,15 +8,20 @@ import org.koin.dsl.module ...@@ -8,15 +8,20 @@ import org.koin.dsl.module
val databaseModule = module { val databaseModule = module {
single { LogDao() }
single { PolicyDao(get()) } single { PolicyDao(get()) }
single { SettingsDao() } single { SettingsDao() }
single { StringDao() } single { StringDao() }
single { createRepoDatabase(get()).repoDao() } single { createRepoDatabase(get()).repoDao() }
single { createSuLogDatabase(get(Protected)).suLogDao() }
single { RepoUpdater(get(), get()) } single { RepoUpdater(get(), get()) }
} }
fun createRepoDatabase(context: Context) = fun createRepoDatabase(context: Context) =
Room.databaseBuilder(context, RepoDatabase::class.java, "repo.db") Room.databaseBuilder(context, RepoDatabase::class.java, "repo.db")
.fallbackToDestructiveMigration() .fallbackToDestructiveMigration()
.build() .build()
fun createSuLogDatabase(context: Context) =
Room.databaseBuilder(context, SuLogDatabase::class.java, "sulogs.db")
.fallbackToDestructiveMigration()
.build()
package com.topjohnwu.magisk.model.entity 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.timeFormatTime
import com.topjohnwu.magisk.extensions.toTime import com.topjohnwu.magisk.extensions.toTime
import com.topjohnwu.magisk.model.entity.MagiskPolicy.Companion.ALLOW import com.topjohnwu.magisk.model.entity.MagiskPolicy.Companion.ALLOW
import java.util.*
@Entity(tableName = "logs")
data class MagiskLog( data class MagiskLog(
val fromUid: Int, val fromUid: Int,
val toUid: Int, val toUid: Int,
...@@ -13,9 +17,10 @@ data class MagiskLog( ...@@ -13,9 +17,10 @@ data class MagiskLog(
val appName: String, val appName: String,
val command: String, val command: String,
val action: Boolean, 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( data class WrappedMagiskLog(
...@@ -23,35 +28,8 @@ data class WrappedMagiskLog( ...@@ -23,35 +28,8 @@ data class WrappedMagiskLog(
val items: List<MagiskLog> 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( fun MagiskPolicy.toLog(
toUid: Int, toUid: Int,
fromPid: Int, fromPid: Int,
command: String, command: String
date: Date ) = MagiskLog(uid, toUid, fromPid, packageName, appName, command, policy == ALLOW, now)
) = MagiskLog(uid, toUid, fromPid, packageName, appName, command, policy == ALLOW, date)
...@@ -50,13 +50,7 @@ class LogItemEntryRvItem(val item: MagiskLog) : ComparableRvItem<LogItemEntryRvI ...@@ -50,13 +50,7 @@ class LogItemEntryRvItem(val item: MagiskLog) : ComparableRvItem<LogItemEntryRvI
fun toggle() = isExpanded.toggle() fun toggle() = isExpanded.toggle()
override fun contentSameAs(other: LogItemEntryRvItem) = item.fromUid == other.item.fromUid && override fun contentSameAs(other: LogItemEntryRvItem) = item == other.item
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 itemSameAs(other: LogItemEntryRvItem) = item.appName == other.item.appName override fun itemSameAs(other: LogItemEntryRvItem) = item.appName == other.item.appName
} }
...@@ -74,4 +68,4 @@ class MagiskLogRvItem : ComparableRvItem<MagiskLogRvItem>() { ...@@ -74,4 +68,4 @@ class MagiskLogRvItem : ComparableRvItem<MagiskLogRvItem>() {
override fun contentSameAs(other: MagiskLogRvItem): Boolean = false override fun contentSameAs(other: MagiskLogRvItem): Boolean = false
override fun itemSameAs(other: MagiskLogRvItem): Boolean = false override fun itemSameAs(other: MagiskLogRvItem): Boolean = false
} }
\ No newline at end of file
...@@ -104,7 +104,6 @@ class LogViewModel( ...@@ -104,7 +104,6 @@ class LogViewModel(
.add() .add()
private fun clearMagiskLogs(callback: () -> Unit) = logRepo.clearMagiskLogs() private fun clearMagiskLogs(callback: () -> Unit) = logRepo.clearMagiskLogs()
.ignoreElement()
.doOnComplete(callback) .doOnComplete(callback)
.subscribeK { SnackbarEvent(R.string.logs_cleared).publish() } .subscribeK { SnackbarEvent(R.string.logs_cleared).publish() }
.add() .add()
...@@ -115,8 +114,7 @@ class LogViewModel( ...@@ -115,8 +114,7 @@ class LogViewModel(
.toList() .toList()
private fun fetchMagiskLog() = logRepo.fetchMagiskLogs() private fun fetchMagiskLog() = logRepo.fetchMagiskLogs()
.flattenAsFlowable { it }
.map { ConsoleRvItem(it) } .map { ConsoleRvItem(it) }
.toList() .toList()
} }
\ No newline at end of file
...@@ -18,7 +18,6 @@ import com.topjohnwu.magisk.model.entity.toPolicy ...@@ -18,7 +18,6 @@ import com.topjohnwu.magisk.model.entity.toPolicy
import com.topjohnwu.magisk.ui.surequest.SuRequestActivity import com.topjohnwu.magisk.ui.surequest.SuRequestActivity
import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.Shell
import timber.log.Timber import timber.log.Timber
import java.util.*
object SuHandler : ProviderCallHandler { object SuHandler : ProviderCallHandler {
...@@ -101,12 +100,11 @@ object SuHandler : ProviderCallHandler { ...@@ -101,12 +100,11 @@ object SuHandler : ProviderCallHandler {
val log = policy.toLog( val log = policy.toLog(
toUid = toUid, toUid = toUid,
fromPid = pid, fromPid = pid,
command = command, command = command
date = Date()
) )
val logRepo = get<LogRepository>() 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) { private fun handleNotify(context: Context, data: Bundle) {
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
#include <daemon.h> #include <daemon.h>
#include <utils.h> #include <utils.h>
#define DB_VERSION 9 #define DB_VERSION 10
using namespace std; using namespace std;
...@@ -72,13 +72,6 @@ static char *open_and_init_db(sqlite3 *&db) { ...@@ -72,13 +72,6 @@ static char *open_and_init_db(sqlite3 *&db) {
"logging INT, notification INT, PRIMARY KEY(uid))", "logging INT, notification INT, PRIMARY KEY(uid))",
nullptr, nullptr, &err); nullptr, nullptr, &err);
err_ret(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 // Settings
sqlite3_exec(db, sqlite3_exec(db,
"CREATE TABLE IF NOT EXISTS settings " "CREATE TABLE IF NOT EXISTS settings "
...@@ -144,6 +137,12 @@ static char *open_and_init_db(sqlite3 *&db) { ...@@ -144,6 +137,12 @@ static char *open_and_init_db(sqlite3 *&db) {
ver = 9; ver = 9;
upgrade = true; upgrade = true;
} }
if (ver < 10) {
sqlite3_exec(db, "DROP TABLE logs", nullptr, nullptr, &err);
err_ret(err);
ver = 10;
upgrade = true;
}
if (upgrade) { if (upgrade) {
// Set version // Set version
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment