xref: /aosp_15_r20/external/android_onboarding/java/com/android/onboarding/tasks/OnboardingTask.kt (revision c625018464ae97c56936c82b1b617e11aa899faa)
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