Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e5d19b38 authored by Weng Su's avatar Weng Su
Browse files

Skip authentication if device was unlocked recently

- Sync the same behavior from SystemUI to Settings

Bug: 365611488
Flag: EXEMPT bugfix
Test: Manual testing
atest -c WifiNetworkDetailsFragmentTest \
         WifiDetailPreferenceController2Test \
         WifiTetherSSIDPreferenceControllerTest \
         com.android.settings.wifi.dpp.WifiDppUtilsTest
atest -c com.android.settings.spa.wifi.dpp.WifiDppUtilsTest

Change-Id: Ie3e8374b1fdbbc61e9e5bbf0f5162b18ba1452f3
parent 626017d1
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -706,7 +706,7 @@ public class NetworkProviderSettings extends RestrictedDashboardFragment
                forget(mSelectedWifiEntry);
                return true;
            case MENU_ID_SHARE:
                WifiDppUtils.showLockScreen(getContext(),
                WifiDppUtils.showLockScreenForWifiSharing(getContext(),
                        () -> launchWifiDppConfiguratorActivity(mSelectedWifiEntry));
                return true;
            case MENU_ID_MODIFY:
+2 −1
Original line number Diff line number Diff line
@@ -57,7 +57,8 @@ public class AddDevicePreferenceController2 extends BasePreferenceController {
    @Override
    public boolean handlePreferenceTreeClick(Preference preference) {
        if (KEY_ADD_DEVICE.equals(preference.getKey())) {
            WifiDppUtils.showLockScreen(mContext, () -> launchWifiDppConfiguratorQrCodeScanner());
            WifiDppUtils.showLockScreenForWifiSharing(mContext,
                    () -> launchWifiDppConfiguratorQrCodeScanner());
            return true; /* click is handled */
        }

+2 −1
Original line number Diff line number Diff line
@@ -980,7 +980,8 @@ public class WifiDetailPreferenceController2 extends AbstractPreferenceControlle
     * Share the wifi network with QR code.
     */
    private void shareNetwork() {
        WifiDppUtils.showLockScreen(mContext, () -> launchWifiDppConfiguratorActivity());
        WifiDppUtils.showLockScreenForWifiSharing(mContext,
                () -> launchWifiDppConfiguratorActivity());
    }

    /**
+79 −40
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.settings.wifi.dpp;

import android.annotation.NonNull;
import android.annotation.SuppressLint;
import android.app.KeyguardManager;
import android.content.Context;
import android.content.Intent;
@@ -33,6 +35,9 @@ import android.os.Vibrator;
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyProperties;
import android.text.TextUtils;
import android.util.Log;

import androidx.annotation.VisibleForTesting;

import com.android.settings.R;
import com.android.settings.Utils;
@@ -58,6 +63,8 @@ import javax.crypto.SecretKey;
 * @see WifiQrCode
 */
public class WifiDppUtils {
    private static final String TAG = "WifiDppUtils";

    /**
     * The fragment tag specified to FragmentManager for container activities to manage fragments.
     */
@@ -109,7 +116,15 @@ public class WifiDppUtils {

    private static final Duration VIBRATE_DURATION_QR_CODE_RECOGNITION = Duration.ofMillis(3);

    private static final String AES_CBC_PKCS7_PADDING = "AES/CBC/PKCS7Padding";
    /**
     * Parameters to check whether the device has been locked recently
     */
    @VisibleForTesting
    public static final String AES_CBC_PKCS7_PADDING = "AES/CBC/PKCS7Padding";
    @VisibleForTesting
    public static final String WIFI_SHARING_KEY_ALIAS = "wifi_sharing_auth_key";
    @VisibleForTesting
    public static final int WIFI_SHARING_MAX_UNLOCK_SECONDS = 60;

    /**
     * Returns whether the device support WiFi DPP.
@@ -430,12 +445,43 @@ public class WifiDppUtils {
     * @param successRunnable The {@code Runnable} which will be executed if the user does not setup
     *                        device security or if lock screen is unlocked
     */
    public static void showLockScreen(Context context, Runnable successRunnable) {
        final KeyguardManager keyguardManager = (KeyguardManager) context.getSystemService(
                Context.KEYGUARD_SERVICE);
    public static void showLockScreen(@NonNull Context context, @NonNull Runnable successRunnable) {
        KeyguardManager keyguardManager = context.getSystemService(KeyguardManager.class);
        if (keyguardManager == null || !keyguardManager.isKeyguardSecure()) {
            successRunnable.run();
            return;
        }
        showLockScreen(context, successRunnable, keyguardManager);
    }

        if (keyguardManager.isKeyguardSecure()) {
            final BiometricPrompt.AuthenticationCallback authenticationCallback =
    /**
     * Shows authentication screen to confirm credentials (pin, pattern or password) for the
     * current user of the device. But if the device has been unlocked recently, the
     * authentication screen will be skipped.
     *
     * @param context         The {@code Context} used to get {@code KeyguardManager} service
     * @param successRunnable The {@code Runnable} which will be executed if the user does not setup
     *                        device security or if lock screen is unlocked
     */
    public static void showLockScreenForWifiSharing(@NonNull Context context,
            @NonNull Runnable successRunnable) {
        KeyguardManager keyguardManager = context.getSystemService(KeyguardManager.class);
        if (keyguardManager == null || !keyguardManager.isKeyguardSecure()) {
            successRunnable.run();
            return;
        }
        if (isUnlockedWithinSeconds(WIFI_SHARING_KEY_ALIAS, WIFI_SHARING_MAX_UNLOCK_SECONDS)) {
            Log.d(TAG, "Bypassing the lock screen because the device was unlocked recently.");
            successRunnable.run();
            return;
        }
        showLockScreen(context, successRunnable, keyguardManager);
    }

    @SuppressLint("MissingPermission")
    private static void showLockScreen(@NonNull Context context, @NonNull Runnable successRunnable,
            @NonNull KeyguardManager keyguardManager) {
        BiometricPrompt.AuthenticationCallback authenticationCallback =
                new BiometricPrompt.AuthenticationCallback() {
                    @Override
                    public void onAuthenticationSucceeded(
@@ -448,12 +494,9 @@ public class WifiDppUtils {
                        //Do nothing
                    }
                };

            final int userId = UserHandle.myUserId();

            final BiometricPrompt.Builder builder = new BiometricPrompt.Builder(context)
        int userId = UserHandle.myUserId();
        BiometricPrompt.Builder builder = new BiometricPrompt.Builder(context)
                .setTitle(context.getText(R.string.wifi_dpp_lockscreen_title));

        if (keyguardManager.isDeviceSecure()) {
            builder.setDeviceCredentialAllowed(true);
            builder.setTextForDeviceCredential(
@@ -462,15 +505,11 @@ public class WifiDppUtils {
                            context, userId, Utils.getCredentialType(context, userId)),
                    null /* description */);
        }

            final BiometricPrompt bp = builder.build();
            final Handler handler = new Handler(Looper.getMainLooper());
        BiometricPrompt bp = builder.build();
        Handler handler = new Handler(Looper.getMainLooper());
        bp.authenticate(new CancellationSignal(),
                runnable -> handler.post(runnable),
                authenticationCallback);
        } else {
            successRunnable.run();
        }
    }

    /**
+1 −1
Original line number Diff line number Diff line
@@ -123,7 +123,7 @@ public class WifiTetherSSIDPreferenceController extends WifiTetherBasePreference
    }

    private void shareHotspotNetwork(Intent intent) {
        WifiDppUtils.showLockScreen(mContext, () -> {
        WifiDppUtils.showLockScreenForWifiSharing(mContext, () -> {
            mMetricsFeatureProvider.action(SettingsEnums.PAGE_UNKNOWN,
                    SettingsEnums.ACTION_SETTINGS_SHARE_WIFI_HOTSPOT_QR_CODE,
                    SettingsEnums.SETTINGS_WIFI_DPP_CONFIGURATOR,
Loading