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);