public class

DeviceCredentialHandlerActivity

extends AppCompatActivity

Overview

Transparent activity that is responsible for re-launching the BiometricPrompt and handling results from in order to allow device credential authentication prior to Q.

Summary

Constructors
publicDeviceCredentialHandlerActivity()

Methods
protected voidonActivityResult(int requestCode, int resultCode, Intent data)

protected voidonCreate(Bundle savedInstanceState)

Perform initialization of all fragments.

protected voidonPause()

Dispatch onPause() to fragments.

from AppCompatActivityaddContentView, attachBaseContext, closeOptionsMenu, dispatchKeyEvent, findViewById, getDelegate, getDrawerToggleDelegate, getMenuInflater, getResources, getSupportActionBar, getSupportParentActivityIntent, invalidateOptionsMenu, onConfigurationChanged, onContentChanged, onCreateSupportNavigateUpTaskStack, onDestroy, onKeyDown, onLocalesChanged, onMenuItemSelected, onMenuOpened, onNightModeChanged, onPanelClosed, onPostCreate, onPostResume, onPrepareSupportNavigateUpTaskStack, onStart, onStop, onSupportActionModeFinished, onSupportActionModeStarted, onSupportContentChanged, onSupportNavigateUp, onTitleChanged, onWindowStartingSupportActionMode, openOptionsMenu, setContentView, setContentView, setContentView, setSupportActionBar, setSupportProgress, setSupportProgressBarIndeterminate, setSupportProgressBarIndeterminateVisibility, setSupportProgressBarVisibility, setTheme, startSupportActionMode, supportInvalidateOptionsMenu, supportNavigateUpTo, supportRequestWindowFeature, supportShouldUpRecreateTask
from FragmentActivitydump, getSupportFragmentManager, getSupportLoaderManager, onAttachFragment, onCreateView, onCreateView, onMenuItemSelected, onRequestPermissionsResult, onResume, onResumeFragments, onStateNotSaved, setEnterSharedElementCallback, setExitSharedElementCallback, startActivityFromFragment, startActivityFromFragment, startIntentSenderFromFragment, supportFinishAfterTransition, supportPostponeEnterTransition, supportStartPostponedEnterTransition, validateRequestPermissionsRequestCode
from ComponentActivityaddMenuProvider, addMenuProvider, addMenuProvider, addOnConfigurationChangedListener, addOnContextAvailableListener, addOnMultiWindowModeChangedListener, addOnNewIntentListener, addOnPictureInPictureModeChangedListener, addOnTrimMemoryListener, getActivityResultRegistry, getDefaultViewModelCreationExtras, getDefaultViewModelProviderFactory, getLastCustomNonConfigurationInstance, getLifecycle, getOnBackPressedDispatcher, getSavedStateRegistry, getViewModelStore, invalidateMenu, onBackPressed, onCreateOptionsMenu, onMultiWindowModeChanged, onMultiWindowModeChanged, onNewIntent, onOptionsItemSelected, onPictureInPictureModeChanged, onPictureInPictureModeChanged, onPrepareOptionsMenu, onRetainCustomNonConfigurationInstance, onRetainNonConfigurationInstance, onSaveInstanceState, onTrimMemory, peekAvailableContext, registerForActivityResult, registerForActivityResult, removeMenuProvider, removeOnConfigurationChangedListener, removeOnContextAvailableListener, removeOnMultiWindowModeChangedListener, removeOnNewIntentListener, removeOnPictureInPictureModeChangedListener, removeOnTrimMemoryListener, reportFullyDrawn, startActivityForResult, startActivityForResult, startIntentSenderForResult, startIntentSenderForResult
from ComponentActivitydispatchKeyShortcutEvent, getExtraData, putExtraData, shouldDumpInternalState, superDispatchKeyEvent
from java.lang.Objectclone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Constructors

public DeviceCredentialHandlerActivity()

Methods

protected void onCreate(Bundle savedInstanceState)

Perform initialization of all fragments.

protected void onPause()

Dispatch onPause() to fragments.

protected void onActivityResult(int requestCode, int resultCode, Intent data)

Deprecated: This method has been deprecated in favor of using the Activity Result API which brings increased type safety via an ActivityResultContract and the prebuilt contracts for common intents available in ActivityResultContracts, provides hooks for testing, and allow receiving results in separate, testable classes independent from your activity. Use ComponentActivity.registerForActivityResult(ActivityResultContract, ActivityResultCallback) with the appropriate ActivityResultContract and handling the result in the callback.

Source

/*
 * Copyright 2019 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 androidx.biometric;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;

import androidx.annotation.Nullable;
import androidx.annotation.RestrictTo;
import androidx.appcompat.app.AppCompatActivity;

/**
 * Transparent activity that is responsible for re-launching the {@link BiometricPrompt} and
 * handling results from {@link android.app.KeyguardManager#createConfirmDeviceCredentialIntent(
 * CharSequence, CharSequence)} in order to allow device credential authentication prior to Q.
 *
 * @hide
 */
@RestrictTo(RestrictTo.Scope.LIBRARY)
@SuppressLint("SyntheticAccessor")
public class DeviceCredentialHandlerActivity extends AppCompatActivity {
    private static final String TAG = "DeviceCredentialHandler";

    static final String EXTRA_PROMPT_INFO_BUNDLE = "prompt_info_bundle";

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        final DeviceCredentialHandlerBridge bridge = DeviceCredentialHandlerBridge.getInstance();

        // Apply the client activity's theme to ensure proper dialog styling.
        if (bridge.getClientThemeResId() != 0) {
            setTheme(bridge.getClientThemeResId());
            getTheme().applyStyle(R.style.TransparentStyle, true /* force */);
        }

        // Must be called after setting the theme.
        super.onCreate(savedInstanceState);
        setTitle(null);
        setContentView(R.layout.device_credential_handler_activity);

        if (bridge.getExecutor() == null || bridge.getAuthenticationCallback() == null) {
            Log.e(TAG, "onCreate: Executor and/or callback was null!");
        } else {
            // (Re)connect to and launch a biometric prompt within this activity.
            final BiometricPrompt biometricPrompt = new BiometricPrompt(this,
                    bridge.getExecutor(), bridge.getAuthenticationCallback());
            final Bundle infoBundle = getIntent().getBundleExtra(EXTRA_PROMPT_INFO_BUNDLE);
            final BiometricPrompt.PromptInfo info = new BiometricPrompt.PromptInfo(infoBundle);
            biometricPrompt.authenticate(info);
        }
    }

    @Override
    protected void onPause() {
        super.onPause();

        // Prevent the client from resetting the bridge in onPause if just changing configuration.
        final DeviceCredentialHandlerBridge bridge =
                DeviceCredentialHandlerBridge.getInstanceIfNotNull();
        if (isChangingConfigurations() && bridge != null) {
            bridge.ignoreNextReset();
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        handleDeviceCredentialResult(resultCode);
    }

    /**
     * Handles a result from the confirm device credential Settings activity.
     *
     * @param resultCode The (actual or simulated) result code from the device credential
     *                   Settings activity. Typically, either {@link android.app.Activity#RESULT_OK}
     *                   or {@link android.app.Activity#RESULT_CANCELED}.
     */
    void handleDeviceCredentialResult(int resultCode) {
        final DeviceCredentialHandlerBridge bridge =
                DeviceCredentialHandlerBridge.getInstanceIfNotNull();
        if (bridge == null) {
            Log.e(TAG, "onActivityResult: Bridge or callback was null!");
        } else if (resultCode == RESULT_OK) {
            bridge.setDeviceCredentialResult(DeviceCredentialHandlerBridge.RESULT_SUCCESS);
            bridge.setConfirmingDeviceCredential(false);
        } else {
            // Treat any non-OK result as a user cancellation.
            bridge.setDeviceCredentialResult(DeviceCredentialHandlerBridge.RESULT_ERROR);
            bridge.setConfirmingDeviceCredential(false);
        }

        finish();
    }
}