Skip to content

Commit

Permalink
Added UID to logs, new per-app filters
Browse files Browse the repository at this point in the history
  • Loading branch information
F0x1d committed Aug 13, 2023
1 parent 0a9caf1 commit dc0a700
Show file tree
Hide file tree
Showing 31 changed files with 831 additions and 70 deletions.
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ android {
applicationId "com.f0x1d.logfox"
minSdk 21
targetSdk 34
versionCode 37
versionName "1.3.5"
versionCode 38
versionName "1.3.6"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

Expand Down
176 changes: 176 additions & 0 deletions app/schemas/com.f0x1d.logfox.database.AppDatabase/9.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
{
"formatVersion": 1,
"database": {
"version": 9,
"identityHash": "533c258b7f37e152867610670d2204c4",
"entities": [
{
"tableName": "AppCrash",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`app_name` TEXT, `package_name` TEXT NOT NULL, `crash_type` INTEGER NOT NULL, `date_and_time` INTEGER NOT NULL, `log` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)",
"fields": [
{
"fieldPath": "appName",
"columnName": "app_name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "packageName",
"columnName": "package_name",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "crashType",
"columnName": "crash_type",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "dateAndTime",
"columnName": "date_and_time",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "log",
"columnName": "log",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "LogRecording",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`title` TEXT NOT NULL, `date_and_time` INTEGER NOT NULL, `file` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)",
"fields": [
{
"fieldPath": "title",
"columnName": "title",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "dateAndTime",
"columnName": "date_and_time",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "file",
"columnName": "file",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "UserFilter",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`including` INTEGER NOT NULL, `allowed_levels` TEXT NOT NULL, `uid` TEXT, `pid` TEXT, `tid` TEXT, `package_name` TEXT, `tag` TEXT, `content` TEXT, `enabled` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)",
"fields": [
{
"fieldPath": "including",
"columnName": "including",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "allowedLevels",
"columnName": "allowed_levels",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "uid",
"columnName": "uid",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "pid",
"columnName": "pid",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "tid",
"columnName": "tid",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "packageName",
"columnName": "package_name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "tag",
"columnName": "tag",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "content",
"columnName": "content",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "enabled",
"columnName": "enabled",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '533c258b7f37e152867610670d2204c4')"
]
}
}
30 changes: 30 additions & 0 deletions app/src/main/java/com/f0x1d/logfox/adapter/AppsAdapter.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.f0x1d.logfox.adapter

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import com.f0x1d.logfox.adapter.base.BaseListAdapter
import com.f0x1d.logfox.databinding.ItemAppBinding
import com.f0x1d.logfox.model.InstalledApp
import com.f0x1d.logfox.ui.viewholder.AppViewHolder

class AppsAdapter(
private val click: (InstalledApp) -> Unit
): BaseListAdapter<InstalledApp, ItemAppBinding>(APP_DIFF) {

companion object {
val APP_DIFF = object : DiffUtil.ItemCallback<InstalledApp>() {
override fun areItemsTheSame(oldItem: InstalledApp, newItem: InstalledApp) = oldItem.packageName == newItem.packageName

override fun areContentsTheSame(oldItem: InstalledApp, newItem: InstalledApp) = oldItem == newItem
}
}

override fun createHolder(
layoutInflater: LayoutInflater,
parent: ViewGroup
) = AppViewHolder(
ItemAppBinding.inflate(layoutInflater, parent, false),
click
)
}
6 changes: 5 additions & 1 deletion app/src/main/java/com/f0x1d/logfox/database/AppDatabase.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import com.f0x1d.logfox.database.entity.LogRecordingDao
import com.f0x1d.logfox.database.entity.UserFilter
import com.f0x1d.logfox.database.entity.UserFilterDao

@Database(entities = [AppCrash::class, LogRecording::class, UserFilter::class], version = 8)
@Database(entities = [AppCrash::class, LogRecording::class, UserFilter::class], version = 9)
@TypeConverters(CrashTypeConverter::class, AllowedLevelsConverter::class)
abstract class AppDatabase: RoomDatabase() {

Expand All @@ -41,6 +41,10 @@ abstract class AppDatabase: RoomDatabase() {
val MIGRATION_7_8 = Migration(7, 8) {
it.execSQL("ALTER TABLE UserFilter ADD COLUMN including INTEGER NOT NULL DEFAULT 1")
}
val MIGRATION_8_9 = Migration(8, 9) {
it.execSQL("ALTER TABLE UserFilter ADD COLUMN uid TEXT")
it.execSQL("ALTER TABLE UserFilter ADD COLUMN package_name TEXT")
}
}

abstract fun appCrashDao(): AppCrashDao
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ import kotlinx.coroutines.flow.Flow
data class UserFilter(
@ColumnInfo(name = "including") val including: Boolean = true,
@ColumnInfo(name = "allowed_levels") val allowedLevels: List<LogLevel> = emptyList(),
@ColumnInfo(name = "uid") val uid: String? = null,
@ColumnInfo(name = "pid") val pid: String? = null,
@ColumnInfo(name = "tid") val tid: String? = null,
@ColumnInfo(name = "package_name") val packageName: String? = null,
@ColumnInfo(name = "tag") val tag: String? = null,
@ColumnInfo(name = "content") val content: String? = null,
@ColumnInfo(name = "enabled") @GsonSkip val enabled: Boolean = true,
Expand Down
3 changes: 2 additions & 1 deletion app/src/main/java/com/f0x1d/logfox/di/RoomModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ object RoomModule {
AppDatabase.MIGRATION_4_5,
AppDatabase.MIGRATION_5_6,
AppDatabase.MIGRATION_6_7,
AppDatabase.MIGRATION_7_8
AppDatabase.MIGRATION_7_8,
AppDatabase.MIGRATION_8_9
).build()
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,47 @@
package com.f0x1d.logfox.extensions.logline

import android.content.pm.PackageManager
import androidx.collection.LruCache
import com.f0x1d.logfox.model.LogLevel
import com.f0x1d.logfox.model.LogLine
import com.f0x1d.logfox.utils.UIDS

private val logRegex = "(.{23}) (.{5}) (.{5}) (.) (.+?): (.+)".toRegex()
private val logRegex = "(.{23}) (.{1,5}) (.{1,5}) (.{1,5}) (.) (.+?): (.+)".toRegex()
// time, uid, pid, tid, level, tag, message

private val uidsCache = LruCache<String, String>(200)

fun LogLine(
id: Long,
line: String,
packageManager: PackageManager
) = logRegex.find(line)?.run {
val uid = groupValues[2].replace(" ", "")
val integerUid = uid.toIntOrNull() ?: UIDS.MAPPINGS[uid]

val packageName = uidsCache.get(uid) ?: integerUid?.let {
packageManager.getPackagesForUid(it)?.firstOrNull()?.also { packageName ->
uidsCache.put(uid, packageName)
}
}

fun LogLine(id: Long, line: String) = logRegex.find(line)?.run {
LogLine(
id,
groupValues[1].replace(" ", "").run {
indexOf(".").let {
substring(0, it).toLong() * 1000 + substring(it + 1).toLong()
}
},
groupValues[2].replace(" ", ""),
uid,
groupValues[3].replace(" ", ""),
mapLevel(groupValues[4]),
groupValues[5],
groupValues[6]
groupValues[4].replace(" ", ""),
packageName,
mapLevel(groupValues[5]),
groupValues[6].trim(),
groupValues[7]
)
}

private fun mapLevel(level: String) = LogLevel.values().find { it.letter == level } ?: throw RuntimeException("wtf is $level")
private fun mapLevel(level: String) = LogLevel.values().find {
it.letter == level
} ?: throw RuntimeException("wtf is $level")
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@ fun List<LogLine>.filterByExtendedFilters(filters: List<UserFilter>): List<LogLi
}

private fun UserFilter.lineSuits(logLine: LogLine) = allowedLevels.contains(logLine.level) &&
uid.equalsOrTrueIfNull(logLine.uid) &&
pid.equalsOrTrueIfNull(logLine.pid) &&
tid.equalsOrTrueIfNull(logLine.tid) &&
packageName.equalsOrTrueIfNull(logLine.packageName ?: "") &&
tag.equalsOrTrueIfNull(logLine.tag) &&
content.containsOrTrueIfNull(logLine.content)

Expand Down
6 changes: 6 additions & 0 deletions app/src/main/java/com/f0x1d/logfox/model/InstalledApp.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.f0x1d.logfox.model

data class InstalledApp(
val title: CharSequence,
val packageName: String
)
19 changes: 17 additions & 2 deletions app/src/main/java/com/f0x1d/logfox/model/LogLine.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,28 @@ import com.f0x1d.logfox.extensions.logsTimeFormatted
data class LogLine(
val id: Long,
val dateAndTime: Long,
val uid: String,
val pid: String,
val tid: String,
val packageName: String?,
val level: LogLevel,
val tag: String,
val content: String
val content: String,

val logsDateFormatted: String = dateAndTime.logsDateFormatted,
val logsTimeFormatted: String = dateAndTime.logsTimeFormatted
) {
val original get() = "${dateAndTime.logsDateFormatted} ${dateAndTime.logsTimeFormatted} $pid $tid ${level.letter}/$tag: $content"
val original = buildString {
append("$logsDateFormatted ")
append("$logsTimeFormatted ")
append("$uid ")
append("$pid ")
append("$tid ")
if (packageName != null)
append("$packageName ")
append("${level.letter}/$tag: ")
append(content)
}
}

@Keep
Expand Down
Loading

0 comments on commit dc0a700

Please sign in to comment.