• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(getIntent(), getCallingPackage());
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(getIntent(),
523                             getCallingPackage());
524                 } else {
525                     mAnalyticsTracker.logRoleHolderUpdaterUpdateFailed();
526                     failRoleHolderUpdate();
527                     ProvisionLogger.loge("Failed to start provisioning after a "
528                             + "platform-requested role holder update. Result is " + resultCode
529                             + " and allow offline provisioning is "
530                             + mController.getParams().allowOffline);
531                     SetupMetricsLogger.logMetrics(this, mScreenKey,
532                             SetupMetric.ofError(setupMetricScreenName, resultCode));
533                 }
534             }
535         } else if (mController.getParams().allowOffline) {
536             ProvisionLogger.logi("Result is " + resultCode + ". Allowed offline provisioning.");
537             mController.performPlatformProvidedProvisioning(getIntent(), getCallingPackage());
538         } else if (isRoleHolderUpdaterRequestingPlatformDrivenProvisioning(resultData)) {
539             ProvisionLogger.logi("Result is " + resultCode + " and applied fallback strategy.");
540             mController.performPlatformProvidedProvisioning(getIntent(), getCallingPackage());
541         } else {
542             mAnalyticsTracker.logRoleHolderUpdaterUpdateFailed();
543             failRoleHolderUpdate();
544             ProvisionLogger.loge("Failed to perform a platform-requested role holder "
545                     + "update. Result is " + resultCode + " and allow offline provisioning"
546                     + " is " + mController.getParams().allowOffline);
547             SetupMetricsLogger.logMetrics(this, mScreenKey,
548                     SetupMetric.ofError(setupMetricScreenName, resultCode));
549         }
550     }
551 
552     private void handleRoleHolderRequestedUpdateResult(int resultCode, Intent resultData) {
553         if ((resultCode
554                 == RESULT_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER_RECOVERABLE_ERROR
555                 || resultCode == RESULT_CANCELED)
556                 && mController.canRetryRoleHolderUpdate()) {
557             mController.startRoleHolderUpdaterWithLastState(
558                     /* isRoleHolderRequestedUpdate= */ true);
559             mController.incrementRoleHolderUpdateRetryCount();
560         } else if (resultCode
561                 == RESULT_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER_PROVISIONING_DISABLED) {
562             mController.performPlatformProvidedProvisioning(getIntent(), getCallingPackage());
563         } else if (resultCode
564                 != RESULT_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER_UNRECOVERABLE_ERROR) {
565             boolean isProvisioningStarted = mController.startAppropriateProvisioning(
566                     getIntent(),
567                     createRoleHolderAdditionalExtras(resultCode),
568                     getCallingPackage());
569             if (!isProvisioningStarted) {
570                 if (isRoleHolderUpdaterRequestingPlatformDrivenProvisioning(resultData)) {
571                     ProvisionLogger.logi("Result is " + resultCode
572                             + " and applied fallback strategy.");
573                     mController.performPlatformProvidedProvisioning(getIntent(),
574                             getCallingPackage());
575                 } else {
576                     failRoleHolderUpdate();
577                     ProvisionLogger.loge("Failed to start provisioning after a "
578                             + "role holder-requested role holder update. Result is "
579                             + resultCode + " and allow offline provisioning is "
580                             + mController.getParams().allowOffline);
581                     SetupMetricsLogger.logMetrics(this, mScreenKey,
582                             SetupMetric.ofError(setupMetricScreenName, resultCode));
583                 }
584             }
585         } else if (mController.getParams().allowOffline) {
586             ProvisionLogger.logi("Result is " + resultCode + ". Allowed offline provisioning.");
587             mController.performPlatformProvidedProvisioning(getIntent(), getCallingPackage());
588         } else if (isRoleHolderUpdaterRequestingPlatformDrivenProvisioning(resultData)) {
589             ProvisionLogger.logi("Result is " + resultCode + " and applied fallback strategy.");
590             mController.performPlatformProvidedProvisioning(getIntent(), getCallingPackage());
591         } else {
592             failRoleHolderUpdate();
593             ProvisionLogger.loge("Failed to perform a role holder-requested role holder "
594                     + "update. Result is " + resultCode + " and allow offline provisioning"
595                     + " is " + mController.getParams().allowOffline);
596             SetupMetricsLogger.logMetrics(this, mScreenKey,
597                     SetupMetric.ofError(setupMetricScreenName, resultCode));
598         }
599     }
600 
601     private boolean isRoleHolderUpdaterRequestingPlatformDrivenProvisioning(
602             @Nullable Intent resultData) {
603         if (resultData == null) {
604             return false;
605         }
606         return resultData.getIntExtra(
607                 EXTRA_ROLE_HOLDER_UPDATE_FAILURE_STRATEGY,
608                 ROLE_HOLDER_UPDATE_FAILURE_STRATEGY_FAIL_PROVISIONING)
609                 == ROLE_HOLDER_UPDATE_FAILURE_STRATEGY_FALLBACK_TO_PLATFORM_PROVISIONING;
610     }
611 
612     private void maybeHandleLaunchIntent(int resultCode, Intent data) {
613         if (data == null || !data.hasExtra(EXTRA_RESULT_LAUNCH_INTENT)) {
614             setResult(resultCode);
615             return;
616         }
617 
618         Intent launchIntent = data.getParcelableExtra(EXTRA_RESULT_LAUNCH_INTENT, Intent.class);
619         ProvisionLogger.logi("Role holder returned result intent: " + launchIntent);
620 
621         if (!mController.getParams().provisioningShouldLaunchResultIntent) {
622             ProvisionLogger.logi("Role Holder result intent to be launched by "
623                     + "provisioning initiator");
624             setResult(resultCode, launchIntent);
625             return;
626         }
627 
628         ProvisionLogger.logi("Role Holder result intent launched by platform");
629         startActivity(launchIntent);
630     }
631 
632     private void failRoleHolderUpdate() {
633         ProvisionLogger.loge("Update failed and offline provisioning is not allowed.");
634         SetupMetricsLogger.logMetrics(this, mScreenKey,
635                 SetupMetric.ofError(setupMetricScreenName, SETUP_METRIC_DEFAULT_ERROR_CODE));
636         if (mUtils.isOrganizationOwnedAllowed(mController.getParams())) {
637             showFactoryResetDialog(R.string.cant_set_up_device,
638                     R.string.contact_your_admin_for_help);
639         } else {
640             showErrorAndClose(
641                     R.string.cant_set_up_device,
642                     R.string.contact_your_admin_for_help,
643                     "Failed to provision personally-owned device.");
644         }
645     }
646 
647     private void showRoleHolderDownloadFailedDialog(@NonNull Intent data) {
648         int dialogTitleResId = data.getIntExtra(
649                 EXTRA_DIALOG_TITLE_ID,
650                 R.string.cant_set_up_device);
651 
652 
653         String dialogMessageRes = data.getStringExtra(EXTRA_ERROR_MESSAGE_RES);
654         LazyStringResource dialogMessage = !dialogMessageRes.isEmpty() ? LazyStringResource.of(
655                 dialogMessageRes) : LazyStringResource.of(R.string.contact_your_admin_for_help);
656 
657 
658         if (data.getBooleanExtra(EXTRA_FACTORY_RESET_REQUIRED, /* defaultValue= */ false)) {
659             showFactoryResetDialog(
660                     LazyStringResource.of(dialogTitleResId),
661                     dialogMessage);
662         } else {
663             showErrorAndClose(
664                     LazyStringResource.of(dialogTitleResId),
665                     dialogMessage,
666                     "Failed to provision personally-owned device.");
667         }
668     }
669 
670     private boolean isDpcInstalled() {
671         String adminPackageName = mController.getParams().inferDeviceAdminPackageName();
672         return mUtils.isPackageInstalled(adminPackageName, getPackageManager());
673     }
674 
675     private void handleAdminIntegratedFlowPreparerResult() {
676         if (isDpcInstalled()) {
677             startAdminIntegratedFlowPostDpcInstall();
678         } else {
679             String adminPackageName = mController.getParams().inferDeviceAdminPackageName();
680             showErrorAndClose(
681                     R.string.cant_set_up_device,
682                     R.string.contact_your_admin_for_help,
683                     "Package name " + adminPackageName + " is not installed.");
684         }
685     }
686 
687     @Override
688     public void showErrorAndClose(Integer titleId, int messageId, String logMessage) {
689         showErrorAndClose(LazyStringResource.of(titleId), LazyStringResource.of(messageId),
690                 logMessage);
691     }
692 
693     @Override
694     public void showErrorAndClose(
695             LazyStringResource title, LazyStringResource message, String logMessage) {
696         SimpleDialog.Builder dialogBuilder =
697                 new SimpleDialog.Builder().setTitle(title).setMessage(message);
698         setShowErrorAndCloseParams(dialogBuilder, logMessage);
699     }
700 
701     private void setShowErrorAndCloseParams(SimpleDialog.Builder dialogBuilder, String logText) {
702         ProvisionLogger.loge(logText);
703 
704         SimpleDialog.Builder builder =
705                 dialogBuilder
706                         .setCancelable(false)
707                         .setPositiveButtonMessage(R.string.device_owner_error_ok);
708         showDialog(builder, ERROR_AND_CLOSE_DIALOG);
709     }
710 
711     @Override
712     public void onNegativeButtonClick(DialogFragment dialog) {
713         switch (dialog.getTag()) {
714             case BACK_PRESSED_DIALOG_CLOSE_ACTIVITY:
715             case BACK_PRESSED_DIALOG_RESET:
716                 // user chose to continue. Do nothing
717                 break;
718             case LAUNCHER_INVALID_DIALOG:
719                 dialog.dismiss();
720                 break;
721             default:
722                 SimpleDialog.throwButtonClickHandlerNotImplemented(dialog);
723         }
724     }
725 
726     @Override
727     public void onPositiveButtonClick(DialogFragment dialog) {
728         switch (dialog.getTag()) {
729             case ERROR_AND_CLOSE_DIALOG:
730             case BACK_PRESSED_DIALOG_CLOSE_ACTIVITY:
731                 onProvisioningAborted();
732                 break;
733             case BACK_PRESSED_DIALOG_RESET:
734                 mUtils.factoryReset(this, "Provisioning cancelled by user on consent screen");
735                 onProvisioningAborted();
736                 break;
737             case LAUNCHER_INVALID_DIALOG:
738                 requestLauncherPick();
739                 break;
740             case ERROR_DIALOG_RESET:
741                 getUtils().factoryReset(this, "Error during preprovisioning");
742                 setResult(Activity.RESULT_CANCELED);
743                 getTransitionHelper().finishActivity(this);
744                 break;
745             default:
746                 SimpleDialog.throwButtonClickHandlerNotImplemented(dialog);
747         }
748     }
749 
750     private void onProvisioningAborted() {
751         setResult(Activity.RESULT_CANCELED);
752         mController.logPreProvisioningCancelled();
753         getTransitionHelper().finishActivity(this);
754     }
755 
756     @Override
757     public void requestEncryption(ProvisioningParams params) {
758         Intent encryptIntent = new Intent(this,
759                 getActivityForScreen(ManagedProvisioningScreens.ENCRYPT));
760         WizardManagerHelper.copyWizardManagerExtras(getIntent(), encryptIntent);
761         encryptIntent.putExtra(ProvisioningParams.EXTRA_PROVISIONING_PARAMS, params);
762         getTransitionHelper().startActivityForResultWithTransition(
763                 this, encryptIntent, ENCRYPT_DEVICE_REQUEST_CODE);
764     }
765 
766     @Override
767     public void requestWifiPick() {
768         final Intent intent = mUtils.getWifiPickIntent();
769         WizardManagerHelper.copyWizardManagerExtras(getIntent(), intent);
770         getTransitionHelper()
771                 .startActivityForResultWithTransition(this, intent, WIFI_REQUEST_CODE);
772     }
773 
774     @Override
775     public void showCurrentLauncherInvalid() {
776         SimpleDialog.Builder dialogBuilder = new SimpleDialog.Builder()
777                 .setCancelable(false)
778                 .setTitle(R.string.change_device_launcher)
779                 .setMessage(R.string.launcher_app_cant_be_used_by_work_profile)
780                 .setNegativeButtonMessage(R.string.cancel_provisioning)
781                 .setPositiveButtonMessage(R.string.pick_launcher);
782         showDialog(dialogBuilder, LAUNCHER_INVALID_DIALOG);
783     }
784 
785     @Override
786     public void abortProvisioning() {
787         onProvisioningAborted();
788     }
789 
790     @Override
791     public void prepareAdminIntegratedFlow(ProvisioningParams params) {
792         if (AdminIntegratedFlowPrepareActivity.shouldRunPrepareActivity(mUtils, this, params)) {
793             Intent intent = new Intent(this,
794                     getActivityForScreen(ManagedProvisioningScreens.ADMIN_INTEGRATED_PREPARE));
795             WizardManagerHelper.copyWizardManagerExtras(getIntent(), intent);
796             intent.putExtra(ProvisioningParams.EXTRA_PROVISIONING_PARAMS, params);
797             getTransitionHelper().startActivityForResultWithTransition(
798                     this, intent, ADMIN_INTEGRATED_FLOW_PREPARE_REQUEST_CODE);
799         } else {
800             handleAdminIntegratedFlowPreparerResult();
801         }
802     }
803 
804     @Override
805     public void startRoleHolderUpdater(boolean isRoleHolderRequestedUpdate) {
806         DeviceManagementRoleHolderUpdaterHelper roleHolderUpdaterHelper =
807                 new DeviceManagementRoleHolderUpdaterHelper(
808                         mRoleHolderUpdaterProvider.getPackageName(this),
809                         RoleHolderProvider.DEFAULT.getPackageName(this),
810                         new DefaultPackageInstallChecker(getPackageManager(), mUtils),
811                         new DefaultIntentResolverChecker(getPackageManager()),
812                         new DefaultFeatureFlagChecker(getContentResolver()));
813         Intent intent = new Intent(this, getActivityForScreen(RETRY_LAUNCH));
814         intent.putExtra(
815                 EXTRA_INTENT_TO_LAUNCH,
816                 roleHolderUpdaterHelper.createRoleHolderUpdaterIntent(
817                         getIntent(),
818                         getIntent().getIntExtra(
819                                 EXTRA_PROVISIONING_TRIGGER, PROVISIONING_TRIGGER_UNSPECIFIED),
820                         isRoleHolderRequestedUpdate));
821         mAnalyticsTracker.logRoleHolderUpdaterUpdateStart();
822         getTransitionHelper().startActivityForResultWithTransition(
823                 this,
824                 intent,
825                 isRoleHolderRequestedUpdate
826                         ? START_ROLE_HOLDER_REQUESTED_UPDATE_REQUEST_CODE
827                         : START_PLATFORM_REQUESTED_ROLE_HOLDER_UPDATE_REQUEST_CODE);
828     }
829 
830     @Override
831     public void startRoleHolderProvisioning(Intent intent) {
832         mAnalyticsTracker.logRoleHolderProvisioningStart();
833         Intent retryLaunchIntent = new Intent(this, getActivityForScreen(RETRY_LAUNCH));
834         retryLaunchIntent.putExtra(RetryLaunchActivity.EXTRA_INTENT_TO_LAUNCH, intent);
835         getTransitionHelper().startActivityForResultWithTransition(
836                 /* activity= */ this,
837                 retryLaunchIntent,
838                 START_DEVICE_MANAGEMENT_ROLE_HOLDER_PROVISIONING_REQUEST_CODE);
839     }
840 
841     @Override
842     public void onParamsValidated(ProvisioningParams params) {
843         ManagedProvisioningBaseApplication application =
844                 (ManagedProvisioningBaseApplication) getApplication();
845         application.keepScreenOn(this);
846     }
847 
848     @Override
849     public void startPlatformDrivenRoleHolderDownload() {
850         mAnalyticsTracker.logPlatformRoleHolderUpdateStart();
851 
852         Intent intent;
853         if (mFlags.isCosmicRayEnabled()) {
854             intent = mDownloadRoleHolderContract.createIntent(
855                     this,
856                     DownloadRoleHolderArguments.of(
857                             mDownloadRoleHolderContract.getSuwArgumentsSerializer().read(
858                                     getIntent()),
859                             requireNonNull(mController.getParams())));
860         } else {
861             intent = new Intent(this,
862                     getActivityForScreen(ManagedProvisioningScreens.DOWNLOAD_ROLE_HOLDER));
863             WizardManagerHelper.copyWizardManagerExtras(getIntent(), intent);
864             intent.putExtra(ProvisioningParams.EXTRA_PROVISIONING_PARAMS,
865                     mController.getParams());
866         }
867         getTransitionHelper().startActivityForResultWithTransition(
868                 this, intent, DOWNLOAD_DEVICE_MANAGEMENT_ROLE_HOLDER_FROM_PLATFORM_REQUEST_CODE);
869     }
870 
871     private void requestLauncherPick() {
872         Intent changeLauncherIntent = new Intent(Settings.ACTION_HOME_SETTINGS);
873         changeLauncherIntent.putExtra(EXTRA_SUPPORT_MANAGED_PROFILES, true);
874         getTransitionHelper().startActivityForResultWithTransition(
875                 this, changeLauncherIntent, CHANGE_LAUNCHER_REQUEST_CODE);
876     }
877 
878     /**
879      * Starts {@link ProvisioningActivity}.
880      */
881     @Override
882     public void startProvisioning(ProvisioningParams params) {
883         Intent intent = new Intent(this,
884                 getActivityForScreen(ManagedProvisioningScreens.PROVISIONING));
885         WizardManagerHelper.copyWizardManagerExtras(getIntent(), intent);
886         intent.putExtra(ProvisioningParams.EXTRA_PROVISIONING_PARAMS, params);
887         getTransitionHelper().startActivityForResultWithTransition(
888                 this, intent, PROVISIONING_REQUEST_CODE);
889     }
890 
891     // TODO: The below group of methods do not belong in the activity.
892     // Move them to the controller instead.
893 
894     /**
895      * Starts either the admin-integrated or the legacy flow, depending on the device state and
896      * DPC capabilities.
897      */
898     private void startAdminIntegratedFlowPostDpcInstall() {
899         boolean canPerformAdminIntegratedFlow = mUtils.canPerformAdminIntegratedFlow(
900                 this,
901                 mController.getParams(),
902                 mController.getPolicyComplianceUtils(),
903                 mController.getGetProvisioningModeUtils());
904         if (canPerformAdminIntegratedFlow) {
905             startAdminIntegratedFlowWithoutPredeterminedMode();
906         } else {
907             ProvisionLogger.loge("The admin app does not have handlers for both "
908                     + "ACTION_GET_PROVISIONING_MODE and ACTION_ADMIN_POLICY_COMPLIANCE "
909                     + "intent actions.");
910             SetupMetricsLogger.logMetrics(this, mScreenKey,
911                     SetupMetric.ofError(setupMetricScreenName, SETUP_METRIC_DEFAULT_ERROR_CODE));
912             if (mUtils.isOrganizationOwnedAllowed(mController.getParams())) {
913                 showFactoryResetDialog(R.string.cant_set_up_device,
914                         R.string.contact_your_admin_for_help);
915             } else {
916                 showErrorAndClose(
917                         R.string.cant_set_up_device,
918                         R.string.contact_your_admin_for_help,
919                         "Failed provisioning personally-owned device.");
920             }
921         }
922         mController.logProvisioningFlowType();
923     }
924 
925     private void startAdminIntegratedFlowWithoutPredeterminedMode() {
926         ProvisionLogger.logi("Starting the admin-integrated flow.");
927         GetProvisioningModeUtils provisioningModeUtils = mController.getGetProvisioningModeUtils();
928         Bundle additionalExtras = mController.getAdditionalExtrasForGetProvisioningModeIntent();
929         provisioningModeUtils.startGetProvisioningModeActivityIfResolved(
930                 this, mController.getParams(), additionalExtras,
931                 GET_PROVISIONING_MODE_REQUEST_CODE, getTransitionHelper());
932     }
933 
934     private void startFinancedDeviceFlow() {
935         ProvisionLogger.logi("Starting the financed device flow.");
936         mController.updateProvisioningFlowState(FLOW_TYPE_LEGACY);
937         mController.continueProvisioningAfterUserConsent();
938     }
939 
940     @Override
941     public void showFactoryResetDialog(Integer titleId, int messageId) {
942         SimpleDialog.Builder dialogBuilder = new SimpleDialog.Builder()
943                 .setTitle(titleId)
944                 .setMessage(messageId)
945                 .setCancelable(false)
946                 .setPositiveButtonMessage(R.string.reset);
947 
948         showDialog(dialogBuilder, ERROR_DIALOG_RESET);
949     }
950 
951     @Override
952     public void showFactoryResetDialog(LazyStringResource titleId, LazyStringResource messageId) {
953         SimpleDialog.Builder dialogBuilder = new SimpleDialog.Builder()
954                 .setTitle(titleId)
955                 .setMessage(messageId)
956                 .setCancelable(false)
957                 .setPositiveButtonMessage(R.string.reset);
958 
959         showDialog(dialogBuilder, ERROR_DIALOG_RESET);
960     }
961 
962     @Override
963     public void initiateUi(UiParams uiParams) {
964         mBridge.initiateUi(uiParams);
965     }
966 
967     @Override
968     public void showOwnershipDisclaimerScreen(ProvisioningParams params) {
969         Intent intent = new Intent(this,
970                 getActivityForScreen(ManagedProvisioningScreens.LANDING));
971         WizardManagerHelper.copyWizardManagerExtras(getIntent(), intent);
972         intent.putExtra(ProvisioningParams.EXTRA_PROVISIONING_PARAMS, params);
973         getTransitionHelper().startActivityForResultWithTransition(
974                 this, intent, ORGANIZATION_OWNED_LANDING_PAGE_REQUEST_CODE);
975     }
976 
977     @Override
978     public void prepareFinancedDeviceFlow(ProvisioningParams params) {
979         Intent intent = new Intent(this,
980                 getActivityForScreen(ManagedProvisioningScreens.FINANCED_DEVICE_LANDING));
981         WizardManagerHelper.copyWizardManagerExtras(getIntent(), intent);
982         intent.putExtra(ProvisioningParams.EXTRA_PROVISIONING_PARAMS, params);
983         getTransitionHelper().startActivityForResultWithTransition(
984                 this, intent, FINANCED_DEVICE_PREPARE_REQUEST_CODE);
985     }
986 
987     @Override
988     public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
989         super.onCreateContextMenu(menu, v, menuInfo);
990         if (v instanceof TextView) {
991             mContextMenuMaker.populateMenuContent(menu, (TextView) v);
992         }
993     }
994 
995     @Override
996     public void onBackPressed() {
997         if (mUtils.isOrganizationOwnedAllowed(mController.getParams())) {
998             showDialog(mUtils.createCancelProvisioningResetDialogBuilder(getApplicationContext()),
999                     BACK_PRESSED_DIALOG_RESET);
1000         } else {
1001             showDialog(mUtils.createCancelProvisioningDialogBuilder(),
1002                     BACK_PRESSED_DIALOG_CLOSE_ACTIVITY);
1003         }
1004     }
1005 
1006     private void logMetrics() {
1007         int nightMode = getResources().getConfiguration().uiMode & UI_MODE_NIGHT_MASK;
1008         mAnalyticsTracker.logIsNightMode(nightMode == UI_MODE_NIGHT_YES);
1009     }
1010 
1011     /**
1012      * Constructs {@link PreProvisioningActivityController} for a given {@link
1013      * PreProvisioningActivity}
1014      */
1015     interface ControllerProvider {
1016         /**
1017          * Constructs {@link PreProvisioningActivityController} for a given {@link
1018          * PreProvisioningActivity}
1019          */
1020         PreProvisioningActivityController getInstance(PreProvisioningActivity activity);
1021     }
1022 }
1023