/* * Copyright (C) 2018 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.settings.biometrics; import static com.android.settings.Utils.SETTINGS_PACKAGE_NAME; import android.annotation.Nullable; import android.content.Intent; import android.content.res.Resources; import android.graphics.Color; import android.os.Bundle; import android.os.UserHandle; import android.text.TextUtils; import android.view.View; import android.widget.TextView; import com.android.settings.R; import com.android.settings.SetupWizardUtils; import com.android.settings.biometrics.fingerprint.FingerprintEnrollEnrolling; import com.android.settings.core.InstrumentedActivity; import com.android.settings.password.ChooseLockSettingsHelper; import com.google.android.setupcompat.template.FooterBarMixin; import com.google.android.setupcompat.template.FooterButton; import com.google.android.setupdesign.GlifLayout; /** * Base activity for all biometric enrollment steps. */ public abstract class BiometricEnrollBase extends InstrumentedActivity { public static final String EXTRA_FROM_SETTINGS_SUMMARY = "from_settings_summary"; public static final String EXTRA_KEY_LAUNCHED_CONFIRM = "launched_confirm_lock"; public static final String EXTRA_KEY_REQUIRE_VISION = "accessibility_vision"; public static final String EXTRA_KEY_REQUIRE_DIVERSITY = "accessibility_diversity"; /** * Used by the choose fingerprint wizard to indicate the wizard is * finished, and each activity in the wizard should finish. *

* Previously, each activity in the wizard would finish itself after * starting the next activity. However, this leads to broken 'Back' * behavior. So, now an activity does not finish itself until it gets this * result. */ public static final int RESULT_FINISHED = RESULT_FIRST_USER; /** * Used by the enrolling screen during setup wizard to skip over setting up fingerprint, which * will be useful if the user accidentally entered this flow. */ public static final int RESULT_SKIP = RESULT_FIRST_USER + 1; /** * Like {@link #RESULT_FINISHED} except this one indicates enrollment failed because the * device was left idle. This is used to clear the credential token to require the user to * re-enter their pin/pattern/password before continuing. */ public static final int RESULT_TIMEOUT = RESULT_FIRST_USER + 2; public static final int CHOOSE_LOCK_GENERIC_REQUEST = 1; public static final int BIOMETRIC_FIND_SENSOR_REQUEST = 2; public static final int LEARN_MORE_REQUEST = 3; public static final int CONFIRM_REQUEST = 4; public static final int ENROLL_REQUEST = 5; protected boolean mLaunchedConfirmLock; protected byte[] mToken; protected int mUserId; protected boolean mFromSettingsSummary; protected FooterBarMixin mFooterBarMixin; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mToken = getIntent().getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN); mFromSettingsSummary = getIntent().getBooleanExtra(EXTRA_FROM_SETTINGS_SUMMARY, false); if (savedInstanceState != null && mToken == null) { mLaunchedConfirmLock = savedInstanceState.getBoolean(EXTRA_KEY_LAUNCHED_CONFIRM); mToken = savedInstanceState.getByteArray( ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN); mFromSettingsSummary = savedInstanceState.getBoolean(EXTRA_FROM_SETTINGS_SUMMARY, false); } mUserId = getIntent().getIntExtra(Intent.EXTRA_USER_ID, UserHandle.myUserId()); } @Override protected void onApplyThemeResource(Resources.Theme theme, int resid, boolean first) { resid = SetupWizardUtils.getTheme(getIntent()); theme.applyStyle(R.style.SetupWizardPartnerResource, true); super.onApplyThemeResource(theme, resid, first); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putBoolean(EXTRA_KEY_LAUNCHED_CONFIRM, mLaunchedConfirmLock); outState.putByteArray(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, mToken); outState.putBoolean(EXTRA_FROM_SETTINGS_SUMMARY, mFromSettingsSummary); } @Override protected void onPostCreate(@Nullable Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); initViews(); } protected void initViews() { getWindow().setStatusBarColor(Color.TRANSPARENT); } protected GlifLayout getLayout() { return (GlifLayout) findViewById(R.id.setup_wizard_layout); } protected void setHeaderText(int resId, boolean force) { TextView layoutTitle = getLayout().getHeaderTextView(); CharSequence previousTitle = layoutTitle.getText(); CharSequence title = getText(resId); if (previousTitle != title || force) { if (!TextUtils.isEmpty(previousTitle)) { layoutTitle.setAccessibilityLiveRegion(View.ACCESSIBILITY_LIVE_REGION_POLITE); } getLayout().setHeaderText(title); setTitle(title); } } protected void setHeaderText(int resId) { setHeaderText(resId, false /* force */); } protected FooterButton getNextButton() { if (mFooterBarMixin != null) { return mFooterBarMixin.getPrimaryButton(); } return null; } protected void onNextButtonClick(View view) { } protected Intent getFingerprintEnrollingIntent() { Intent intent = new Intent(); intent.setClassName(SETTINGS_PACKAGE_NAME, FingerprintEnrollEnrolling.class.getName()); intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, mToken); intent.putExtra(EXTRA_FROM_SETTINGS_SUMMARY, mFromSettingsSummary); if (mUserId != UserHandle.USER_NULL) { intent.putExtra(Intent.EXTRA_USER_ID, mUserId); } return intent; } protected void launchConfirmLock(int titleResId, long challenge) { ChooseLockSettingsHelper helper = new ChooseLockSettingsHelper(this); boolean launchedConfirmationActivity; if (mUserId == UserHandle.USER_NULL) { launchedConfirmationActivity = helper.launchConfirmationActivity(CONFIRM_REQUEST, getString(titleResId), null, null, challenge, true /* foregroundOnly */); } else { launchedConfirmationActivity = helper.launchConfirmationActivity(CONFIRM_REQUEST, getString(titleResId), null, null, challenge, mUserId, true /* foregroundOnly */); } if (!launchedConfirmationActivity) { // This shouldn't happen, as we should only end up at this step if a lock thingy is // already set. finish(); } else { mLaunchedConfirmLock = true; } } }