1 /*
2  * Copyright 2016, The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.managedprovisioning.preprovisioning;
18 
19 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_TRIGGER;
20 import static android.app.admin.DevicePolicyManager.EXTRA_RESULT_LAUNCH_INTENT;
21 import static android.app.admin.DevicePolicyManager.EXTRA_ROLE_HOLDER_UPDATE_FAILURE_STRATEGY;
22 import static android.app.admin.DevicePolicyManager.EXTRA_ROLE_HOLDER_UPDATE_RESULT_CODE;
23 import static android.app.admin.DevicePolicyManager.PROVISIONING_TRIGGER_UNSPECIFIED;
24 import static android.app.admin.DevicePolicyManager.RESULT_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER_PROVISIONING_DISABLED;
25 import static android.app.admin.DevicePolicyManager.RESULT_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER_RECOVERABLE_ERROR;
26 import static android.app.admin.DevicePolicyManager.RESULT_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER_UNRECOVERABLE_ERROR;
27 import static android.app.admin.DevicePolicyManager.RESULT_UPDATE_ROLE_HOLDER;
28 import static android.app.admin.DevicePolicyManager.ROLE_HOLDER_UPDATE_FAILURE_STRATEGY_FAIL_PROVISIONING;
29 import static android.app.admin.DevicePolicyManager.ROLE_HOLDER_UPDATE_FAILURE_STRATEGY_FALLBACK_TO_PLATFORM_PROVISIONING;
30 import static android.content.res.Configuration.UI_MODE_NIGHT_MASK;
31 import static android.content.res.Configuration.UI_MODE_NIGHT_YES;
32 
33 import static com.android.managedprovisioning.ManagedProvisioningScreens.RETRY_LAUNCH;
34 import static com.android.managedprovisioning.common.ErrorDialogUtils.EXTRA_DIALOG_TITLE_ID;
35 import static com.android.managedprovisioning.common.ErrorDialogUtils.EXTRA_ERROR_MESSAGE_RES;
36 import static com.android.managedprovisioning.common.ErrorDialogUtils.EXTRA_FACTORY_RESET_REQUIRED;
37 import static com.android.managedprovisioning.common.RetryLaunchActivity.EXTRA_INTENT_TO_LAUNCH;
38 import static com.android.managedprovisioning.model.ProvisioningParams.FLOW_TYPE_LEGACY;
39 import static com.android.managedprovisioning.preprovisioning.PreProvisioningViewModel.STATE_PREPROVISIONING_INITIALIZING;
40 import static com.android.managedprovisioning.preprovisioning.PreProvisioningViewModel.STATE_SHOWING_USER_CONSENT;
41 import static com.android.managedprovisioning.provisioning.Constants.PROVISIONING_SERVICE_INTENT;
42 
43 import static com.google.android.setupcompat.util.WizardManagerHelper.EXTRA_IS_SETUP_FLOW;
44 
45 import static java.util.Objects.requireNonNull;
46 
47 import android.annotation.NonNull;
48 import android.annotation.Nullable;
49 import android.app.Activity;
50 import android.app.BackgroundServiceStartNotAllowedException;
51 import android.app.DialogFragment;
52 import android.app.admin.DevicePolicyManager;
53 import android.content.Intent;
54 import android.os.Bundle;
55 import android.os.PersistableBundle;
56 import android.provider.Settings;
57 import android.text.TextUtils;
58 import android.view.ContextMenu;
59 import android.view.ContextMenu.ContextMenuInfo;
60 import android.view.View;
61 import android.widget.TextView;
62 
63 import androidx.annotation.VisibleForTesting;
64 
65 import com.android.managedprovisioning.ManagedProvisioningBaseApplication;
66 import com.android.managedprovisioning.ManagedProvisioningScreens;
67 import com.android.managedprovisioning.R;
68 import com.android.managedprovisioning.analytics.MetricsWriterFactory;
69 import com.android.managedprovisioning.analytics.ProvisioningAnalyticsTracker;
70 import com.android.managedprovisioning.common.AccessibilityContextMenuMaker;
71 import com.android.managedprovisioning.common.DefaultFeatureFlagChecker;
72 import com.android.managedprovisioning.common.DefaultIntentResolverChecker;
73 import com.android.managedprovisioning.common.DefaultPackageInstallChecker;
74 import com.android.managedprovisioning.common.DeviceManagementRoleHolderUpdaterHelper;
75 import com.android.managedprovisioning.common.Flags;
76 import com.android.managedprovisioning.common.GetProvisioningModeUtils;
77 import com.android.managedprovisioning.common.ManagedProvisioningSharedPreferences;
78 import com.android.managedprovisioning.common.ProvisionLogger;
79 import com.android.managedprovisioning.common.RetryLaunchActivity;
80 import com.android.managedprovisioning.common.RoleHolderProvider;
81 import com.android.managedprovisioning.common.RoleHolderUpdaterProvider;
82 import com.android.managedprovisioning.common.SettingsFacade;
83 import com.android.managedprovisioning.common.SetupGlifLayoutActivity;
84 import com.android.managedprovisioning.common.SimpleDialog;
85 import com.android.managedprovisioning.common.ThemeHelper;
86 import com.android.managedprovisioning.common.ThemeHelper.DefaultNightModeChecker;
87 import com.android.managedprovisioning.common.ThemeHelper.DefaultSetupWizardBridge;
88 import com.android.managedprovisioning.common.Utils;
89 import com.android.managedprovisioning.contracts.DownloadRoleHolderArguments;
90 import com.android.managedprovisioning.contracts.DownloadRoleHolderContract;
91 import com.android.managedprovisioning.model.ProvisioningParams;
92 import com.android.managedprovisioning.preprovisioning.PreProvisioningActivityController.UiParams;
93 import com.android.managedprovisioning.provisioning.AdminIntegratedFlowPrepareActivity;
94 import com.android.managedprovisioning.provisioning.ProvisioningActivity;
95 import com.android.managedprovisioning.util.LazyStringResource;
96 
97 import com.google.android.setupcompat.logging.ScreenKey;
98 import com.google.android.setupcompat.logging.SetupMetric;
99 import com.google.android.setupcompat.logging.SetupMetricsLogger;
100 import com.google.android.setupcompat.util.WizardManagerHelper;
101 import com.google.android.setupdesign.transition.TransitionHelper;
102 
103 import dagger.hilt.android.AndroidEntryPoint;
104 
105 import javax.inject.Inject;
106 
107 @AndroidEntryPoint(SetupGlifLayoutActivity.class)
108 public class PreProvisioningActivity extends Hilt_PreProvisioningActivity implements
109         SimpleDialog.SimpleDialogListener, PreProvisioningActivityController.Ui {
110 
111     private static final int ENCRYPT_DEVICE_REQUEST_CODE = 1;
112     @VisibleForTesting
113     protected static final int PROVISIONING_REQUEST_CODE = 2;
114     private static final int WIFI_REQUEST_CODE = 3;
115     private static final int CHANGE_LAUNCHER_REQUEST_CODE = 4;
116     private static final int ORGANIZATION_OWNED_LANDING_PAGE_REQUEST_CODE = 5;
117     private static final int GET_PROVISIONING_MODE_REQUEST_CODE = 6;
118     private static final int FINANCED_DEVICE_PREPARE_REQUEST_CODE = 7;
119     private static final int ADMIN_INTEGRATED_FLOW_PREPARE_REQUEST_CODE = 8;
120     private static final int START_PLATFORM_REQUESTED_ROLE_HOLDER_UPDATE_REQUEST_CODE = 9;
121     private static final int START_DEVICE_MANAGEMENT_ROLE_HOLDER_PROVISIONING_REQUEST_CODE = 10;
122     private static final int DOWNLOAD_DEVICE_MANAGEMENT_ROLE_HOLDER_FROM_PLATFORM_REQUEST_CODE = 11;
123     private static final int START_ROLE_HOLDER_REQUESTED_UPDATE_REQUEST_CODE = 12;
124 
125     // Note: must match the constant defined in HomeSettings
126     private static final String EXTRA_SUPPORT_MANAGED_PROFILES = "support_managed_profiles";
127 
128     private static final String ERROR_AND_CLOSE_DIALOG = "PreProvErrorAndCloseDialog";
129     private static final String BACK_PRESSED_DIALOG_RESET = "PreProvBackPressedDialogReset";
130     private static final String BACK_PRESSED_DIALOG_CLOSE_ACTIVITY =
131             "PreProvBackPressedDialogCloseActivity";
132     private static final String LAUNCHER_INVALID_DIALOG = "PreProvCurrentLauncherInvalidDialog";
133     private static final String SETUP_METRIC_PREPROVISIONING_SCREEN_NAME =
134             "ShowPreProvisioningScreen";
135 
136     private PreProvisioningActivityController mController;
137     private final ControllerProvider mControllerProvider;
138     private final AccessibilityContextMenuMaker mContextMenuMaker;
139     private PreProvisioningActivityBridge mBridge;
140     private boolean mShouldForwardTransition;
141     private final RoleHolderUpdaterProvider mRoleHolderUpdaterProvider;
142     private final RoleHolderProvider mRoleHolderProvider;
143 
144     private static final String ERROR_DIALOG_RESET = "ErrorDialogReset";
145     private static final int SETUP_METRIC_DEFAULT_ERROR_CODE = -1;
146     private ProvisioningAnalyticsTracker mAnalyticsTracker;
147     private boolean mAlreadyInitialized;
148     protected ScreenKey mScreenKey;
149     protected String setupMetricScreenName;
150 
151     @Inject
152     protected Flags mFlags;
153     @Inject
154     protected DownloadRoleHolderContract mDownloadRoleHolderContract;
155 
PreProvisioningActivity()156     public PreProvisioningActivity() {
157         this(activity ->
158                         new PreProvisioningActivityController(activity, activity),
159                 null,
160                 new Utils(),
161                 new SettingsFacade(),
162                 new ThemeHelper(
163                         new DefaultNightModeChecker(),
164                         new DefaultSetupWizardBridge()),
165                 RoleHolderProvider.DEFAULT,
166                 RoleHolderUpdaterProvider.DEFAULT);
167     }
168 
169     @VisibleForTesting
PreProvisioningActivity( ControllerProvider controllerProvider, AccessibilityContextMenuMaker contextMenuMaker, Utils utils, SettingsFacade settingsFacade, ThemeHelper themeHelper, RoleHolderProvider roleHolderProvider, RoleHolderUpdaterProvider roleHolderUpdaterProvider)170     public PreProvisioningActivity(
171             ControllerProvider controllerProvider,
172             AccessibilityContextMenuMaker contextMenuMaker, Utils utils,
173             SettingsFacade settingsFacade, ThemeHelper themeHelper,
174             RoleHolderProvider roleHolderProvider,
175             RoleHolderUpdaterProvider roleHolderUpdaterProvider) {
176         super(utils, settingsFacade, themeHelper);
177         mControllerProvider = requireNonNull(controllerProvider);
178         mContextMenuMaker =
179                 contextMenuMaker != null ? contextMenuMaker : new AccessibilityContextMenuMaker(
180                         this);
181         mRoleHolderUpdaterProvider = requireNonNull(roleHolderUpdaterProvider);
182         mRoleHolderProvider = requireNonNull(roleHolderProvider);
183     }
184 
185     @Override
onCreate(Bundle savedInstanceState)186     protected void onCreate(Bundle savedInstanceState) {
187         // TODO(b/192074477): Remove deferred setup-specific logic after the managed account flow
188         //  starts ManagedProvisioning with the isSetupFlow extra
189         // This temporary fix only works when called before super.onCreate
190         if (mSettingsFacade.isDeferredSetup(getApplicationContext())) {
191             getIntent().putExtra(EXTRA_IS_SETUP_FLOW, true);
192         }
193 
194         super.onCreate(savedInstanceState);
195         setupMetricScreenName = SETUP_METRIC_PREPROVISIONING_SCREEN_NAME;
196         mScreenKey = ScreenKey.of(setupMetricScreenName, this);
197 
198         if (savedInstanceState == null) {
199             mAlreadyInitialized = false;
200         }
201         mController = mControllerProvider.getInstance(this);
202         mBridge = createBridge();
203         mController.getState().observe(this, this::onStateChanged);
204 
205         mAnalyticsTracker =
206                 new ProvisioningAnalyticsTracker(
207                         MetricsWriterFactory.getMetricsWriter(this, new SettingsFacade()),
208                         new ManagedProvisioningSharedPreferences(this));
209         logMetrics();
210     }
211 
212     @Override
onStart()213     protected void onStart() {
214         super.onStart();
215         try {
216             getApplicationContext().startService(PROVISIONING_SERVICE_INTENT);
217         } catch (BackgroundServiceStartNotAllowedException e) {
218             ProvisionLogger.loge(e);
219         }
220         mController.getState().observe(this, this::onStateChanged);
221     }
222 
223     @Override
onResume()224     protected void onResume() {
225         super.onResume();
226         SetupMetricsLogger.logMetrics(this, mScreenKey,
227                 SetupMetric.ofImpression(setupMetricScreenName));
228         if (mShouldForwardTransition) {
229             TransitionHelper.applyForwardTransition(
230                     this, TransitionHelper.TRANSITION_FADE_THROUGH);
231             mShouldForwardTransition = false;
232         }
233     }
234 
createBridge()235     protected PreProvisioningActivityBridge createBridge() {
236         return new PreProvisioningActivityBridgeImpl(
237                 /* activity= */ this,
238                 mUtils,
239                 PreProvisioningActivity.this::initializeLayoutParams,
240                 createBridgeCallbacks(),
241                 getThemeHelper(),
242                 setupMetricScreenName);
243     }
244 
createBridgeCallbacks()245     protected final PreProvisioningActivityBridgeCallbacks createBridgeCallbacks() {
246         return new PreProvisioningActivityBridgeCallbacks() {
247             @Override
248             public void onTermsAccepted() {
249                 mController.continueProvisioningAfterUserConsent();
250             }
251 
252             @Override
253             public void onTermsButtonClicked() {
254                 getTransitionHelper()
255                         .startActivityWithTransition(PreProvisioningActivity.this,
256                                 mController.createViewTermsIntent());
257             }
258         };
259     }
260 
261     private void onStateChanged(Integer state) {
262         switch (state) {
263             case STATE_PREPROVISIONING_INITIALIZING:
264                 if (!mAlreadyInitialized) {
265                     mController.initiateProvisioning(getIntent(), getCallingPackage());
266                     mAlreadyInitialized = true;
267                 }
268                 break;
269             case STATE_SHOWING_USER_CONSENT:
270                 mController.showUserConsentScreen();
271                 break;
272         }
273     }
274 
275     @Override
276     public void finish() {
277         // The user has backed out of provisioning, so we perform the necessary clean up steps.
278         ProvisioningParams params = mController.getParams();
279         if (params != null) {
280             params.cleanUp();
281         }
282         getEncryptionController().cancelEncryptionReminder();
283         getApplicationContext().stopService(PROVISIONING_SERVICE_INTENT);
284         super.finish();
285     }
286 
287     @SuppressWarnings("MissingSuperCall") // TODO: Fix me
288     @Override
289     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
290         switch (requestCode) {
291             case ENCRYPT_DEVICE_REQUEST_CODE:
292                 if (resultCode == RESULT_CANCELED) {
293                     ProvisionLogger.loge("User canceled device encryption.");
294                 }
295                 break;
296             case PROVISIONING_REQUEST_CODE:
297                 mController.onReturnFromProvisioning();
298                 setResult(resultCode);
299                 getTransitionHelper().finishActivity(this);
300                 break;
301             case CHANGE_LAUNCHER_REQUEST_CODE:
302                 mController.continueProvisioningAfterUserConsent();
303                 break;
304             case WIFI_REQUEST_CODE:
305                 if (resultCode == RESULT_CANCELED) {
306                     ProvisionLogger.loge("User canceled wifi picking.");
307                     setResult(resultCode);
308                     getTransitionHelper().finishActivity(this);
309                 } else {
310                     if (resultCode == RESULT_OK) {
311                         ProvisionLogger.logd("Wifi request result is OK");
312                     }
313                     mController.initiateProvisioning(getIntent(), getCallingPackage());
314                 }
315                 break;
316             case ORGANIZATION_OWNED_LANDING_PAGE_REQUEST_CODE:
317             case ADMIN_INTEGRATED_FLOW_PREPARE_REQUEST_CODE:
318                 if (resultCode == RESULT_OK) {
319                     handleAdminIntegratedFlowPreparerResult();
320                 } else {
321                     ProvisionLogger.loge(
322                             "Provisioning was aborted in the preparation stage, "
323                                     + "requestCode = " + requestCode);
324                     SetupMetricsLogger.logMetrics(this, mScreenKey,
325                             SetupMetric.ofError(setupMetricScreenName, resultCode));
326                     if (isDpcInstalled()
327                             && mUtils.isOrganizationOwnedAllowed(mController.getParams())) {
328                         showFactoryResetDialog(R.string.cant_set_up_device,
329                                 R.string.contact_your_admin_for_help);
330                     } else {
331                         showErrorAndClose(
332                                 R.string.cant_set_up_device,
333                                 R.string.contact_your_admin_for_help,
334                                 "Failed provisioning device.");
335                     }
336                 }
337                 break;
338             case GET_PROVISIONING_MODE_REQUEST_CODE:
339                 mShouldForwardTransition = true;
340                 if (resultCode == RESULT_OK) {
341                     if (data != null && mController.updateProvisioningParamsFromIntent(data)) {
342                         mController.showUserConsentScreen();
343                     } else {
344                         ProvisionLogger.loge(
345                                 "Invalid data object returned from GET_PROVISIONING_MODE.");
346                         SetupMetricsLogger.logMetrics(this, mScreenKey,
347                                 SetupMetric.ofError(setupMetricScreenName, resultCode));
348                         if (mUtils.isOrganizationOwnedAllowed(mController.getParams())) {
349                             showFactoryResetDialog(R.string.cant_set_up_device,
350                                     R.string.contact_your_admin_for_help);
351                         } else {
352                             showErrorAndClose(
353                                     R.string.cant_set_up_device,
354                                     R.string.contact_your_admin_for_help,
355                                     "Failed provisioning personally-owned device.");
356                         }
357                     }
358                 } else {
359                     ProvisionLogger.loge("Invalid result code from GET_PROVISIONING_MODE. Expected "
360                             + RESULT_OK + " but got " + resultCode + ".");
361                     SetupMetricsLogger.logMetrics(this, mScreenKey,
362                             SetupMetric.ofError(setupMetricScreenName, resultCode));
363                     if (mUtils.isOrganizationOwnedAllowed(mController.getParams())) {
364                         showFactoryResetDialog(R.string.cant_set_up_device,
365                                 R.string.contact_your_admin_for_help);
366                     } else {
367                         showErrorAndClose(
368                                 R.string.cant_set_up_device,
369                                 R.string.contact_your_admin_for_help,
370                                 "Failed to provision personally-owned device.");
371                     }
372                 }
373                 break;
374             case FINANCED_DEVICE_PREPARE_REQUEST_CODE:
375                 if (resultCode == RESULT_OK) {
376                     startFinancedDeviceFlow();
377                 } else {
378                     setResult(resultCode);
379                     getTransitionHelper().finishActivity(this);
380                 }
381                 break;
382             case START_PLATFORM_REQUESTED_ROLE_HOLDER_UPDATE_REQUEST_CODE:
383                 handlePlatformRequestedUpdateResult(resultCode, data);
384                 break;
385             case START_ROLE_HOLDER_REQUESTED_UPDATE_REQUEST_CODE:
386                 handleRoleHolderRequestedUpdateResult(resultCode, data);
387                 break;
388             case START_DEVICE_MANAGEMENT_ROLE_HOLDER_PROVISIONING_REQUEST_CODE:
389                 ProvisionLogger.logw("Role holder returned result code " + resultCode);
390                 mAnalyticsTracker.logRoleHolderProvisioningFinish();
391                 if (resultCode == RESULT_UPDATE_ROLE_HOLDER) {
392                     if (handleUpdateRequestedWithNoRoleHolderUpdater(resultCode)) {
393                         return;
394                     }
395                     if (handleUpdateRequestedWithWrongStateType(data)) {
396                         return;
397                     }
398                     PersistableBundle roleHolderState =
399                             data.getParcelableExtra(DevicePolicyManager.EXTRA_ROLE_HOLDER_STATE);
400                     mController.resetRoleHolderUpdateRetryCount();
401                     mController.startRoleHolderUpdater(
402                             /* isRoleHolderRequestedUpdate= */ true, roleHolderState);
403                 } else {
404                     maybeHandleLaunchIntent(resultCode, data);
405                     getTransitionHelper().finishActivity(this);
406                 }
407                 break;
408             case DOWNLOAD_DEVICE_MANAGEMENT_ROLE_HOLDER_FROM_PLATFORM_REQUEST_CODE:
409                 mAnalyticsTracker.logPlatformRoleHolderUpdateFinished(resultCode);
410                 if (resultCode == RESULT_OK
411                         || mController.getParams().allowOffline) {
412                     boolean isProvisioningStarted = mController.startAppropriateProvisioning(
413                             getIntent(),
414                             new Bundle(),
415                             getCallingPackage());
416                     if (!isProvisioningStarted) {
417                         mAnalyticsTracker.logPlatformRoleHolderUpdateFailed();
418                         ProvisionLogger.loge("Provisioning could not be started following "
419                                 + "platform-side role holder download.");
420                         SetupMetricsLogger.logMetrics(this, mScreenKey,
421                                 SetupMetric.ofError(setupMetricScreenName, resultCode));
422                         showRoleHolderDownloadFailedDialog(new Intent());
423                     }
424                 } else if (data != null && data.hasExtra(EXTRA_ERROR_MESSAGE_RES)) {
425                     mAnalyticsTracker.logPlatformRoleHolderUpdateFailed();
426                     ProvisionLogger.loge("Role holder download failed and offline provisioning is "
427                             + "not allowed.");
428                     SetupMetricsLogger.logMetrics(this, mScreenKey,
429                             SetupMetric.ofError(setupMetricScreenName, resultCode));
430                     showRoleHolderDownloadFailedDialog(data);
431                 } else {
432                     mAnalyticsTracker.logPlatformRoleHolderUpdateFailed();
433                     ProvisionLogger.loge("Role holder download failed and offline provisioning is "
434                             + "not allowed.");
435                     SetupMetricsLogger.logMetrics(this, mScreenKey,
436                             SetupMetric.ofError(setupMetricScreenName, resultCode));
437                     showRoleHolderDownloadFailedDialog(new Intent());
438                 }
439                 break;
440             default:
441                 ProvisionLogger.logw("Unknown result code :" + resultCode);
442                 SetupMetricsLogger.logMetrics(this, mScreenKey,
443                         SetupMetric.ofError(setupMetricScreenName, resultCode));
444                 break;
445         }
446     }
447 
448     private boolean handleUpdateRequestedWithWrongStateType(Intent data) {
449         if (!(data.getParcelableExtra(DevicePolicyManager.EXTRA_ROLE_HOLDER_STATE)
450                 instanceof PersistableBundle)) {
451             ProvisionLogger.loge("Failed to process role holder state result.");
452             SetupMetricsLogger.logMetrics(this, mScreenKey,
453                     SetupMetric.ofError(setupMetricScreenName, SETUP_METRIC_DEFAULT_ERROR_CODE));
454             if (mUtils.isOrganizationOwnedAllowed(mController.getParams())) {
455                 showFactoryResetDialog(R.string.cant_set_up_device,
456                         R.string.contact_your_admin_for_help);
457             } else {
458                 showErrorAndClose(
459                         R.string.cant_set_up_device,
460                         R.string.contact_your_admin_for_help,
461                         "Failed to process role holder state result.");
462             }
463             return true;
464         }
465         return false;
466     }
467 
468     private boolean handleUpdateRequestedWithNoRoleHolderUpdater(int resultCode) {
469         if (TextUtils.isEmpty(
470                 mRoleHolderUpdaterProvider.getPackageName(this))) {
471             ProvisionLogger.logw("Role holder requested update, but there is no role "
472                     + "holder updater present. Restarting the role holder.");
473             boolean isProvisioningStarted = mController.startAppropriateProvisioning(
474                     getIntent(),
475                     createRoleHolderAdditionalExtras(resultCode),
476                     getCallingPackage());
477             if (!isProvisioningStarted) {
478                 failRoleHolderUpdate();
479                 ProvisionLogger.loge("Failed to start provisioning after a "
480                         + "role holder-requested role holder update and no updater "
481                         + "present. Result is " + resultCode + " and allow offline "
482                         + "provisioning is " + mController.getParams().allowOffline);
483                 SetupMetricsLogger.logMetrics(this, mScreenKey,
484                         SetupMetric.ofError(setupMetricScreenName, resultCode));
485             }
486             return true;
487         }
488         return false;
489     }
490 
491     private Bundle createRoleHolderAdditionalExtras(int resultCode) {
492         Bundle additionalExtras = new Bundle();
493         additionalExtras.putInt(EXTRA_ROLE_HOLDER_UPDATE_RESULT_CODE, resultCode);
494         return additionalExtras;
495     }
496 
497     private void handlePlatformRequestedUpdateResult(int resultCode, @Nullable Intent resultData) {
498         mAnalyticsTracker.logRoleHolderUpdaterUpdateFinish(resultCode);
499         if ((resultCode
500                 == RESULT_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER_RECOVERABLE_ERROR
501                 || resultCode == RESULT_CANCELED)
502                 && mController.canRetryRoleHolderUpdate()) {
503             mController.startRoleHolderUpdaterWithLastState(
504                     /* isRoleHolderRequestedUpdate= */ false);
505             mController.incrementRoleHolderUpdateRetryCount();
506             mAnalyticsTracker.logRoleHolderUpdaterUpdateRetry();
507         } else if (resultCode
508                 == RESULT_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER_PROVISIONING_DISABLED
509         ) {
510             mController.performPlatformProvidedProvisioning();
511         } else if (resultCode
512                 != RESULT_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER_UNRECOVERABLE_ERROR) {
513             mController.resetRoleHolderUpdateRetryCount();
514             boolean isProvisioningStarted = mController.startAppropriateProvisioning(
515                     getIntent(),
516                     createRoleHolderAdditionalExtras(resultCode),
517                     getCallingPackage());
518             if (!isProvisioningStarted) {
519                 if (isRoleHolderUpdaterRequestingPlatformDrivenProvisioning(resultData)) {
520                     ProvisionLogger.logi("Result is " + resultCode
521                             + " and applied fallback strategy.");
522                     mController.performPlatformProvidedProvisioning();
523                 } else {
524                     mAnalyticsTracker.logRoleHolderUpdaterUpdateFailed();
525                     failRoleHolderUpdate();
526                     ProvisionLogger.loge("Failed to start provisioning after a "
527                             + "platform-requested role holder update. Result is " + resultCode
528                             + " and allow offline provisioning is "
529                             + mController.getParams().allowOffline);
530                     SetupMetricsLogger.logMetrics(this, mScreenKey,
531                             SetupMetric.ofError(setupMetricScreenName, resultCode));
532                 }
533             }
534         } else if (mController.getParams().allowOffline) {
535             ProvisionLogger.logi("Result is " + resultCode + ". Allowed offline provisioning.");
536             mController.performPlatformProvidedProvisioning();
537         } else if (isRoleHolderUpdaterRequestingPlatformDrivenProvisioning(resultData)) {
538             ProvisionLogger.logi("Result is " + resultCode + " and applied fallback strategy.");
539             mController.performPlatformProvidedProvisioning();
540         } else {
541             mAnalyticsTracker.logRoleHolderUpdaterUpdateFailed();
542             failRoleHolderUpdate();
543             ProvisionLogger.loge("Failed to perform a platform-requested role holder "
544                     + "update. Result is " + resultCode + " and allow offline provisioning"
545                     + " is " + mController.getParams().allowOffline);
546             SetupMetricsLogger.logMetrics(this, mScreenKey,
547                     SetupMetric.ofError(setupMetricScreenName, resultCode));
548         }
549     }
550 
551     private void handleRoleHolderRequestedUpdateResult(int resultCode, Intent resultData) {
552         if ((resultCode
553                 == RESULT_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER_RECOVERABLE_ERROR
554                 || resultCode == RESULT_CANCELED)
555                 && mController.canRetryRoleHolderUpdate()) {
556             mController.startRoleHolderUpdaterWithLastState(
557                     /* isRoleHolderRequestedUpdate= */ true);
558             mController.incrementRoleHolderUpdateRetryCount();
559         } else if (resultCode
560                 == RESULT_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER_PROVISIONING_DISABLED) {
561             mController.performPlatformProvidedProvisioning();
562         } else if (resultCode
563                 != RESULT_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER_UNRECOVERABLE_ERROR) {
564             boolean isProvisioningStarted = mController.startAppropriateProvisioning(
565                     getIntent(),
566                     createRoleHolderAdditionalExtras(resultCode),
567                     getCallingPackage());
568             if (!isProvisioningStarted) {
569                 if (isRoleHolderUpdaterRequestingPlatformDrivenProvisioning(resultData)) {
570                     ProvisionLogger.logi("Result is " + resultCode
571                             + " and applied fallback strategy.");
572                     mController.performPlatformProvidedProvisioning();
573                 } else {
574                     failRoleHolderUpdate();
575                     ProvisionLogger.loge("Failed to start provisioning after a "
576                             + "role holder-requested role holder update. Result is "
577                             + resultCode + " and allow offline provisioning is "
578                             + mController.getParams().allowOffline);
579                     SetupMetricsLogger.logMetrics(this, mScreenKey,
580                             SetupMetric.ofError(setupMetricScreenName, resultCode));
581                 }
582             }
583         } else if (mController.getParams().allowOffline) {
584             ProvisionLogger.logi("Result is " + resultCode + ". Allowed offline provisioning.");
585             mController.performPlatformProvidedProvisioning();
586         } else if (isRoleHolderUpdaterRequestingPlatformDrivenProvisioning(resultData)) {
587             ProvisionLogger.logi("Result is " + resultCode + " and applied fallback strategy.");
588             mController.performPlatformProvidedProvisioning();
589         } else {
590             failRoleHolderUpdate();
591             ProvisionLogger.loge("Failed to perform a role holder-requested role holder "
592                     + "update. Result is " + resultCode + " and allow offline provisioning"
593                     + " is " + mController.getParams().allowOffline);
594             SetupMetricsLogger.logMetrics(this, mScreenKey,
595                     SetupMetric.ofError(setupMetricScreenName, resultCode));
596         }
597     }
598 
599     private boolean isRoleHolderUpdaterRequestingPlatformDrivenProvisioning(
600             @Nullable Intent resultData) {
601         if (resultData == null) {
602             return false;
603         }
604         return resultData.getIntExtra(
605                 EXTRA_ROLE_HOLDER_UPDATE_FAILURE_STRATEGY,
606                 ROLE_HOLDER_UPDATE_FAILURE_STRATEGY_FAIL_PROVISIONING)
607                 == ROLE_HOLDER_UPDATE_FAILURE_STRATEGY_FALLBACK_TO_PLATFORM_PROVISIONING;
608     }
609 
610     private void maybeHandleLaunchIntent(int resultCode, Intent data) {
611         if (data == null || !data.hasExtra(EXTRA_RESULT_LAUNCH_INTENT)) {
612             setResult(resultCode);
613             return;
614         }
615 
616         Intent launchIntent = data.getParcelableExtra(EXTRA_RESULT_LAUNCH_INTENT, Intent.class);
617         ProvisionLogger.logi("Role holder returned result intent: " + launchIntent);
618 
619         if (!mController.getParams().provisioningShouldLaunchResultIntent) {
620             ProvisionLogger.logi("Role Holder result intent to be launched by "
621                     + "provisioning initiator");
622             setResult(resultCode, launchIntent);
623             return;
624         }
625 
626         ProvisionLogger.logi("Role Holder result intent launched by platform");
627         startActivity(launchIntent);
628     }
629 
630     private void failRoleHolderUpdate() {
631         ProvisionLogger.loge("Update failed and offline provisioning is not allowed.");
632         SetupMetricsLogger.logMetrics(this, mScreenKey,
633                 SetupMetric.ofError(setupMetricScreenName, SETUP_METRIC_DEFAULT_ERROR_CODE));
634         if (mUtils.isOrganizationOwnedAllowed(mController.getParams())) {
635             showFactoryResetDialog(R.string.cant_set_up_device,
636                     R.string.contact_your_admin_for_help);
637         } else {
638             showErrorAndClose(
639                     R.string.cant_set_up_device,
640                     R.string.contact_your_admin_for_help,
641                     "Failed to provision personally-owned device.");
642         }
643     }
644 
645     private void showRoleHolderDownloadFailedDialog(@NonNull Intent data) {
646         int dialogTitleResId = data.getIntExtra(
647                 EXTRA_DIALOG_TITLE_ID,
648                 R.string.cant_set_up_device);
649 
650 
651         String dialogMessageRes = data.getStringExtra(EXTRA_ERROR_MESSAGE_RES);
652         LazyStringResource dialogMessage = !dialogMessageRes.isEmpty() ? LazyStringResource.of(
653                 dialogMessageRes) : LazyStringResource.of(R.string.contact_your_admin_for_help);
654 
655 
656         if (data.getBooleanExtra(EXTRA_FACTORY_RESET_REQUIRED, /* defaultValue= */ false)) {
657             showFactoryResetDialog(
658                     LazyStringResource.of(dialogTitleResId),
659                     dialogMessage);
660         } else {
661             showErrorAndClose(
662                     LazyStringResource.of(dialogTitleResId),
663                     dialogMessage,
664                     "Failed to provision personally-owned device.");
665         }
666     }
667 
668     private boolean isDpcInstalled() {
669         String adminPackageName = mController.getParams().inferDeviceAdminPackageName();
670         return mUtils.isPackageInstalled(adminPackageName, getPackageManager());
671     }
672 
673     private void handleAdminIntegratedFlowPreparerResult() {
674         if (isDpcInstalled()) {
675             startAdminIntegratedFlowPostDpcInstall();
676         } else {
677             String adminPackageName = mController.getParams().inferDeviceAdminPackageName();
678             showErrorAndClose(
679                     R.string.cant_set_up_device,
680                     R.string.contact_your_admin_for_help,
681                     "Package name " + adminPackageName + " is not installed.");
682         }
683     }
684 
685     @Override
686     public void showErrorAndClose(Integer titleId, int messageId, String logMessage) {
687         showErrorAndClose(LazyStringResource.of(titleId), LazyStringResource.of(messageId),
688                 logMessage);
689     }
690 
691     @Override
692     public void showErrorAndClose(
693             LazyStringResource title, LazyStringResource message, String logMessage) {
694         SimpleDialog.Builder dialogBuilder =
695                 new SimpleDialog.Builder().setTitle(title).setMessage(message);
696         setShowErrorAndCloseParams(dialogBuilder, logMessage);
697     }
698 
699     private void setShowErrorAndCloseParams(SimpleDialog.Builder dialogBuilder, String logText) {
700         ProvisionLogger.loge(logText);
701 
702         SimpleDialog.Builder builder =
703                 dialogBuilder
704                         .setCancelable(false)
705                         .setPositiveButtonMessage(R.string.device_owner_error_ok);
706         showDialog(builder, ERROR_AND_CLOSE_DIALOG);
707     }
708 
709     @Override
710     public void onNegativeButtonClick(DialogFragment dialog) {
711         switch (dialog.getTag()) {
712             case BACK_PRESSED_DIALOG_CLOSE_ACTIVITY:
713             case BACK_PRESSED_DIALOG_RESET:
714                 // user chose to continue. Do nothing
715                 break;
716             case LAUNCHER_INVALID_DIALOG:
717                 dialog.dismiss();
718                 break;
719             default:
720                 SimpleDialog.throwButtonClickHandlerNotImplemented(dialog);
721         }
722     }
723 
724     @Override
725     public void onPositiveButtonClick(DialogFragment dialog) {
726         switch (dialog.getTag()) {
727             case ERROR_AND_CLOSE_DIALOG:
728             case BACK_PRESSED_DIALOG_CLOSE_ACTIVITY:
729                 onProvisioningAborted();
730                 break;
731             case BACK_PRESSED_DIALOG_RESET:
732                 mUtils.factoryReset(this, "Provisioning cancelled by user on consent screen");
733                 onProvisioningAborted();
734                 break;
735             case LAUNCHER_INVALID_DIALOG:
736                 requestLauncherPick();
737                 break;
738             case ERROR_DIALOG_RESET:
739                 getUtils().factoryReset(this, "Error during preprovisioning");
740                 setResult(Activity.RESULT_CANCELED);
741                 getTransitionHelper().finishActivity(this);
742                 break;
743             default:
744                 SimpleDialog.throwButtonClickHandlerNotImplemented(dialog);
745         }
746     }
747 
748     private void onProvisioningAborted() {
749         setResult(Activity.RESULT_CANCELED);
750         mController.logPreProvisioningCancelled();
751         getTransitionHelper().finishActivity(this);
752     }
753 
754     @Override
755     public void requestEncryption(ProvisioningParams params) {
756         Intent encryptIntent = new Intent(this,
757                 getActivityForScreen(ManagedProvisioningScreens.ENCRYPT));
758         WizardManagerHelper.copyWizardManagerExtras(getIntent(), encryptIntent);
759         encryptIntent.putExtra(ProvisioningParams.EXTRA_PROVISIONING_PARAMS, params);
760         getTransitionHelper().startActivityForResultWithTransition(
761                 this, encryptIntent, ENCRYPT_DEVICE_REQUEST_CODE);
762     }
763 
764     @Override
765     public void requestWifiPick() {
766         final Intent intent = mUtils.getWifiPickIntent();
767         WizardManagerHelper.copyWizardManagerExtras(getIntent(), intent);
768         getTransitionHelper()
769                 .startActivityForResultWithTransition(this, intent, WIFI_REQUEST_CODE);
770     }
771 
772     @Override
773     public void showCurrentLauncherInvalid() {
774         SimpleDialog.Builder dialogBuilder = new SimpleDialog.Builder()
775                 .setCancelable(false)
776                 .setTitle(R.string.change_device_launcher)
777                 .setMessage(R.string.launcher_app_cant_be_used_by_work_profile)
778                 .setNegativeButtonMessage(R.string.cancel_provisioning)
779                 .setPositiveButtonMessage(R.string.pick_launcher);
780         showDialog(dialogBuilder, LAUNCHER_INVALID_DIALOG);
781     }
782 
783     @Override
784     public void abortProvisioning() {
785         onProvisioningAborted();
786     }
787 
788     @Override
789     public void prepareAdminIntegratedFlow(ProvisioningParams params) {
790         if (AdminIntegratedFlowPrepareActivity.shouldRunPrepareActivity(mUtils, this, params)) {
791             Intent intent = new Intent(this,
792                     getActivityForScreen(ManagedProvisioningScreens.ADMIN_INTEGRATED_PREPARE));
793             WizardManagerHelper.copyWizardManagerExtras(getIntent(), intent);
794             intent.putExtra(ProvisioningParams.EXTRA_PROVISIONING_PARAMS, params);
795             getTransitionHelper().startActivityForResultWithTransition(
796                     this, intent, ADMIN_INTEGRATED_FLOW_PREPARE_REQUEST_CODE);
797         } else {
798             handleAdminIntegratedFlowPreparerResult();
799         }
800     }
801 
802     @Override
803     public void startRoleHolderUpdater(boolean isRoleHolderRequestedUpdate) {
804         DeviceManagementRoleHolderUpdaterHelper roleHolderUpdaterHelper =
805                 new DeviceManagementRoleHolderUpdaterHelper(
806                         mRoleHolderUpdaterProvider.getPackageName(this),
807                         RoleHolderProvider.DEFAULT.getPackageName(this),
808                         new DefaultPackageInstallChecker(getPackageManager(), mUtils),
809                         new DefaultIntentResolverChecker(getPackageManager()),
810                         new DefaultFeatureFlagChecker(getContentResolver()));
811         Intent intent = new Intent(this, getActivityForScreen(RETRY_LAUNCH));
812         intent.putExtra(
813                 EXTRA_INTENT_TO_LAUNCH,
814                 roleHolderUpdaterHelper.createRoleHolderUpdaterIntent(
815                         getIntent(),
816                         getIntent().getIntExtra(
817                                 EXTRA_PROVISIONING_TRIGGER, PROVISIONING_TRIGGER_UNSPECIFIED),
818                         isRoleHolderRequestedUpdate));
819         mAnalyticsTracker.logRoleHolderUpdaterUpdateStart();
820         getTransitionHelper().startActivityForResultWithTransition(
821                 this,
822                 intent,
823                 isRoleHolderRequestedUpdate
824                         ? START_ROLE_HOLDER_REQUESTED_UPDATE_REQUEST_CODE
825                         : START_PLATFORM_REQUESTED_ROLE_HOLDER_UPDATE_REQUEST_CODE);
826     }
827 
828     @Override
829     public void startRoleHolderProvisioning(Intent intent) {
830         mAnalyticsTracker.logRoleHolderProvisioningStart();
831         Intent retryLaunchIntent = new Intent(this, getActivityForScreen(RETRY_LAUNCH));
832         retryLaunchIntent.putExtra(RetryLaunchActivity.EXTRA_INTENT_TO_LAUNCH, intent);
833         getTransitionHelper().startActivityForResultWithTransition(
834                 /* activity= */ this,
835                 retryLaunchIntent,
836                 START_DEVICE_MANAGEMENT_ROLE_HOLDER_PROVISIONING_REQUEST_CODE);
837     }
838 
839     @Override
840     public void onParamsValidated(ProvisioningParams params) {
841         ManagedProvisioningBaseApplication application =
842                 (ManagedProvisioningBaseApplication) getApplication();
843         application.keepScreenOn(this);
844     }
845 
846     @Override
847     public void startPlatformDrivenRoleHolderDownload() {
848         mAnalyticsTracker.logPlatformRoleHolderUpdateStart();
849 
850         Intent intent;
851         if (mFlags.isCosmicRayEnabled()) {
852             intent = mDownloadRoleHolderContract.createIntent(
853                     this,
854                     DownloadRoleHolderArguments.of(
855                             mDownloadRoleHolderContract.getSuwArgumentsSerializer().read(
856                                     getIntent()),
857                             requireNonNull(mController.getParams())));
858         } else {
859             intent = new Intent(this,
860                     getActivityForScreen(ManagedProvisioningScreens.DOWNLOAD_ROLE_HOLDER));
861             WizardManagerHelper.copyWizardManagerExtras(getIntent(), intent);
862             intent.putExtra(ProvisioningParams.EXTRA_PROVISIONING_PARAMS,
863                     mController.getParams());
864         }
865         getTransitionHelper().startActivityForResultWithTransition(
866                 this, intent, DOWNLOAD_DEVICE_MANAGEMENT_ROLE_HOLDER_FROM_PLATFORM_REQUEST_CODE);
867     }
868 
869     private void requestLauncherPick() {
870         Intent changeLauncherIntent = new Intent(Settings.ACTION_HOME_SETTINGS);
871         changeLauncherIntent.putExtra(EXTRA_SUPPORT_MANAGED_PROFILES, true);
872         getTransitionHelper().startActivityForResultWithTransition(
873                 this, changeLauncherIntent, CHANGE_LAUNCHER_REQUEST_CODE);
874     }
875 
876     /**
877      * Starts {@link ProvisioningActivity}.
878      */
879     @Override
880     public void startProvisioning(ProvisioningParams params) {
881         Intent intent = new Intent(this,
882                 getActivityForScreen(ManagedProvisioningScreens.PROVISIONING));
883         WizardManagerHelper.copyWizardManagerExtras(getIntent(), intent);
884         intent.putExtra(ProvisioningParams.EXTRA_PROVISIONING_PARAMS, params);
885         getTransitionHelper().startActivityForResultWithTransition(
886                 this, intent, PROVISIONING_REQUEST_CODE);
887     }
888 
889     // TODO: The below group of methods do not belong in the activity.
890     // Move them to the controller instead.
891 
892     /**
893      * Starts either the admin-integrated or the legacy flow, depending on the device state and
894      * DPC capabilities.
895      */
896     private void startAdminIntegratedFlowPostDpcInstall() {
897         boolean canPerformAdminIntegratedFlow = mUtils.canPerformAdminIntegratedFlow(
898                 this,
899                 mController.getParams(),
900                 mController.getPolicyComplianceUtils(),
901                 mController.getGetProvisioningModeUtils());
902         if (canPerformAdminIntegratedFlow) {
903             startAdminIntegratedFlowWithoutPredeterminedMode();
904         } else {
905             ProvisionLogger.loge("The admin app does not have handlers for both "
906                     + "ACTION_GET_PROVISIONING_MODE and ACTION_ADMIN_POLICY_COMPLIANCE "
907                     + "intent actions.");
908             SetupMetricsLogger.logMetrics(this, mScreenKey,
909                     SetupMetric.ofError(setupMetricScreenName, SETUP_METRIC_DEFAULT_ERROR_CODE));
910             if (mUtils.isOrganizationOwnedAllowed(mController.getParams())) {
911                 showFactoryResetDialog(R.string.cant_set_up_device,
912                         R.string.contact_your_admin_for_help);
913             } else {
914                 showErrorAndClose(
915                         R.string.cant_set_up_device,
916                         R.string.contact_your_admin_for_help,
917                         "Failed provisioning personally-owned device.");
918             }
919         }
920         mController.logProvisioningFlowType();
921     }
922 
923     private void startAdminIntegratedFlowWithoutPredeterminedMode() {
924         ProvisionLogger.logi("Starting the admin-integrated flow.");
925         GetProvisioningModeUtils provisioningModeUtils = mController.getGetProvisioningModeUtils();
926         Bundle additionalExtras = mController.getAdditionalExtrasForGetProvisioningModeIntent();
927         provisioningModeUtils.startGetProvisioningModeActivityIfResolved(
928                 this, mController.getParams(), additionalExtras,
929                 GET_PROVISIONING_MODE_REQUEST_CODE, getTransitionHelper());
930     }
931 
932     private void startFinancedDeviceFlow() {
933         ProvisionLogger.logi("Starting the financed device flow.");
934         mController.updateProvisioningFlowState(FLOW_TYPE_LEGACY);
935         mController.continueProvisioningAfterUserConsent();
936     }
937 
938     @Override
939     public void showFactoryResetDialog(Integer titleId, int messageId) {
940         SimpleDialog.Builder dialogBuilder = new SimpleDialog.Builder()
941                 .setTitle(titleId)
942                 .setMessage(messageId)
943                 .setCancelable(false)
944                 .setPositiveButtonMessage(R.string.reset);
945 
946         showDialog(dialogBuilder, ERROR_DIALOG_RESET);
947     }
948 
949     @Override
950     public void showFactoryResetDialog(LazyStringResource titleId, LazyStringResource messageId) {
951         SimpleDialog.Builder dialogBuilder = new SimpleDialog.Builder()
952                 .setTitle(titleId)
953                 .setMessage(messageId)
954                 .setCancelable(false)
955                 .setPositiveButtonMessage(R.string.reset);
956 
957         showDialog(dialogBuilder, ERROR_DIALOG_RESET);
958     }
959 
960     @Override
961     public void initiateUi(UiParams uiParams) {
962         mBridge.initiateUi(uiParams);
963     }
964 
965     @Override
966     public void showOwnershipDisclaimerScreen(ProvisioningParams params) {
967         Intent intent = new Intent(this,
968                 getActivityForScreen(ManagedProvisioningScreens.LANDING));
969         WizardManagerHelper.copyWizardManagerExtras(getIntent(), intent);
970         intent.putExtra(ProvisioningParams.EXTRA_PROVISIONING_PARAMS, params);
971         getTransitionHelper().startActivityForResultWithTransition(
972                 this, intent, ORGANIZATION_OWNED_LANDING_PAGE_REQUEST_CODE);
973     }
974 
975     @Override
976     public void prepareFinancedDeviceFlow(ProvisioningParams params) {
977         Intent intent = new Intent(this,
978                 getActivityForScreen(ManagedProvisioningScreens.FINANCED_DEVICE_LANDING));
979         WizardManagerHelper.copyWizardManagerExtras(getIntent(), intent);
980         intent.putExtra(ProvisioningParams.EXTRA_PROVISIONING_PARAMS, params);
981         getTransitionHelper().startActivityForResultWithTransition(
982                 this, intent, FINANCED_DEVICE_PREPARE_REQUEST_CODE);
983     }
984 
985     @Override
986     public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
987         super.onCreateContextMenu(menu, v, menuInfo);
988         if (v instanceof TextView) {
989             mContextMenuMaker.populateMenuContent(menu, (TextView) v);
990         }
991     }
992 
993     @Override
994     public void onBackPressed() {
995         if (mUtils.isOrganizationOwnedAllowed(mController.getParams())) {
996             showDialog(mUtils.createCancelProvisioningResetDialogBuilder(getApplicationContext()),
997                     BACK_PRESSED_DIALOG_RESET);
998         } else {
999             showDialog(mUtils.createCancelProvisioningDialogBuilder(),
1000                     BACK_PRESSED_DIALOG_CLOSE_ACTIVITY);
1001         }
1002     }
1003 
1004     private void logMetrics() {
1005         int nightMode = getResources().getConfiguration().uiMode & UI_MODE_NIGHT_MASK;
1006         mAnalyticsTracker.logIsNightMode(nightMode == UI_MODE_NIGHT_YES);
1007     }
1008 
1009     /**
1010      * Constructs {@link PreProvisioningActivityController} for a given {@link
1011      * PreProvisioningActivity}
1012      */
1013     interface ControllerProvider {
1014         /**
1015          * Constructs {@link PreProvisioningActivityController} for a given {@link
1016          * PreProvisioningActivity}
1017          */
1018         PreProvisioningActivityController getInstance(PreProvisioningActivity activity);
1019     }
1020 }
1021