• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.android.onboarding.tasks.crossApp
2 
3 import android.app.Service
4 import android.content.Intent
5 import android.os.IBinder
6 import android.os.Parcelable
7 import android.os.PersistableBundle
8 import com.android.onboarding.tasks.OnboardingTaskContract
9 import com.android.onboarding.tasks.OnboardingTaskManager
10 import com.android.onboarding.tasks.OnboardingTaskToken
11 
12 /**
13  * [AbstractOnboardingTaskManagerService] is a base class for services that manage onboarding tasks.
14  * Subclasses of [AbstractOnboardingTaskManagerService] must implement the [taskManager] property to
15  * provide an implementation of AbstractOnboardingTaskManager.
16  *
17  * This service allows clients to interact with the onboarding task manager by binding to it and
18  * invoking tasks.
19  */
20 abstract class AbstractOnboardingTaskManagerService : Service() {
21 
22   protected abstract val taskManager: OnboardingTaskManager
23 
onBindnull24   override fun onBind(intent: Intent): IBinder {
25     return object : IOnboardingTaskManagerService.Stub() {
26 
27       override fun runTask(bundle: PersistableBundle): OnboardingTaskToken {
28         val contractClass = getContractClass(bundle) ?: return OnboardingTaskToken.INVALID
29         val contractInstance =
30           OnboardingTaskContract.tryCreateContractInstance(contractClass)
31             ?: return OnboardingTaskToken.INVALID
32         val contractArgument = contractInstance.extractArgs(bundle)
33 
34         return taskManager.runTask(contractInstance, contractArgument)
35       }
36     }
37   }
38 
39   /**
40    * Parses the contract class name from the given [PersistableBundle]. This function extracts the
41    * contract class name from the provided bundle and attempts to find the corresponding contract
42    * class in the task manager's mapping. If found, it returns the class; otherwise, it returns
43    * null.
44    */
getContractClassnull45   private fun getContractClass(
46     bundle: PersistableBundle
47   ): Class<OnboardingTaskContract<Any?, Parcelable?>>? {
48     val contractClassName = bundle.getString(OnboardingTaskContract.EXTRA_CONTRACT_CLASS)
49     val matchingContractClass =
50       taskManager
51         .getContractAndTaskMap()
52         .filterKeys { it.name == contractClassName }
53         .keys
54         .firstOrNull()
55     if (matchingContractClass != null) {
56       @Suppress("UNCHECKED_CAST")
57       // Because we don't send the input/output types via IPC.
58       return matchingContractClass as Class<OnboardingTaskContract<Any?, Parcelable?>>
59     } else {
60       throw IllegalArgumentException("Contract class not found: $contractClassName")
61     }
62   }
63 
64   companion object {
65     private const val TAG: String = "OTMService"
66   }
67 }
68