diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index e0e9e7d..38c707b 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -94,6 +94,20 @@
+
+
+
+
+
+
+
+
+
+
()
+ vm.params = vm.getParamsFromIntent(intent)
+ setContent {
+ val theme by myApp.container.themeState.collectAsState()
+ OwnDroidTheme(theme) {
+ ProvisioningScreen(vm.params) {
+ setResult(RESULT_OK, vm.buildResultIntent(it))
+ finish()
+ }
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/com/bintianqi/owndroid/activity/ProvisioningPolicyComplianceActivity.kt b/app/src/main/java/com/bintianqi/owndroid/activity/ProvisioningPolicyComplianceActivity.kt
new file mode 100644
index 0000000..e317298
--- /dev/null
+++ b/app/src/main/java/com/bintianqi/owndroid/activity/ProvisioningPolicyComplianceActivity.kt
@@ -0,0 +1,15 @@
+package com.bintianqi.owndroid.activity
+
+import android.os.Bundle
+import androidx.activity.ComponentActivity
+import com.bintianqi.owndroid.R
+import com.bintianqi.owndroid.utils.popToast
+
+class ProvisioningPolicyComplianceActivity: ComponentActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setResult(RESULT_OK)
+ popToast(R.string.app_name)
+ finish()
+ }
+}
diff --git a/app/src/main/java/com/bintianqi/owndroid/feature/provisioning/ProvisioningModel.kt b/app/src/main/java/com/bintianqi/owndroid/feature/provisioning/ProvisioningModel.kt
new file mode 100644
index 0000000..0d1b13e
--- /dev/null
+++ b/app/src/main/java/com/bintianqi/owndroid/feature/provisioning/ProvisioningModel.kt
@@ -0,0 +1,9 @@
+package com.bintianqi.owndroid.feature.provisioning
+
+class ProvisioningParams(
+ val imei: String?, val serial: String?, val modes: List
+)
+
+class ProvisioningOptions(
+ val skipEncryption: Boolean
+)
diff --git a/app/src/main/java/com/bintianqi/owndroid/feature/provisioning/ProvisioningScreen.kt b/app/src/main/java/com/bintianqi/owndroid/feature/provisioning/ProvisioningScreen.kt
new file mode 100644
index 0000000..1c6d1c9
--- /dev/null
+++ b/app/src/main/java/com/bintianqi/owndroid/feature/provisioning/ProvisioningScreen.kt
@@ -0,0 +1,87 @@
+package com.bintianqi.owndroid.feature.provisioning
+
+import android.app.admin.DevicePolicyManager
+import androidx.annotation.RequiresApi
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.verticalScroll
+import androidx.compose.material3.Button
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Scaffold
+import androidx.compose.material3.Text
+import androidx.compose.material3.TopAppBar
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.unit.dp
+import com.bintianqi.owndroid.R
+import com.bintianqi.owndroid.ui.FullWidthCheckBoxItem
+import com.bintianqi.owndroid.utils.BottomPadding
+import com.bintianqi.owndroid.utils.HorizontalPadding
+import com.bintianqi.owndroid.utils.adaptiveInsets
+
+@RequiresApi(29)
+@OptIn(ExperimentalMaterial3Api::class)
+@Composable
+fun ProvisioningScreen(params: ProvisioningParams, callback: (ProvisioningOptions) -> Unit) {
+ Scaffold(
+ topBar = {
+ TopAppBar(
+ { Text(stringResource(R.string.app_name)) }
+ )
+ },
+ contentWindowInsets = adaptiveInsets()
+ ) { paddingValues ->
+ Column(
+ Modifier
+ .padding(paddingValues)
+ .verticalScroll(rememberScrollState())
+ ) {
+ Column(Modifier.padding(horizontal = HorizontalPadding)) {
+ if (!params.imei.isNullOrEmpty()) {
+ Text("IMEI", style = MaterialTheme.typography.titleMedium)
+ Text(params.imei, Modifier.padding(bottom = 8.dp))
+ }
+ if (!params.serial.isNullOrEmpty()) {
+ Text(
+ stringResource(R.string.serial_number),
+ style = MaterialTheme.typography.titleMedium
+ )
+ Text(params.serial, Modifier.padding(bottom = 8.dp))
+ }
+ }
+ if (DevicePolicyManager.PROVISIONING_MODE_FULLY_MANAGED_DEVICE in params.modes) {
+ Spacer(Modifier.height(10.dp))
+ var skipEncryption by remember { mutableStateOf(false) }
+ FullWidthCheckBoxItem(R.string.skip_encryption, skipEncryption) {
+ skipEncryption = it
+ }
+ Button(
+ {
+ callback(ProvisioningOptions(skipEncryption))
+ },
+ Modifier
+ .fillMaxWidth()
+ .padding(HorizontalPadding, 4.dp)
+ ) {
+ Text(stringResource(R.string.continue_str))
+ }
+ } else {
+ Text(
+ stringResource(R.string.unsupported),
+ style = MaterialTheme.typography.titleLarge
+ )
+ }
+ Spacer(Modifier.height(BottomPadding))
+ }
+ }
+}
diff --git a/app/src/main/java/com/bintianqi/owndroid/feature/provisioning/ProvisioningViewModel.kt b/app/src/main/java/com/bintianqi/owndroid/feature/provisioning/ProvisioningViewModel.kt
new file mode 100644
index 0000000..9de3114
--- /dev/null
+++ b/app/src/main/java/com/bintianqi/owndroid/feature/provisioning/ProvisioningViewModel.kt
@@ -0,0 +1,31 @@
+package com.bintianqi.owndroid.feature.provisioning
+
+import android.app.admin.DevicePolicyManager
+import android.content.Intent
+import android.os.Build
+import androidx.annotation.RequiresApi
+import androidx.lifecycle.ViewModel
+
+@RequiresApi(29)
+class ProvisioningViewModel : ViewModel() {
+ lateinit var params: ProvisioningParams
+
+ fun getParamsFromIntent(intent: Intent): ProvisioningParams {
+ val modes = if (Build.VERSION.SDK_INT >= 31) intent.getIntegerArrayListExtra(
+ DevicePolicyManager.EXTRA_PROVISIONING_ALLOWED_PROVISIONING_MODES
+ ) else null
+ return ProvisioningParams(
+ intent.getStringExtra(DevicePolicyManager.EXTRA_PROVISIONING_IMEI),
+ intent.getStringExtra(DevicePolicyManager.EXTRA_PROVISIONING_SERIAL_NUMBER),
+ modes ?: listOf(DevicePolicyManager.PROVISIONING_MODE_FULLY_MANAGED_DEVICE)
+ )
+ }
+
+ fun buildResultIntent(options: ProvisioningOptions): Intent {
+ val intent = Intent()
+ intent.putExtra(
+ DevicePolicyManager.EXTRA_PROVISIONING_SKIP_ENCRYPTION, options.skipEncryption
+ )
+ return intent
+ }
+}