aboutsummaryrefslogtreecommitdiff
path: root/core/src/main/kotlin
diff options
context:
space:
mode:
authorAllan Wang <me@allanwang.ca>2017-12-31 15:07:05 -0500
committerGitHub <noreply@github.com>2017-12-31 15:07:05 -0500
commite2009a3e33a58bab37f433845f6d105cb7821da1 (patch)
treeb23f3587db872be7b7ac6a4885862c7d56e35be3 /core/src/main/kotlin
parent2718156fe63304ffb792cc3cb8592ad6e494a8b0 (diff)
downloadkau-e2009a3e33a58bab37f433845f6d105cb7821da1.tar.gz
kau-e2009a3e33a58bab37f433845f6d105cb7821da1.tar.bz2
kau-e2009a3e33a58bab37f433845f6d105cb7821da1.zip
Enhancement/logger (#120)
* Rewrite logger to use lazy loading * Clean up and add to changelog
Diffstat (limited to 'core/src/main/kotlin')
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/email/EmailBuilder.kt2
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/kotlin/Debouncer.kt8
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/kpref/KPref.kt2
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/logging/KauLogger.kt127
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/permissions/PermissionManager.kt12
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackHelper.kt4
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackLayout.kt10
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackPage.kt2
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/utils/ContextUtils.kt4
9 files changed, 86 insertions, 85 deletions
diff --git a/core/src/main/kotlin/ca/allanwang/kau/email/EmailBuilder.kt b/core/src/main/kotlin/ca/allanwang/kau/email/EmailBuilder.kt
index 8c6acff..94a79ab 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/email/EmailBuilder.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/email/EmailBuilder.kt
@@ -60,7 +60,7 @@ class EmailBuilder(val email: String, val subject: String) {
.append("\nApp Version Name: ").append(appInfo.versionName)
.append("\nApp Version Code: ").append(appInfo.versionCode).append("\n")
} catch (e: PackageManager.NameNotFoundException) {
- KL.e("EmailBuilder packageInfo not found")
+ KL.e{"EmailBuilder packageInfo not found"}
}
}
diff --git a/core/src/main/kotlin/ca/allanwang/kau/kotlin/Debouncer.kt b/core/src/main/kotlin/ca/allanwang/kau/kotlin/Debouncer.kt
index 4fba2c8..4c27e19 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/kotlin/Debouncer.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/kotlin/Debouncer.kt
@@ -30,7 +30,7 @@ open class Debouncer(var interval: Long) {
synchronized(this) {
task?.invalidate()
val newTask = DebounceTask(callback)
- KL.v("Debouncer task created: $newTask in $this")
+ KL.v { "Debouncer task created: $newTask in $this" }
sched.schedule(newTask, interval, TimeUnit.MILLISECONDS)
task = newTask
}
@@ -47,7 +47,7 @@ open class Debouncer(var interval: Long) {
*/
fun cancel() {
synchronized(this) {
- if (task != null) KL.v("Debouncer cancelled for $task in $this")
+ if (task != null) KL.v { "Debouncer cancelled for $task in $this" }
task?.invalidate()
task = null
}
@@ -74,11 +74,11 @@ private class DebounceTask(inline val callback: () -> Unit) : Runnable {
override fun run() {
if (!valid) return
valid = false
- KL.v("Debouncer task executed $this")
+ KL.v { "Debouncer task executed $this" }
try {
callback()
} catch (e: Exception) {
- KL.e(e, "DebouncerTask exception")
+ KL.e(e) { "DebouncerTask exception" }
}
}
}
diff --git a/core/src/main/kotlin/ca/allanwang/kau/kpref/KPref.kt b/core/src/main/kotlin/ca/allanwang/kau/kpref/KPref.kt
index fbb8c7d..12f9606 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/kpref/KPref.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/kpref/KPref.kt
@@ -29,7 +29,7 @@ open class KPref {
fun initialize(c: Context, preferenceName: String) {
PREFERENCE_NAME = preferenceName
sp = c.applicationContext.getSharedPreferences(preferenceName, Context.MODE_PRIVATE)
- KL.d("Shared Preference $preferenceName has been initialized")
+ KL.d { "Shared Preference $preferenceName has been initialized" }
val toDelete = deleteKeys()
if (toDelete.isNotEmpty()) {
val edit = sp.edit()
diff --git a/core/src/main/kotlin/ca/allanwang/kau/logging/KauLogger.kt b/core/src/main/kotlin/ca/allanwang/kau/logging/KauLogger.kt
index 61f0708..da1c05b 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/logging/KauLogger.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/logging/KauLogger.kt
@@ -5,13 +5,22 @@ package ca.allanwang.kau.logging
import android.os.Looper
import android.util.Log
-
/**
* Created by Allan Wang on 2017-05-28.
*
* Base logger class with a predefined tag
* This may be extended by an object to effectively replace [Log]
- * Almost everything is opened to make everything customizable
+ * Only direct lazy logging is supported, as for best results,
+ * applications should extend this and use const/final flags to decide whether logging occurs
+ * That way, it will be stripped away by proguard
+ *
+ * Generally speaking, verbose log may contain private information,
+ * as it should be stripped away from production build
+ *
+ * Debug and info logs may contain sensitive info, and may be differentiated by creating a method such as
+ * inline fun _d(message: () -> Any?) {
+ * if (BuildConfig.DEBUG) d(message)
+ * }
*/
open class KauLogger(val tag: String) {
@@ -20,83 +29,71 @@ open class KauLogger(val tag: String) {
*/
open var enabled = true
- /**
- * Global toggle to show private text
- */
- open var showPrivateText = false
+ inline fun v(message: () -> Any?) = log(Log.VERBOSE, message)
- /**
- * If both msg and priv msg are accepted, output the combined output
- */
- open var messageJoiner: (msg: String, privMsg: String) -> String = { msg, privMsg -> "$msg: $privMsg" }
+ inline fun i(message: () -> Any?) = log(Log.INFO, message)
- /**
- * Open hook to change the output of the logger (for instance, output to stdout rather than Android log files
- * Does not use reference notation to avoid constructor leaks
- */
- open var logFun: (priority: Int, message: String?, privateMessage: String?, t: Throwable?) -> Unit = { p, m, pm, t ->
- logImpl(p, m, pm, t)
- }
+ inline fun d(message: () -> Any?) = log(Log.DEBUG, message)
- /**
- * Filter pass-through to decide what we wish to log
- * By default, we will ignore verbose and debug logs
- * @returns {@code true} to log the message, {@code false} to ignore
- */
- open var filter: (Int) -> Boolean = { it != Log.VERBOSE && it != Log.DEBUG }
+ inline fun e(t: Throwable? = null, message: () -> Any?) = log(Log.ERROR, message, t)
- open fun disable(disable: Boolean = true): KauLogger {
- enabled = !disable
- return this
+ inline fun eThrow(message: Any) = with(message.toString()) {
+ log(Log.ERROR, { this }, Throwable(this))
}
- open fun debug(enable: Boolean) {
- filter = if (enable) { _ -> true } else { i -> i != Log.VERBOSE && i != Log.DEBUG }
- showPrivateText = enable
+ inline fun log(priority: Int, message: () -> Any?, t: Throwable? = null) {
+ if (enabled)
+ logImpl(priority, message()?.toString() ?: "null", t)
}
- private fun log(priority: Int, message: String?, privateMessage: String?, t: Throwable? = null) {
- if (!shouldLog(priority, message, privateMessage, t)) return
- logImpl(priority, message, privateMessage, t)
+ open fun logImpl(priority: Int, message: String, t: Throwable?) {
+ if (t != null)
+ Log.e(tag, message, t)
+ else
+ Log.println(priority, tag, message)
}
/**
- * Condition to pass to allow the input to be logged
- */
- protected open fun shouldLog(priority: Int, message: String?, privateMessage: String?, t: Throwable?): Boolean
- = enabled && filter(priority)
-
- /**
- * Base implementation of the Android logger
+ * Log the looper
*/
- protected open fun logImpl(priority: Int, message: String?, privateMessage: String?, t: Throwable?) {
- val text = if (showPrivateText) {
- if (message == null) privateMessage
- else if (privateMessage == null) message
- else messageJoiner(message, privateMessage)
- } else message
-
- if (t != null) Log.e(tag, text ?: "Error", t)
- else if (!text.isNullOrBlank()) Log.println(priority, tag, text)
+ inline fun checkThread(id: Int) {
+ d {
+ val name = Thread.currentThread().name
+ val status = if (Looper.myLooper() == Looper.getMainLooper()) "is" else "is not"
+ "$id $status in the main thread - thread name: $name"
+ }
}
- open fun v(text: String?, privateText: String? = null) = log(Log.VERBOSE, text, privateText)
- open fun d(text: String?, privateText: String? = null) = log(Log.DEBUG, text, privateText)
- open fun i(text: String?, privateText: String? = null) = log(Log.INFO, text, privateText)
- open fun e(text: String?, privateText: String? = null) = log(Log.ERROR, text, privateText)
- open fun a(text: String?, privateText: String? = null) = log(Log.ASSERT, text, privateText)
- open fun e(t: Throwable?, text: String?, privateText: String? = null) = log(Log.ERROR, text, privateText, t)
- open fun eThrow(text: String?) {
- if (text != null)
- e(Throwable(text), text)
+ fun extend(tag: String) = KauLoggerExtension(tag, this)
+}
+
+/**
+ * Tag extender for [KauLogger]
+ * Will prepend [tag] to any expected log output by [logger]
+ * Note that if the parent logger is disabled, the extension logger will not output anything either
+ */
+class KauLoggerExtension(val tag: String, val logger: KauLogger) {
+
+ inline fun v(message: () -> Any?) = log(Log.VERBOSE, message)
+
+ inline fun i(message: () -> Any?) = log(Log.INFO, message)
+
+ inline fun d(message: () -> Any?) = log(Log.DEBUG, message)
+
+ inline fun e(t: Throwable? = null, message: () -> Any?) = log(Log.ERROR, message, t)
+
+ inline fun eThrow(message: Any) = with(message.toString()) {
+ log(Log.ERROR, { this }, Throwable(this))
}
- /**
- * Log the looper
- */
- open fun checkThread(id: Int) {
- val name = Thread.currentThread().name
- val status = if (Looper.myLooper() == Looper.getMainLooper()) "is" else "is not"
- d("$id $status in the main thread - thread name: $name")
+ inline fun log(priority: Int, message: () -> Any?, t: Throwable? = null) =
+ logger.log(priority, { "$tag: ${message()?.toString() ?: "null"}" }, t)
+
+ inline fun checkThread(id: Int) {
+ d {
+ val name = Thread.currentThread().name
+ val status = if (Looper.myLooper() == Looper.getMainLooper()) "is" else "is not"
+ "$id $status in the main thread - thread name: $name"
+ }
}
-} \ No newline at end of file
+}
diff --git a/core/src/main/kotlin/ca/allanwang/kau/permissions/PermissionManager.kt b/core/src/main/kotlin/ca/allanwang/kau/permissions/PermissionManager.kt
index 18f3e41..8b639ad 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/permissions/PermissionManager.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/permissions/PermissionManager.kt
@@ -33,7 +33,7 @@ internal object PermissionManager {
}
operator fun invoke(context: Context, permissions: Array<out String>, callback: (granted: Boolean, deniedPerm: String?) -> Unit) {
- KL.d("Permission manager for: ${permissions.contentToString()}")
+ KL.d { "Permission manager for: ${permissions.contentToString()}" }
if (!buildIsMarshmallowAndUp) return callback(true, null)
val missingPermissions = permissions.filter { !context.hasPermission(it) }
if (missingPermissions.isEmpty()) return callback(true, null)
@@ -41,24 +41,24 @@ internal object PermissionManager {
if (!requestInProgress) {
requestInProgress = true
requestPermissions(context, missingPermissions.toTypedArray())
- } else KL.d("Request is postponed since another one is still in progress; did you remember to override onRequestPermissionsResult?")
+ } else KL.d { "Request is postponed since another one is still in progress; did you remember to override onRequestPermissionsResult?" }
}
@Synchronized internal fun requestPermissions(context: Context, permissions: Array<out String>) {
permissions.forEach {
if (!manifestPermission(context).contains(it)) {
- KL.e("Requested permission $it is not stated in the manifest")
+ KL.e { "Requested permission $it is not stated in the manifest" }
context.toast("$it is not in the manifest")
//we'll let the request pass through so it can be denied and so the callback can be triggered
}
}
val activity = (context as? Activity) ?: throw KauException("Context is not an instance of an activity; cannot request permissions")
- KL.i("Requesting permissions ${permissions.contentToString()}")
+ KL.i { "Requesting permissions ${permissions.contentToString()}" }
ActivityCompat.requestPermissions(activity, permissions, 1)
}
fun onRequestPermissionsResult(context: Context, permissions: Array<out String>, grantResults: IntArray) {
- KL.i("On permission result: pending ${pendingResults.size}")
+ KL.i { "On permission result: pending ${pendingResults.size}" }
val count = Math.min(permissions.size, grantResults.size)
val iter = pendingResults.iterator()
while (iter.hasNext()) {
@@ -77,7 +77,7 @@ internal object PermissionManager {
}
requestPermissions(context, action.permissions.toTypedArray())
}
- KL.i("Post on permission result: pending ${pendingResults.size}")
+ KL.i { "Post on permission result: pending ${pendingResults.size}" }
}
} \ No newline at end of file
diff --git a/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackHelper.kt b/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackHelper.kt
index bc909be..4bc216d 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackHelper.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackHelper.kt
@@ -29,14 +29,14 @@ internal object SwipeBackHelper {
}
activity.overridePendingTransition(startAnimation, 0)
page.onPostCreate()
- KL.v("KauSwipe onCreate ${activity.localClassName}")
+ KL.v { "KauSwipe onCreate ${activity.localClassName}" }
}
fun onDestroy(activity: Activity) {
val page: SwipeBackPage? = this[activity]
pageStack.kauRemoveIf { it.activityRef.get() == null || it === page }
page?.activityRef?.clear()
- KL.v("KauSwipe onDestroy ${activity.localClassName}")
+ KL.v { "KauSwipe onDestroy ${activity.localClassName}" }
}
fun finish(activity: Activity) = this[activity]?.scrollToFinishActivity()
diff --git a/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackLayout.kt b/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackLayout.kt
index a8e8ec3..ae09c8a 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackLayout.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackLayout.kt
@@ -205,7 +205,8 @@ internal class SwipeBackLayout @JvmOverloads constructor(context: Context, attrs
* Scroll out contentView and finish the activity
*/
override fun scrollToFinishActivity() {
- val contentView = contentViewRef.get() ?: return KL.e("KauSwipe cannot scroll to finish as contentView is null. Is onPostCreate called?")
+ val contentView = contentViewRef.get()
+ ?: return KL.e { "KauSwipe cannot scroll to finish as contentView is null. Is onPostCreate called?" }
val childWidth = contentView.width
val top = 0
val left = childWidth + OVERSCROLL_DISTANCE
@@ -222,6 +223,7 @@ internal class SwipeBackLayout @JvmOverloads constructor(context: Context, attrs
}
}
+ @SuppressLint("ClickableViewAccessibility")
override fun onTouchEvent(event: MotionEvent): Boolean {
if (!swipeEnabled) return false
try {
@@ -233,7 +235,8 @@ internal class SwipeBackLayout @JvmOverloads constructor(context: Context, attrs
}
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
- val contentView = contentViewRef.get() ?: return KL.e("KauSwipe cannot change layout as contentView is null. Is onPostCreate called?")
+ val contentView = contentViewRef.get()
+ ?: return KL.e { "KauSwipe cannot change layout as contentView is null. Is onPostCreate called?" }
inLayout = true
val xOffset: Int
val yOffset: Int
@@ -335,7 +338,8 @@ internal class SwipeBackLayout @JvmOverloads constructor(context: Context, attrs
override fun onViewPositionChanged(changedView: View, left: Int, top: Int, dx: Int, dy: Int) {
super.onViewPositionChanged(changedView, left, top, dx, dy)
- val contentView = contentViewRef.get() ?: return KL.e("KauSwipe cannot change view position as contentView is null; is onPostCreate called?")
+ val contentView = contentViewRef.get()
+ ?: return KL.e { "KauSwipe cannot change view position as contentView is null; is onPostCreate called?" }
//make sure that we are using the proper axis
scrollPercent = Math.abs(
if (horizontal) left.toFloat() / contentView.width
diff --git a/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackPage.kt b/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackPage.kt
index 3132f8c..7b6654d 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackPage.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackPage.kt
@@ -40,7 +40,7 @@ internal class SwipeBackPage(activity: Activity) : SwipeBackContractInternal by
}
private fun handleLayout() {
- val activity = activityRef.get() ?: return KL.v("KauSwipe activity ref gone during handleLayout")
+ val activity = activityRef.get() ?: return KL.v { "KauSwipe activity ref gone during handleLayout" }
if (swipeEnabled) swipeBackLayout.attachToActivity(activity)
else swipeBackLayout.removeFromActivity(activity)
}
diff --git a/core/src/main/kotlin/ca/allanwang/kau/utils/ContextUtils.kt b/core/src/main/kotlin/ca/allanwang/kau/utils/ContextUtils.kt
index 06b9601..1b8d58c 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/utils/ContextUtils.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/utils/ContextUtils.kt
@@ -80,7 +80,7 @@ inline fun View.toast(text: String, duration: Int = Toast.LENGTH_LONG, log: Bool
inline fun Context.toast(text: String, duration: Int = Toast.LENGTH_LONG, log: Boolean = false) {
Toast.makeText(this, text, duration).show()
- if (log) KL.i("Toast: $text")
+ if (log) KL.i { "Toast: $text" }
}
//Resource retrievers
@@ -142,7 +142,7 @@ inline fun Context.materialDialog(action: MaterialDialog.Builder.() -> Unit): Ma
val builder = MaterialDialog.Builder(this)
builder.action()
if (isFinishing) {
- KL.d("Material Dialog triggered from finishing context; did not show")
+ KL.d { "Material Dialog triggered from finishing context; did not show" }
return builder.build()
}
return builder.show()