summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Marcello Galhardo <mgalhardo@google.com> 2023-04-21 15:35:29 +0000
committer Marcello Galhardo <mgalhardo@google.com> 2023-04-27 21:02:48 +0000
commitad7ef8b159f35c3ab73dbee692999afd14725576 (patch)
treeebac83e896d96c465f927c732c203d76d2310d8e
parentec396f015d60d5a29df43a8f464b004fd97c75de (diff)
Add logging utilities for development with Kotlin
Test: manual Flag: not needed Fixes: b/274509846 Change-Id: I5d800d1bf94fbcbee85dfa706d7a43c92bbc4164
-rw-r--r--packages/SystemUI/src-debug/com/android/systemui/log/DebugLogger.kt80
-rw-r--r--packages/SystemUI/src-release/com/android/systemui/log/DebugLogger.kt35
-rw-r--r--packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt32
-rw-r--r--packages/SystemUI/src/com/android/systemui/notetask/shortcut/LaunchNoteTaskActivity.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/stylus/StylusManager.kt28
-rw-r--r--packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerUI.kt20
6 files changed, 148 insertions, 57 deletions
diff --git a/packages/SystemUI/src-debug/com/android/systemui/log/DebugLogger.kt b/packages/SystemUI/src-debug/com/android/systemui/log/DebugLogger.kt
new file mode 100644
index 000000000000..af29b05a3fb1
--- /dev/null
+++ b/packages/SystemUI/src-debug/com/android/systemui/log/DebugLogger.kt
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.log
+
+import android.os.Build
+import android.util.Log
+import android.util.Log.LOG_ID_MAIN
+
+/**
+ * A simplified debug logger built as a wrapper around Android's [Log]. Internal for development.
+ *
+ * The main advantages are:
+ * - Sensible defaults, automatically retrieving the class name from the call-site (i.e., tag);
+ * - The messages are purged from source on release builds (keep in mind they are visible on AOSP);
+ * - Lazily evaluate Strings for zero impact in production builds or when disabled;
+ *
+ * Usage example:
+ * ```kotlin
+ * // Logging a message:
+ * debugLog { "message" }
+ *
+ * // Logging an error:
+ * debugLog(error = exception) { "message" }
+ *
+ * // Logging the current stack trace, for debugging:
+ * debugLog(error = Throwable()) { "message" }
+ * ```
+ */
+object DebugLogger {
+
+ /**
+ * Log a debug message, with sensible defaults.
+ *
+ * For example:
+ * ```kotlin
+ * val one = 1
+ * debugLog { "message#$one" }
+ * ```
+ *
+ * The output will be: `D/NoteTaskController: message#1`
+ *
+ * Beware, the [debugLog] content is **REMOVED FROM SOURCE AND BINARY** in Release builds.
+ *
+ * @param enabled: whether or not the message should be logged. By default, it is
+ * [Build.IS_DEBUGGABLE].
+ * @param priority: type of this log. By default, it is [Log.DEBUG].
+ * @param tag: identifies the source of a log. By default, it is the receiver's simple name.
+ * @param error: a [Throwable] to log.
+ * @param message: a lazily evaluated message you wish to log.
+ */
+ inline fun Any.debugLog(
+ enabled: Boolean = Build.IS_DEBUGGABLE,
+ priority: Int = Log.DEBUG,
+ tag: String = this::class.simpleName.orEmpty(),
+ error: Throwable? = null,
+ message: () -> String,
+ ) {
+ if (enabled) {
+ if (error == null) {
+ Log.println(priority, tag, message())
+ } else {
+ Log.printlns(LOG_ID_MAIN, priority, tag, message(), error)
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/src-release/com/android/systemui/log/DebugLogger.kt b/packages/SystemUI/src-release/com/android/systemui/log/DebugLogger.kt
new file mode 100644
index 000000000000..2764a1fdfe3d
--- /dev/null
+++ b/packages/SystemUI/src-release/com/android/systemui/log/DebugLogger.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.log
+
+import android.os.Build
+import android.util.Log
+
+/** An empty logger for release builds. */
+object DebugLogger {
+
+ @JvmName("logcatMessage")
+ inline fun Any.debugLog(
+ enabled: Boolean = Build.IS_DEBUGGABLE,
+ priority: Int = Log.DEBUG,
+ tag: String = this::class.simpleName.orEmpty(),
+ error: Throwable? = null,
+ message: () -> String,
+ ) {
+ // no-op.
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
index d4052f54b3da..f288b06678a7 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
@@ -31,15 +31,14 @@ import android.content.Intent
import android.content.pm.PackageManager
import android.content.pm.ShortcutManager
import android.graphics.drawable.Icon
-import android.os.Build
import android.os.UserHandle
import android.os.UserManager
-import android.util.Log
import android.widget.Toast
import androidx.annotation.VisibleForTesting
import com.android.systemui.R
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.devicepolicy.areKeyguardShortcutsDisabled
+import com.android.systemui.log.DebugLogger.debugLog
import com.android.systemui.notetask.NoteTaskRoleManagerExt.createNoteShortcutInfoAsUser
import com.android.systemui.notetask.NoteTaskRoleManagerExt.getDefaultRoleHolderAsUser
import com.android.systemui.notetask.shortcut.LaunchNoteTaskManagedProfileProxyActivity
@@ -92,10 +91,10 @@ constructor(
if (info.launchMode != NoteTaskLaunchMode.AppBubble) return
if (isExpanding) {
- logDebug { "onBubbleExpandChanged - expanding: $info" }
+ debugLog { "onBubbleExpandChanged - expanding: $info" }
eventLogger.logNoteTaskOpened(info)
} else {
- logDebug { "onBubbleExpandChanged - collapsing: $info" }
+ debugLog { "onBubbleExpandChanged - collapsing: $info" }
eventLogger.logNoteTaskClosed(info)
}
}
@@ -168,14 +167,14 @@ constructor(
isKeyguardLocked &&
devicePolicyManager.areKeyguardShortcutsDisabled(userId = user.identifier)
) {
- logDebug { "Enterprise policy disallows launching note app when the screen is locked." }
+ debugLog { "Enterprise policy disallows launching note app when the screen is locked." }
return
}
val info = resolver.resolveInfo(entryPoint, isKeyguardLocked, user)
if (info == null) {
- logDebug { "Default notes app isn't set" }
+ debugLog { "Default notes app isn't set" }
showNoDefaultNotesAppToast()
return
}
@@ -184,7 +183,7 @@ constructor(
try {
// TODO(b/266686199): We should handle when app not available. For now, we log.
- logDebug { "onShowNoteTask - start: $info on user#${user.identifier}" }
+ debugLog { "onShowNoteTask - start: $info on user#${user.identifier}" }
when (info.launchMode) {
is NoteTaskLaunchMode.AppBubble -> {
val intent = createNoteTaskIntent(info)
@@ -192,7 +191,7 @@ constructor(
Icon.createWithResource(context, R.drawable.ic_note_task_shortcut_widget)
bubbles.showOrHideAppBubble(intent, user, icon)
// App bubble logging happens on `onBubbleExpandChanged`.
- logDebug { "onShowNoteTask - opened as app bubble: $info" }
+ debugLog { "onShowNoteTask - opened as app bubble: $info" }
}
is NoteTaskLaunchMode.Activity -> {
if (activityManager.isInForeground(info.packageName)) {
@@ -200,20 +199,20 @@ constructor(
val intent = createHomeIntent()
context.startActivityAsUser(intent, user)
eventLogger.logNoteTaskClosed(info)
- logDebug { "onShowNoteTask - closed as activity: $info" }
+ debugLog { "onShowNoteTask - closed as activity: $info" }
} else {
val intent = createNoteTaskIntent(info)
context.startActivityAsUser(intent, user)
eventLogger.logNoteTaskOpened(info)
- logDebug { "onShowNoteTask - opened as activity: $info" }
+ debugLog { "onShowNoteTask - opened as activity: $info" }
}
}
}
- logDebug { "onShowNoteTask - success: $info" }
+ debugLog { "onShowNoteTask - success: $info" }
} catch (e: ActivityNotFoundException) {
- logDebug { "onShowNoteTask - failed: $info" }
+ debugLog { "onShowNoteTask - failed: $info" }
}
- logDebug { "onShowNoteTask - completed: $info" }
+ debugLog { "onShowNoteTask - completed: $info" }
}
@VisibleForTesting
@@ -253,7 +252,7 @@ constructor(
PackageManager.DONT_KILL_APP,
)
- logDebug { "setNoteTaskShortcutEnabled - completed: $isEnabled" }
+ debugLog { "setNoteTaskShortcutEnabled - completed: $isEnabled" }
}
/**
@@ -352,11 +351,6 @@ private fun createNoteTaskIntent(info: NoteTaskInfo): Intent =
}
}
-/** [Log.println] a [Log.DEBUG] message, only when [Build.IS_DEBUGGABLE]. */
-private inline fun Any.logDebug(message: () -> String) {
- if (Build.IS_DEBUGGABLE) Log.d(this::class.java.simpleName.orEmpty(), message())
-}
-
/** Creates an [Intent] which forces the current app to background by calling home. */
private fun createHomeIntent(): Intent =
Intent(Intent.ACTION_MAIN).apply {
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/shortcut/LaunchNoteTaskActivity.kt b/packages/SystemUI/src/com/android/systemui/notetask/shortcut/LaunchNoteTaskActivity.kt
index 0f38d32e0b64..8ca13b9776bb 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/shortcut/LaunchNoteTaskActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/shortcut/LaunchNoteTaskActivity.kt
@@ -18,12 +18,11 @@ package com.android.systemui.notetask.shortcut
import android.content.Context
import android.content.Intent
-import android.os.Build
import android.os.Bundle
import android.os.UserHandle
import android.os.UserManager
-import android.util.Log
import androidx.activity.ComponentActivity
+import com.android.systemui.log.DebugLogger.debugLog
import com.android.systemui.notetask.NoteTaskController
import com.android.systemui.notetask.NoteTaskEntryPoint
import com.android.systemui.settings.UserTracker
@@ -68,7 +67,7 @@ constructor(
val mainUser: UserHandle? = userManager.mainUser
if (userManager.isManagedProfile) {
if (mainUser == null) {
- logDebug { "Can't find the main user. Skipping the notes app launch." }
+ debugLog { "Can't find the main user. Skipping the notes app launch." }
} else {
controller.startNoteTaskProxyActivityForUser(mainUser)
}
@@ -89,8 +88,3 @@ constructor(
}
}
}
-
-/** [Log.println] a [Log.DEBUG] message, only when [Build.IS_DEBUGGABLE]. */
-private inline fun Any.logDebug(message: () -> String) {
- if (Build.IS_DEBUGGABLE) Log.d(this::class.java.simpleName.orEmpty(), message())
-}
diff --git a/packages/SystemUI/src/com/android/systemui/stylus/StylusManager.kt b/packages/SystemUI/src/com/android/systemui/stylus/StylusManager.kt
index 412b3150489c..27aaa6828036 100644
--- a/packages/SystemUI/src/com/android/systemui/stylus/StylusManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/stylus/StylusManager.kt
@@ -22,7 +22,6 @@ import android.content.Context
import android.hardware.BatteryState
import android.hardware.input.InputManager
import android.hardware.input.InputSettings
-import android.os.Build
import android.os.Handler
import android.util.ArrayMap
import android.util.Log
@@ -35,6 +34,7 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
+import com.android.systemui.log.DebugLogger.debugLog
import com.android.systemui.shared.hardware.hasInputDevice
import com.android.systemui.shared.hardware.isInternalStylusSource
import java.util.concurrent.CopyOnWriteArrayList
@@ -81,7 +81,7 @@ constructor(
fun startListener() {
handler.post {
if (hasStarted) return@post
- logDebug { "Listener has started." }
+ debugLog { "Listener has started." }
hasStarted = true
isInUsiSession =
@@ -109,7 +109,7 @@ constructor(
val device: InputDevice = inputManager.getInputDevice(deviceId) ?: return
if (!device.supportsSource(InputDevice.SOURCE_STYLUS)) return
- logDebug {
+ debugLog {
"Stylus InputDevice added: $deviceId ${device.name}, " +
"External: ${device.isExternal}"
}
@@ -134,7 +134,7 @@ constructor(
val device: InputDevice = inputManager.getInputDevice(deviceId) ?: return
if (!device.supportsSource(InputDevice.SOURCE_STYLUS)) return
- logDebug { "Stylus InputDevice changed: $deviceId ${device.name}" }
+ debugLog { "Stylus InputDevice changed: $deviceId ${device.name}" }
val currAddress: String? = device.bluetoothAddress
val prevAddress: String? = inputDeviceAddressMap[deviceId]
@@ -155,7 +155,7 @@ constructor(
if (!hasStarted) return
if (!inputDeviceAddressMap.contains(deviceId)) return
- logDebug { "Stylus InputDevice removed: $deviceId" }
+ debugLog { "Stylus InputDevice removed: $deviceId" }
unregisterBatteryListener(deviceId)
@@ -180,7 +180,7 @@ constructor(
val isCharging = String(value) == "true"
- logDebug {
+ debugLog {
"Charging state metadata changed for device $inputDeviceId " +
"${device.address}: $isCharging"
}
@@ -199,7 +199,7 @@ constructor(
handler.post {
if (!hasStarted) return@post
- logDebug {
+ debugLog {
"Battery state changed for $deviceId. " +
"batteryState present: ${batteryState.isPresent}, " +
"capacity: ${batteryState.capacity}"
@@ -247,7 +247,7 @@ constructor(
if (!featureFlags.isEnabled(Flags.TRACK_STYLUS_EVER_USED)) return
if (InputSettings.isStylusEverUsed(context)) return
- logDebug { "Stylus used for the first time." }
+ debugLog { "Stylus used for the first time." }
InputSettings.setStylusEverUsed(context, true)
executeStylusCallbacks { cb -> cb.onStylusFirstUsed() }
}
@@ -264,7 +264,7 @@ constructor(
val hasBtConnection = if (inputDeviceBtSessionIdMap.isEmpty()) 0 else 1
if (batteryStateValid && usiSessionId == null) {
- logDebug { "USI battery newly present, entering new USI session: $deviceId" }
+ debugLog { "USI battery newly present, entering new USI session: $deviceId" }
usiSessionId = instanceIdSequence.newInstanceId()
uiEventLogger.logWithInstanceIdAndPosition(
StylusUiEvent.USI_STYLUS_BATTERY_PRESENCE_FIRST_DETECTED,
@@ -274,7 +274,7 @@ constructor(
hasBtConnection,
)
} else if (!batteryStateValid && usiSessionId != null) {
- logDebug { "USI battery newly absent, exiting USI session: $deviceId" }
+ debugLog { "USI battery newly absent, exiting USI session: $deviceId" }
uiEventLogger.logWithInstanceIdAndPosition(
StylusUiEvent.USI_STYLUS_BATTERY_PRESENCE_REMOVED,
0,
@@ -291,7 +291,7 @@ constructor(
btAddress: String,
btConnected: Boolean
) {
- logDebug {
+ debugLog {
"Bluetooth stylus ${if (btConnected) "connected" else "disconnected"}:" +
" $deviceId $btAddress"
}
@@ -386,9 +386,3 @@ constructor(
val TAG = StylusManager::class.simpleName.orEmpty()
}
}
-
-private inline fun logDebug(message: () -> String) {
- if (Build.IS_DEBUGGABLE) {
- Log.d(StylusManager.TAG, message())
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerUI.kt b/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerUI.kt
index 21b0efadb8d5..6eddd9eb7ad2 100644
--- a/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerUI.kt
+++ b/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerUI.kt
@@ -26,7 +26,6 @@ import android.content.Intent
import android.content.IntentFilter
import android.hardware.BatteryState
import android.hardware.input.InputManager
-import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.os.UserHandle
@@ -40,6 +39,7 @@ import com.android.internal.logging.UiEventLogger
import com.android.systemui.R
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.log.DebugLogger.debugLog
import com.android.systemui.shared.hardware.hasInputDevice
import com.android.systemui.shared.hardware.isAnyStylusSource
import com.android.systemui.util.NotificationChannels
@@ -110,7 +110,7 @@ constructor(
inputDeviceId = deviceId
batteryCapacity = batteryState.capacity
- logDebug {
+ debugLog {
"Updating notification battery state to $batteryCapacity " +
"for InputDevice $deviceId."
}
@@ -130,14 +130,14 @@ constructor(
handler.post updateSuppressed@{
if (suppressed == suppress) return@updateSuppressed
- logDebug { "Updating notification suppression to $suppress." }
+ debugLog { "Updating notification suppression to $suppress." }
suppressed = suppress
refresh()
}
}
private fun hideNotification() {
- logDebug { "Cancelling USI low battery notification." }
+ debugLog { "Cancelling USI low battery notification." }
instanceId = null
notificationManager.cancel(USI_NOTIFICATION_ID)
}
@@ -160,7 +160,7 @@ constructor(
.setAutoCancel(true)
.build()
- logDebug { "Show or update USI low battery notification at $batteryCapacity." }
+ debugLog { "Show or update USI low battery notification at $batteryCapacity." }
logUiEvent(StylusUiEvent.STYLUS_LOW_BATTERY_NOTIFICATION_SHOWN)
notificationManager.notify(USI_NOTIFICATION_ID, notification)
}
@@ -188,12 +188,12 @@ constructor(
override fun onReceive(context: Context, intent: Intent) {
when (intent.action) {
ACTION_DISMISSED_LOW_BATTERY -> {
- logDebug { "USI low battery notification dismissed." }
+ debugLog { "USI low battery notification dismissed." }
logUiEvent(StylusUiEvent.STYLUS_LOW_BATTERY_NOTIFICATION_DISMISSED)
updateSuppression(true)
}
ACTION_CLICKED_LOW_BATTERY -> {
- logDebug { "USI low battery notification clicked." }
+ debugLog { "USI low battery notification clicked." }
logUiEvent(StylusUiEvent.STYLUS_LOW_BATTERY_NOTIFICATION_CLICKED)
updateSuppression(true)
if (inputDeviceId == null) return
@@ -263,9 +263,3 @@ constructor(
@VisibleForTesting const val KEY_SETTINGS_FRAGMENT_ARGS = ":settings:show_fragment_args"
}
}
-
-private inline fun logDebug(message: () -> String) {
- if (Build.IS_DEBUGGABLE) {
- Log.d(StylusUsiPowerUI.TAG, message())
- }
-}