Skip to content

Commit

Permalink
- Add debugging ability
Browse files Browse the repository at this point in the history
- Update notification version to v4
  • Loading branch information
lhwdev committed Nov 17, 2020
1 parent b3debd8 commit ca775bd
Show file tree
Hide file tree
Showing 7 changed files with 159 additions and 22 deletions.
6 changes: 3 additions & 3 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ android {
applicationId "com.lhwdev.selfTestMacro"
minSdkVersion 19
targetSdkVersion 30
versionCode 1004
versionName "2.4"
versionCode 1005
versionName "2.5"

multiDexEnabled true

Expand All @@ -24,7 +24,7 @@ android {

buildTypes {
release {
minifyEnabled true
minifyEnabled false
proguardFiles getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro"
}
}
Expand Down
32 changes: 26 additions & 6 deletions app/src/main/java/com/lhwdev/selfTestMacro/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package com.lhwdev.selfTestMacro

import android.annotation.SuppressLint
import android.app.TimePickerDialog
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
import android.net.Uri
Expand All @@ -16,6 +18,7 @@ import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.getSystemService
import androidx.core.text.HtmlCompat
import androidx.lifecycle.lifecycleScope
import com.lhwdev.selfTestMacro.api.getDetailedUserInfo
Expand Down Expand Up @@ -64,7 +67,7 @@ class MainActivity : AppCompatActivity() {
val detailedUserInfo = try {
getDetailedUserInfo(pref.school!!, pref.user!!)
} catch(e: Throwable) {
Log.e("hOI", null, e)
onError(e, "사용자 정보 불러오기")
showToastSuspendAsync("사용자 정보를 불러오지 못했습니다.")
return@withContext
}
Expand Down Expand Up @@ -140,20 +143,20 @@ class MainActivity : AppCompatActivity() {
val title: String,
val message: String
) {
enum class Priority { once, every }
enum class Priority { once, everyWithDoNotShowAgain, every }
}

private fun checkNotice() = lifecycleScope.launch(Dispatchers.IO) {
var content: String? = null
val content: String?
try {
content =
URL("https://raw.githubusercontent.com/wiki/lhwdev/covid-selftest-macro/notice_v3.json").readText()
URL("https://raw.githubusercontent.com/wiki/lhwdev/covid-selftest-macro/notice_v4.json").readText()

val notificationObject = Json {
ignoreUnknownKeys = true /* loose */
}.decodeFromString(NotificationObject.serializer(), content)

if(notificationObject.notificationVersion != 3) {
if(notificationObject.notificationVersion != 4) {
// incapable of displaying this
return@launch
}
Expand All @@ -165,6 +168,7 @@ class MainActivity : AppCompatActivity() {
for(entry in notificationObject.entries) {
var show = when(entry.priority) {
NotificationEntry.Priority.once -> entry.id !in preferenceState.shownNotices
NotificationEntry.Priority.everyWithDoNotShowAgain -> entry.id !in preferenceState.doNotShowAgainNotices
NotificationEntry.Priority.every -> true
}
show = show && (entry.version?.let { currentVersion in it } ?: true)
Expand All @@ -176,6 +180,11 @@ class MainActivity : AppCompatActivity() {
setPositiveButton("확인") { _, _ ->
preferenceState.shownNotices += entry.id
}
if(entry.priority == NotificationEntry.Priority.everyWithDoNotShowAgain)
setNegativeButton("다시 보지 않기") { _, _ ->
preferenceState.doNotShowAgainNotices += entry.id
preferenceState.shownNotices += entry.id
}
}.show().apply {
findViewById<TextView>(android.R.id.message)!!.movementMethod =
LinkMovementMethod.getInstance()
Expand All @@ -185,7 +194,8 @@ class MainActivity : AppCompatActivity() {
} catch(e: Exception) {
// ignore; - network error or etc
// notification is not that important
Log.e("hOI", content, e)

onError(e, "알림")
}
}

Expand Down Expand Up @@ -237,6 +247,16 @@ class MainActivity : AppCompatActivity() {
startActivity(Intent(this, FirstActivity::class.java))
true
}
R.id.debug_info -> lifecycleScope.launch {
val info = getLogcat()
AlertDialog.Builder(this@MainActivity).apply {
setTitle("진단정보")
setMessage(info)
setPositiveButton("복사") { _, _ ->
getSystemService<ClipboardManager>()!!.setPrimaryClip(ClipData.newPlainText("진단정보", info))
}
}.show()
}.let { true }
else -> super.onOptionsItemSelected(item)
}
}
Expand Down
16 changes: 16 additions & 0 deletions app/src/main/java/com/lhwdev/selfTestMacro/MainApplication.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package com.lhwdev.selfTestMacro

import android.app.Application
import kotlinx.coroutines.DEBUG_PROPERTY_NAME
import kotlinx.coroutines.DEBUG_PROPERTY_VALUE_OFF
import kotlinx.coroutines.DEBUG_PROPERTY_VALUE_ON
import kotlinx.coroutines.runBlocking


@Suppress("unused")
Expand All @@ -9,5 +13,17 @@ class MainApplication : Application() {
super.onCreate()
sDummyForInitialization
sDebugFetch = BuildConfig.DEBUG

// debug code
System.setProperty(
DEBUG_PROPERTY_NAME,
if(BuildConfig.DEBUG) DEBUG_PROPERTY_VALUE_ON else DEBUG_PROPERTY_VALUE_OFF
)

Thread.setDefaultUncaughtExceptionHandler { _, exception ->
runBlocking {
writeErrorLog(getErrorInfo(exception, "defaultUncaughtExceptionHandler"))
}
}
}
}
88 changes: 88 additions & 0 deletions app/src/main/java/com/lhwdev/selfTestMacro/debugUtils.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package com.lhwdev.selfTestMacro

import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.os.Build
import androidx.appcompat.app.AlertDialog
import androidx.core.content.getSystemService
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File


suspend fun Context.onError(error: Throwable, description: String = "error") {
val info = getErrorInfo(error, description)
if(getExternalFilesDir(null)?.let { File(it, "debug.txt").exists() } == true) withContext(
Dispatchers.Main
) {
showErrorInfo(info)
}
writeErrorLog(info)
}

suspend fun Context.writeErrorLog(info: String) {
withContext(Dispatchers.IO) {
getExternalFilesDir(null)?.appendText(info)
}
}

suspend fun getErrorInfo(error: Throwable, description: String) = """
$description
Android sdk version: ${Build.VERSION.SDK_INT}
Model: ${Build.DEVICE} / ${Build.PRODUCT}
Stacktrace:
${error.stackTraceToString()}
Logcat:
${getLogcat()}
""".trimIndent()

private fun Context.showErrorInfo(info: String) {
AlertDialog.Builder(this).apply {
setTitle("오류 발생")
setMessage("* 복사된 오류정보는 기기의 정보 등 민감한 정보를 포함할 수 있습니다.\n$info")

setPositiveButton("오류정보 복사") { _, _ ->
CoroutineScope(Dispatchers.Main).launch {
getSystemService<ClipboardManager>()!!
.setPrimaryClip(ClipData.newPlainText("오류정보", info))
showToastSuspendAsync("복사 완료")
}
}
setNegativeButton("취소", null)
}.show()
}


suspend fun getLogcat(): String = withContext(Dispatchers.IO) {
val command = arrayOf("logcat", "-d", "-v", "threadtime")
val process = Runtime.getRuntime().exec(command)
process.inputStream.reader().use { it.readText() }
}

// //Code here
// val log: StringBuilder
// get() {
// val builder = StringBuilder()
// try {
// val command = arrayOf("logcat", "-d", "-v", "threadtime")
// val process = Runtime.getRuntime().exec(command)
// val bufferedReader = process.inputStream.bufferedReader()
//
//
// var line: String
// while(bufferedReader.readLine().also { line = it } != null) {
// if(line.contains(processId)) {
// builder.append(line)
// //Code here
// }
// }
// } catch(ex: IOException) {
// Log.e(TAG, "getLog failed", ex)
// }
// return builder
// }

3 changes: 1 addition & 2 deletions app/src/main/java/com/lhwdev/selfTestMacro/selfTestUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import android.annotation.SuppressLint
import android.app.AlarmManager
import android.app.PendingIntent
import android.content.Context
import android.util.Log
import com.lhwdev.selfTestMacro.api.SurveyData
import com.lhwdev.selfTestMacro.api.registerSurvey
import java.util.Calendar
Expand All @@ -29,7 +28,7 @@ suspend fun Context.submitSuspend(notification: Boolean = true) {
}
} catch(e: Throwable) {
showTestFailedNotification(e.stackTraceToString())
Log.e("hOI", null, e)
onError(e, "제출 실패")
}
}

Expand Down
22 changes: 16 additions & 6 deletions app/src/main/java/com/lhwdev/selfTestMacro/utils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,25 @@
package com.lhwdev.selfTestMacro

import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.content.*
import android.os.Build
import android.os.Handler
import android.util.Base64
import android.view.View
import android.widget.EditText
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.edit
import androidx.core.content.getSystemService
import com.google.android.material.snackbar.Snackbar
import com.lhwdev.selfTestMacro.api.LoginType
import com.lhwdev.selfTestMacro.api.SchoolInfo
import com.lhwdev.selfTestMacro.api.UserInfo
import com.lhwdev.selfTestMacro.api.encodeBase64
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.KSerializer
Expand Down Expand Up @@ -89,10 +92,14 @@ class PreferenceState(val pref: SharedPreferences) {
set(value) = pref.edit {
putStringSet("shownNotices", value)
}
var doNotShowAgainNotices: Set<String>
get() = pref.getStringSet("shownNotices", setOf())!!
set(value) = pref.edit {
putStringSet("shownNotices", value)
}
}



// I knew that global things are bad in android(i waz lazy), but didn't know would be by far worst.
// Only one line below caused TWO bugs; I WON'T do like this in the future
//
Expand All @@ -115,7 +122,6 @@ val Context.preferenceState: PreferenceState
}



fun SharedPreferences.preferenceInt(key: String, defaultValue: Int) =
object : ReadWriteProperty<Any?, Int> {
override fun setValue(thisRef: Any?, property: KProperty<*>, value: Int) {
Expand All @@ -137,7 +143,11 @@ fun SharedPreferences.preferenceString(key: String, defaultValue: String? = null
}

@OptIn(ExperimentalSerializationApi::class)
fun <T> SharedPreferences.preferenceSerialized(key: String, serializer: KSerializer<T>, formatter: StringFormat = Json) =
fun <T> SharedPreferences.preferenceSerialized(
key: String,
serializer: KSerializer<T>,
formatter: StringFormat = Json
) =
object : ReadWriteProperty<Any?, T?> {
var updated = false
var cache: T? = null
Expand Down
14 changes: 9 additions & 5 deletions app/src/main/res/menu/menu_main.xml
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.lhwdev.selfTestMacro.MainActivity">
tools:context="com.lhwdev.selfTestMacro.MainActivity"
tools:ignore="HardcodedText">
<item
android:id="@+id/action_settings"
android:orderInCategory="100"
android:title="@string/action_settings"
app:showAsAction="never" />
android:title="@string/action_settings" />
<item
android:id="@+id/debug_info"
android:title="진단정보 수집" />
<item
android:id="@+id/info"
android:title="정보" />
</menu>

0 comments on commit ca775bd

Please sign in to comment.