1 package com.android.onboarding.contracts 2 3 import android.app.Activity 4 import android.content.Intent 5 import androidx.activity.result.ActivityResult 6 7 /** A result returned by an onboarding node. */ 8 sealed interface NodeResult { 9 interface Success : NodeResult 10 11 interface Failure : NodeResult 12 } 13 14 /* A result returned by an [Activity] node. */ 15 interface ActivityNodeResult { toActivityResultnull16 fun toActivityResult(): ActivityResult 17 } 18 19 /** A result that is common to all activity nodes. */ 20 sealed interface CommonActivityNodeResult : ActivityNodeResult { 21 /** User navigated back. */ 22 data object Back : CommonActivityNodeResult, NodeResult.Success { 23 override fun toActivityResult() = 24 ActivityResult( 25 Activity.RESULT_CANCELED, 26 Intent().apply { putExtra(EXTRA_BACK_PRESSED, true) }, 27 ) 28 } 29 30 /** 31 * The process hosting the activity has crashed. 32 * 33 * Marked as Success until all nodes rollout go/aoj-arch-dd-back-press to avoid misleading people. 34 */ 35 data object Crash : CommonActivityNodeResult, NodeResult.Success { 36 override fun toActivityResult() = ActivityResult(Activity.RESULT_CANCELED, data = null) 37 } 38 39 companion object { 40 const val EXTRA_BACK_PRESSED = "com.android.onboarding.EXTRA_BACK_PRESSED" 41 } 42 } 43 44 internal object CommonActivityNodeResultFactory { createnull45 fun create(activityResult: ActivityResult): CommonActivityNodeResult = 46 if (activityResult.resultCode == Activity.RESULT_CANCELED && activityResult.data == null) 47 CommonActivityNodeResult.Crash 48 else if ( 49 activityResult.resultCode == Activity.RESULT_CANCELED && 50 activityResult.data?.getBooleanExtra(CommonActivityNodeResult.EXTRA_BACK_PRESSED, false) == 51 true 52 ) 53 CommonActivityNodeResult.Back 54 else 55 throw IllegalArgumentException( 56 "activity result: $activityResult is not a common activity node result" 57 ) 58 } 59