summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartynas Petuška <petuska@google.com>2023-10-24 09:05:49 -0700
committerCopybara-Service <copybara-worker@google.com>2023-10-24 09:07:18 -0700
commit4a20ef0dd672cbdec5e108b6f3044c9ae4013014 (patch)
tree36af6609218f06d77d21d983700ffa05cce2887f
parent7a0ee905ca1438313669b7e28fb3265f7ef1d674 (diff)
downloadandroid_onboarding-4a20ef0dd672cbdec5e108b6f3044c9ae4013014.tar.gz
Copybara ❤️: PreProvisioningActivity Contract
CL: cl/576158890 Bug: 298376528 NO_IFTTT=no API changes PiperOrigin-RevId: 576158890 Change-Id: Ie8795b9dc7e3004041dae91b4d95b0f356263054
-rw-r--r--Android.bp1
-rw-r--r--src/com/android/onboarding/contracts/IntentSerializer.kt68
-rw-r--r--src/com/android/onboarding/contracts/provisioning/ACTIONS.kt10
-rw-r--r--src/com/android/onboarding/contracts/provisioning/FLAGS.kt2
-rw-r--r--src/com/android/onboarding/contracts/provisioning/FinalizationInsideSuwContract.kt53
-rw-r--r--src/com/android/onboarding/contracts/provisioning/ManagedDeviceProvisioningArguments.kt545
-rw-r--r--src/com/android/onboarding/contracts/provisioning/PreProvisioningViaNfcContract.kt40
-rw-r--r--src/com/android/onboarding/contracts/provisioning/ProvisionOfflineOrViaRoleHolderApiContract.kt54
-rw-r--r--src/com/android/onboarding/contracts/provisioning/ProvisioningMode.kt26
-rw-r--r--src/com/android/onboarding/contracts/provisioning/ProvisioningTrigger.kt30
-rw-r--r--src/com/android/onboarding/contracts/provisioning/RESULTS.kt9
-rw-r--r--src/com/android/onboarding/contracts/provisioning/managed/profile/Android.bp18
-rw-r--r--src/com/android/onboarding/contracts/provisioning/managed/profile/ProvisionManagedProfileArguments.kt15
-rw-r--r--src/com/android/onboarding/contracts/provisioning/managed/profile/ProvisionManagedProfileArgumentsSerializer.kt36
-rw-r--r--src/com/android/onboarding/contracts/provisioning/managed/profile/ProvisionManagedProfileContract.kt32
-rw-r--r--src/com/android/onboarding/nodes/OnboardingGraphLog.kt13
16 files changed, 141 insertions, 811 deletions
diff --git a/Android.bp b/Android.bp
index 6014218..3e37fef 100644
--- a/Android.bp
+++ b/Android.bp
@@ -19,7 +19,6 @@ android_library {
"android_onboarding.contracts.annotations",
"android_onboarding.contracts.fragment",
"android_onboarding.contracts.provisioning",
- "android_onboarding.contracts.provisioning.managed.profile",
"android_onboarding.contracts.setupwizard",
"android_onboarding.flags",
"android_onboarding.nodes",
diff --git a/src/com/android/onboarding/contracts/IntentSerializer.kt b/src/com/android/onboarding/contracts/IntentSerializer.kt
index 23a17f0..1f7e314 100644
--- a/src/com/android/onboarding/contracts/IntentSerializer.kt
+++ b/src/com/android/onboarding/contracts/IntentSerializer.kt
@@ -7,8 +7,38 @@ import android.os.Bundle
import android.os.Parcelable
import androidx.annotation.RequiresApi
+/** Marks functions that read or write intent data */
+@DslMarker internal annotation class IntentManipulationDsl
+
/** Interface for writing an object to an [Intent] and reading the same object from an [Intent]. */
interface IntentSerializer<V> {
+ /**
+ * Utility intent builder that allows writing the [arg] and customising the intent settings
+ *
+ * @param arg to serialize into intent extras
+ * @param builder to configure the intent
+ */
+ @IntentManipulationDsl
+ fun Intent(arg: V, builder: Intent.() -> Unit = {}): Intent =
+ Intent().also {
+ write(it, arg)
+ it.builder()
+ }
+
+ /**
+ * Utility intent builder that allows writing the [arg] and customising the intent settings
+ *
+ * @param action the intent should send
+ * @param arg to serialize into intent extras
+ * @param builder to configure the intent
+ */
+ @IntentManipulationDsl
+ fun Intent(action: String, arg: V, builder: Intent.() -> Unit = {}): Intent =
+ Intent(arg) {
+ this.action = action
+ builder()
+ }
+
fun write(intent: Intent, value: V)
fun read(intent: Intent): V
@@ -29,12 +59,14 @@ interface ScopedIntentSerializer<V> : IntentSerializer<V> {
fun IntentScope.write(value: V)
/** Writes a [value] to the [IntentScope] via a given [serializer] */
+ @IntentManipulationDsl
fun <T> IntentScope.write(serializer: ScopedIntentSerializer<T>, value: T): Unit =
with(serializer) { write(value) }
fun IntentScope.read(): V
/** Reads a value [T] from the [IntentScope] via a given [serializer] */
+ @IntentManipulationDsl
fun <T> IntentScope.read(serializer: ScopedIntentSerializer<T>): T = with(serializer) { read() }
}
@@ -45,7 +77,7 @@ interface ScopedIntentSerializer<V> : IntentSerializer<V> {
* @param afterRead function to call after each read
* @param beforeWrite function to call before each write
*/
-@IntentScope.IntentManipulationDsl
+@IntentManipulationDsl
data class IntentScope(
@PublishedApi internal val androidIntent: Intent,
@PublishedApi internal val afterRead: (key: String, value: Any?) -> Unit = { _, _ -> },
@@ -53,11 +85,9 @@ data class IntentScope(
) {
companion object {
const val KEY_DATA = "com.android.onboarding.INTENT_DATA"
+ const val KEY_ACTION = "com.android.onboarding.INTENT_ACTION"
}
- /** Marks functions that read or write intent data */
- @DslMarker internal annotation class IntentManipulationDsl
-
/**
* Self-reference for more fluid write access
*
@@ -69,6 +99,24 @@ data class IntentScope(
*/
@IntentManipulationDsl val intent: IntentScope = this
+ /** Provides observable access to [Intent.getAction] */
+ @IntentManipulationDsl
+ var action: String?
+ get() = androidIntent.action.also { afterRead(KEY_ACTION, it) }
+ set(value) {
+ beforeWrite(KEY_ACTION, value)
+ value?.let(androidIntent::setAction)
+ }
+
+ /** Provides observable access to [Intent.getType] */
+ @IntentManipulationDsl
+ var type: String?
+ get() = androidIntent.type.also { afterRead(KEY_ACTION, it) }
+ set(value) {
+ beforeWrite(KEY_ACTION, value)
+ value?.let(androidIntent::setType)
+ }
+
/** Provides observable access to [Intent.getData] */
@IntentManipulationDsl
var data: Uri?
@@ -78,17 +126,13 @@ data class IntentScope(
value?.let(androidIntent::setData)
}
- /**
- * Copy over all [extras] to this [IntentScope]
- */
+ /** Copy over all [extras] to this [IntentScope] */
@IntentManipulationDsl
operator fun plusAssign(extras: Bundle) {
androidIntent.putExtras(extras)
}
- /**
- * Copy over all extras from [other] to this [IntentScope]
- */
+ /** Copy over all extras from [other] to this [IntentScope] */
@IntentManipulationDsl
operator fun plusAssign(other: IntentScope) {
androidIntent.putExtras(other.androidIntent)
@@ -222,6 +266,10 @@ data class IntentScope(
}
@IntentManipulationDsl
+ operator fun set(key: String, value: List<Parcelable>?): IntentScope =
+ set(key, value?.toTypedArray())
+
+ @IntentManipulationDsl
operator fun set(key: String, value: Bundle?): IntentScope = apply {
beforeWrite(key, value)
value?.let { androidIntent.putExtra(key, value) }
diff --git a/src/com/android/onboarding/contracts/provisioning/ACTIONS.kt b/src/com/android/onboarding/contracts/provisioning/ACTIONS.kt
index 8bac608..3f66477 100644
--- a/src/com/android/onboarding/contracts/provisioning/ACTIONS.kt
+++ b/src/com/android/onboarding/contracts/provisioning/ACTIONS.kt
@@ -1,6 +1,7 @@
package com.android.onboarding.contracts.provisioning
import android.app.admin.DevicePolicyManager
+import android.nfc.NfcAdapter
import android.os.Build
import androidx.annotation.RequiresApi
@@ -21,9 +22,11 @@ object ACTIONS {
inline val ACTION_DEVICE_OWNER_CHANGED: String
get() = DevicePolicyManager.ACTION_DEVICE_OWNER_CHANGED
+ @get:RequiresApi(Build.VERSION_CODES.Q)
inline val ACTION_GET_PROVISIONING_MODE: String
get() = DevicePolicyManager.ACTION_GET_PROVISIONING_MODE
+ @get:RequiresApi(Build.VERSION_CODES.Q)
inline val ACTION_ADMIN_POLICY_COMPLIANCE: String
get() = DevicePolicyManager.ACTION_ADMIN_POLICY_COMPLIANCE
@@ -52,6 +55,10 @@ object ACTIONS {
get() = DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE
@get:Suppress("UNRESOLVED_REFERENCE")
+ inline val ACTION_ROLE_HOLDER_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE: String
+ get() = DevicePolicyManager.ACTION_ROLE_HOLDER_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE
+
+ @get:Suppress("UNRESOLVED_REFERENCE")
inline val ACTION_PROVISION_FINANCED_DEVICE: String
get() = DevicePolicyManager.ACTION_PROVISION_FINANCED_DEVICE
@@ -91,4 +98,7 @@ object ACTIONS {
*/
inline val ACTION_PROVISION_MANAGED_DEVICE_SILENTLY: String
get() = "com.android.managedprovisioning.action.PROVISION_MANAGED_DEVICE_SILENTLY"
+
+ inline val ACTION_NDEF_DISCOVERED: String
+ get() = NfcAdapter.ACTION_NDEF_DISCOVERED
}
diff --git a/src/com/android/onboarding/contracts/provisioning/FLAGS.kt b/src/com/android/onboarding/contracts/provisioning/FLAGS.kt
index 091f0e6..98ea669 100644
--- a/src/com/android/onboarding/contracts/provisioning/FLAGS.kt
+++ b/src/com/android/onboarding/contracts/provisioning/FLAGS.kt
@@ -4,9 +4,11 @@ import android.app.admin.DevicePolicyManager
/** Container for various intent flags used by provisioning */
object FLAGS {
+ @get:Suppress("UNRESOLVED_REFERENCE")
inline val FLAG_SUPPORTED_MODES_ORGANIZATION_OWNED: Int
get() = DevicePolicyManager.FLAG_SUPPORTED_MODES_ORGANIZATION_OWNED
+ @get:Suppress("UNRESOLVED_REFERENCE")
inline val FLAG_SUPPORTED_MODES_DEVICE_OWNER: Int
get() = DevicePolicyManager.FLAG_SUPPORTED_MODES_DEVICE_OWNER
}
diff --git a/src/com/android/onboarding/contracts/provisioning/FinalizationInsideSuwContract.kt b/src/com/android/onboarding/contracts/provisioning/FinalizationInsideSuwContract.kt
deleted file mode 100644
index 64d90e0..0000000
--- a/src/com/android/onboarding/contracts/provisioning/FinalizationInsideSuwContract.kt
+++ /dev/null
@@ -1,53 +0,0 @@
-package com.android.onboarding.contracts.provisioning
-
-import android.content.Context
-import android.content.Intent
-import com.android.onboarding.common.MANAGED_PROVISIONING
-import com.android.onboarding.contracts.ContractResult
-import com.android.onboarding.contracts.IntentScope
-import com.android.onboarding.contracts.OnboardingActivityApiContract
-import com.android.onboarding.contracts.ScopedIntentSerializer
-import com.android.onboarding.contracts.annotations.OnboardingNode
-import com.android.onboarding.contracts.setupwizard.SuwArguments
-import com.android.onboarding.contracts.setupwizard.SuwArgumentsSerializer
-import com.android.onboarding.contracts.setupwizard.WithOptionalSuwArguments
-import javax.inject.Inject
-
-data class FinalizationInsideSuwArguments(
- override val suwArguments: SuwArguments?,
-) : WithOptionalSuwArguments
-
-/**
- * Result is propagated from the child activities the activity described by this contract launches.
- *
- * The activity uses [ProvisioningParams], however they are fetched from the FS rather than intent
- * extras.
- */
-@OnboardingNode(
- component = MANAGED_PROVISIONING,
- name = "FinalizationInsideSuw",
- hasUi = OnboardingNode.HasUi.YES
-)
-class FinalizationInsideSuwContract
-@Inject
-constructor(val suwArgumentsSerializer: SuwArgumentsSerializer) :
- OnboardingActivityApiContract<FinalizationInsideSuwArguments, ContractResult>(),
- ScopedIntentSerializer<FinalizationInsideSuwArguments> {
- override fun performCreateIntent(context: Context, arg: FinalizationInsideSuwArguments): Intent =
- Intent(ACTIONS.ACTION_ROLE_HOLDER_PROVISION_FINALIZATION).also { write(it, arg) }
-
- override fun IntentScope.write(value: FinalizationInsideSuwArguments) {
- value.suwArguments?.let { write(suwArgumentsSerializer, it) }
- }
-
- override fun IntentScope.read(): FinalizationInsideSuwArguments =
- FinalizationInsideSuwArguments(
- suwArguments = read(suwArgumentsSerializer),
- )
-
- override fun performExtractArgument(intent: Intent): FinalizationInsideSuwArguments = read(intent)
-
- override fun performParseResult(result: ContractResult): ContractResult = result
-
- override fun performSetResult(result: ContractResult): ContractResult = result
-}
diff --git a/src/com/android/onboarding/contracts/provisioning/ManagedDeviceProvisioningArguments.kt b/src/com/android/onboarding/contracts/provisioning/ManagedDeviceProvisioningArguments.kt
deleted file mode 100644
index d8aede0..0000000
--- a/src/com/android/onboarding/contracts/provisioning/ManagedDeviceProvisioningArguments.kt
+++ /dev/null
@@ -1,545 +0,0 @@
-package com.android.onboarding.contracts.provisioning
-
-import android.app.admin.DevicePolicyManager
-import android.content.ComponentName
-import android.content.Intent
-import android.os.PersistableBundle
-import android.webkit.URLUtil
-import com.android.onboarding.contracts.IntentSerializer
-import com.android.onboarding.contracts.provisioning.DeviceAdminChecksum.PackageChecksum
-import com.android.onboarding.contracts.provisioning.DeviceAdminChecksum.SignatureChecksum
-import com.android.onboarding.contracts.provisioning.WifiSecurityType.EAP
-import com.android.onboarding.contracts.provisioning.WifiSecurityType.NONE
-import com.android.onboarding.contracts.provisioning.WifiSecurityType.WEP
-import com.android.onboarding.contracts.provisioning.WifiSecurityType.WPA
-import java.lang.IllegalArgumentException
-import java.time.Instant
-import java.util.Locale
-import java.util.TimeZone
-
-/** The Checksum used to validate a Device Admin app. */
-sealed class DeviceAdminChecksum {
-
- abstract val checksum: String
-
- /** A base64 encoded SHA-256 hash of the Device Admin APK. */
- data class PackageChecksum(override val checksum: String) : DeviceAdminChecksum()
-
- /** A base64 encoded SHA-256 checksum of any signature applied to the Device Admin APK. */
- data class SignatureChecksum(override val checksum: String) : DeviceAdminChecksum()
-}
-
-/** Arguments related to the device admin app to be provisioned. */
-data class DeviceAdmin(
- /**
- * The component name of the [android.app.admin.DeviceAdminReceiver] subclass which will be set as
- * active.
- */
- val componentName: ComponentName,
-
- /**
- * Details related to the download of the Device Admin APK.
- *
- * <p>If this is not provided, then it will be assumed that the APK is already installed on the
- * device
- */
- val download: DeviceAdminDownload? = null,
-)
-
-/**
- * Information used to control the download of a Device Admin APK.
- *
- * @param location The URL to download the APK from
- * @param cookieHeader An optional cookie header which will be used in the download request
- * @param checksum The checksum used to validate the device admin APK
- */
-data class DeviceAdminDownload(
- val location: String,
- val cookieHeader: String? = null,
- val checksum: DeviceAdminChecksum
-)
-
-/** The security of a Wifi Network. */
-sealed class WifiSecurityType {
- /** An unsecured network. */
- object NONE : WifiSecurityType()
-
- /**
- * A WPA-secured network
- *
- * @param password Plaintext representation of the password
- */
- data class WPA(val password: String) : WifiSecurityType()
-
- /**
- * A WEP-secured network
- *
- * @param password Plaintext representation of the password
- */
- data class WEP(val password: String) : WifiSecurityType()
-
- /**
- * A EAP-secured network
- *
- * @param password Plaintext representation of the password
- */
- data class EAP(val password: String) : WifiSecurityType()
-}
-
-/**
- * Arguments for proxy settings when specifying wifi
- *
- * @param host The hostname of the proxy
- * @param port The port of the proxy
- * @param bypassHosts A list of hostnames for whom the proxy will be bypassed
- * @param autoConfigUrl TODO: What does this do?
- */
-data class ProxyArguments(
- val host: String,
- val port: Int,
- val bypassHosts: List<String> = listOf(),
- val autoConfigUrl: String?
-)
-
-/** Arguments for specifying wifi connectivity */
-data class WifiArguments(
- /** SSID of Wifi Network to be used during provisioning. */
- val ssid: String,
-
- /** {@code true} if the SSID represents a hidden network. */
- val hidden: Boolean = false,
-
- /** The security type of the network. */
- val security: WifiSecurityType,
-
- /** The proxy to use with this connection, if any. */
- val proxy: ProxyArguments? = null
-)
-
-enum class ProvisioningTrigger(val intVal: Int) {
- UNSPECIFIED(0),
- CLOUD_ENROLLMENT(1),
- QR_CODE(2),
- PERSISTENT_DEVICE_OWNER(3),
- MANAGED_ACCOUNT(4),
- NFC(5)
-}
-
-enum class ProvisioningMode(val intVal: Int) {
- FULLY_MANAGED_DEVICE(1),
- MANAGED_PROFILE(2);
-
- companion object {
- fun fromIntVal(intVal: Int): ProvisioningMode =
- when (intVal) {
- FULLY_MANAGED_DEVICE.intVal -> FULLY_MANAGED_DEVICE
- MANAGED_PROFILE.intVal -> MANAGED_PROFILE
- else -> throw IllegalArgumentException("Unknown provisioning mode: $intVal")
- }
- }
-}
-
-/** Arguments for provisioning a managed device. */
-data class ManagedDeviceProvisioningArguments(
-
- /** The Device Admin to be provisioned. */
- val deviceAdmin: DeviceAdmin,
-
- /**
- * If not set to {@code true}, will require that a connection is made before proceeding with
- * enterprise provisioning.
- */
- val allowOfflineProvisioning: Boolean = false,
- /** Indicates if mobile data should be used when wifi is unavailable. */
- val useMobileData: Boolean = false,
-
- /** Configures wifi connectivity. */
- val wifi: WifiArguments? = null,
- /**
- * The time which will be set as the device's local time upon provisioning complete.
- *
- * <p>If the provisioning request results in any mode other than Device Owner, this argument will
- * be ignored.
- */
- val localTime: Instant? = null,
-
- /**
- * The time zone which will be set as the device's time zone upon provisioning complete.
- *
- * <p>If the provisioning request results in any mode other than Device Owner, this argument will
- * be ignored.
- */
- val timeZone: TimeZone? = null,
-
- /**
- * The locale which will be set as the device's locale upon provisioning complete.
- *
- * <p>If the provisioning request results in any mode other than Device Owner, this argument will
- * be ignored.
- */
- val locale: Locale? = null,
-
- /** The name of the organization under management. */
- val organizationName: String? = null,
-
- /**
- * The modes which are allowed to be provisioned into.
- *
- * <p>Defaults to all modes
- */
- val allowedProvisioningModes: List<ProvisioningMode> = ProvisioningMode.values().asList(),
-
- /**
- * Indicates if system apps should be left enabled after provisioning.
- *
- * <p>By default (if left to false), system apps will be disabled.
- */
- val leaveAllSystemAppsEnabled: Boolean = false,
-
- /** Indicates if device encryption should be skipped. */
- val skipEncryption: Boolean = false,
-
- /** The action which triggered enterprise provisioning. */
- val provisioningTrigger: ProvisioningTrigger = ProvisioningTrigger.UNSPECIFIED,
-
- /**
- * A URL to give more information to the user during provisioning.
- *
- * <p>This URL must use HTTPS.
- */
- val supportUrl: String? = null,
-
- /** Arbitrary extras which will be passed to the Device Admin app upon provisioning. */
- val adminExtras: PersistableBundle? = null,
-
- /** Indicates if the provisioning education screens should be skipped. */
- val skipEducationScreens: Boolean = false
-) {
- init {
- if (supportUrl != null && !URLUtil.isHttpsUrl(supportUrl)) {
- throw IllegalArgumentException(
- "If supplied, supportUrl must be a HTTPS URL. Was: $supportUrl"
- )
- }
- if (allowedProvisioningModes.isEmpty()) {
- throw IllegalArgumentException("There must be at least one allowed provisioning mode")
- }
- }
-}
-
-/** Argument Parser for [ManagedDeviceProvisioningArguments]. */
-class ManagedDeviceProvisioningArgumentsSerializer :
- IntentSerializer<ManagedDeviceProvisioningArguments> {
- override fun write(intent: Intent, value: ManagedDeviceProvisioningArguments) {
- encodeDeviceAdmin(intent, value.deviceAdmin)
- intent.putExtra(EXTRAS.EXTRA_PROVISIONING_ALLOW_OFFLINE, value.allowOfflineProvisioning)
- intent.putExtra(EXTRAS.EXTRA_PROVISIONING_USE_MOBILE_DATA, value.useMobileData)
- if (value.wifi != null) {
- encodeWifi(intent, value.wifi)
- }
- intent.putExtra(
- DevicePolicyManager.EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED,
- value.leaveAllSystemAppsEnabled
- )
- intent.putExtra(DevicePolicyManager.EXTRA_PROVISIONING_SKIP_ENCRYPTION, value.skipEncryption)
- intent.putExtra(EXTRAS.EXTRA_PROVISIONING_TRIGGER, value.provisioningTrigger.intVal)
- if (value.localTime != null) {
- intent.putExtra(EXTRAS.EXTRA_PROVISIONING_LOCAL_TIME, value.localTime.toEpochMilli())
- }
- if (value.timeZone != null) {
- intent.putExtra(EXTRAS.EXTRA_PROVISIONING_TIME_ZONE, value.timeZone.toZoneId().id)
- }
- if (value.locale != null) {
- intent.putExtra(DevicePolicyManager.EXTRA_PROVISIONING_LOCALE, value.locale.toLanguageTag())
- }
- if (value.organizationName != null) {
- intent.putExtra(EXTRAS.EXTRA_PROVISIONING_ORGANIZATION_NAME, value.organizationName)
- }
- if (value.supportUrl != null) {
- intent.putExtra(EXTRAS.EXTRA_PROVISIONING_SUPPORT_URL, value.supportUrl)
- }
- if (value.adminExtras != null) {
- intent.putExtra(EXTRAS.EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE, value.adminExtras)
- }
- intent.putIntegerArrayListExtra(
- EXTRAS.EXTRA_PROVISIONING_ALLOWED_PROVISIONING_MODES,
- ArrayList(value.allowedProvisioningModes.map { it.intVal }.toList())
- )
- intent.putExtra(EXTRAS.EXTRA_PROVISIONING_SKIP_EDUCATION_SCREENS, value.skipEducationScreens)
- }
-
- private fun encodeWifi(intent: Intent, wifi: WifiArguments) {
- intent.putExtra(DevicePolicyManager.EXTRA_PROVISIONING_WIFI_SSID, wifi.ssid)
- intent.putExtra(DevicePolicyManager.EXTRA_PROVISIONING_WIFI_HIDDEN, wifi.hidden)
- encodeWifiSecurity(intent, wifi.security)
- if (wifi.proxy != null) {
- encodeWifiProxy(intent, wifi.proxy)
- }
- }
-
- private fun encodeWifiProxy(intent: Intent, proxy: ProxyArguments) {
- intent.putExtra(DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PROXY_HOST, proxy.host)
- intent.putExtra(DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PROXY_PORT, proxy.port)
- if (proxy.bypassHosts.isNotEmpty()) {
- intent.putExtra(
- DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PROXY_BYPASS,
- proxy.bypassHosts.joinToString(",")
- )
- }
- if (proxy.autoConfigUrl != null) {
- intent.putExtra(DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PAC_URL, proxy.autoConfigUrl)
- }
- }
-
- private fun encodeWifiSecurity(intent: Intent, security: WifiSecurityType) {
- when (security) {
- is WPA -> {
- intent.putExtra(DevicePolicyManager.EXTRA_PROVISIONING_WIFI_SECURITY_TYPE, "WPA")
- intent.putExtra(DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PASSWORD, security.password)
- }
- is WEP -> {
- intent.putExtra(DevicePolicyManager.EXTRA_PROVISIONING_WIFI_SECURITY_TYPE, "WEP")
- intent.putExtra(DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PASSWORD, security.password)
- }
- is EAP -> {
- intent.putExtra(DevicePolicyManager.EXTRA_PROVISIONING_WIFI_SECURITY_TYPE, "EAP")
- intent.putExtra(DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PASSWORD, security.password)
- }
- is NONE -> intent.putExtra(DevicePolicyManager.EXTRA_PROVISIONING_WIFI_SECURITY_TYPE, "NONE")
- }
- }
-
- private fun encodeDeviceAdmin(intent: Intent, deviceAdmin: DeviceAdmin) {
- intent.putExtra(
- DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME,
- deviceAdmin.componentName
- )
-
- if (deviceAdmin.download != null) {
- encodeDeviceAdminDownload(intent, deviceAdmin.download)
- }
- }
-
- private fun encodeDeviceAdminDownload(intent: Intent, download: DeviceAdminDownload) {
- intent.putExtra(
- DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION,
- download.location
- )
- if (download.cookieHeader != null) {
- intent.putExtra(
- DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER,
- download.cookieHeader
- )
- }
- when (download.checksum) {
- is PackageChecksum ->
- intent.putExtra(
- DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM,
- download.checksum.checksum
- )
- is SignatureChecksum ->
- intent.putExtra(
- DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM,
- download.checksum.checksum
- )
- }
- }
-
- override fun read(intent: Intent) =
- ManagedDeviceProvisioningArguments(
- deviceAdmin = extractDeviceAdmin(intent),
- allowOfflineProvisioning =
- intent.getBooleanExtra(EXTRAS.EXTRA_PROVISIONING_ALLOW_OFFLINE, false),
- useMobileData = intent.getBooleanExtra(EXTRAS.EXTRA_PROVISIONING_USE_MOBILE_DATA, false),
- wifi = extractWifi(intent),
- leaveAllSystemAppsEnabled =
- intent.getBooleanExtra(
- DevicePolicyManager.EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED,
- false
- ),
- skipEncryption =
- intent.getBooleanExtra(DevicePolicyManager.EXTRA_PROVISIONING_SKIP_ENCRYPTION, false),
- provisioningTrigger = extractProvisioningTrigger(intent),
- localTime = extractLocalTime(intent),
- timeZone = extractTimeZone(intent),
- locale = extractLocale(intent),
- organizationName = intent.getStringExtra(EXTRAS.EXTRA_PROVISIONING_ORGANIZATION_NAME),
- supportUrl = intent.getStringExtra(EXTRAS.EXTRA_PROVISIONING_SUPPORT_URL),
- allowedProvisioningModes =
- (intent
- .getIntegerArrayListExtra(EXTRAS.EXTRA_PROVISIONING_ALLOWED_PROVISIONING_MODES)
- ?.map { ProvisioningMode.fromIntVal(it) })
- ?: ProvisioningMode.values().asList(),
- adminExtras =
- intent.getParcelableExtra(DevicePolicyManager.EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE)
- as PersistableBundle?,
- skipEducationScreens =
- intent.getBooleanExtra(EXTRAS.EXTRA_PROVISIONING_SKIP_EDUCATION_SCREENS, false),
- )
-
- private fun extractProvisioningTrigger(intent: Intent): ProvisioningTrigger {
- return when (val c = intent.getIntExtra(EXTRAS.EXTRA_PROVISIONING_TRIGGER, 0)) {
- 0 -> ProvisioningTrigger.UNSPECIFIED
- 1 -> ProvisioningTrigger.CLOUD_ENROLLMENT
- 2 -> ProvisioningTrigger.QR_CODE
- 3 -> ProvisioningTrigger.PERSISTENT_DEVICE_OWNER
- 4 -> ProvisioningTrigger.MANAGED_ACCOUNT
- 5 -> ProvisioningTrigger.NFC
- else -> throw IllegalArgumentException("Unknown value for EXTRA_PROVISIONING_TRIGGER: $c")
- }
- }
-
- private fun extractLocale(intent: Intent): Locale? =
- if (intent.hasExtra(DevicePolicyManager.EXTRA_PROVISIONING_LOCALE)) {
- Locale.Builder()
- // I don't know why this replacement is needed - it came from the existing
- // ManagedProvisioning code
- .setLanguageTag(
- intent.getStringExtra(DevicePolicyManager.EXTRA_PROVISIONING_LOCALE)!!.replace("_", "-")
- )
- .build()
- } else {
- null
- }
-
- private fun extractTimeZone(intent: Intent): TimeZone? =
- if (intent.hasExtra(DevicePolicyManager.EXTRA_PROVISIONING_TIME_ZONE)) {
- TimeZone.getTimeZone(intent.getStringExtra(DevicePolicyManager.EXTRA_PROVISIONING_TIME_ZONE))
- } else {
- null
- }
-
- private fun extractLocalTime(intent: Intent): Instant? =
- if (intent.hasExtra(DevicePolicyManager.EXTRA_PROVISIONING_LOCAL_TIME)) {
- Instant.ofEpochMilli(
- intent.getLongExtra(DevicePolicyManager.EXTRA_PROVISIONING_LOCAL_TIME, 0)
- ) // Will never be 0 due to previous check
- } else {
- null
- }
-
- private fun extractWifi(intent: Intent): WifiArguments? =
- if (intent.hasExtra(DevicePolicyManager.EXTRA_PROVISIONING_WIFI_SSID)) {
- WifiArguments(
- ssid =
- intent.getStringExtra(
- DevicePolicyManager.EXTRA_PROVISIONING_WIFI_SSID
- )!!, // Must exist due to previous check
- hidden = intent.getBooleanExtra(DevicePolicyManager.EXTRA_PROVISIONING_WIFI_HIDDEN, false),
- security = extractWifiSecurity(intent),
- proxy = extractWifiProxy(intent)
- )
- } else {
- null
- }
-
- private fun extractWifiProxy(intent: Intent): ProxyArguments? =
- if (intent.hasExtra(DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PROXY_HOST)) {
- if (!intent.hasExtra(DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PROXY_PORT)) {
- throw IllegalArgumentException(
- "Cannot specify EXTRA_PROVISIONING_WIFI_PROXY_HOST without EXTRA_PROVISIONING_WIFI_PROXY_PORT"
- )
- }
-
- ProxyArguments(
- host =
- intent.getStringExtra(
- DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PROXY_HOST
- )!!, // Must exist due to previous check
- port =
- intent.getIntExtra(
- DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PROXY_PORT,
- 0
- ), // Will never be 0 due to previous check
- bypassHosts = extractProxyBypassHosts(intent),
- autoConfigUrl = intent.getStringExtra(DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PAC_URL)
- )
- } else {
- null
- }
-
- private fun extractProxyBypassHosts(intent: Intent): List<String> =
- (intent.getStringExtra(DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PROXY_BYPASS) ?: "").split(
- ","
- )
-
- private fun extractWifiSecurity(intent: Intent): WifiSecurityType =
- when (
- val type = intent.getStringExtra(DevicePolicyManager.EXTRA_PROVISIONING_WIFI_SECURITY_TYPE)
- ) {
- null -> NONE
- "NONE" -> NONE
- "WEP" -> WEP(password = extractWifiPassword(intent))
- "WPA" -> WPA(password = extractWifiPassword(intent))
- "EAP" -> EAP(password = extractWifiPassword(intent))
- else ->
- throw IllegalArgumentException(
- "Unknown value for EXTRA_PROVISIONING_WIFI_SECURITY_TYPE: $type"
- )
- }
-
- private fun extractWifiPassword(intent: Intent): String =
- intent.getStringExtra(DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PASSWORD)
- ?: throw IllegalArgumentException("EXTRA_PROVISIONING_WIFI_PASSWORD must be specified")
-
- private fun extractDeviceAdmin(intent: Intent): DeviceAdmin =
- DeviceAdmin(
- componentName = extractDeviceAdminComponentName(intent),
- download = extractDeviceAdminDownload(intent)
- )
-
- private fun extractDeviceAdminDownload(intent: Intent): DeviceAdminDownload? =
- if (
- intent.hasExtra(DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION)
- ) {
- DeviceAdminDownload(
- location =
- intent.getStringExtra(
- DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION
- )!!, // Must exist due to previous check
- cookieHeader =
- intent.getStringExtra(
- DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER
- ),
- checksum = extractDeviceAdminChecksum(intent)
- )
- } else {
- null
- }
-
- private fun extractDeviceAdminComponentName(intent: Intent): ComponentName {
- return intent.getParcelableExtra(
- DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME
- )
- ?: throw IllegalArgumentException(
- "Intent is missing EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME extra"
- )
- }
-
- private fun extractDeviceAdminChecksum(intent: Intent): DeviceAdminChecksum {
- val packageChecksum =
- intent.getStringExtra(DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM)
- val signatureChecksum =
- intent.getStringExtra(DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM)
-
- return if (packageChecksum != null) {
- if (signatureChecksum != null) {
- throw IllegalArgumentException(
- "Intent has both " +
- "EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM and " +
- "EXTRA_PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM"
- )
- }
-
- PackageChecksum(checksum = packageChecksum)
- } else if (signatureChecksum != null) {
- SignatureChecksum(checksum = signatureChecksum)
- } else {
- throw IllegalArgumentException(
- "Intent has no " +
- "EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM or " +
- "EXTRA_PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM"
- )
- }
- }
-}
diff --git a/src/com/android/onboarding/contracts/provisioning/PreProvisioningViaNfcContract.kt b/src/com/android/onboarding/contracts/provisioning/PreProvisioningViaNfcContract.kt
deleted file mode 100644
index 7b45fac..0000000
--- a/src/com/android/onboarding/contracts/provisioning/PreProvisioningViaNfcContract.kt
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.android.onboarding.contracts.provisioning
-
-import android.content.Context
-import android.content.Intent
-import android.nfc.NfcAdapter
-import android.os.Parcelable
-import com.android.onboarding.common.MANAGED_PROVISIONING
-import com.android.onboarding.contracts.IntentScope
-import com.android.onboarding.contracts.ScopedIntentSerializer
-import com.android.onboarding.contracts.VoidOnboardingActivityApiContract
-import com.android.onboarding.contracts.annotations.OnboardingNode
-import javax.inject.Inject
-
-data class PreProvisioningViaNfcArguments(
- val ndefMessages: Array<Parcelable>,
-)
-
-@OnboardingNode(
- component = MANAGED_PROVISIONING,
- name = "PreProvisioningViaNfc",
- hasUi = OnboardingNode.HasUi.YES
-)
-class PreProvisioningViaNfcContract @Inject constructor() :
- VoidOnboardingActivityApiContract<PreProvisioningViaNfcArguments>(),
- ScopedIntentSerializer<PreProvisioningViaNfcArguments> {
-
- override fun performCreateIntent(context: Context, arg: PreProvisioningViaNfcArguments): Intent =
- Intent(NfcAdapter.ACTION_NDEF_DISCOVERED).also { write(it, arg) }
-
- override fun performExtractArgument(intent: Intent): PreProvisioningViaNfcArguments = read(intent)
-
- override fun IntentScope.write(value: PreProvisioningViaNfcArguments) {
- this[NfcAdapter.EXTRA_NDEF_MESSAGES] = value.ndefMessages
- }
-
- override fun IntentScope.read(): PreProvisioningViaNfcArguments =
- PreProvisioningViaNfcArguments(
- ndefMessages = parcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)
- )
-}
diff --git a/src/com/android/onboarding/contracts/provisioning/ProvisionOfflineOrViaRoleHolderApiContract.kt b/src/com/android/onboarding/contracts/provisioning/ProvisionOfflineOrViaRoleHolderApiContract.kt
deleted file mode 100644
index 705c3ff..0000000
--- a/src/com/android/onboarding/contracts/provisioning/ProvisionOfflineOrViaRoleHolderApiContract.kt
+++ /dev/null
@@ -1,54 +0,0 @@
-package com.android.onboarding.contracts.provisioning
-
-import android.content.Context
-import android.content.Intent
-import com.android.onboarding.common.MANAGED_PROVISIONING
-import com.android.onboarding.contracts.VoidOnboardingActivityApiContract
-import com.android.onboarding.contracts.annotations.OnboardingNode
-
-// From DevicePolicyManager
-private const val ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE =
- "android.app.action.PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE"
-
-val PARSER = ManagedDeviceProvisioningArgumentsSerializer()
-
-/**
- * Starts the enterprise provisioning flow, either by updating and using the Device Policy Manager
- * Role Holder or by offline provisioning if the role holder is not available or
- * [ManagedDeviceProvisioningArguments.allowOfflineProvisioning] is set to true.
- *
- * <p>During device owner provisioning, a device admin app is downloaded and set as the owner of the
- * device. A device owner has full control over the device. The device owner can not be modified by
- * the user and the only way of resetting the device is via factory reset.
- *
- * <p>If there is no internet connection, and
- * [ManagedDeviceProvisioningArguments.allowOfflineProvisioning] is not set to {code true}, then
- * (TODO: How do we expose the failure?)
- *
- * <p>The DPMRH updater will be launched to allow updating of the Device Policy Manager Role Holder.
- *
- * <p>After interacting with the updater, (TODO: We will pass control to the role holder using X
- * contract)
- *
- * <p>This API should only be called on a device which is not yet provisioned (TODO: Define what
- * this means)
- */
-@OnboardingNode(
- component = MANAGED_PROVISIONING,
- name = "ProvisionOfflineOrViaRoleHolder",
- hasUi = OnboardingNode.HasUi.YES_TEMPORARILY
-)
-class ProvisionOfflineOrViaRoleHolderApiContract :
- VoidOnboardingActivityApiContract<ManagedDeviceProvisioningArguments>() {
- override fun performCreateIntent(
- context: Context,
- arg: ManagedDeviceProvisioningArguments
- ): Intent {
- val intent = Intent(ACTIONS.ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE)
- PARSER.write(intent, arg)
- return intent
- }
-
- override fun performExtractArgument(intent: Intent): ManagedDeviceProvisioningArguments =
- PARSER.read(intent)
-}
diff --git a/src/com/android/onboarding/contracts/provisioning/ProvisioningMode.kt b/src/com/android/onboarding/contracts/provisioning/ProvisioningMode.kt
new file mode 100644
index 0000000..fcb0f8f
--- /dev/null
+++ b/src/com/android/onboarding/contracts/provisioning/ProvisioningMode.kt
@@ -0,0 +1,26 @@
+package com.android.onboarding.contracts.provisioning
+
+import android.app.admin.DevicePolicyManager
+import android.os.Build
+import androidx.annotation.RequiresApi
+
+@RequiresApi(Build.VERSION_CODES.Q)
+enum class ProvisioningMode(val id: Int) {
+ FullyManagedDevice(DevicePolicyManager.PROVISIONING_MODE_FULLY_MANAGED_DEVICE),
+
+ ManagedProfile(DevicePolicyManager.PROVISIONING_MODE_MANAGED_PROFILE),
+
+ ManagedProfileOnPersonalDevice(
+ DevicePolicyManager.PROVISIONING_MODE_MANAGED_PROFILE_ON_PERSONAL_DEVICE
+ );
+
+ companion object {
+ operator fun invoke(id: Int): ProvisioningMode =
+ when (id) {
+ FullyManagedDevice.id -> FullyManagedDevice
+ ManagedProfile.id -> ManagedProfile
+ ManagedProfileOnPersonalDevice.id -> ManagedProfileOnPersonalDevice
+ else -> error("Unknown ProvisioningMode(id=$id)")
+ }
+ }
+}
diff --git a/src/com/android/onboarding/contracts/provisioning/ProvisioningTrigger.kt b/src/com/android/onboarding/contracts/provisioning/ProvisioningTrigger.kt
new file mode 100644
index 0000000..416dc81
--- /dev/null
+++ b/src/com/android/onboarding/contracts/provisioning/ProvisioningTrigger.kt
@@ -0,0 +1,30 @@
+package com.android.onboarding.contracts.provisioning
+
+import android.app.admin.DevicePolicyManager
+
+enum class ProvisioningTrigger(val id: Int) {
+ @Suppress("UNRESOLVED_REFERENCE")
+ Unspecified(DevicePolicyManager.PROVISIONING_TRIGGER_UNSPECIFIED),
+ @Suppress("UNRESOLVED_REFERENCE")
+ CloudEnrollment(DevicePolicyManager.PROVISIONING_TRIGGER_CLOUD_ENROLLMENT),
+ @Suppress("UNRESOLVED_REFERENCE") QR(DevicePolicyManager.PROVISIONING_TRIGGER_QR_CODE),
+ @Deprecated("Deprecated in DevicePolicyManager")
+ @Suppress("UNRESOLVED_REFERENCE")
+ PersistentDeviceOwner(DevicePolicyManager.PROVISIONING_TRIGGER_PERSISTENT_DEVICE_OWNER),
+ @Suppress("UNRESOLVED_REFERENCE")
+ ManagedAccount(DevicePolicyManager.PROVISIONING_TRIGGER_MANAGED_ACCOUNT),
+ @Suppress("UNRESOLVED_REFERENCE") NFC(DevicePolicyManager.PROVISIONING_TRIGGER_NFC);
+
+ companion object {
+ operator fun invoke(id: Int): ProvisioningTrigger =
+ when (id) {
+ Unspecified.id -> Unspecified
+ CloudEnrollment.id -> CloudEnrollment
+ QR.id -> QR
+ PersistentDeviceOwner.id -> PersistentDeviceOwner
+ ManagedAccount.id -> ManagedAccount
+ NFC.id -> NFC
+ else -> error("Unknown ProvisioningTrigger(id=$id)")
+ }
+ }
+}
diff --git a/src/com/android/onboarding/contracts/provisioning/RESULTS.kt b/src/com/android/onboarding/contracts/provisioning/RESULTS.kt
new file mode 100644
index 0000000..11bf041
--- /dev/null
+++ b/src/com/android/onboarding/contracts/provisioning/RESULTS.kt
@@ -0,0 +1,9 @@
+package com.android.onboarding.contracts.provisioning
+
+import android.app.admin.DevicePolicyManager
+
+object RESULTS {
+ @get:Suppress("UNRESOLVED_REFERENCE")
+ inline val RESULT_UPDATE_ROLE_HOLDER: Int
+ get() = DevicePolicyManager.RESULT_UPDATE_ROLE_HOLDER
+}
diff --git a/src/com/android/onboarding/contracts/provisioning/managed/profile/Android.bp b/src/com/android/onboarding/contracts/provisioning/managed/profile/Android.bp
deleted file mode 100644
index 9e3e4f0..0000000
--- a/src/com/android/onboarding/contracts/provisioning/managed/profile/Android.bp
+++ /dev/null
@@ -1,18 +0,0 @@
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-android_library {
- name: "android_onboarding.contracts.provisioning.managed.profile",
- manifest: ":android_onboarding.AndroidManifest",
- srcs: [
- "*.kt",
- ],
- dont_merge_manifests: true,
- static_libs: [
- "android_onboarding.common",
- "android_onboarding.contracts",
- "android_onboarding.contracts.provisioning",
- "android_onboarding.contracts.setupwizard",
- ],
-}
diff --git a/src/com/android/onboarding/contracts/provisioning/managed/profile/ProvisionManagedProfileArguments.kt b/src/com/android/onboarding/contracts/provisioning/managed/profile/ProvisionManagedProfileArguments.kt
deleted file mode 100644
index c15240e..0000000
--- a/src/com/android/onboarding/contracts/provisioning/managed/profile/ProvisionManagedProfileArguments.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.android.onboarding.contracts.provisioning.managed.profile
-
-import android.content.pm.ActivityInfo
-import android.net.Uri
-import com.android.onboarding.contracts.setupwizard.SuwArguments
-import com.android.onboarding.contracts.setupwizard.WithSuwArguments
-
-/** */
-data class ProvisionManagedProfileArguments(
- override val suwArguments: SuwArguments,
- val trigger: Int,
- val deviceAdminComponentName: ActivityInfo,
- val deviceAdminSignatureChecksum: String,
- val deviceAdminPackageDownloadLocation: Uri,
-) : WithSuwArguments
diff --git a/src/com/android/onboarding/contracts/provisioning/managed/profile/ProvisionManagedProfileArgumentsSerializer.kt b/src/com/android/onboarding/contracts/provisioning/managed/profile/ProvisionManagedProfileArgumentsSerializer.kt
deleted file mode 100644
index b30fc75..0000000
--- a/src/com/android/onboarding/contracts/provisioning/managed/profile/ProvisionManagedProfileArgumentsSerializer.kt
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.android.onboarding.contracts.provisioning.managed.profile
-
-import android.net.Uri
-import com.android.onboarding.contracts.IntentScope
-import com.android.onboarding.contracts.ScopedIntentSerializer
-import com.android.onboarding.contracts.provisioning.EXTRAS
-import com.android.onboarding.contracts.setupwizard.SuwArgumentsSerializer
-
-class ProvisionManagedProfileArgumentsSerializer(
- private val suwArgumentsSerializer: SuwArgumentsSerializer = SuwArgumentsSerializer(),
-) : ScopedIntentSerializer<ProvisionManagedProfileArguments> {
-
- override fun IntentScope.write(value: ProvisionManagedProfileArguments) {
- intent.write(suwArgumentsSerializer, value.suwArguments)
- intent["trigger"] = value.trigger
- intent[EXTRAS.EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME] = value.deviceAdminComponentName
- intent[EXTRAS.EXTRA_PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM] =
- value.deviceAdminSignatureChecksum
- intent[EXTRAS.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION] =
- value.deviceAdminPackageDownloadLocation
- }
-
- override fun IntentScope.read(): ProvisionManagedProfileArguments =
- ProvisionManagedProfileArguments(
- suwArguments = intent.read(suwArgumentsSerializer),
- trigger = intent.intExtra(EXTRAS.EXTRA_PROVISIONING_TRIGGER),
- deviceAdminComponentName =
- intent.parcelableExtra(EXTRAS.EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME),
- deviceAdminSignatureChecksum =
- intent.stringExtra(EXTRAS.EXTRA_PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM),
- deviceAdminPackageDownloadLocation =
- intent
- .stringExtra(EXTRAS.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION)
- .let(Uri::parse),
- )
-}
diff --git a/src/com/android/onboarding/contracts/provisioning/managed/profile/ProvisionManagedProfileContract.kt b/src/com/android/onboarding/contracts/provisioning/managed/profile/ProvisionManagedProfileContract.kt
deleted file mode 100644
index 5d9bee8..0000000
--- a/src/com/android/onboarding/contracts/provisioning/managed/profile/ProvisionManagedProfileContract.kt
+++ /dev/null
@@ -1,32 +0,0 @@
-package com.android.onboarding.contracts.provisioning.managed.profile
-
-import android.content.Context
-import android.content.Intent
-import com.android.onboarding.common.MANAGED_PROVISIONING
-import com.android.onboarding.contracts.VoidOnboardingActivityApiContract
-import com.android.onboarding.contracts.annotations.OnboardingNode
-import com.android.onboarding.contracts.provisioning.ACTIONS
-
-/**
- * | Activity | com.android.managedprovisioning.preprovisioning.PreProvisioningActivity |
- * |----------|-------------------------------------------------------------------------|
- * | | |
- */
-@OnboardingNode(
- component = MANAGED_PROVISIONING,
- name = "ProvisionManagedProfile",
- hasUi = OnboardingNode.HasUi.YES
-)
-class ProvisionManagedProfileContract(
- private val serializer: ProvisionManagedProfileArgumentsSerializer =
- ProvisionManagedProfileArgumentsSerializer(),
-) : VoidOnboardingActivityApiContract<ProvisionManagedProfileArguments>() {
-
- override fun performCreateIntent(
- context: Context,
- arg: ProvisionManagedProfileArguments
- ): Intent = Intent(ACTIONS.ACTION_PROVISION_MANAGED_PROFILE).also { serializer.write(it, arg) }
-
- override fun performExtractArgument(intent: Intent): ProvisionManagedProfileArguments =
- serializer.read(intent)
-}
diff --git a/src/com/android/onboarding/nodes/OnboardingGraphLog.kt b/src/com/android/onboarding/nodes/OnboardingGraphLog.kt
index b100923..c34966d 100644
--- a/src/com/android/onboarding/nodes/OnboardingGraphLog.kt
+++ b/src/com/android/onboarding/nodes/OnboardingGraphLog.kt
@@ -540,13 +540,12 @@ interface OnboardingGraphLog {
companion object {
- private fun extractNodeNameFromClass(nodeClass: Class<*>) =
- nodeClass.getAnnotation(OnboardingNode::class.java)?.name?.takeIf {
- it.length <= MAX_NODE_NAME_LENGTH
- }
- ?: throw IllegalArgumentException(
- "All nodes must be annotated @OnboardingNode and have a valid node name"
- )
+ private fun extractNodeNameFromClass(nodeClass: Class<*>): String =
+ nodeClass.getAnnotation(OnboardingNode::class.java)?.name?.also {
+ require(it.length <= MAX_NODE_NAME_LENGTH) {
+ "Node name length (${it.length}) exceeds maximum length of $MAX_NODE_NAME_LENGTH characters"
+ }
+ } ?: throw IllegalArgumentException("All nodes must be annotated @OnboardingNode")
fun deserialize(str: String): OnboardingEvent {
val proto = OnboardingProtos.LogProto.parseFrom(BaseEncoding.base64().decode(str))