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