Finish FinalizationActivity after starting the admin app.
Bug: 131315856
Test: manual
Change-Id: Ic6b7fb786560536e8e67813426e512c45dfbb76e
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index efc8729..0a2f82d 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -246,7 +246,7 @@
<!-- TODO: Add permission for setup-wizard to guard access? -->
<activity android:name=".finalization.FinalizationActivity"
- android:theme="@android:style/Theme.NoDisplay"
+ android:theme="@style/SudThemeGlifV3.Light"
android:noHistory="true"
android:excludeFromRecents="true"
android:exported="true"
diff --git a/src/com/android/managedprovisioning/finalization/FinalizationActivity.java b/src/com/android/managedprovisioning/finalization/FinalizationActivity.java
index ea3612f..16093fd 100644
--- a/src/com/android/managedprovisioning/finalization/FinalizationActivity.java
+++ b/src/com/android/managedprovisioning/finalization/FinalizationActivity.java
@@ -36,7 +36,13 @@
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- new FinalizationController(this).provisioningFinalized();
- finish();
+ // To prevent b/131315856, we finish this activity now only if we do not expect to launch
+ // the admin app. Otherwise let android:noHistory automatically finish it.
+ final FinalizationController finalizationController = new FinalizationController(this);
+ finalizationController.provisioningFinalized();
+ final int result = finalizationController.getProvisioningFinalizedResult();
+ if (result != FinalizationController.PROVISIONING_FINALIZED_RESULT_ADMIN_WILL_LAUNCH) {
+ finish();
+ }
}
}
diff --git a/src/com/android/managedprovisioning/finalization/FinalizationController.java b/src/com/android/managedprovisioning/finalization/FinalizationController.java
index 1ea806e..ba09868 100644
--- a/src/com/android/managedprovisioning/finalization/FinalizationController.java
+++ b/src/com/android/managedprovisioning/finalization/FinalizationController.java
@@ -22,6 +22,7 @@
import static com.android.internal.util.Preconditions.checkNotNull;
import static com.android.managedprovisioning.finalization.SendDpcBroadcastService.EXTRA_PROVISIONING_PARAMS;
+import android.annotation.IntDef;
import android.app.NotificationManager;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
@@ -51,6 +52,14 @@
public class FinalizationController {
private static final String PROVISIONING_PARAMS_FILE_NAME =
"finalization_activity_provisioning_params.xml";
+ static final int PROVISIONING_FINALIZED_RESULT_DEFAULT = 1;
+ static final int PROVISIONING_FINALIZED_RESULT_ADMIN_WILL_LAUNCH = 2;
+ static final int PROVISIONING_FINALIZED_RESULT_EARLY_EXIT = 3;
+ @IntDef({
+ PROVISIONING_FINALIZED_RESULT_DEFAULT,
+ PROVISIONING_FINALIZED_RESULT_ADMIN_WILL_LAUNCH,
+ PROVISIONING_FINALIZED_RESULT_EARLY_EXIT})
+ @interface ProvisioningFinalizedResult {}
private final Context mContext;
private final Utils mUtils;
@@ -59,6 +68,7 @@
private final ProvisioningIntentProvider mProvisioningIntentProvider;
private final NotificationHelper mNotificationHelper;
private final DeferredMetricsReader mDeferredMetricsReader;
+ private @ProvisioningFinalizedResult int mProvisioningFinalizedResult;
public FinalizationController(Context context,
UserProvisioningStateHelper userProvisioningStateHelper) {
@@ -171,9 +181,13 @@
* <p>This method has to be invoked after {@link #provisioningInitiallyDone(ProvisioningParams)}
* was called. It is commonly invoked at the end of SUW if provisioning occurs during SUW. It
* loads the provisioning params from the storage, notifies the DPC about the completed
- * provisioning and sets the right user provisioning states.</p>
+ * provisioning and sets the right user provisioning states.
+ *
+ * <p>To retrieve the resulting state of this method, use
+ * {@link #getProvisioningFinalizedResult()}
*/
void provisioningFinalized() {
+ mProvisioningFinalizedResult = PROVISIONING_FINALIZED_RESULT_EARLY_EXIT;
mDeferredMetricsReader.scheduleDumpMetrics(mContext);
if (mUserProvisioningStateHelper.isStateUnmanagedOrFinalized()) {
@@ -188,6 +202,7 @@
return;
}
+ mProvisioningFinalizedResult = PROVISIONING_FINALIZED_RESULT_DEFAULT;
if (mUtils.isAdminIntegratedFlow(params)) {
// Don't send ACTION_PROFILE_PROVISIONING_COMPLETE broadcast to DPC or launch DPC by
// ACTION_PROVISIONING_SUCCESSFUL intent if it's admin integrated flow.
@@ -202,6 +217,12 @@
} else {
if (params.provisioningAction.equals(ACTION_PROVISION_MANAGED_PROFILE)) {
notifyDpcManagedProfile(params);
+ final UserHandle managedProfileUserHandle = mUtils.getManagedProfile(mContext);
+ final int userId = managedProfileUserHandle.getIdentifier();
+ mProvisioningFinalizedResult =
+ mProvisioningIntentProvider.canLaunchDpc(params, userId, mUtils, mContext)
+ ? PROVISIONING_FINALIZED_RESULT_ADMIN_WILL_LAUNCH
+ : PROVISIONING_FINALIZED_RESULT_DEFAULT;
} else {
// For managed user and device owner, we send the provisioning complete intent and
// maybe launch the DPC.
@@ -226,6 +247,16 @@
}
/**
+ * @throws IllegalStateException if {@link #provisioningFinalized()} was not called before.
+ */
+ @ProvisioningFinalizedResult int getProvisioningFinalizedResult() {
+ if (mProvisioningFinalizedResult == 0) {
+ throw new IllegalStateException("provisioningFinalized() has not been called.");
+ }
+ return mProvisioningFinalizedResult;
+ }
+
+ /**
* Start a service which notifies the DPC on the managed profile that provisioning has
* completed. When the DPC has received the intent, send notify the primary instance that the
* profile is ready. The service is needed to prevent the managed provisioning process from
diff --git a/src/com/android/managedprovisioning/finalization/ProvisioningIntentProvider.java b/src/com/android/managedprovisioning/finalization/ProvisioningIntentProvider.java
index 1311200..6627456 100644
--- a/src/com/android/managedprovisioning/finalization/ProvisioningIntentProvider.java
+++ b/src/com/android/managedprovisioning/finalization/ProvisioningIntentProvider.java
@@ -44,6 +44,11 @@
}
}
+ boolean canLaunchDpc(ProvisioningParams params, int userId, Utils utils, Context context) {
+ final Intent dpcLaunchIntent = createDpcLaunchIntent(params);
+ return utils.canResolveIntentAsUser(context, dpcLaunchIntent, userId);
+ }
+
Intent createProvisioningCompleteIntent(
@NonNull ProvisioningParams params, int userId, Utils utils, Context context) {
Intent intent = new Intent(ACTION_PROFILE_PROVISIONING_COMPLETE);