1 package com.android.onboarding.tasks 2 3 import android.content.Context 4 import java.time.Duration 5 import kotlinx.coroutines.TimeoutCancellationException 6 import kotlinx.coroutines.withTimeout 7 8 /** 9 * An abstract base class for defining onboarding tasks in the onboarding process. 10 * 11 * @param context The application context to be used during task execution. 12 * @param TaskArgsT The type representing the input arguments for the onboarding task. 13 * @param TaskResultT The type representing the result of the onboarding task. 14 * @param TaskContractT The type representing the onboarindg contract which can work with this task. 15 */ 16 abstract class OnboardingTask< 17 TaskArgsT, 18 TaskResultT, 19 TaskContractT : OnboardingTaskContract<TaskArgsT, TaskResultT>, 20 >(val context: Context) { 21 22 // Default timeout value if not specified by the child class 23 protected open val defaultTimeout: Duration = Duration.ofSeconds(5) 24 25 /** 26 * Runs an onboarding task. 27 * 28 * @param taskContract The contract representing the onboarding task to be executed. 29 * @param taskArgs The input arguments for the task. 30 * @param timeout The timeout duration. If not specified, the default timeout defined by the 31 * implementing class will be used. 32 * @return An [OnboardingTaskState] representing the result of the task execution. If the task 33 * times out, a failed result will be returned. 34 */ runTasknull35 suspend fun runTask( 36 taskContract: TaskContractT, 37 taskArgs: TaskArgsT, 38 timeout: Duration = defaultTimeout, 39 ): OnboardingTaskState<TaskResultT> { 40 var result: TaskResultT? = null 41 return try { 42 if (!taskContract.validate(taskArgs)) { 43 return OnboardingTaskState.Failed( 44 "Task argument doesn't align with the contract(${taskContract::class.java.simpleName})" + 45 "definition. Failed returned immediately before execution.", 46 null, 47 ) 48 } 49 50 withTimeout(timeout.toMillis()) { 51 result = runTask(taskContract, taskArgs) 52 OnboardingTaskState.Completed(result) 53 } 54 } catch (timeout: TimeoutCancellationException) { 55 OnboardingTaskState.Failed("Task timed out: " + timeout.message, result) 56 } catch (e: Exception) { 57 OnboardingTaskState.Failed("Task failed : " + e.message, result) 58 } 59 } 60 61 /** 62 * Abstract method to be implemented by child classes. Executes the onboarding task 63 * asynchronously. 64 * 65 * @param taskContract The contract representing the onboarding task to be executed. 66 * @param taskArgs The input arguments for the task. 67 * @return The result of the onboarding task. 68 */ runTasknull69 protected abstract suspend fun runTask( 70 taskContract: TaskContractT, 71 taskArgs: TaskArgsT, 72 ): TaskResultT 73 } 74