summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAoJ Architecture Team <aoj-architecture-team@google.com>2023-11-23 11:39:24 -0800
committerCopybara-Service <copybara-worker@google.com>2023-11-23 11:42:18 -0800
commit24300ba7e496a810b756283332ef53640b67f919 (patch)
treec800a177ee8c3d028d957dc40f0a25e0c54ed800
parent21e9a95cb5eb49ad3da7f1c0152467737697447f (diff)
downloadandroid_onboarding-24300ba7e496a810b756283332ef53640b67f919.tar.gz
Copybara ❤️: Add capability to log all transitions to logcat. This can be used to get high level visibility into how much of the flow is covered by contracts.
CL: cl/584924583 PiperOrigin-RevId: 584924583 Change-Id: I66842b5caf0c12d7cb93b39522147bbb849b9f2d
-rw-r--r--src/com/android/onboarding/flags/DefaultOnboardingFlagsProvider.kt8
-rw-r--r--src/com/android/onboarding/flags/OnboardingFlagsProvider.kt3
-rw-r--r--src/com/android/onboarding/flags/testing/FakeOnboardingFlagsProvider.kt1
-rw-r--r--src/com/android/onboarding/nodes/Android.bp5
-rw-r--r--src/com/android/onboarding/nodes/AndroidOnboardingGraphLog.kt20
-rw-r--r--src/com/android/onboarding/nodes/DefaultOnboardingGraphLog.kt3
-rw-r--r--src/com/android/onboarding/nodes/LogcatObserver.kt19
-rw-r--r--src/com/android/onboarding/nodes/OnboardingGraphLog.kt66
-rw-r--r--src/com/android/onboarding/nodes/OnboardingGraphLogcatObserver.kt15
-rw-r--r--src/com/android/onboarding/nodes/OnboardingGraphNodeTransitionObserver.kt25
10 files changed, 110 insertions, 55 deletions
diff --git a/src/com/android/onboarding/flags/DefaultOnboardingFlagsProvider.kt b/src/com/android/onboarding/flags/DefaultOnboardingFlagsProvider.kt
index 6ca251c..5539233 100644
--- a/src/com/android/onboarding/flags/DefaultOnboardingFlagsProvider.kt
+++ b/src/com/android/onboarding/flags/DefaultOnboardingFlagsProvider.kt
@@ -18,6 +18,13 @@ class DefaultOnboardingFlagsProvider : OnboardingFlagsProvider {
override val isDebug: Boolean
get() = SystemProperties.getBoolean("$SYSTEM_PROPERTY_NAMESPACE.$FEATURE_DEBUG_ENABLED", false)
+ override val shouldVisualiseNodeTransitionsInLogcat: Boolean
+ get() =
+ SystemProperties.getBoolean(
+ "$SYSTEM_PROPERTY_NAMESPACE.$FEATURE_VISUALISE_TRANSITIONS",
+ false
+ ) || isDebug
+
companion object {
// The key length has to be less that 31 characters (<18 if excluding namespace)
const val SYSTEM_PROPERTY_NAMESPACE = "aoj.feature"
@@ -25,5 +32,6 @@ class DefaultOnboardingFlagsProvider : OnboardingFlagsProvider {
private const val FEATURE_NODE_LOGGING_ENABLED = "node_logging"
private const val FEATURE_DEBUG_ENABLED = "debug"
private const val FEATURE_UI_LOGGING_ENABLED = "ui_logging"
+ private const val FEATURE_VISUALISE_TRANSITIONS = "vis_transitions"
}
}
diff --git a/src/com/android/onboarding/flags/OnboardingFlagsProvider.kt b/src/com/android/onboarding/flags/OnboardingFlagsProvider.kt
index 7472fc6..ffe6486 100644
--- a/src/com/android/onboarding/flags/OnboardingFlagsProvider.kt
+++ b/src/com/android/onboarding/flags/OnboardingFlagsProvider.kt
@@ -28,4 +28,7 @@ interface OnboardingFlagsProvider {
* other flag values.
*/
val isDebug: Boolean
+
+ /** Returns true if node transitions should be visualised in logcat. */
+ val shouldVisualiseNodeTransitionsInLogcat: Boolean
}
diff --git a/src/com/android/onboarding/flags/testing/FakeOnboardingFlagsProvider.kt b/src/com/android/onboarding/flags/testing/FakeOnboardingFlagsProvider.kt
index 11bfd18..5bfbde4 100644
--- a/src/com/android/onboarding/flags/testing/FakeOnboardingFlagsProvider.kt
+++ b/src/com/android/onboarding/flags/testing/FakeOnboardingFlagsProvider.kt
@@ -8,6 +8,7 @@ class FakeOnboardingFlagsProvider(
override var isNodeLoggingEnabled: Boolean = false,
override var isUiLoggingEnabled: Boolean = false,
override var isDebug: Boolean = false,
+ override val shouldVisualiseNodeTransitionsInLogcat: Boolean = false,
) : OnboardingFlagsProvider {
@Deprecated(message = "Replaced with overrides", replaceWith = ReplaceWith("isContractEnabled"))
var isOnboardingContractEnabledFlag: Boolean by ::isContractEnabled
diff --git a/src/com/android/onboarding/nodes/Android.bp b/src/com/android/onboarding/nodes/Android.bp
index e63de84..f0b1099 100644
--- a/src/com/android/onboarding/nodes/Android.bp
+++ b/src/com/android/onboarding/nodes/Android.bp
@@ -13,7 +13,8 @@ android_library {
"androidx.activity_activity-ktx",
"guava",
"android_onboarding.nodes_proto_lite",
- "android_onboarding.contracts.annotations"
+ "android_onboarding.contracts.annotations",
+ "android_onboarding.flags",
]
}
@@ -28,7 +29,7 @@ java_library_host {
static_libs: [
"guava",
"android_onboarding.nodes_proto_full",
- "android_onboarding.contracts.annotations_host"
+ "android_onboarding.contracts.annotations_host",
]
}
diff --git a/src/com/android/onboarding/nodes/AndroidOnboardingGraphLog.kt b/src/com/android/onboarding/nodes/AndroidOnboardingGraphLog.kt
index eb01bf4..c6a1961 100644
--- a/src/com/android/onboarding/nodes/AndroidOnboardingGraphLog.kt
+++ b/src/com/android/onboarding/nodes/AndroidOnboardingGraphLog.kt
@@ -1,11 +1,27 @@
package com.android.onboarding.nodes
+import com.android.onboarding.flags.DefaultOnboardingFlagsProvider
+
/** A Singleton [OnboardingGraphLog] which automatically logs all events to logcat. */
object AndroidOnboardingGraphLog : OnboardingGraphLog {
- private val logcatObserver = OnboardingGraphLogcatObserver()
+ const val LOG_TAG = "ZZZOnboardingGraph"
+ private val onboardingFlags = DefaultOnboardingFlagsProvider()
+ private val logcatObserver = LogcatObserver(LOG_TAG) { it.serializeToString() }
private val defaultOnboardingGraphLog =
- DefaultOnboardingGraphLog().also { it.addObserver(logcatObserver) }
+ DefaultOnboardingGraphLog().also {
+ it.addObserver(logcatObserver)
+
+ if (onboardingFlags.shouldVisualiseNodeTransitionsInLogcat) {
+ it.addObserver(
+ OnboardingGraphNodeTransitionObserver(
+ LogcatObserver(logTag = "OnboardingGraph") { node ->
+ "${node.nodeName}(${node.nodeId})"
+ }
+ )
+ )
+ }
+ }
override fun addObserver(observer: OnboardingGraphLog.Observer) {
defaultOnboardingGraphLog.addObserver(observer)
diff --git a/src/com/android/onboarding/nodes/DefaultOnboardingGraphLog.kt b/src/com/android/onboarding/nodes/DefaultOnboardingGraphLog.kt
index 7c6b717..048798f 100644
--- a/src/com/android/onboarding/nodes/DefaultOnboardingGraphLog.kt
+++ b/src/com/android/onboarding/nodes/DefaultOnboardingGraphLog.kt
@@ -1,8 +1,5 @@
package com.android.onboarding.nodes
-import java.util.Collections
-import java.util.WeakHashMap
-
class DefaultOnboardingGraphLog : OnboardingGraphLog {
private val observers = mutableSetOf<OnboardingGraphLog.Observer>()
diff --git a/src/com/android/onboarding/nodes/LogcatObserver.kt b/src/com/android/onboarding/nodes/LogcatObserver.kt
new file mode 100644
index 0000000..cf80141
--- /dev/null
+++ b/src/com/android/onboarding/nodes/LogcatObserver.kt
@@ -0,0 +1,19 @@
+package com.android.onboarding.nodes
+
+import android.util.Log
+
+/** An [OnboardingGraphLog.Observer] which logs human readable events to logcat. */
+class LogcatObserver(
+ private val logTag: String = LOG_TAG,
+ private val toString: (e: OnboardingGraphLog.OnboardingEvent) -> String =
+ OnboardingGraphLog.OnboardingEvent::toString
+) : OnboardingGraphLog.Observer {
+
+ override fun onEvent(event: OnboardingGraphLog.OnboardingEvent) {
+ Log.i(logTag, toString(event))
+ }
+
+ companion object {
+ const val LOG_TAG = "RawLogcatGraph"
+ }
+}
diff --git a/src/com/android/onboarding/nodes/OnboardingGraphLog.kt b/src/com/android/onboarding/nodes/OnboardingGraphLog.kt
index c34966d..0c8ff52 100644
--- a/src/com/android/onboarding/nodes/OnboardingGraphLog.kt
+++ b/src/com/android/onboarding/nodes/OnboardingGraphLog.kt
@@ -40,7 +40,7 @@ interface OnboardingGraphLog {
// LINT.IfChange
/** Possible Events. */
- sealed class OnboardingEvent {
+ sealed class OnboardingEvent(open val nodeId: Long, open val nodeName: String?) {
/** Writes this event to a string which can be parsed by [OnboardingGraphLog#deserialize]. */
fun serializeToString(): String {
@@ -59,11 +59,11 @@ interface OnboardingGraphLog {
data class ActivityNodeExecutedDirectly
private constructor(
val sourceNodeId: Long,
- val nodeId: Long,
- val nodeName: String,
+ override val nodeId: Long,
+ override val nodeName: String,
val argument: Any? = null,
val timestamp: Instant = Instant.now()
- ) : OnboardingEvent() {
+ ) : OnboardingEvent(nodeId, nodeName) {
constructor(
sourceNodeId: Long,
@@ -106,11 +106,11 @@ interface OnboardingGraphLog {
data class ActivityNodeExecutedForResult
private constructor(
val sourceNodeId: Long,
- val nodeId: Long,
- val nodeName: String,
+ override val nodeId: Long,
+ override val nodeName: String,
val argument: Any? = null,
val timestamp: Instant = Instant.now()
- ) : OnboardingEvent() {
+ ) : OnboardingEvent(nodeId, nodeName) {
constructor(
sourceNodeId: Long,
@@ -151,11 +151,11 @@ interface OnboardingGraphLog {
*/
data class ActivityNodeValidating
private constructor(
- val nodeId: Long,
- val nodeName: String,
+ override val nodeId: Long,
+ override val nodeName: String,
val intent: IntentData? = null,
val timestamp: Instant = Instant.now()
- ) : OnboardingEvent() {
+ ) : OnboardingEvent(nodeId, nodeName) {
constructor(
nodeId: Long,
@@ -193,12 +193,12 @@ interface OnboardingGraphLog {
*/
data class ActivityNodeFailedValidation
private constructor(
- val nodeId: Long,
- val nodeName: String,
+ override val nodeId: Long,
+ override val nodeName: String,
val exception: Exception = IllegalArgumentException("Failed validation"),
val intent: IntentData? = null,
val timestamp: Instant = Instant.now()
- ) : OnboardingEvent() {
+ ) : OnboardingEvent(nodeId, nodeName) {
constructor(
nodeId: Long,
@@ -238,11 +238,11 @@ interface OnboardingGraphLog {
*/
data class ActivityNodeExtractArgument
private constructor(
- val nodeId: Long,
- val nodeName: String,
+ override val nodeId: Long,
+ override val nodeName: String,
val intent: IntentData,
val timestamp: Instant = Instant.now()
- ) : OnboardingEvent() {
+ ) : OnboardingEvent(nodeId, nodeName) {
constructor(
nodeId: Long,
@@ -287,11 +287,11 @@ interface OnboardingGraphLog {
*/
data class ActivityNodeArgumentExtracted
private constructor(
- val nodeId: Long,
- val nodeName: String,
+ override val nodeId: Long,
+ override val nodeName: String,
val argument: Any?,
val timestamp: Instant = Instant.now()
- ) : OnboardingEvent() {
+ ) : OnboardingEvent(nodeId, nodeName) {
constructor(
nodeId: Long,
@@ -330,11 +330,11 @@ interface OnboardingGraphLog {
*/
data class ActivityNodeSetResult
private constructor(
- val nodeId: Long,
- val nodeName: String,
+ override val nodeId: Long,
+ override val nodeName: String,
val result: Any?,
val timestamp: Instant = Instant.now()
- ) : OnboardingEvent() {
+ ) : OnboardingEvent(nodeId, nodeName) {
constructor(
nodeId: Long,
@@ -372,10 +372,10 @@ interface OnboardingGraphLog {
* because of [reason].
*/
data class ActivityNodeFail(
- val nodeId: Long,
+ override val nodeId: Long,
val reason: String?,
val timestamp: Instant = Instant.now()
- ) : OnboardingEvent() {
+ ) : OnboardingEvent(nodeId, nodeName = null) {
override fun serialize(): OnboardingProtos.LogProto {
return OnboardingProtos.LogProto.newBuilder()
@@ -408,11 +408,11 @@ interface OnboardingGraphLog {
*/
data class ActivityNodeResultReceived
private constructor(
- val nodeId: Long,
- val nodeName: String,
+ override val nodeId: Long,
+ override val nodeName: String,
val result: Any?,
val timestamp: Instant = Instant.now()
- ) : OnboardingEvent() {
+ ) : OnboardingEvent(nodeId, nodeName) {
constructor(
nodeId: Long,
@@ -452,11 +452,11 @@ interface OnboardingGraphLog {
data class ActivityNodeStartExecuteSynchronously
private constructor(
val sourceNodeId: Long,
- val nodeId: Long,
- val nodeName: String,
+ override val nodeId: Long,
+ override val nodeName: String,
val argument: Any?,
val timestamp: Instant = Instant.now()
- ) : OnboardingEvent() {
+ ) : OnboardingEvent(nodeId, nodeName) {
constructor(
sourceNodeId: Long,
@@ -495,11 +495,11 @@ interface OnboardingGraphLog {
/** At [timestamp], the synchronously executing node with id [nodeId] got result [result]. */
data class ActivityNodeExecutedSynchronously
private constructor(
- val nodeId: Long,
- val nodeName: String,
+ override val nodeId: Long,
+ override val nodeName: String,
val result: Any?,
val timestamp: Instant = Instant.now()
- ) : OnboardingEvent() {
+ ) : OnboardingEvent(nodeId, nodeName) {
constructor(
nodeId: Long,
diff --git a/src/com/android/onboarding/nodes/OnboardingGraphLogcatObserver.kt b/src/com/android/onboarding/nodes/OnboardingGraphLogcatObserver.kt
deleted file mode 100644
index 4bab5d8..0000000
--- a/src/com/android/onboarding/nodes/OnboardingGraphLogcatObserver.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.android.onboarding.nodes
-
-import android.util.Log
-
-/** An [OnboardingGraphLog.Observer] which serializes all logs into logcat. */
-class OnboardingGraphLogcatObserver : OnboardingGraphLog.Observer {
-
- override fun onEvent(event: OnboardingGraphLog.OnboardingEvent) {
- Log.i(LOG_TAG, event.serializeToString())
- }
-
- companion object {
- const val LOG_TAG = "ZZZOnboardingGraph"
- }
-}
diff --git a/src/com/android/onboarding/nodes/OnboardingGraphNodeTransitionObserver.kt b/src/com/android/onboarding/nodes/OnboardingGraphNodeTransitionObserver.kt
new file mode 100644
index 0000000..6e21d69
--- /dev/null
+++ b/src/com/android/onboarding/nodes/OnboardingGraphNodeTransitionObserver.kt
@@ -0,0 +1,25 @@
+package com.android.onboarding.nodes
+
+/**
+ * An [OnboardingGraphLog.Observer] which logs a single entry each time we "transition" from one
+ * node to another.
+ *
+ * This will only make sense when the flow is serial and there are no nodes executing in parallel.
+ * Once parallel nodes is common this should be removed.
+ *
+ * This is only for use exploring how much of the Onboarding flow is covered by nodes. It should not
+ * be depended upon for any other purpose.
+ */
+class OnboardingGraphNodeTransitionObserver(private val observer: OnboardingGraphLog.Observer) :
+ OnboardingGraphLog.Observer {
+
+ private var currentNodeId: Long? = null
+
+ override fun onEvent(event: OnboardingGraphLog.OnboardingEvent) {
+ if (event.nodeId != currentNodeId) {
+ currentNodeId = event.nodeId
+
+ observer.onEvent(event)
+ }
+ }
+}