/* * Copyright 2016, The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.managedprovisioning.provisioning; import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.PROVISIONING_PROVISIONING_ACTIVITY_TIME_MS; import android.Manifest.permission; import android.annotation.ColorRes; import android.app.Activity; import android.app.DialogFragment; import android.app.admin.DevicePolicyManager; import android.content.ComponentName; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.res.ColorStateList; import android.graphics.drawable.Animatable2; import android.graphics.drawable.AnimatedVectorDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.Handler; import android.support.annotation.VisibleForTesting; import android.view.View; import android.widget.ImageView; import android.widget.ProgressBar; import android.widget.TextView; import com.android.managedprovisioning.R; import com.android.managedprovisioning.common.DialogBuilder; import com.android.managedprovisioning.common.ProvisionLogger; import com.android.managedprovisioning.common.SetupGlifLayoutActivity; import com.android.managedprovisioning.common.SimpleDialog; import com.android.managedprovisioning.common.Utils; import com.android.managedprovisioning.model.CustomizationParams; import com.android.managedprovisioning.model.ProvisioningParams; import com.android.setupwizardlib.GlifLayout; import java.util.List; /** * Progress activity shown whilst provisioning is ongoing. * *
This activity registers for updates of the provisioning process from the * {@link ProvisioningManager}. It shows progress updates as provisioning progresses and handles * showing of cancel and error dialogs.
*/ public class ProvisioningActivity extends SetupGlifLayoutActivity implements SimpleDialog.SimpleDialogListener, ProvisioningManagerCallback { private static final String KEY_PROVISIONING_STARTED = "ProvisioningStarted"; private static final String ERROR_DIALOG_OK = "ErrorDialogOk"; private static final String ERROR_DIALOG_RESET = "ErrorDialogReset"; private static final String CANCEL_PROVISIONING_DIALOG_OK = "CancelProvisioningDialogOk"; private static final String CANCEL_PROVISIONING_DIALOG_RESET = "CancelProvisioningDialogReset"; private ProvisioningParams mParams; private ProvisioningManager mProvisioningManager; private AnimatedVectorDrawable mAnimatedVectorDrawable; private Handler mUiThreadHandler = new Handler(); /** Repeats the animation once it is done **/ private final Animatable2.AnimationCallback mAnimationCallback = new Animatable2.AnimationCallback() { @Override public void onAnimationEnd(Drawable drawable) { super.onAnimationEnd(drawable); mUiThreadHandler.post(mAnimatedVectorDrawable::start); } }; public ProvisioningActivity() { this(null, new Utils()); } @VisibleForTesting public ProvisioningActivity(ProvisioningManager provisioningManager, Utils utils) { super(utils); mProvisioningManager = provisioningManager; } // Lazily initialize ProvisioningManager, since we can't call in ProvisioningManager.getInstance // in constructor as base context is not available in constructor private ProvisioningManager getProvisioningManager() { if (mProvisioningManager == null) { mProvisioningManager = ProvisioningManager.getInstance(this); } return mProvisioningManager; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mParams = getIntent().getParcelableExtra(ProvisioningParams.EXTRA_PROVISIONING_PARAMS); initializeUi(mParams); if (savedInstanceState == null || !savedInstanceState.getBoolean(KEY_PROVISIONING_STARTED)) { getProvisioningManager().maybeStartProvisioning(mParams); } } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putBoolean(KEY_PROVISIONING_STARTED, true); } @Override protected void onResume() { super.onResume(); if (!isAnyDialogAdded()) { getProvisioningManager().registerListener(this); } if (mAnimatedVectorDrawable != null) { mAnimatedVectorDrawable.registerAnimationCallback(mAnimationCallback); mAnimatedVectorDrawable.reset(); mAnimatedVectorDrawable.start(); } } private boolean isAnyDialogAdded() { return isDialogAdded(ERROR_DIALOG_OK) || isDialogAdded(ERROR_DIALOG_RESET) || isDialogAdded(CANCEL_PROVISIONING_DIALOG_OK) || isDialogAdded(CANCEL_PROVISIONING_DIALOG_RESET); } @Override public void onPause() { getProvisioningManager().unregisterListener(this); if (mAnimatedVectorDrawable != null) { mAnimatedVectorDrawable.stop(); mAnimatedVectorDrawable.unregisterAnimationCallback(mAnimationCallback); } super.onPause(); } @Override public void onBackPressed() { // if EXTRA_PROVISIONING_SKIP_USER_CONSENT is specified, don't allow user to cancel if (mParams.skipUserConsent) { return; } showCancelProvisioningDialog(); } @Override public void preFinalizationCompleted() { ProvisionLogger.logi("ProvisioningActivity pre-finalization completed"); setResult(Activity.RESULT_OK); maybeLaunchNfcUserSetupCompleteIntent(); finish(); } private void maybeLaunchNfcUserSetupCompleteIntent() { if (mParams != null && mParams.isNfc) { // Start SetupWizard to complete the intent. final Intent intent = new Intent(DevicePolicyManager.ACTION_STATE_USER_SETUP_COMPLETE) .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); final PackageManager pm = getPackageManager(); List