| package com.android.onboarding.contracts |
| |
| import android.app.Activity |
| import android.content.Context |
| import android.content.Intent |
| import com.android.onboarding.nodes.AndroidOnboardingGraphLog |
| import com.android.onboarding.nodes.OnboardingEvent |
| import java.util.UUID |
| import javax.inject.Qualifier |
| |
| typealias NodeId = Long |
| |
| /** |
| * A DI qualifier to inject node ID where applicable. Consuming module should scope this to a given |
| * activity's lifecycle. |
| */ |
| @Retention(AnnotationRetention.RUNTIME) @Qualifier annotation class OnboardingNodeId |
| |
| /** |
| * Marks entities that require awareness of onboarding node currently being executed |
| * |
| * @property nodeId the ID of the currently executing node |
| */ |
| interface NodeAware { |
| @OnboardingNodeId val nodeId: NodeId |
| } |
| |
| /** Extra key used when storing a node id */ |
| const val EXTRA_ONBOARDING_NODE_ID = "com.android.onboarding.ONBOARDING_NODE_ID" |
| |
| const val UNKNOWN_NODE_ID: NodeId = -1L |
| |
| val Intent.nodeId: NodeId |
| get() = |
| getLongExtra(EXTRA_ONBOARDING_NODE_ID, UNKNOWN_NODE_ID).let { |
| if (it == UNKNOWN_NODE_ID) { |
| val id = UUID.randomUUID().leastSignificantBits |
| this.putExtra(EXTRA_ONBOARDING_NODE_ID, id) |
| id |
| } else { |
| it |
| } |
| } |
| |
| val Activity.nodeId: NodeId |
| get() { |
| intent = intent ?: Intent() |
| return intent.nodeId |
| } |
| |
| /** |
| * Extract a [NodeId] from this [Context] making an assumption that this is an [Activity]. Returns |
| * unknown [UNKNOWN_NODE_ID] if this [Context] is not an [Activity]. |
| */ |
| fun Context.activityNodeId(): NodeId = |
| if (this is Activity) { |
| nodeId |
| } else { |
| UNKNOWN_NODE_ID |
| } |
| |
| /** Mark the executing node as failed with [reason]. */ |
| fun Activity.failNode(reason: String? = null) { |
| AndroidOnboardingGraphLog.log(OnboardingEvent.ActivityNodeFail(nodeId, reason)) |
| } |