Skip to content

Commit

Permalink
[feat]: update v1.5.2
Browse files Browse the repository at this point in the history
* [build]: updated dependencies

* [fix]: empty logs placeholder animation

* [build]: bumped version to 1.5.2

* [refactor]: 1 second delay to show empty logs placeholder

* [fix]: some crash idk

* [feat]: show all logs since device boot

* [fix]: first line dropping
  • Loading branch information
F0x1d authored Dec 5, 2023
1 parent 3633989 commit 27c82dd
Show file tree
Hide file tree
Showing 20 changed files with 338 additions and 66 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 24
targetSdk 34
versionCode 53
versionName "1.5.1"
versionCode 54
versionName "1.5.2"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

Expand Down
198 changes: 198 additions & 0 deletions app/schemas/com.f0x1d.logfox.database.AppDatabase/12.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
{
"formatVersion": 1,
"database": {
"version": 12,
"identityHash": "6a7fde8f15f3c9a2f984798e872b69c2",
"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, `log_dump` TEXT, `log_dump_file` TEXT, `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": "logDump",
"columnName": "log_dump",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "logDumpFile",
"columnName": "log_dump_file",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
},
"indices": [
{
"name": "index_AppCrash_date_and_time",
"unique": false,
"columnNames": [
"date_and_time"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_AppCrash_date_and_time` ON `${TABLE_NAME}` (`date_and_time`)"
}
],
"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, '6a7fde8f15f3c9a2f984798e872b69c2')"
]
}
}
5 changes: 4 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 = 11)
@Database(entities = [AppCrash::class, LogRecording::class, UserFilter::class], version = 12)
@TypeConverters(CrashTypeConverter::class, AllowedLevelsConverter::class)
abstract class AppDatabase: RoomDatabase() {

Expand Down Expand Up @@ -51,6 +51,9 @@ abstract class AppDatabase: RoomDatabase() {
val MIGRATION_10_11 = Migration(10, 11) {
it.execSQL("ALTER TABLE AppCrash ADD COLUMN log_dump_file TEXT")
}
val MIGRATION_11_12 = Migration(11, 12) {
it.execSQL("CREATE INDEX index_AppCrash_date_and_time ON AppCrash(date_and_time)")
}
}

abstract fun appCrashDao(): AppCrashDao
Expand Down
17 changes: 14 additions & 3 deletions app/src/main/java/com/f0x1d/logfox/database/entity/AppCrash.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
package com.f0x1d.logfox.database.entity

import androidx.room.*
import androidx.room.ColumnInfo
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Entity
import androidx.room.Insert
import androidx.room.PrimaryKey
import androidx.room.Query
import androidx.room.TypeConverter
import androidx.room.Update
import kotlinx.coroutines.flow.Flow
import java.io.File

Expand All @@ -9,9 +17,9 @@ data class AppCrash(
@ColumnInfo(name = "app_name") val appName: String?,
@ColumnInfo(name = "package_name") val packageName: String,
@ColumnInfo(name = "crash_type") val crashType: CrashType,
@ColumnInfo(name = "date_and_time") val dateAndTime: Long,
@ColumnInfo(name = "date_and_time", index = true) val dateAndTime: Long,
@ColumnInfo(name = "log") val log: String,
@ColumnInfo(name = "log_dump") val logDump: String? = null,
@Deprecated("Use logDumpFile") @ColumnInfo(name = "log_dump") val logDump: String? = null,
@ColumnInfo(name = "log_dump_file") val logDumpFile: String? = null,
@PrimaryKey(autoGenerate = true) val id: Long = 0
) {
Expand All @@ -32,6 +40,9 @@ interface AppCrashDao {
@Query("SELECT * FROM AppCrash WHERE package_name = :packageName")
suspend fun getAllByPackageName(packageName: String): List<AppCrash>

@Query("SELECT * FROM AppCrash WHERE date_and_time = :dateAndTime")
suspend fun getAllByDateAndTime(dateAndTime: Long): List<AppCrash>

@Query("SELECT * FROM AppCrash WHERE id = :id")
fun get(id: Long): Flow<AppCrash?>

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 @@ -27,6 +27,7 @@ object RoomModule {
AppDatabase.MIGRATION_7_8,
AppDatabase.MIGRATION_8_9,
AppDatabase.MIGRATION_9_10,
AppDatabase.MIGRATION_10_11
AppDatabase.MIGRATION_10_11,
AppDatabase.MIGRATION_11_12
).build()
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,38 @@ class CrashesRepository @Inject constructor(
if (!exists()) mkdirs()
}

private val crashCollected: suspend (AppCrash) -> Unit = {
override val readers = listOf(
dumpCollector,
JavaCrashDetector(this::collectCrash),
JNICrashDetector(this::collectCrash),
ANRDetector(this::collectCrash)
)

override suspend fun setup() {
dumpCollector.capacity = appPreferences.logsDumpLinesCount
appPreferences.registerListener(this)
}

override suspend fun stop() {
appPreferences.unregisterListener(this)
}

fun deleteAllByPackageName(appCrash: AppCrash) = runOnAppScope {
database.appCrashDao().getAllByPackageName(appCrash.packageName).forEach {
it.deleteDumpFile()
context.cancelCrashNotificationFor(it)
}

database.appCrashDao().deleteByPackageName(appCrash.packageName)
}

private suspend fun collectCrash(it: AppCrash) {
database.appCrashDao().getAllByDateAndTime(it.dateAndTime).filter { crash ->
crash.packageName == it.packageName
}.also {
if (it.isNotEmpty()) return
}

val sendNotificationIfNeeded = { appCrash: AppCrash ->
if (appPreferences.showingNotificationsFor(appCrash.crashType)) {
context.sendErrorNotification(appCrash)
Expand Down Expand Up @@ -64,31 +95,6 @@ class CrashesRepository @Inject constructor(
)
}

override val readers = listOf(
dumpCollector,
JavaCrashDetector(crashCollected),
JNICrashDetector(crashCollected),
ANRDetector(crashCollected)
)

override suspend fun setup() {
dumpCollector.capacity = appPreferences.logsDumpLinesCount
appPreferences.registerListener(this)
}

override suspend fun stop() {
appPreferences.unregisterListener(this)
}

fun deleteAllByPackageName(appCrash: AppCrash) = runOnAppScope {
database.appCrashDao().getAllByPackageName(appCrash.packageName).forEach {
it.deleteDumpFile()
context.cancelCrashNotificationFor(it)
}

database.appCrashDao().deleteByPackageName(appCrash.packageName)
}

override suspend fun updateInternal(item: AppCrash) = database.appCrashDao().update(item)

override suspend fun deleteInternal(item: AppCrash) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ class LoggingRepository @Inject constructor(
): BaseRepository(), SharedPreferences.OnSharedPreferenceChangeListener {

companion object {
private val COMMAND = arrayOf("logcat" , "-v", "uid", "-v", "epoch", "-T", "1")
private val COMMAND = arrayOf("logcat" , "-v", "uid", "-v", "epoch")
private val SHOW_LOGS_FROM_NOW_FLAGS = arrayOf("-T", "1")
}

val logsFlow = MutableStateFlow(emptyList<LogLine>())
Expand Down Expand Up @@ -128,7 +129,13 @@ class LoggingRepository @Inject constructor(
return@coroutineScope
}

val process = loggingTerminal.execute(*COMMAND)
val command = COMMAND + when (appPreferences.showLogsFromAppLaunch) {
true -> SHOW_LOGS_FROM_NOW_FLAGS

else -> emptyArray()
}

val process = loggingTerminal.execute(*command)
if (process == null) {
fallbackToDefaultTerminal()
return@coroutineScope
Expand Down Expand Up @@ -156,7 +163,7 @@ class LoggingRepository @Inject constructor(

try {
process.output.bufferedReader().useLines {
var droppedFirst = false
var droppedFirst = !appPreferences.showLogsFromAppLaunch
// avoiding getting the same line after logging restart because of
// WARNING: -T 0 invalid, setting to 1
for (line in it) {
Expand Down
Loading

0 comments on commit 27c82dd

Please sign in to comment.