1 package com.android.managedprovisioning.contracts 2 3 import android.content.Context 4 import android.content.Intent 5 import com.android.managedprovisioning.ManagedProvisioningScreens.DOWNLOAD_ROLE_HOLDER 6 import com.android.managedprovisioning.ScreenManager 7 import com.android.managedprovisioning.annotations.LegacyApi 8 import com.android.managedprovisioning.contracts.Checksum.SignatureChecksum 9 import com.android.managedprovisioning.model.PackageDownloadInfo 10 import com.android.managedprovisioning.model.ProvisioningParams 11 import com.android.onboarding.common.MANAGED_PROVISIONING 12 import com.android.onboarding.contracts.NodeAwareIntentScope 13 import com.android.onboarding.contracts.NodeAwareIntentSerializer 14 import com.android.onboarding.contracts.NodeId 15 import com.android.onboarding.contracts.OnboardingNodeId 16 import com.android.onboarding.contracts.VoidOnboardingActivityApiContract 17 import com.android.onboarding.contracts.annotations.OnboardingNode 18 import com.android.onboarding.contracts.provisioning.EXTRAS 19 import com.android.onboarding.contracts.require 20 import com.android.onboarding.contracts.setupwizard.SuwArguments 21 import com.android.onboarding.contracts.setupwizard.SuwArgumentsSerializer 22 import com.android.onboarding.contracts.setupwizard.WithSuwArguments 23 import javax.inject.Inject 24 25 /** 26 * @property location Url where the package (.apk) can be downloaded from. {@code null} if there is no download location specified. 27 * @property cookieHeader Cookie header for http request. 28 * @property checksum SHA-256 hash of the signature in the .apk file 29 * @property minVersion Minimum supported version code of the downloaded package. 30 */ 31 interface DownloadRoleHolderArguments : WithProvisioningParams, WithSuwArguments { 32 val location: String 33 val checksum: SignatureChecksum 34 val cookieHeader: String? 35 val minVersion: Int 36 37 companion object { 38 @JvmStatic 39 @JvmName("of") invokenull40 operator fun invoke( 41 suwArguments: SuwArguments, 42 provisioningParams: ProvisioningParams, 43 location: String, 44 checksum: SignatureChecksum, 45 cookieHeader: String? = null, 46 minVersion: Int = Int.MAX_VALUE, 47 ): DownloadRoleHolderArguments = object : DownloadRoleHolderArguments { 48 override val suwArguments = suwArguments 49 override val provisioningParams = provisioningParams 50 override val location = location 51 override val checksum = checksum 52 override val cookieHeader = cookieHeader 53 override val minVersion = minVersion 54 } 55 56 @LegacyApi 57 @JvmStatic 58 @JvmName("of") invokenull59 operator fun invoke( 60 suwArguments: SuwArguments, 61 provisioningParams: ProvisioningParams, 62 ): DownloadRoleHolderArguments = invoke( 63 suwArguments = suwArguments, 64 provisioningParams = provisioningParams, 65 location = provisioningParams.roleHolderDownloadInfo?.location 66 ?.require("Download location must not be empty.", String::isNotBlank) 67 ?: error("Missing download location."), 68 checksum = provisioningParams.roleHolderDownloadInfo.signatureChecksum 69 .require("Checksum is missing", ByteArray::isNotEmpty) 70 .let(Checksum::SignatureChecksum), 71 cookieHeader = provisioningParams.roleHolderDownloadInfo.cookieHeader, 72 minVersion = provisioningParams.roleHolderDownloadInfo.minVersion 73 ) 74 } 75 } 76 77 @OnboardingNode( 78 component = MANAGED_PROVISIONING, 79 name = "DownloadRoleHolder", 80 uiType = OnboardingNode.UiType.LOADING) 81 class DownloadRoleHolderContract 82 @Inject 83 constructor( 84 @OnboardingNodeId override val nodeId: NodeId, 85 private val screenManager: ScreenManager, 86 val suwArgumentsSerializer: SuwArgumentsSerializer 87 ) : VoidOnboardingActivityApiContract<DownloadRoleHolderArguments>(), 88 NodeAwareIntentSerializer<DownloadRoleHolderArguments> { 89 90 override fun performCreateIntent(context: Context, arg: DownloadRoleHolderArguments): Intent = 91 Intent(context, screenManager.getActivityClassForScreen(DOWNLOAD_ROLE_HOLDER)) 92 .also { write(it, arg) } 93 94 override fun performExtractArgument(intent: Intent): DownloadRoleHolderArguments = read(intent) 95 override fun NodeAwareIntentScope.write(value: DownloadRoleHolderArguments) { 96 this[suwArgumentsSerializer] = value::suwArguments 97 this[EXTRAS.EXTRA_PROVISIONING_PARAMS] = 98 value::provisioningParams.map { 99 it.toBuilder() 100 .setRoleHolderDownloadInfo( 101 PackageDownloadInfo.Builder() 102 .setLocation(value.location) 103 .setCookieHeader(value.cookieHeader) 104 .setMinVersion(value.minVersion) 105 .setSignatureChecksum(value.checksum.bytes) 106 .build()) 107 .build() 108 } 109 } 110 111 override fun NodeAwareIntentScope.read(): DownloadRoleHolderArguments { 112 val provisioningParams = 113 parcelable<ProvisioningParams>(EXTRAS.EXTRA_PROVISIONING_PARAMS).required 114 val params = provisioningParams.map { 115 it.roleHolderDownloadInfo ?: error("Missing role holder extras") 116 } 117 return object : DownloadRoleHolderArguments { 118 override val suwArguments by read(suwArgumentsSerializer) 119 override val provisioningParams by provisioningParams 120 override val location by params.map(PackageDownloadInfo::location) 121 override val checksum by params.map(PackageDownloadInfo::signatureChecksum).map(::SignatureChecksum) 122 override val cookieHeader by params.map(PackageDownloadInfo::cookieHeader) 123 override val minVersion by params.map(PackageDownloadInfo::minVersion) 124 } 125 } 126 }