diff --git a/res/layout/search_bar_two_pane_version.xml b/res/layout/search_bar_two_pane_version.xml index f98985ce46d..337294e0280 100644 --- a/res/layout/search_bar_two_pane_version.xml +++ b/res/layout/search_bar_two_pane_version.xml @@ -29,6 +29,9 @@ android:paddingStart="@dimen/search_bar_padding_start_two_pane" android:paddingEnd="@dimen/search_bar_padding_end_two_pane" android:background="@drawable/search_bar_selected_background" + android:focusable="true" + android:focusableInTouchMode="true" + android:nextFocusForward="@+id/homepage_container" android:contentInsetStartWithNavigation="@dimen/search_bar_content_inset" android:navigationIcon="@drawable/ic_homepage_search"> - \ No newline at end of file + diff --git a/res/values/config.xml b/res/values/config.xml index 9d7167101d7..afd6fdd16d2 100644 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -679,6 +679,13 @@ 0.3636 + + 600 + + + 720 + diff --git a/res/values/strings.xml b/res/values/strings.xml index 5873b1abe8c..ad35e26d0d5 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -132,6 +132,8 @@ Pair new device bluetooth + + Automatically turn on again tomorrow @@ -1370,6 +1372,12 @@ Set a password for your private space Set a pattern for your private space + + Apps and notifications + + Sensitive notifications on lock screen + + Show sensitive content when private space is unlocked You can add up to %d fingerprints @@ -1800,8 +1808,12 @@ Pair & connect When Bluetooth is turned on, your device can communicate with other nearby Bluetooth devices + + When Bluetooth is on, your device can communicate with other nearby Bluetooth devices. Features like Quick Share, Find My Device, and device location use Bluetooth. When Bluetooth is turned on, your device can communicate with other nearby Bluetooth devices.\n\nTo improve device experience, apps and services can still scan for nearby devices at any time, even when Bluetooth is off. This can be used, for example, to improve location-based features and services. You can change this in Bluetooth scanning settings. + + When Bluetooth is on, your device can communicate with other nearby Bluetooth devices. Features like Quick Share, Find My Device, and device location use Bluetooth.\n\nApps and services can still scan for nearby devices at any time, even when Bluetooth is off. This can be used, for example, to improve location-based features and services. You can change this in Bluetooth scanning settings. Change @@ -5144,7 +5156,7 @@ About hearing devices - Make sure your hearing device is turned on and ready to pair + Make sure your hearing device is turned on and ready to pair. Only ASHA and LE Audio hearing devices show on this page. Pair hearing device @@ -11580,7 +11592,7 @@ Calls Texts - + Automatic data switching Use data from either SIM depending on coverage and availability diff --git a/res/xml/bluetooth_screen.xml b/res/xml/bluetooth_screen.xml index 86dc8a12c72..51507fb0ba1 100644 --- a/res/xml/bluetooth_screen.xml +++ b/res/xml/bluetooth_screen.xml @@ -18,6 +18,11 @@ xmlns:settings="http://schemas.android.com/apk/res-auto" android:title="@string/bluetooth_settings_title"> + + - @@ -77,12 +77,12 @@ android:key="time_format_preference_category" android:title="@string/time_format_category_title" settings:keywords="@string/keywords_time_format"> - - diff --git a/res/xml/private_space_settings.xml b/res/xml/private_space_settings.xml index 0ed9c93fb84..e718ca81a6b 100644 --- a/res/xml/private_space_settings.xml +++ b/res/xml/private_space_settings.xml @@ -59,6 +59,17 @@ + + + + + + diff --git a/src/com/android/settings/activityembedding/ActivityEmbeddingRulesController.java b/src/com/android/settings/activityembedding/ActivityEmbeddingRulesController.java index 50134ba7eb6..4e39070febd 100644 --- a/src/com/android/settings/activityembedding/ActivityEmbeddingRulesController.java +++ b/src/com/android/settings/activityembedding/ActivityEmbeddingRulesController.java @@ -113,8 +113,9 @@ public class ActivityEmbeddingRulesController { .setFinishPrimaryWithSecondary(finishPrimaryWithSecondary) .setFinishSecondaryWithPrimary(finishSecondaryWithPrimary) .setClearTop(clearTop) - .setMinWidthDp(ActivityEmbeddingUtils.getMinCurrentScreenSplitWidthDp()) - .setMinSmallestWidthDp(ActivityEmbeddingUtils.getMinSmallestScreenSplitWidthDp()) + .setMinWidthDp(ActivityEmbeddingUtils.getMinCurrentScreenSplitWidthDp(context)) + .setMinSmallestWidthDp( + ActivityEmbeddingUtils.getMinSmallestScreenSplitWidthDp(context)) .setMaxAspectRatioInPortrait(EmbeddingAspectRatio.ALWAYS_ALLOW) .setDefaultSplitAttributes(attributes) .build(); @@ -234,8 +235,9 @@ public class ActivityEmbeddingRulesController { .build(); final SplitPlaceholderRule placeholderRule = new SplitPlaceholderRule.Builder( activityFilters, intent) - .setMinWidthDp(ActivityEmbeddingUtils.getMinCurrentScreenSplitWidthDp()) - .setMinSmallestWidthDp(ActivityEmbeddingUtils.getMinSmallestScreenSplitWidthDp()) + .setMinWidthDp(ActivityEmbeddingUtils.getMinCurrentScreenSplitWidthDp(mContext)) + .setMinSmallestWidthDp( + ActivityEmbeddingUtils.getMinSmallestScreenSplitWidthDp(mContext)) .setMaxAspectRatioInPortrait(EmbeddingAspectRatio.ALWAYS_ALLOW) .setSticky(false) .setFinishPrimaryWithPlaceholder(SplitRule.FinishBehavior.ADJACENT) diff --git a/src/com/android/settings/activityembedding/ActivityEmbeddingUtils.java b/src/com/android/settings/activityembedding/ActivityEmbeddingUtils.java index 74a967332da..b91e0e5eacd 100644 --- a/src/com/android/settings/activityembedding/ActivityEmbeddingUtils.java +++ b/src/com/android/settings/activityembedding/ActivityEmbeddingUtils.java @@ -33,11 +33,6 @@ import com.google.android.setupcompat.util.WizardManagerHelper; /** An util class collecting all common methods for the embedding activity features. */ public class ActivityEmbeddingUtils { - // The smallest value of current width of the window when the split should be used. - private static final int MIN_CURRENT_SCREEN_SPLIT_WIDTH_DP = 720; - // The smallest value of the smallest-width (sw) of the window in any rotation when - // the split should be used. - private static final int MIN_SMALLEST_SCREEN_SPLIT_WIDTH_DP = 600; // The minimum width of the activity to show the regular homepage layout. private static final float MIN_REGULAR_HOMEPAGE_LAYOUT_WIDTH_DP = 380f; @@ -58,16 +53,16 @@ public class ActivityEmbeddingUtils { private static final String TAG = "ActivityEmbeddingUtils"; /** Get the smallest width dp of the window when the split should be used. */ - public static int getMinCurrentScreenSplitWidthDp() { - return MIN_CURRENT_SCREEN_SPLIT_WIDTH_DP; + public static int getMinCurrentScreenSplitWidthDp(Context context) { + return context.getResources().getInteger(R.integer.config_activity_embed_split_min_cur_dp); } /** * Get the smallest dp value of the smallest-width (sw) of the window in any rotation when * the split should be used. */ - public static int getMinSmallestScreenSplitWidthDp() { - return MIN_SMALLEST_SCREEN_SPLIT_WIDTH_DP; + public static int getMinSmallestScreenSplitWidthDp(Context context) { + return context.getResources().getInteger(R.integer.config_activity_embed_split_min_sw_dp); } /** diff --git a/src/com/android/settings/biometrics/BiometricUtils.java b/src/com/android/settings/biometrics/BiometricUtils.java index 53892bd9a1c..3376d86c115 100644 --- a/src/com/android/settings/biometrics/BiometricUtils.java +++ b/src/com/android/settings/biometrics/BiometricUtils.java @@ -25,6 +25,7 @@ import android.app.admin.DevicePolicyManager; import android.content.Context; import android.content.Intent; import android.content.IntentSender; +import android.hardware.biometrics.BiometricManager; import android.hardware.biometrics.SensorProperties; import android.hardware.face.FaceManager; import android.hardware.face.FaceSensorPropertiesInternal; @@ -65,6 +66,7 @@ import java.lang.annotation.RetentionPolicy; */ public class BiometricUtils { private static final String TAG = "BiometricUtils"; + public static final String EXTRA_ENROLL_REASON = BiometricManager.EXTRA_ENROLL_REASON; /** The character ' • ' to separate the setup choose options */ public static final String SEPARATOR = " \u2022 "; diff --git a/src/com/android/settings/biometrics/face/FaceEnrollEducation.java b/src/com/android/settings/biometrics/face/FaceEnrollEducation.java index 62e9757b365..6862bc921d7 100644 --- a/src/com/android/settings/biometrics/face/FaceEnrollEducation.java +++ b/src/com/android/settings/biometrics/face/FaceEnrollEducation.java @@ -265,6 +265,8 @@ public class FaceEnrollEducation extends BiometricEnrollBase { } intent.putExtra(EXTRA_KEY_REQUIRE_DIVERSITY, !mSwitchDiversity.isChecked()); + intent.putExtra(BiometricUtils.EXTRA_ENROLL_REASON, + getIntent().getIntExtra(BiometricUtils.EXTRA_ENROLL_REASON, -1)); if (!mSwitchDiversity.isChecked() && mAccessibilityEnabled) { FaceEnrollAccessibilityDialog dialog = FaceEnrollAccessibilityDialog.newInstance(); diff --git a/src/com/android/settings/biometrics/face/FaceEnrollEnrolling.java b/src/com/android/settings/biometrics/face/FaceEnrollEnrolling.java index e8bd0efea26..da3689a6b95 100644 --- a/src/com/android/settings/biometrics/face/FaceEnrollEnrolling.java +++ b/src/com/android/settings/biometrics/face/FaceEnrollEnrolling.java @@ -165,7 +165,7 @@ public class FaceEnrollEnrolling extends BiometricsEnrollEnrolling { disabledFeatures[i] = mDisabledFeatures.get(i); } - return new FaceEnrollSidecar(disabledFeatures); + return new FaceEnrollSidecar(disabledFeatures, getIntent()); } @Override diff --git a/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java b/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java index eb50e0874c0..b0996a4f2b6 100644 --- a/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java +++ b/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java @@ -484,6 +484,9 @@ public class FaceEnrollIntroduction extends BiometricEnrollIntroduction { protected Intent getEnrollingIntent() { Intent intent = new Intent(this, FaceEnrollEducation.class); WizardManagerHelper.copyWizardManagerExtras(getIntent(), intent); + intent.putExtra(BiometricUtils.EXTRA_ENROLL_REASON, + getIntent().getIntExtra(BiometricUtils.EXTRA_ENROLL_REASON, -1)); + return intent; } diff --git a/src/com/android/settings/biometrics/face/FaceEnrollSidecar.java b/src/com/android/settings/biometrics/face/FaceEnrollSidecar.java index de713dd3386..b7ba1b52508 100644 --- a/src/com/android/settings/biometrics/face/FaceEnrollSidecar.java +++ b/src/com/android/settings/biometrics/face/FaceEnrollSidecar.java @@ -18,6 +18,7 @@ package com.android.settings.biometrics.face; import android.app.Activity; import android.app.settings.SettingsEnums; +import android.content.Intent; import android.hardware.face.FaceManager; import com.android.settings.biometrics.BiometricEnrollSidecar; @@ -33,8 +34,11 @@ public class FaceEnrollSidecar extends BiometricEnrollSidecar { private FaceUpdater mFaceUpdater; - public FaceEnrollSidecar(int[] disabledFeatures) { + private Intent mIntent; + + public FaceEnrollSidecar(int[] disabledFeatures, Intent intent) { mDisabledFeatures = Arrays.copyOf(disabledFeatures, disabledFeatures.length); + mIntent = intent; } @Override @@ -47,7 +51,7 @@ public class FaceEnrollSidecar extends BiometricEnrollSidecar { public void startEnrollment() { super.startEnrollment(); mFaceUpdater.enroll(mUserId, mToken, mEnrollmentCancel, - mEnrollmentCallback, mDisabledFeatures); + mEnrollmentCallback, mDisabledFeatures, mIntent); } private FaceManager.EnrollmentCallback mEnrollmentCallback diff --git a/src/com/android/settings/biometrics/face/FaceUpdater.java b/src/com/android/settings/biometrics/face/FaceUpdater.java index 57c11953d6a..ddb68129df1 100644 --- a/src/com/android/settings/biometrics/face/FaceUpdater.java +++ b/src/com/android/settings/biometrics/face/FaceUpdater.java @@ -17,8 +17,10 @@ package com.android.settings.biometrics.face; import android.content.Context; +import android.content.Intent; import android.hardware.face.Face; import android.hardware.face.FaceEnrollCell; +import android.hardware.face.FaceEnrollOptions; import android.hardware.face.FaceManager; import android.os.CancellationSignal; import android.view.Surface; @@ -26,6 +28,7 @@ import android.view.Surface; import androidx.annotation.Nullable; import com.android.settings.Utils; +import com.android.settings.biometrics.BiometricUtils; import com.android.settings.safetycenter.BiometricsSafetySource; /** @@ -49,19 +52,19 @@ public class FaceUpdater { /** Wrapper around the {@link FaceManager#enroll} method. */ public void enroll(int userId, byte[] hardwareAuthToken, CancellationSignal cancel, - FaceManager.EnrollmentCallback callback, int[] disabledFeatures) { + FaceManager.EnrollmentCallback callback, int[] disabledFeatures, Intent intent) { this.enroll(userId, hardwareAuthToken, cancel, new NotifyingEnrollmentCallback(mContext, callback), disabledFeatures, - null, false); + null, false, intent); } /** Wrapper around the {@link FaceManager#enroll} method. */ public void enroll(int userId, byte[] hardwareAuthToken, CancellationSignal cancel, FaceManager.EnrollmentCallback callback, int[] disabledFeatures, - @Nullable Surface previewSurface, boolean debugConsent) { + @Nullable Surface previewSurface, boolean debugConsent, Intent intent) { mFaceManager.enroll(userId, hardwareAuthToken, cancel, new NotifyingEnrollmentCallback(mContext, callback), disabledFeatures, - previewSurface, debugConsent); + previewSurface, debugConsent, toFaceEnrollOptions(intent)); } /** Wrapper around the {@link FaceManager#remove} method. */ @@ -135,4 +138,14 @@ public class FaceUpdater { BiometricsSafetySource.onBiometricsChanged(mContext); // biometrics data changed } } + + private FaceEnrollOptions toFaceEnrollOptions(Intent intent) { + final int reason = intent.getIntExtra(BiometricUtils.EXTRA_ENROLL_REASON, -1); + final FaceEnrollOptions.Builder builder = new FaceEnrollOptions.Builder(); + builder.setEnrollReason(FaceEnrollOptions.ENROLL_REASON_UNKNOWN); + if (reason != -1) { + builder.setEnrollReason(reason); + } + return builder.build(); + } } diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java index 175e8f908ba..90b93461b9c 100644 --- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java +++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java @@ -352,7 +352,7 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling { @Override protected BiometricEnrollSidecar getSidecar() { final FingerprintEnrollSidecar sidecar = new FingerprintEnrollSidecar(this, - FingerprintManager.ENROLL_ENROLL); + FingerprintManager.ENROLL_ENROLL, getIntent()); return sidecar; } diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFindSensor.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFindSensor.java index be3a769839e..6b7538ae220 100644 --- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFindSensor.java +++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFindSensor.java @@ -292,6 +292,8 @@ public class FingerprintEnrollFindSensor extends BiometricEnrollBase implements @Override protected Intent getFingerprintEnrollingIntent() { final Intent ret = super.getFingerprintEnrollingIntent(); + ret.putExtra(BiometricUtils.EXTRA_ENROLL_REASON, + getIntent().getIntExtra(BiometricUtils.EXTRA_ENROLL_REASON, -1)); if (Flags.udfpsEnrollCalibration()) { if (mCalibrator != null) { ret.putExtras(mCalibrator.getExtrasForNextIntent(true)); @@ -349,7 +351,7 @@ public class FingerprintEnrollFindSensor extends BiometricEnrollBase implements FingerprintEnrollEnrolling.TAG_SIDECAR); if (mSidecar == null) { mSidecar = new FingerprintEnrollSidecar(this, - FingerprintManager.ENROLL_FIND_SENSOR); + FingerprintManager.ENROLL_FIND_SENSOR, getIntent()); getSupportFragmentManager().beginTransaction() .add(mSidecar, FingerprintEnrollEnrolling.TAG_SIDECAR) .commitAllowingStateLoss(); diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroduction.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroduction.java index 242b7450c4d..f92cfbf6696 100644 --- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroduction.java +++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroduction.java @@ -59,7 +59,6 @@ import com.google.android.setupdesign.util.DeviceHelper; import java.util.List; public class FingerprintEnrollIntroduction extends BiometricEnrollIntroduction { - private static final String TAG = "FingerprintIntro"; @VisibleForTesting @@ -388,6 +387,8 @@ public class FingerprintEnrollIntroduction extends BiometricEnrollIntroduction { intent.putExtras(mCalibrator.getExtrasForNextIntent(false)); } } + intent.putExtra(BiometricUtils.EXTRA_ENROLL_REASON, + getIntent().getIntExtra(BiometricUtils.EXTRA_ENROLL_REASON, -1)); return intent; } diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollSidecar.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollSidecar.java index 493302bd13c..52d7d2be7a3 100644 --- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollSidecar.java +++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollSidecar.java @@ -21,6 +21,8 @@ import static android.hardware.fingerprint.FingerprintManager.ENROLL_ENROLL; import android.app.Activity; import android.app.settings.SettingsEnums; import android.content.Context; +import android.content.Intent; +import android.hardware.fingerprint.FingerprintEnrollOptions; import android.hardware.fingerprint.FingerprintManager; import android.os.SystemClock; import android.util.Log; @@ -28,6 +30,9 @@ import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.settings.R; import com.android.settings.biometrics.BiometricEnrollSidecar; +import com.android.settings.biometrics.BiometricUtils; + +import com.google.android.setupcompat.util.WizardManagerHelper; /** * Sidecar fragment to handle the state around fingerprint enrollment. @@ -39,15 +44,18 @@ public class FingerprintEnrollSidecar extends BiometricEnrollSidecar { private @FingerprintManager.EnrollReason int mEnrollReason; private final MessageDisplayController mMessageDisplayController; private final boolean mMessageDisplayControllerFlag; + private final Intent mIntent; /** * Create a new FingerprintEnrollSidecar object. - * @param context associated context + * + * @param context associated context * @param enrollReason reason for enrollment */ public FingerprintEnrollSidecar(Context context, - @FingerprintManager.EnrollReason int enrollReason) { + @FingerprintManager.EnrollReason int enrollReason, Intent intent) { mEnrollReason = enrollReason; + mIntent = intent; int helpMinimumDisplayTime = context.getResources().getInteger( R.integer.enrollment_help_minimum_time_display); @@ -85,14 +93,21 @@ public class FingerprintEnrollSidecar extends BiometricEnrollSidecar { return; } + if (mIntent.getIntExtra(BiometricUtils.EXTRA_ENROLL_REASON, -1) == -1) { + final boolean isSuw = WizardManagerHelper.isAnySetupWizard(mIntent); + mIntent.putExtra(BiometricUtils.EXTRA_ENROLL_REASON, + isSuw ? FingerprintEnrollOptions.ENROLL_REASON_SUW : + FingerprintEnrollOptions.ENROLL_REASON_SETTINGS); + } + if (mEnrollReason == ENROLL_ENROLL && mMessageDisplayControllerFlag) { //API calls need to be processed for {@link FingerprintEnrollEnrolling} mFingerprintUpdater.enroll(mToken, mEnrollmentCancel, mUserId, - mMessageDisplayController, mEnrollReason); + mMessageDisplayController, mEnrollReason, mIntent); } else { //No processing required for {@link FingerprintEnrollFindSensor} mFingerprintUpdater.enroll(mToken, mEnrollmentCancel, mUserId, mEnrollmentCallback, - mEnrollReason); + mEnrollReason, mIntent); } } @@ -100,7 +115,8 @@ public class FingerprintEnrollSidecar extends BiometricEnrollSidecar { mEnrollReason = enrollReason; } - @VisibleForTesting FingerprintManager.EnrollmentCallback mEnrollmentCallback + @VisibleForTesting + FingerprintManager.EnrollmentCallback mEnrollmentCallback = new FingerprintManager.EnrollmentCallback() { @Override diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintUpdater.java b/src/com/android/settings/biometrics/fingerprint/FingerprintUpdater.java index 306b1a3e136..ea9abf1bb5c 100644 --- a/src/com/android/settings/biometrics/fingerprint/FingerprintUpdater.java +++ b/src/com/android/settings/biometrics/fingerprint/FingerprintUpdater.java @@ -17,13 +17,16 @@ package com.android.settings.biometrics.fingerprint; import android.content.Context; +import android.content.Intent; import android.hardware.fingerprint.Fingerprint; +import android.hardware.fingerprint.FingerprintEnrollOptions; import android.hardware.fingerprint.FingerprintManager; import android.os.CancellationSignal; import androidx.annotation.Nullable; import com.android.settings.Utils; +import com.android.settings.biometrics.BiometricUtils; import com.android.settings.safetycenter.BiometricsSafetySource; /** @@ -48,9 +51,10 @@ public class FingerprintUpdater { /** Wrapper around the {@link FingerprintManager#enroll} method. */ public void enroll(byte [] hardwareAuthToken, CancellationSignal cancel, int userId, FingerprintManager.EnrollmentCallback callback, - @FingerprintManager.EnrollReason int enrollReason) { + @FingerprintManager.EnrollReason int enrollReason, Intent intent) { mFingerprintManager.enroll(hardwareAuthToken, cancel, userId, - new NotifyingEnrollmentCallback(mContext, callback), enrollReason); + new NotifyingEnrollmentCallback(mContext, callback), enrollReason, + toFingerprintEnrollOptions(intent)); } /** Wrapper around the {@link FingerprintManager#remove} method. */ @@ -138,4 +142,14 @@ public class FingerprintUpdater { BiometricsSafetySource.onBiometricsChanged(mContext); // biometrics data changed } } + + private FingerprintEnrollOptions toFingerprintEnrollOptions(Intent intent) { + final int reason = intent.getIntExtra(BiometricUtils.EXTRA_ENROLL_REASON, -1); + final FingerprintEnrollOptions.Builder builder = new FingerprintEnrollOptions.Builder(); + builder.setEnrollReason(FingerprintEnrollOptions.ENROLL_REASON_UNKNOWN); + if (reason != -1) { + builder.setEnrollReason(reason); + } + return builder.build(); + } } diff --git a/src/com/android/settings/biometrics/fingerprint/feature/SfpsEnrollmentFeatureImpl.java b/src/com/android/settings/biometrics/fingerprint/feature/SfpsEnrollmentFeatureImpl.java index abc31c94580..60ced6e95f1 100644 --- a/src/com/android/settings/biometrics/fingerprint/feature/SfpsEnrollmentFeatureImpl.java +++ b/src/com/android/settings/biometrics/fingerprint/feature/SfpsEnrollmentFeatureImpl.java @@ -33,11 +33,14 @@ import android.view.animation.AccelerateInterpolator; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import com.android.internal.annotations.VisibleForTesting; import com.android.settings.R; import java.util.function.Function; public class SfpsEnrollmentFeatureImpl implements SfpsEnrollmentFeature { + @VisibleForTesting + public static final int HELP_ANIMATOR_DURATION = 550; @Nullable private FingerprintManager mFingerprintManager = null; @@ -96,12 +99,11 @@ public class SfpsEnrollmentFeatureImpl implements SfpsEnrollmentFeature { @Override public Animator getHelpAnimator(@NonNull View target) { final float translationX = 40; - final int duration = 550; final ObjectAnimator help = ObjectAnimator.ofFloat(target, "translationX" /* propertyName */, 0, translationX, -1 * translationX, translationX, 0f); help.setInterpolator(new AccelerateInterpolator()); - help.setDuration(duration); + help.setDuration(HELP_ANIMATOR_DURATION); help.setAutoCancel(false); return help; } diff --git a/src/com/android/settings/biometrics/fingerprint2/domain/interactor/FingerprintManagerInteractorImpl.kt b/src/com/android/settings/biometrics/fingerprint2/domain/interactor/FingerprintManagerInteractorImpl.kt index 135a36ce538..900f7cfb734 100644 --- a/src/com/android/settings/biometrics/fingerprint2/domain/interactor/FingerprintManagerInteractorImpl.kt +++ b/src/com/android/settings/biometrics/fingerprint2/domain/interactor/FingerprintManagerInteractorImpl.kt @@ -18,12 +18,16 @@ package com.android.settings.biometrics.fingerprint2.domain.interactor import android.content.Context import android.content.Intent +import android.hardware.biometrics.BiometricConstants; +import android.hardware.biometrics.BiometricFingerprintConstants +import android.hardware.fingerprint.FingerprintEnrollOptions; import android.hardware.fingerprint.FingerprintManager import android.hardware.fingerprint.FingerprintManager.GenerateChallengeCallback import android.hardware.fingerprint.FingerprintManager.RemovalCallback import android.os.CancellationSignal import android.util.Log import com.android.settings.biometrics.GatekeeperPasswordProvider +import com.android.settings.biometrics.BiometricUtils import com.android.settings.biometrics.fingerprint2.conversion.Util.toEnrollError import com.android.settings.biometrics.fingerprint2.conversion.Util.toOriginalReason import com.android.settings.biometrics.fingerprint2.data.repository.FingerprintSensorRepository @@ -35,6 +39,8 @@ import com.android.settings.biometrics.fingerprint2.lib.model.FingerprintData import com.android.settings.biometrics.fingerprint2.lib.model.FingerprintFlow import com.android.settings.biometrics.fingerprint2.lib.model.SetupWizard import com.android.settings.password.ChooseLockSettingsHelper +import com.android.systemui.biometrics.shared.model.toFingerprintSensor +import com.google.android.setupcompat.util.WizardManagerHelper import kotlin.coroutines.resume import kotlin.coroutines.suspendCoroutine import kotlinx.coroutines.CancellableContinuation @@ -60,6 +66,7 @@ class FingerprintManagerInteractorImpl( private val gatekeeperPasswordProvider: GatekeeperPasswordProvider, private val pressToAuthInteractor: PressToAuthInteractor, private val fingerprintFlow: FingerprintFlow, + private val intent: Intent, ) : FingerprintManagerInteractor { private val maxFingerprints = @@ -158,12 +165,21 @@ class FingerprintManagerInteractorImpl( } val cancellationSignal = CancellationSignal() + + if (intent.getIntExtra(BiometricUtils.EXTRA_ENROLL_REASON, -1) === -1) { + val isSuw: Boolean = WizardManagerHelper.isAnySetupWizard(intent) + intent.putExtra(BiometricUtils.EXTRA_ENROLL_REASON, + if (isSuw) FingerprintEnrollOptions.ENROLL_REASON_SUW else + FingerprintEnrollOptions.ENROLL_REASON_SETTINGS) + } + fingerprintManager.enroll( hardwareAuthToken, cancellationSignal, applicationContext.userId, enrollmentCallback, enrollReason.toOriginalReason(), + toFingerprintEnrollOptions(intent) ) awaitClose { // If the stream has not been ended, and the user has stopped collecting the flow @@ -244,4 +260,15 @@ class FingerprintManagerInteractorImpl( applicationContext.userId, ) } + + private fun toFingerprintEnrollOptions(intent: Intent): FingerprintEnrollOptions { + val reason: Int = + intent.getIntExtra(BiometricUtils.EXTRA_ENROLL_REASON, -1) + val builder: FingerprintEnrollOptions.Builder = FingerprintEnrollOptions.Builder() + builder.setEnrollReason(FingerprintEnrollOptions.ENROLL_REASON_UNKNOWN) + if (reason != -1) { + builder.setEnrollReason(reason) + } + return builder.build() + } } diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/activity/FingerprintEnrollmentV2Activity.kt b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/activity/FingerprintEnrollmentV2Activity.kt index 9f3935bf070..65030de3f07 100644 --- a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/activity/FingerprintEnrollmentV2Activity.kt +++ b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/activity/FingerprintEnrollmentV2Activity.kt @@ -191,6 +191,7 @@ class FingerprintEnrollmentV2Activity : FragmentActivity() { GatekeeperPasswordProvider(LockPatternUtils(context)), pressToAuthInteractor, enrollType, + getIntent(), ) var challenge: Long? = intent.getExtra(BiometricEnrollBase.EXTRA_KEY_CHALLENGE) as Long? diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/settings/fragment/FingerprintSettingsV2Fragment.kt b/src/com/android/settings/biometrics/fingerprint2/ui/settings/fragment/FingerprintSettingsV2Fragment.kt index a5f20212180..bd905242fc3 100644 --- a/src/com/android/settings/biometrics/fingerprint2/ui/settings/fragment/FingerprintSettingsV2Fragment.kt +++ b/src/com/android/settings/biometrics/fingerprint2/ui/settings/fragment/FingerprintSettingsV2Fragment.kt @@ -232,6 +232,7 @@ class FingerprintSettingsV2Fragment : GatekeeperPasswordProvider(LockPatternUtils(context.applicationContext)), pressToAuthInteractor, Settings, + getIntent() ) val token = intent.getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN) diff --git a/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollProgressViewModel.java b/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollProgressViewModel.java index 9b25ee8f0a1..1cfec52df69 100644 --- a/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollProgressViewModel.java +++ b/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollProgressViewModel.java @@ -23,6 +23,7 @@ import static com.android.settings.biometrics2.ui.model.EnrollmentProgress.INITI import static com.android.settings.biometrics2.ui.model.EnrollmentProgress.INITIAL_STEPS; import android.app.Application; +import android.content.Intent; import android.content.res.Resources; import android.hardware.fingerprint.FingerprintManager.EnrollReason; import android.hardware.fingerprint.FingerprintManager.EnrollmentCallback; @@ -212,10 +213,11 @@ public class FingerprintEnrollProgressViewModel extends AndroidViewModel { res.getBoolean(R.bool.enrollment_progress_priority_over_help), res.getBoolean(R.bool.enrollment_prioritize_acquire_messages), res.getInteger(R.integer.enrollment_collect_time)); - mFingerprintUpdater.enroll(mToken, mCancellationSignal, mUserId, callback, reason); + mFingerprintUpdater.enroll(mToken, mCancellationSignal, mUserId, callback, reason, + new Intent()); } else { mFingerprintUpdater.enroll(mToken, mCancellationSignal, mUserId, mEnrollmentCallback, - reason); + reason, new Intent()); } return mCancellationSignal; } diff --git a/src/com/android/settings/bluetooth/BluetoothAutoOnPreferenceController.java b/src/com/android/settings/bluetooth/BluetoothAutoOnPreferenceController.java new file mode 100644 index 00000000000..f6f62e8ffd8 --- /dev/null +++ b/src/com/android/settings/bluetooth/BluetoothAutoOnPreferenceController.java @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2024 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.bluetooth; + +import android.content.Context; +import android.database.ContentObserver; +import android.os.Handler; +import android.os.UserHandle; +import android.provider.Settings; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.VisibleForTesting; +import androidx.preference.PreferenceScreen; +import androidx.preference.TwoStatePreference; + +import com.android.settings.core.TogglePreferenceController; +import com.android.settingslib.core.lifecycle.LifecycleObserver; +import com.android.settingslib.core.lifecycle.events.OnStart; +import com.android.settingslib.core.lifecycle.events.OnStop; +import com.android.settingslib.flags.Flags; +import com.android.settingslib.utils.ThreadUtils; + +public class BluetoothAutoOnPreferenceController extends TogglePreferenceController + implements LifecycleObserver, OnStart, OnStop { + private static final String TAG = "BluetoothAutoOnPreferenceController"; + @VisibleForTesting static final String PREF_KEY = "bluetooth_auto_on_settings_toggle"; + static final String SETTING_NAME = "bluetooth_automatic_turn_on"; + static final int UNSET = -1; + @VisibleForTesting static final int ENABLED = 1; + @VisibleForTesting static final int DISABLED = 0; + private final ContentObserver mContentObserver = + new ContentObserver(new Handler(/* async= */ true)) { + @Override + public void onChange(boolean selfChange) { + var unused = + ThreadUtils.postOnBackgroundThread( + () -> { + updateValue(); + mContext.getMainExecutor() + .execute( + () -> { + if (mPreference != null) { + updateState(mPreference); + } + }); + }); + } + }; + private int mAutoOnValue = UNSET; + @Nullable private TwoStatePreference mPreference; + + public BluetoothAutoOnPreferenceController( + @NonNull Context context, @NonNull String preferenceKey) { + super(context, preferenceKey); + } + + @Override + public void onStart() { + mContext.getContentResolver() + .registerContentObserver( + Settings.Secure.getUriFor(SETTING_NAME), + /* notifyForDescendants= */ false, + mContentObserver); + } + + @Override + public void onStop() { + mContext.getContentResolver().unregisterContentObserver(mContentObserver); + } + + @Override + public int getAvailabilityStatus() { + if (!Flags.bluetoothQsTileDialogAutoOnToggle()) { + return UNSUPPORTED_ON_DEVICE; + } + updateValue(); + return mAutoOnValue != UNSET ? AVAILABLE : UNSUPPORTED_ON_DEVICE; + } + + @Override + public void displayPreference(@NonNull PreferenceScreen screen) { + super.displayPreference(screen); + mPreference = screen.findPreference(getPreferenceKey()); + } + + @Override + public String getPreferenceKey() { + return PREF_KEY; + } + + @Override + public boolean isChecked() { + return mAutoOnValue == ENABLED; + } + + @Override + public boolean setChecked(boolean isChecked) { + if (getAvailabilityStatus() != AVAILABLE) { + Log.w(TAG, "Trying to set toggle value while feature not available."); + return false; + } + var unused = + ThreadUtils.postOnBackgroundThread( + () -> { + boolean updated = + Settings.Secure.putIntForUser( + mContext.getContentResolver(), + SETTING_NAME, + isChecked ? ENABLED : DISABLED, + UserHandle.myUserId()); + if (updated) { + updateValue(); + } + }); + return true; + } + + @Override + public int getSliceHighlightMenuRes() { + return 0; + } + + private void updateValue() { + mAutoOnValue = + Settings.Secure.getIntForUser( + mContext.getContentResolver(), SETTING_NAME, UNSET, UserHandle.myUserId()); + } +} diff --git a/src/com/android/settings/bluetooth/BluetoothSwitchPreferenceController.java b/src/com/android/settings/bluetooth/BluetoothSwitchPreferenceController.java index 6fd5070303c..ac5575803c1 100644 --- a/src/com/android/settings/bluetooth/BluetoothSwitchPreferenceController.java +++ b/src/com/android/settings/bluetooth/BluetoothSwitchPreferenceController.java @@ -15,8 +15,13 @@ */ package com.android.settings.bluetooth; +import static com.android.settings.bluetooth.BluetoothAutoOnPreferenceController.SETTING_NAME; +import static com.android.settings.bluetooth.BluetoothAutoOnPreferenceController.UNSET; + import android.app.settings.SettingsEnums; import android.content.Context; +import android.os.UserHandle; +import android.provider.Settings; import android.view.View; import androidx.annotation.VisibleForTesting; @@ -29,6 +34,7 @@ import com.android.settings.widget.SwitchWidgetController; import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnStart; import com.android.settingslib.core.lifecycle.events.OnStop; +import com.android.settingslib.flags.Flags; import com.android.settingslib.widget.FooterPreference; /** @@ -36,8 +42,11 @@ import com.android.settingslib.widget.FooterPreference; * is delegated to the SwitchWidgetController it uses. */ public class BluetoothSwitchPreferenceController - implements LifecycleObserver, OnStart, OnStop, - SwitchWidgetController.OnSwitchChangeListener, View.OnClickListener { + implements LifecycleObserver, + OnStart, + OnStop, + SwitchWidgetController.OnSwitchChangeListener, + View.OnClickListener { private BluetoothEnabler mBluetoothEnabler; private RestrictionUtils mRestrictionUtils; @@ -46,18 +55,21 @@ public class BluetoothSwitchPreferenceController private FooterPreference mFooterPreference; private boolean mIsAlwaysDiscoverable; - @VisibleForTesting - AlwaysDiscoverable mAlwaysDiscoverable; + @VisibleForTesting AlwaysDiscoverable mAlwaysDiscoverable; - public BluetoothSwitchPreferenceController(Context context, + public BluetoothSwitchPreferenceController( + Context context, SwitchWidgetController switchController, FooterPreference footerPreference) { this(context, new RestrictionUtils(), switchController, footerPreference); } @VisibleForTesting - public BluetoothSwitchPreferenceController(Context context, RestrictionUtils restrictionUtils, - SwitchWidgetController switchController, FooterPreference footerPreference) { + public BluetoothSwitchPreferenceController( + Context context, + RestrictionUtils restrictionUtils, + SwitchWidgetController switchController, + FooterPreference footerPreference) { mRestrictionUtils = restrictionUtils; mSwitch = switchController; mContext = context; @@ -66,11 +78,13 @@ public class BluetoothSwitchPreferenceController mSwitch.setupView(); updateText(mSwitch.isChecked()); - mBluetoothEnabler = new BluetoothEnabler(context, - switchController, - FeatureFactory.getFeatureFactory().getMetricsFeatureProvider(), - SettingsEnums.ACTION_SETTINGS_MASTER_SWITCH_BLUETOOTH_TOGGLE, - mRestrictionUtils); + mBluetoothEnabler = + new BluetoothEnabler( + context, + switchController, + FeatureFactory.getFeatureFactory().getMetricsFeatureProvider(), + SettingsEnums.ACTION_SETTINGS_MASTER_SWITCH_BLUETOOTH_TOGGLE, + mRestrictionUtils); mBluetoothEnabler.setToggleCallback(this); mAlwaysDiscoverable = new AlwaysDiscoverable(context); } @@ -97,8 +111,8 @@ public class BluetoothSwitchPreferenceController /** * Set whether the device can be discovered. By default the value will be {@code false}. * - * @param isAlwaysDiscoverable {@code true} if the device can be discovered, - * otherwise {@code false} + * @param isAlwaysDiscoverable {@code true} if the device can be discovered, otherwise {@code + * false} */ public void setAlwaysDiscoverable(boolean isAlwaysDiscoverable) { mIsAlwaysDiscoverable = isAlwaysDiscoverable; @@ -119,15 +133,35 @@ public class BluetoothSwitchPreferenceController .launch(); } - @VisibleForTesting void updateText(boolean isChecked) { + @VisibleForTesting + void updateText(boolean isChecked) { if (!isChecked && Utils.isBluetoothScanningEnabled(mContext)) { - mFooterPreference.setTitle(R.string.bluetooth_scanning_on_info_message); + if (isAutoOnFeatureAvailable()) { + mFooterPreference.setTitle( + R.string.bluetooth_scanning_on_info_message_auto_on_available); + } else { + mFooterPreference.setTitle(R.string.bluetooth_scanning_on_info_message); + } mFooterPreference.setLearnMoreText(mContext.getString(R.string.bluetooth_scan_change)); mFooterPreference.setLearnMoreAction(v -> onClick(v)); } else { - mFooterPreference.setTitle(R.string.bluetooth_empty_list_bluetooth_off); + if (isAutoOnFeatureAvailable()) { + mFooterPreference.setTitle( + R.string.bluetooth_empty_list_bluetooth_off_auto_on_available); + } else { + mFooterPreference.setTitle(R.string.bluetooth_empty_list_bluetooth_off); + } mFooterPreference.setLearnMoreText(""); mFooterPreference.setLearnMoreAction(null); } } + + private boolean isAutoOnFeatureAvailable() { + if (!Flags.bluetoothQsTileDialogAutoOnToggle()) { + return false; + } + return Settings.Secure.getIntForUser( + mContext.getContentResolver(), SETTING_NAME, UNSET, UserHandle.myUserId()) + != UNSET; + } } diff --git a/src/com/android/settings/network/NetworkProviderSettings.java b/src/com/android/settings/network/NetworkProviderSettings.java index 0da1034994c..bcf0d00089b 100644 --- a/src/com/android/settings/network/NetworkProviderSettings.java +++ b/src/com/android/settings/network/NetworkProviderSettings.java @@ -1261,7 +1261,8 @@ public class NetworkProviderSettings extends RestrictedSettingsFragment WifiEntryConnectCallback callback = new WifiEntryConnectCallback(wifiEntry, editIfNoConfig, fullScreenEdit); - if (Flags.wepUsage() && wifiEntry.getSecurityTypes().contains(WifiEntry.SECURITY_WEP)) { + if (Flags.androidVWifiApi() && wifiEntry.getSecurityTypes() + .contains(WifiEntry.SECURITY_WEP)) { WepNetworkDialogActivity.checkWepAllowed( getContext(), getViewLifecycleOwner(), wifiEntry.getSsid(), () -> { wifiEntry.connect(callback); diff --git a/src/com/android/settings/privatespace/HidePrivateSpaceSensitiveNotificationsController.java b/src/com/android/settings/privatespace/HidePrivateSpaceSensitiveNotificationsController.java new file mode 100644 index 00000000000..1a89d37b8b6 --- /dev/null +++ b/src/com/android/settings/privatespace/HidePrivateSpaceSensitiveNotificationsController.java @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2024 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.privatespace; + +import static android.provider.Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS; + +import android.content.Context; +import android.os.UserHandle; +import android.provider.Settings; + +import androidx.annotation.NonNull; + +import com.android.settings.core.TogglePreferenceController; + +import java.util.Objects; + +/** + * A controller object for sensitive notifications in Private Space settings page. + */ +public class HidePrivateSpaceSensitiveNotificationsController extends TogglePreferenceController { + private final PrivateSpaceMaintainer mPrivateSpaceMaintainer; + private final UserHandle mPrivateProfileId; + public static final int ENABLED = 1; + public static final int DISABLED = 0; + private static final int DEVICE_SENSITIVE_NOTIFICATIONS_DEFAULT = ENABLED; + private static final int DEVICE_LOCK_SCREEN_NOTIFICATIONS_DEFAULT = ENABLED; + private static final int PRIVATE_SPACE_SENSITIVE_NOTIFICATIONS_DEFAULT = DISABLED; + + public HidePrivateSpaceSensitiveNotificationsController(@NonNull Context context, + @NonNull String preferenceKey) { + super(context, preferenceKey); + mPrivateSpaceMaintainer = PrivateSpaceMaintainer.getInstance(context); + mPrivateProfileId = Objects.requireNonNull( + mPrivateSpaceMaintainer.getPrivateProfileHandle()); + } + + @Override + public int getAvailabilityStatus() { + if (!android.os.Flags.allowPrivateProfile() + || !android.multiuser.Flags.enablePsSensitiveNotificationsToggle() + || !mPrivateSpaceMaintainer.doesPrivateSpaceExist()) { + return UNSUPPORTED_ON_DEVICE; + } + if (!getLockscreenNotificationsEnabled(mContext) + || !getLockscreenSensitiveNotificationsEnabledOnDevice(mContext)) { + return DISABLED_DEPENDENT_SETTING; + } + return AVAILABLE; + } + + @Override + public boolean isChecked() { + return Settings.Secure.getIntForUser(mContext.getContentResolver(), + LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, + PRIVATE_SPACE_SENSITIVE_NOTIFICATIONS_DEFAULT, mPrivateProfileId.getIdentifier()) + != DISABLED; + } + + @Override + public boolean setChecked(boolean isChecked) { + Settings.Secure.putIntForUser(mContext.getContentResolver(), + Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, + isChecked ? ENABLED : DISABLED, mPrivateProfileId.getIdentifier()); + return true; + } + + @Override + public int getSliceHighlightMenuRes() { + return 0; + } + + /** + * If notifications are disabled on the device, the toggle for private space sensitive + * notifications should be unavailable. + */ + private static boolean getLockscreenNotificationsEnabled(Context context) { + return Settings.Secure.getInt(context.getContentResolver(), + Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, + DEVICE_LOCK_SCREEN_NOTIFICATIONS_DEFAULT) != DISABLED; + } + + /** + * If sensitive notifications are hidden on the device, they should be hidden for private space + * also. + */ + private static boolean getLockscreenSensitiveNotificationsEnabledOnDevice(Context context) { + return Settings.Secure.getInt(context.getContentResolver(), + Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, + DEVICE_SENSITIVE_NOTIFICATIONS_DEFAULT) != DISABLED; + } +} diff --git a/src/com/android/settings/privatespace/PrivateSpaceAuthenticationActivity.java b/src/com/android/settings/privatespace/PrivateSpaceAuthenticationActivity.java index 149c0d6881e..63b1dc95a98 100644 --- a/src/com/android/settings/privatespace/PrivateSpaceAuthenticationActivity.java +++ b/src/com/android/settings/privatespace/PrivateSpaceAuthenticationActivity.java @@ -18,6 +18,8 @@ package com.android.settings.privatespace; import static android.app.admin.DevicePolicyManager.ACTION_SET_NEW_PASSWORD; +import static com.android.internal.app.SetScreenLockDialogActivity.LAUNCH_REASON_PRIVATE_SPACE_SETTINGS_ACCESS; + import android.app.ActivityOptions; import android.app.AlertDialog; import android.app.KeyguardManager; @@ -37,6 +39,7 @@ import androidx.annotation.Nullable; import androidx.fragment.app.FragmentActivity; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.app.SetScreenLockDialogActivity; import com.android.settings.R; import com.android.settings.core.SubSettingLauncher; import com.android.settingslib.transition.SettingsTransitionHelper; @@ -112,23 +115,31 @@ public class PrivateSpaceAuthenticationActivity extends FragmentActivity { private void promptToSetDeviceLock() { Log.d(TAG, "Show prompt to set device lock before using private space feature"); - new AlertDialog.Builder(this) - .setTitle(R.string.no_device_lock_title) - .setMessage(R.string.no_device_lock_summary) - .setPositiveButton( - R.string.no_device_lock_action_label, - (DialogInterface dialog, int which) -> { - Log.d(TAG, "Start activity to set new device lock"); - mSetDeviceLock.launch(new Intent(ACTION_SET_NEW_PASSWORD)); - }) - .setNegativeButton( - R.string.no_device_lock_cancel, - (DialogInterface dialog, int which) -> finish()) - .setOnCancelListener( - (DialogInterface dialog) -> { - finish(); - }) - .show(); + if (android.multiuser.Flags.showSetScreenLockDialog()) { + Intent setScreenLockPromptIntent = + SetScreenLockDialogActivity + .createBaseIntent(LAUNCH_REASON_PRIVATE_SPACE_SETTINGS_ACCESS); + startActivity(setScreenLockPromptIntent); + finish(); + } else { + new AlertDialog.Builder(this) + .setTitle(R.string.no_device_lock_title) + .setMessage(R.string.no_device_lock_summary) + .setPositiveButton( + R.string.no_device_lock_action_label, + (DialogInterface dialog, int which) -> { + Log.d(TAG, "Start activity to set new device lock"); + mSetDeviceLock.launch(new Intent(ACTION_SET_NEW_PASSWORD)); + }) + .setNegativeButton( + R.string.no_device_lock_cancel, + (DialogInterface dialog, int which) -> finish()) + .setOnCancelListener( + (DialogInterface dialog) -> { + finish(); + }) + .show(); + } } private KeyguardManager getKeyguardManager() { diff --git a/src/com/android/settings/privatespace/PrivateSpaceMaintainer.java b/src/com/android/settings/privatespace/PrivateSpaceMaintainer.java index a2831478a8b..2d38ae2007f 100644 --- a/src/com/android/settings/privatespace/PrivateSpaceMaintainer.java +++ b/src/com/android/settings/privatespace/PrivateSpaceMaintainer.java @@ -45,6 +45,7 @@ import com.android.internal.annotations.GuardedBy; import java.util.List; // TODO(b/293569406): Update the javadoc when we have the setup flow in place to create PS + /** A class to help with the creation / deletion of Private Space */ public class PrivateSpaceMaintainer { private static final String TAG = "PrivateSpaceMaintainer"; @@ -65,9 +66,9 @@ public class PrivateSpaceMaintainer { public static final int PRIVATE_SPACE_AUTO_LOCK_DEFAULT_VAL = PRIVATE_SPACE_AUTO_LOCK_NEVER; public enum ErrorDeletingPrivateSpace { - DELETE_PS_ERROR_NONE, - DELETE_PS_ERROR_NO_PRIVATE_SPACE, - DELETE_PS_ERROR_INTERNAL + DELETE_PS_ERROR_NONE, + DELETE_PS_ERROR_NO_PRIVATE_SPACE, + DELETE_PS_ERROR_INTERNAL } /** @@ -90,7 +91,7 @@ public class PrivateSpaceMaintainer { if (mUserHandle == null) { try { mUserHandle = mUserManager.createProfile( - userName, USER_TYPE_PROFILE_PRIVATE, new ArraySet<>()); + userName, USER_TYPE_PROFILE_PRIVATE, new ArraySet<>()); } catch (Exception e) { Log.e(TAG, "Error creating private space", e); return false; @@ -117,7 +118,8 @@ public class PrivateSpaceMaintainer { return true; } - /** Returns the {@link ErrorDeletingPrivateSpace} enum representing the result of operation. + /** + * Returns the {@link ErrorDeletingPrivateSpace} enum representing the result of operation. * *

This method should be used ONLY by the delete-PS controller in the PS Settings page. */ @@ -212,6 +214,7 @@ public class PrivateSpaceMaintainer { // TODO(b/307281644): Remove this method once new auth change is merged + /** * Returns true if private space exists and a separate private profile lock is set * otherwise false when the private space does not exit or exists but does not have a @@ -290,9 +293,20 @@ public class PrivateSpaceMaintainer { return false; } + @GuardedBy("this") private void resetPrivateSpaceSettings() { setHidePrivateSpaceEntryPointSetting(HIDE_PRIVATE_SPACE_ENTRY_POINT_DISABLED_VAL); setPrivateSpaceAutoLockSetting(PRIVATE_SPACE_AUTO_LOCK_DEFAULT_VAL); + setPrivateSpaceSensitiveNotificationsDefaultValue(); + } + + /** Sets private space sensitive notifications hidden on lockscreen by default */ + @GuardedBy("this") + private void setPrivateSpaceSensitiveNotificationsDefaultValue() { + Settings.Secure.putIntForUser(mContext.getContentResolver(), + Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, + HidePrivateSpaceSensitiveNotificationsController.DISABLED, + mUserHandle.getIdentifier()); } /** diff --git a/src/com/android/settings/wifi/WepNetworksPreferenceController.kt b/src/com/android/settings/wifi/WepNetworksPreferenceController.kt index fca75a93710..6263bfdafbf 100644 --- a/src/com/android/settings/wifi/WepNetworksPreferenceController.kt +++ b/src/com/android/settings/wifi/WepNetworksPreferenceController.kt @@ -48,7 +48,7 @@ class WepNetworksPreferenceController(context: Context, preferenceKey: String) : preference = screen.findPreference(preferenceKey)!! } - override fun getAvailabilityStatus() = if (Flags.wepUsage()) AVAILABLE + override fun getAvailabilityStatus() = if (Flags.androidVWifiApi()) AVAILABLE else UNSUPPORTED_ON_DEVICE @Composable diff --git a/src/com/android/settings/wifi/WifiConfigController.java b/src/com/android/settings/wifi/WifiConfigController.java index 1627056e5a0..5d45cb235b8 100644 --- a/src/com/android/settings/wifi/WifiConfigController.java +++ b/src/com/android/settings/wifi/WifiConfigController.java @@ -276,7 +276,7 @@ public class WifiConfigController implements TextWatcher, mDoNotProvideEapUserCertString = mContext.getString(R.string.wifi_do_not_provide_eap_user_cert); - if (Flags.wepUsage() && mAccessPointSecurity == WifiEntry.SECURITY_WEP) { + if (Flags.androidVWifiApi() && mAccessPointSecurity == WifiEntry.SECURITY_WEP) { LinearLayout wepWarningLayout = (LinearLayout) mView.findViewById(R.id.wep_warning_layout); wepWarningLayout.setVisibility(View.VISIBLE); diff --git a/src/com/android/settings/wifi/WifiConfigController2.java b/src/com/android/settings/wifi/WifiConfigController2.java index 6a6244b6f09..7c9b1d1b471 100644 --- a/src/com/android/settings/wifi/WifiConfigController2.java +++ b/src/com/android/settings/wifi/WifiConfigController2.java @@ -289,7 +289,7 @@ public class WifiConfigController2 implements TextWatcher, mContext.getString(R.string.wifi_do_not_provide_eap_user_cert); mInstallCertsString = mContext.getString(R.string.wifi_install_credentials); - if (Flags.wepUsage() && mWifiEntrySecurity == WifiEntry.SECURITY_WEP) { + if (Flags.androidVWifiApi() && mWifiEntrySecurity == WifiEntry.SECURITY_WEP) { LinearLayout wepWarningLayout = (LinearLayout) mView.findViewById(R.id.wep_warning_layout); wepWarningLayout.setVisibility(View.VISIBLE); diff --git a/tests/robotests/src/com/android/settings/biometrics/face/FaceEnrollIntroductionTest.java b/tests/robotests/src/com/android/settings/biometrics/face/FaceEnrollIntroductionTest.java index beb7a9f4f11..a56c34cacdf 100644 --- a/tests/robotests/src/com/android/settings/biometrics/face/FaceEnrollIntroductionTest.java +++ b/tests/robotests/src/com/android/settings/biometrics/face/FaceEnrollIntroductionTest.java @@ -43,6 +43,7 @@ import android.content.Intent; import android.content.res.Configuration; import android.content.res.Resources; import android.hardware.face.Face; +import android.hardware.face.FaceEnrollOptions; import android.hardware.face.FaceManager; import android.hardware.face.FaceSensorProperties; import android.hardware.face.FaceSensorPropertiesInternal; @@ -196,6 +197,8 @@ public class FaceEnrollIntroductionTest { final Intent testIntent = new Intent(); // Set the challenge token so the confirm screen will not be shown testIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, new byte[0]); + testIntent.putExtra(BiometricUtils.EXTRA_ENROLL_REASON, + FaceEnrollOptions.ENROLL_REASON_SETTINGS); when(mFakeFeatureFactory.mFaceFeatureProvider.getPostureGuidanceIntent(any())).thenReturn( null /* Simulate no posture intent */); @@ -220,6 +223,8 @@ public class FaceEnrollIntroductionTest { testIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, new byte[0]); testIntent.putExtra(EXTRA_KEY_NEXT_LAUNCHED, false); testIntent.putExtra(EXTRA_LAUNCHED_POSTURE_GUIDANCE, false); + testIntent.putExtra(BiometricUtils.EXTRA_ENROLL_REASON, + FaceEnrollOptions.ENROLL_REASON_SETTINGS); when(mFakeFeatureFactory.mFaceFeatureProvider.getPostureGuidanceIntent(any())).thenReturn( testIntent); @@ -641,4 +646,14 @@ public class FaceEnrollIntroductionTest { final AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog(); assertThat(dialog).isNull(); } + + @Test + public void testFaceEnrollIntroduction_forwardsEnrollOptions() { + setupActivity(); + final Intent intent = mActivity.getEnrollingIntent(); + + assertThat(intent.getIntExtra(BiometricUtils.EXTRA_ENROLL_REASON, -1)) + .isEqualTo(FaceEnrollOptions.ENROLL_REASON_SETTINGS); + } + } diff --git a/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrollingTest.java b/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrollingTest.java index 4de369e5f41..91707cd6e84 100644 --- a/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrollingTest.java +++ b/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrollingTest.java @@ -669,7 +669,8 @@ public class FingerprintEnrollEnrollingTest { any(CancellationSignal.class), anyInt(), callbackCaptor.capture(), - eq(FingerprintManager.ENROLL_ENROLL)); + eq(FingerprintManager.ENROLL_ENROLL), + any()); return callbackCaptor.getValue(); } diff --git a/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFindSensorTest.java b/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFindSensorTest.java index 4d13bb63d19..68395b27001 100644 --- a/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFindSensorTest.java +++ b/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFindSensorTest.java @@ -227,7 +227,8 @@ public class FingerprintEnrollFindSensorTest { any(CancellationSignal.class), anyInt(), callbackCaptor.capture(), - eq(FingerprintManager.ENROLL_FIND_SENSOR)); + eq(FingerprintManager.ENROLL_FIND_SENSOR), + any()); return callbackCaptor.getValue(); } diff --git a/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroductionTest.java b/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroductionTest.java index 3eba91c854f..1aedce53980 100644 --- a/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroductionTest.java +++ b/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroductionTest.java @@ -40,6 +40,7 @@ import android.content.res.Resources; import android.hardware.biometrics.ComponentInfoInternal; import android.hardware.biometrics.SensorProperties; import android.hardware.fingerprint.Fingerprint; +import android.hardware.fingerprint.FingerprintEnrollOptions; import android.hardware.fingerprint.FingerprintManager; import android.hardware.fingerprint.FingerprintSensorProperties; import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; @@ -52,6 +53,7 @@ import androidx.annotation.Nullable; import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.VerifyCredentialResponse; import com.android.settings.R; +import com.android.settings.biometrics.BiometricUtils; import com.android.settings.biometrics.GatekeeperPasswordProvider; import com.google.android.setupcompat.util.WizardManagerHelper; @@ -289,6 +291,18 @@ public class FingerprintEnrollIntroductionTest { assertThat(mFingerprintEnrollIntroduction.shouldFinishWhenBackgrounded()).isEqualTo(true); } + @Test + public void testFingerprintEnrollIntroduction_forwardsEnrollOptions() { + final Intent intent = newTokenOnlyIntent(); + intent.putExtra(BiometricUtils.EXTRA_ENROLL_REASON, + FingerprintEnrollOptions.ENROLL_REASON_SETTINGS); + setupFingerprintEnrollIntroWith(intent); + + final Intent enrollingIntent = mFingerprintEnrollIntroduction.getEnrollingIntent(); + assertThat(enrollingIntent.getIntExtra(BiometricUtils.EXTRA_ENROLL_REASON, -1)) + .isEqualTo(FingerprintEnrollOptions.ENROLL_REASON_SETTINGS); + } + private Intent newTokenOnlyIntent() { return new Intent() .putExtra(EXTRA_KEY_CHALLENGE_TOKEN, new byte[] { 1 }); diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothAutoOnPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothAutoOnPreferenceControllerTest.java new file mode 100644 index 00000000000..d82dcc43ac3 --- /dev/null +++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothAutoOnPreferenceControllerTest.java @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2024 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.bluetooth; + +import static com.android.settings.bluetooth.BluetoothAutoOnPreferenceController.DISABLED; +import static com.android.settings.bluetooth.BluetoothAutoOnPreferenceController.ENABLED; +import static com.android.settings.bluetooth.BluetoothAutoOnPreferenceController.PREF_KEY; +import static com.android.settings.bluetooth.BluetoothAutoOnPreferenceController.SETTING_NAME; +import static com.android.settings.bluetooth.BluetoothAutoOnPreferenceController.UNSET; +import static com.android.settings.core.BasePreferenceController.AVAILABLE; +import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE; +import static com.android.settingslib.flags.Flags.FLAG_BLUETOOTH_QS_TILE_DIALOG_AUTO_ON_TOGGLE; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.spy; + +import android.content.ContentResolver; +import android.content.Context; +import android.platform.test.flag.junit.SetFlagsRule; +import android.provider.Settings; + +import androidx.test.core.app.ApplicationProvider; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; + +@RunWith(RobolectricTestRunner.class) +public class BluetoothAutoOnPreferenceControllerTest { + @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + private Context mContext; + private ContentResolver mContentResolver; + private BluetoothAutoOnPreferenceController mController; + + @Before + public void setUp() { + mSetFlagsRule.enableFlags(FLAG_BLUETOOTH_QS_TILE_DIALOG_AUTO_ON_TOGGLE); + mContext = spy(ApplicationProvider.getApplicationContext()); + mContentResolver = mContext.getContentResolver(); + mController = new BluetoothAutoOnPreferenceController(mContext, PREF_KEY); + } + + @Test + public void getAvailability_valueUnset_returnUnsupported() { + Settings.Secure.putInt(mContentResolver, SETTING_NAME, UNSET); + + assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE); + } + + @Test + public void getAvailability_valueSet_returnAvailable() { + Settings.Secure.putInt(mContentResolver, SETTING_NAME, DISABLED); + + assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); + } + + @Test + public void isChecked_valueEnabled_returnTrue() { + Settings.Secure.putInt(mContentResolver, SETTING_NAME, ENABLED); + + assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); + assertThat(mController.isChecked()).isEqualTo(true); + } + + @Test + public void setChecked_returnTrue() { + Settings.Secure.putInt(mContentResolver, SETTING_NAME, DISABLED); + + mController.setChecked(true); + assertThat(mController.isChecked()).isEqualTo(true); + } + + @Test + public void setChecked_returnFalse() { + Settings.Secure.putInt(mContentResolver, SETTING_NAME, ENABLED); + + mController.setChecked(false); + assertThat(mController.isChecked()).isEqualTo(false); + } +} diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryInfoTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryInfoTest.java index 0339f574b0b..e99c4e0a778 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryInfoTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryInfoTest.java @@ -64,7 +64,7 @@ public class BatteryInfoTest { private static final String STATUS_CHARGING_NO_TIME = "50% - charging"; private static final String STATUS_CHARGING_TIME = "50% - 0 min left until full"; private static final String STATUS_NOT_CHARGING = "Not charging"; - private static final String STATUS_CHARGING_FUTURE_BYPASS = "50% - Charging optimized"; + private static final String STATUS_CHARGING_FUTURE_BYPASS = "50% - Charging"; private static final String STATUS_CHARGING_PAUSED = "50% - Charging optimized"; private static final long REMAINING_TIME_NULL = -1; private static final long REMAINING_TIME = 2; diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/BatteryDefenderTipTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/BatteryDefenderTipTest.java index 4efd8509fab..a605ee32dfa 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/BatteryDefenderTipTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/BatteryDefenderTipTest.java @@ -82,7 +82,7 @@ public class BatteryDefenderTipTest { @Test public void getIcon_showIcon() { assertThat(mBatteryDefenderTip.getIconId()) - .isEqualTo(R.drawable.ic_battery_status_good_theme); + .isEqualTo(R.drawable.ic_battery_defender_tip_shield); } @Test diff --git a/tests/robotests/src/com/android/settings/survey/SurveyMixinTest.java b/tests/robotests/src/com/android/settings/survey/SurveyMixinTest.java index 635343e2142..c38e36afea5 100644 --- a/tests/robotests/src/com/android/settings/survey/SurveyMixinTest.java +++ b/tests/robotests/src/com/android/settings/survey/SurveyMixinTest.java @@ -2,53 +2,56 @@ package com.android.settings.survey; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import android.content.Context; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.testing.FragmentScenario; +import androidx.test.core.app.ApplicationProvider; -import androidx.fragment.app.FragmentActivity; - -import com.android.settings.core.InstrumentedPreferenceFragment; import com.android.settings.overlay.SurveyFeatureProvider; import com.android.settings.testutils.FakeFeatureFactory; import org.junit.Before; -import org.junit.Ignore; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.Robolectric; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; @RunWith(RobolectricTestRunner.class) public class SurveyMixinTest { + @Rule + public final MockitoRule mMockitoRule = MockitoJUnit.rule(); private static final String FAKE_KEY = "fake_key"; - - private Context mContext; private SurveyFeatureProvider mProvider; - @Mock - private InstrumentedPreferenceFragment mFragment; @Before public void setUp() { // set up the fakefeature factory to mock out the survey provider - MockitoAnnotations.initMocks(this); - mContext = RuntimeEnvironment.application; - mProvider = FakeFeatureFactory.setupForTest().getSurveyFeatureProvider(mContext); + mProvider = FakeFeatureFactory.setupForTest().getSurveyFeatureProvider( + ApplicationProvider.getApplicationContext()); } - @Ignore("b/314929422") @Test public void onResume_noActionIfActivityDoesNotExist() { - // Pretend we are an activity that is starting up - FragmentActivity temp = Robolectric.setupActivity(FragmentActivity.class); - when(mFragment.getActivity()).thenReturn(null); - SurveyMixin mixin = new SurveyMixin(mFragment, FAKE_KEY); + // Initialize a fragment without associating with an activity + Fragment fragment = new Fragment(); + SurveyMixin mixin = new SurveyMixin(fragment, FAKE_KEY); mixin.onResume(); verify(mProvider, times(0)).sendActivityIfAvailable(FAKE_KEY); } + + @Test + public void onResume_sendActivityWhenSurveyFeatureExists() { + try (var fragmentScenario = FragmentScenario.launch(Fragment.class)) { + fragmentScenario.onFragment(fragment -> { + SurveyMixin mixin = new SurveyMixin(fragment, FAKE_KEY); + mixin.onResume(); + }); + } + // Verify one send activity action is attempted + verify(mProvider).sendActivityIfAvailable(FAKE_KEY); + } } diff --git a/tests/uitests/src/com/android/settings/ui/privatespace/PrivateSpaceAuthenticationActivityTest.kt b/tests/uitests/src/com/android/settings/ui/privatespace/PrivateSpaceAuthenticationActivityTest.kt index 87514716082..8eadd9dde92 100644 --- a/tests/uitests/src/com/android/settings/ui/privatespace/PrivateSpaceAuthenticationActivityTest.kt +++ b/tests/uitests/src/com/android/settings/ui/privatespace/PrivateSpaceAuthenticationActivityTest.kt @@ -18,9 +18,11 @@ package com.android.settings.ui.privatespace import android.os.Flags +import android.platform.test.annotations.RequiresFlagsDisabled import android.platform.test.annotations.RequiresFlagsEnabled import android.platform.test.flag.junit.DeviceFlagsValueProvider import android.provider.Settings +import android.util.Log import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.platform.app.InstrumentationRegistry import androidx.test.uiautomator.By @@ -77,15 +79,18 @@ class PrivateSpaceAuthenticationActivityTest { Thread.sleep(1000) device.assertHasTexts(listOf(SET_LOCK_BUTTON,CANCEL_TEXT)) device.clickObject(By.text(SET_LOCK_BUTTON)) - device.assertHasTexts(listOf(LOCK_SCREEN_TITLE)) + Thread.sleep(1000) + device.assertHasTexts(listOf(PATTERN_TEXT, PIN_TEXT, PASSWORD_TEXT)) } private companion object { // Items we really want to always show - val PRIVATE_SPACE_SETTING = "Private Space" + val PRIVATE_SPACE_SETTING = "Private space" const val SET_LOCK_BUTTON = "Set screen lock" val CANCEL_TEXT = "Cancel" val DIALOG_TITLE = "Set a screen lock" - val LOCK_SCREEN_TITLE = "Choose screen lock" + val PATTERN_TEXT = "Pattern" + val PIN_TEXT = "PIN" + val PASSWORD_TEXT = "Password" } } diff --git a/tests/unit/src/com/android/settings/biometrics/face/FaceUpdaterTest.java b/tests/unit/src/com/android/settings/biometrics/face/FaceUpdaterTest.java index 9190d0a5b82..1701eaae14e 100644 --- a/tests/unit/src/com/android/settings/biometrics/face/FaceUpdaterTest.java +++ b/tests/unit/src/com/android/settings/biometrics/face/FaceUpdaterTest.java @@ -25,6 +25,7 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import android.content.Context; +import android.content.Intent; import android.hardware.face.Face; import android.hardware.face.FaceEnrollCell; import android.hardware.face.FaceEnrollStages; @@ -93,7 +94,7 @@ public class FaceUpdaterTest { ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(FaceManager.EnrollmentCallback.class); mFaceUpdater.enroll(USER_ID, HARDWARE_AUTH_TOKEN, CANCELLATION_SIGNAL, mEnrollmentCallback, - DISABLED_FEATURES); + DISABLED_FEATURES, new Intent()); verify(mFaceManager).enroll( eq(USER_ID), same(HARDWARE_AUTH_TOKEN), @@ -101,7 +102,8 @@ public class FaceUpdaterTest { callbackCaptor.capture(), same(DISABLED_FEATURES), same(null), - eq(false)); + eq(false), + any()); FaceManager.EnrollmentCallback callback = callbackCaptor.getValue(); callback.onEnrollmentError(ERR_MSG_ID, ERR_STRING); @@ -121,7 +123,7 @@ public class FaceUpdaterTest { ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(FaceManager.EnrollmentCallback.class); mFaceUpdater.enroll(USER_ID, HARDWARE_AUTH_TOKEN, CANCELLATION_SIGNAL, mEnrollmentCallback, - DISABLED_FEATURES); + DISABLED_FEATURES, new Intent()); verify(mFaceManager).enroll( eq(USER_ID), same(HARDWARE_AUTH_TOKEN), @@ -129,7 +131,8 @@ public class FaceUpdaterTest { callbackCaptor.capture(), same(DISABLED_FEATURES), same(null), - eq(false)); + eq(false), + any()); FaceManager.EnrollmentCallback callback = callbackCaptor.getValue(); callback.onEnrollmentProgress(/* remaining= */ 0); @@ -142,7 +145,7 @@ public class FaceUpdaterTest { ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(FaceManager.EnrollmentCallback.class); mFaceUpdater.enroll(USER_ID, HARDWARE_AUTH_TOKEN, CANCELLATION_SIGNAL, mEnrollmentCallback, - DISABLED_FEATURES); + DISABLED_FEATURES, new Intent()); verify(mFaceManager).enroll( eq(USER_ID), same(HARDWARE_AUTH_TOKEN), @@ -150,7 +153,8 @@ public class FaceUpdaterTest { callbackCaptor.capture(), same(DISABLED_FEATURES), same(null), - eq(false)); + eq(false), + any()); FaceManager.EnrollmentCallback callback = callbackCaptor.getValue(); callback.onEnrollmentProgress(/* remaining= */ 1); @@ -163,7 +167,7 @@ public class FaceUpdaterTest { ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(FaceManager.EnrollmentCallback.class); mFaceUpdater.enroll(USER_ID, HARDWARE_AUTH_TOKEN, CANCELLATION_SIGNAL, mEnrollmentCallback, - DISABLED_FEATURES, PREVIEW_SURFACE, DEBUG_CONSENT); + DISABLED_FEATURES, PREVIEW_SURFACE, DEBUG_CONSENT, new Intent()); verify(mFaceManager).enroll( eq(USER_ID), same(HARDWARE_AUTH_TOKEN), @@ -171,7 +175,8 @@ public class FaceUpdaterTest { callbackCaptor.capture(), same(DISABLED_FEATURES), same(PREVIEW_SURFACE), - eq(DEBUG_CONSENT)); + eq(DEBUG_CONSENT), + any()); FaceManager.EnrollmentCallback callback = callbackCaptor.getValue(); callback.onEnrollmentError(ERR_MSG_ID, ERR_STRING); @@ -191,7 +196,7 @@ public class FaceUpdaterTest { ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(FaceManager.EnrollmentCallback.class); mFaceUpdater.enroll(USER_ID, HARDWARE_AUTH_TOKEN, CANCELLATION_SIGNAL, mEnrollmentCallback, - DISABLED_FEATURES, PREVIEW_SURFACE, DEBUG_CONSENT); + DISABLED_FEATURES, PREVIEW_SURFACE, DEBUG_CONSENT, new Intent()); verify(mFaceManager).enroll( eq(USER_ID), same(HARDWARE_AUTH_TOKEN), @@ -199,7 +204,8 @@ public class FaceUpdaterTest { callbackCaptor.capture(), same(DISABLED_FEATURES), same(PREVIEW_SURFACE), - eq(DEBUG_CONSENT)); + eq(DEBUG_CONSENT), + any()); FaceManager.EnrollmentCallback callback = callbackCaptor.getValue(); callback.onEnrollmentProgress(/* remaining= */ 0); @@ -212,7 +218,7 @@ public class FaceUpdaterTest { ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(FaceManager.EnrollmentCallback.class); mFaceUpdater.enroll(USER_ID, HARDWARE_AUTH_TOKEN, CANCELLATION_SIGNAL, mEnrollmentCallback, - DISABLED_FEATURES, PREVIEW_SURFACE, DEBUG_CONSENT); + DISABLED_FEATURES, PREVIEW_SURFACE, DEBUG_CONSENT, new Intent()); verify(mFaceManager).enroll( eq(USER_ID), same(HARDWARE_AUTH_TOKEN), @@ -220,7 +226,8 @@ public class FaceUpdaterTest { callbackCaptor.capture(), same(DISABLED_FEATURES), same(PREVIEW_SURFACE), - eq(DEBUG_CONSENT)); + eq(DEBUG_CONSENT), + any()); FaceManager.EnrollmentCallback callback = callbackCaptor.getValue(); callback.onEnrollmentProgress(/* remaining= */ 1); diff --git a/tests/unit/src/com/android/settings/biometrics/fingerprint/FingerprintUpdaterTest.java b/tests/unit/src/com/android/settings/biometrics/fingerprint/FingerprintUpdaterTest.java index 62435b4f8b2..6218efb0172 100644 --- a/tests/unit/src/com/android/settings/biometrics/fingerprint/FingerprintUpdaterTest.java +++ b/tests/unit/src/com/android/settings/biometrics/fingerprint/FingerprintUpdaterTest.java @@ -24,6 +24,7 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import android.content.Context; +import android.content.Intent; import android.hardware.fingerprint.Fingerprint; import android.hardware.fingerprint.FingerprintManager; import android.os.CancellationSignal; @@ -78,13 +79,14 @@ public class FingerprintUpdaterTest { ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(FingerprintManager.EnrollmentCallback.class); mFingerprintUpdater.enroll(HARDWARE_AUTH_TOKEN, CANCELLATION_SIGNAL, USER_ID, - mEnrollmentCallback, ENROLL_REASON); + mEnrollmentCallback, ENROLL_REASON, new Intent()); verify(mFingerprintManager).enroll( same(HARDWARE_AUTH_TOKEN), same(CANCELLATION_SIGNAL), eq(USER_ID), callbackCaptor.capture(), - eq(ENROLL_REASON)); + eq(ENROLL_REASON), + any()); FingerprintManager.EnrollmentCallback callback = callbackCaptor.getValue(); callback.onEnrollmentError(ERR_MSG_ID, ERR_STRING); @@ -101,13 +103,14 @@ public class FingerprintUpdaterTest { ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(FingerprintManager.EnrollmentCallback.class); mFingerprintUpdater.enroll(HARDWARE_AUTH_TOKEN, CANCELLATION_SIGNAL, USER_ID, - mEnrollmentCallback, ENROLL_REASON); + mEnrollmentCallback, ENROLL_REASON, new Intent()); verify(mFingerprintManager).enroll( same(HARDWARE_AUTH_TOKEN), same(CANCELLATION_SIGNAL), eq(USER_ID), callbackCaptor.capture(), - eq(ENROLL_REASON)); + eq(ENROLL_REASON), + any()); FingerprintManager.EnrollmentCallback callback = callbackCaptor.getValue(); callback.onEnrollmentProgress(/* remaining= */ 0); @@ -120,13 +123,14 @@ public class FingerprintUpdaterTest { ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(FingerprintManager.EnrollmentCallback.class); mFingerprintUpdater.enroll(HARDWARE_AUTH_TOKEN, CANCELLATION_SIGNAL, USER_ID, - mEnrollmentCallback, ENROLL_REASON); + mEnrollmentCallback, ENROLL_REASON, new Intent()); verify(mFingerprintManager).enroll( same(HARDWARE_AUTH_TOKEN), same(CANCELLATION_SIGNAL), eq(USER_ID), callbackCaptor.capture(), - eq(ENROLL_REASON)); + eq(ENROLL_REASON), + any()); FingerprintManager.EnrollmentCallback callback = callbackCaptor.getValue(); callback.onEnrollmentProgress(/* remaining= */ 1); diff --git a/tests/unit/src/com/android/settings/biometrics/fingerprint/feature/SfpsEnrollmentFeatureImplTest.kt b/tests/unit/src/com/android/settings/biometrics/fingerprint/feature/SfpsEnrollmentFeatureImplTest.kt index 794cfec1b3a..f7256b9d754 100644 --- a/tests/unit/src/com/android/settings/biometrics/fingerprint/feature/SfpsEnrollmentFeatureImplTest.kt +++ b/tests/unit/src/com/android/settings/biometrics/fingerprint/feature/SfpsEnrollmentFeatureImplTest.kt @@ -44,16 +44,24 @@ import org.mockito.Mockito.`when` as whenever @RunWith(AndroidJUnit4::class) class SfpsEnrollmentFeatureImplTest { + private val STAGE_0 = 0 + private val STAGE_1 = 1 + private val STAGE_2 = 2 + private val STAGE_3 = 3 + private val STAGE_4 = 4 + + private val THRESHOLD_0 = 0f + private val THRESHOLD_1 = .36f + private val THRESHOLD_2 = .52f + private val THRESHOLD_3 = .76f + private val THRESHOLD_4 = 1f + @get:Rule val mockito: MockitoRule = MockitoJUnit.rule() @Spy private val context: Context = ApplicationProvider.getApplicationContext() - private val settingsPackageName = "com.android.settings" - - private lateinit var settingsContext: Context - @Mock private lateinit var mockFingerprintManager: FingerprintManager @@ -61,31 +69,34 @@ class SfpsEnrollmentFeatureImplTest { @Before fun setUp() { - assertThat(mSfpsEnrollmentFeatureImpl).isInstanceOf(SfpsEnrollmentFeatureImpl::class.java) whenever(context.getSystemService(FingerprintManager::class.java)) .thenReturn(mockFingerprintManager) - doReturn(0f).`when`(mockFingerprintManager).getEnrollStageThreshold(0) - doReturn(0.36f).`when`(mockFingerprintManager).getEnrollStageThreshold(1) - doReturn(0.52f).`when`(mockFingerprintManager).getEnrollStageThreshold(2) - doReturn(0.76f).`when`(mockFingerprintManager).getEnrollStageThreshold(3) - doReturn(1f).`when`(mockFingerprintManager).getEnrollStageThreshold(4) - settingsContext = context.createPackageContext(settingsPackageName, 0) + doReturn(THRESHOLD_0).`when`(mockFingerprintManager).getEnrollStageThreshold(STAGE_0) + doReturn(THRESHOLD_1).`when`(mockFingerprintManager).getEnrollStageThreshold(STAGE_1) + doReturn(THRESHOLD_2).`when`(mockFingerprintManager).getEnrollStageThreshold(STAGE_2) + doReturn(THRESHOLD_3).`when`(mockFingerprintManager).getEnrollStageThreshold(STAGE_3) + doReturn(THRESHOLD_4).`when`(mockFingerprintManager).getEnrollStageThreshold(STAGE_4) } @Test fun testGetEnrollStageThreshold() { - assertThat(mSfpsEnrollmentFeatureImpl.getEnrollStageThreshold(context, 0)).isEqualTo(0f) - assertThat(mSfpsEnrollmentFeatureImpl.getEnrollStageThreshold(context, 1)).isEqualTo(0.36f) - assertThat(mSfpsEnrollmentFeatureImpl.getEnrollStageThreshold(context, 2)).isEqualTo(0.52f) - assertThat(mSfpsEnrollmentFeatureImpl.getEnrollStageThreshold(context, 3)).isEqualTo(0.76f) - assertThat(mSfpsEnrollmentFeatureImpl.getEnrollStageThreshold(context, 4)).isEqualTo(1f) + assertThat(mSfpsEnrollmentFeatureImpl.getEnrollStageThreshold(context, STAGE_0)) + .isEqualTo(THRESHOLD_0) + assertThat(mSfpsEnrollmentFeatureImpl.getEnrollStageThreshold(context, STAGE_1)) + .isEqualTo(THRESHOLD_1) + assertThat(mSfpsEnrollmentFeatureImpl.getEnrollStageThreshold(context, STAGE_2)) + .isEqualTo(THRESHOLD_2) + assertThat(mSfpsEnrollmentFeatureImpl.getEnrollStageThreshold(context, STAGE_3)) + .isEqualTo(THRESHOLD_3) + assertThat(mSfpsEnrollmentFeatureImpl.getEnrollStageThreshold(context, STAGE_4)) + .isEqualTo(THRESHOLD_4) } @Test fun testGetHelpAnimator() { val mockView: View = mock(View::class.java) val animator: Animator = mSfpsEnrollmentFeatureImpl.getHelpAnimator(mockView) - assertThat(animator.duration).isEqualTo(550) + assertThat(animator.duration).isEqualTo(SfpsEnrollmentFeatureImpl.HELP_ANIMATOR_DURATION) } @Test @@ -115,42 +126,27 @@ class SfpsEnrollmentFeatureImplTest { assertThat( mSfpsEnrollmentFeatureImpl.getFeaturedStageHeaderResource(SFPS_STAGE_NO_ANIMATION) ).isEqualTo( - settingsContext.resources.getIdentifier( - "security_settings_fingerprint_enroll_repeat_title", - type, - settingsPackageName) + getSettingsResourcesId(type, "security_settings_fingerprint_enroll_repeat_title") ) assertThat( mSfpsEnrollmentFeatureImpl.getFeaturedStageHeaderResource(SFPS_STAGE_CENTER) ).isEqualTo( - settingsContext.resources.getIdentifier( - "security_settings_sfps_enroll_finger_center_title", - type, - settingsPackageName) + getSettingsResourcesId(type, "security_settings_sfps_enroll_finger_center_title") ) assertThat( mSfpsEnrollmentFeatureImpl.getFeaturedStageHeaderResource(SFPS_STAGE_FINGERTIP) ).isEqualTo( - settingsContext.resources.getIdentifier( - "security_settings_sfps_enroll_fingertip_title", - type, - settingsPackageName) + getSettingsResourcesId(type, "security_settings_sfps_enroll_fingertip_title") ) assertThat( mSfpsEnrollmentFeatureImpl.getFeaturedStageHeaderResource(SFPS_STAGE_LEFT_EDGE) ).isEqualTo( - settingsContext.resources.getIdentifier( - "security_settings_sfps_enroll_left_edge_title", - type, - settingsPackageName) + getSettingsResourcesId(type, "security_settings_sfps_enroll_left_edge_title") ) assertThat( mSfpsEnrollmentFeatureImpl.getFeaturedStageHeaderResource(SFPS_STAGE_RIGHT_EDGE) ).isEqualTo( - settingsContext.resources.getIdentifier( - "security_settings_sfps_enroll_right_edge_title", - type, - settingsPackageName) + getSettingsResourcesId(type, "security_settings_sfps_enroll_right_edge_title") ) } @@ -159,43 +155,22 @@ class SfpsEnrollmentFeatureImplTest { val type = "raw" assertThat( mSfpsEnrollmentFeatureImpl.getSfpsEnrollLottiePerStage(SFPS_STAGE_NO_ANIMATION) - ).isEqualTo( - settingsContext.resources.getIdentifier( - "sfps_lottie_no_animation", - type, - settingsPackageName) - ) + ).isEqualTo(getSettingsResourcesId(type, "sfps_lottie_no_animation")) assertThat( mSfpsEnrollmentFeatureImpl.getSfpsEnrollLottiePerStage(SFPS_STAGE_CENTER) - ).isEqualTo( - settingsContext.resources.getIdentifier( - "sfps_lottie_pad_center", - type, - settingsPackageName) - ) + ).isEqualTo(getSettingsResourcesId(type, "sfps_lottie_pad_center")) assertThat( mSfpsEnrollmentFeatureImpl.getSfpsEnrollLottiePerStage(SFPS_STAGE_FINGERTIP) - ).isEqualTo( - settingsContext.resources.getIdentifier( - "sfps_lottie_tip", - type, - settingsPackageName) - ) + ).isEqualTo(getSettingsResourcesId(type, "sfps_lottie_tip")) assertThat( mSfpsEnrollmentFeatureImpl.getSfpsEnrollLottiePerStage(SFPS_STAGE_LEFT_EDGE) - ).isEqualTo( - settingsContext.resources.getIdentifier( - "sfps_lottie_left_edge", - type, - settingsPackageName) - ) + ).isEqualTo(getSettingsResourcesId(type, "sfps_lottie_left_edge")) assertThat( mSfpsEnrollmentFeatureImpl.getSfpsEnrollLottiePerStage(SFPS_STAGE_RIGHT_EDGE) - ).isEqualTo( - settingsContext.resources.getIdentifier( - "sfps_lottie_right_edge", - type, - settingsPackageName) - ) + ).isEqualTo(getSettingsResourcesId(type, "sfps_lottie_right_edge")) + } + + private fun getSettingsResourcesId(type: String, name: String) : Int { + return context.resources.getIdentifier(name, type, context.packageName) } } \ No newline at end of file diff --git a/tests/unit/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollProgressViewModelTest.java b/tests/unit/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollProgressViewModelTest.java index 418db04f7cc..2c7afa62fe4 100644 --- a/tests/unit/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollProgressViewModelTest.java +++ b/tests/unit/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollProgressViewModelTest.java @@ -98,7 +98,7 @@ public class FingerprintEnrollProgressViewModelTest { mCallbackWrapper.mValue = invocation.getArgument(3); return null; }).when(mFingerprintUpdater).enroll(any(byte[].class), any(CancellationSignal.class), - eq(TEST_USER_ID), any(EnrollmentCallback.class), anyInt()); + eq(TEST_USER_ID), any(EnrollmentCallback.class), anyInt(), any()); } @Test @@ -112,7 +112,7 @@ public class FingerprintEnrollProgressViewModelTest { assertThat(ret).isNotNull(); verify(mFingerprintUpdater, only()).enroll(eq(token), any(CancellationSignal.class), - eq(TEST_USER_ID), any(EnrollmentCallback.class), eq(enrollReason)); + eq(TEST_USER_ID), any(EnrollmentCallback.class), eq(enrollReason), any()); assertThat(mCallbackWrapper.mValue instanceof MessageDisplayController).isFalse(); } @@ -127,7 +127,7 @@ public class FingerprintEnrollProgressViewModelTest { assertThat(ret).isNotNull(); verify(mFingerprintUpdater, only()).enroll(eq(token), any(CancellationSignal.class), - eq(TEST_USER_ID), any(EnrollmentCallback.class), eq(enrollReason)); + eq(TEST_USER_ID), any(EnrollmentCallback.class), eq(enrollReason), any()); assertThat(mCallbackWrapper.mValue instanceof MessageDisplayController).isFalse(); } @@ -146,7 +146,7 @@ public class FingerprintEnrollProgressViewModelTest { assertThat(ret).isNotNull(); verify(mFingerprintUpdater, only()).enroll(eq(token), any(CancellationSignal.class), - eq(TEST_USER_ID), any(MessageDisplayController.class), eq(enrollReason)); + eq(TEST_USER_ID), any(MessageDisplayController.class), eq(enrollReason), any()); assertThat(mCallbackWrapper.mValue).isNotNull(); assertThat(mCallbackWrapper.mValue instanceof MessageDisplayController).isTrue(); @@ -158,7 +158,7 @@ public class FingerprintEnrollProgressViewModelTest { // Shall not use the same MessageDisplayController verify(mFingerprintUpdater, times(2)).enroll(eq(token), any(CancellationSignal.class), - eq(TEST_USER_ID), any(MessageDisplayController.class), eq(enrollReason)); + eq(TEST_USER_ID), any(MessageDisplayController.class), eq(enrollReason), any()); assertThat(mCallbackWrapper.mValue).isNotNull(); assertThat(callback1).isNotEqualTo(mCallbackWrapper.mValue); } @@ -170,7 +170,8 @@ public class FingerprintEnrollProgressViewModelTest { assertThat(ret).isNull(); verify(mFingerprintUpdater, never()).enroll(any(byte[].class), - any(CancellationSignal.class), anyInt(), any(EnrollmentCallback.class), anyInt()); + any(CancellationSignal.class), anyInt(), any(EnrollmentCallback.class), anyInt(), + any()); } @Test diff --git a/tests/unit/src/com/android/settings/fingerprint2/domain/interactor/FingerprintManagerInteractorTest.kt b/tests/unit/src/com/android/settings/fingerprint2/domain/interactor/FingerprintManagerInteractorTest.kt index c284a6fee7f..2b4bff77bc7 100644 --- a/tests/unit/src/com/android/settings/fingerprint2/domain/interactor/FingerprintManagerInteractorTest.kt +++ b/tests/unit/src/com/android/settings/fingerprint2/domain/interactor/FingerprintManagerInteractorTest.kt @@ -19,6 +19,7 @@ package com.android.settings.fingerprint2.domain.interactor import android.content.Context import android.content.Intent import android.hardware.fingerprint.Fingerprint +import android.hardware.fingerprint.FingerprintEnrollOptions import android.hardware.fingerprint.FingerprintManager import android.hardware.fingerprint.FingerprintManager.CryptoObject import android.hardware.fingerprint.FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT @@ -99,6 +100,7 @@ class FingerprintManagerInteractorTest { gateKeeperPasswordProvider, pressToAuthInteractor, Default, + Intent(), ) } @@ -312,7 +314,8 @@ class FingerprintManagerInteractorTest { any(CancellationSignal::class.java), anyInt(), capture(enrollCallback), - eq(FingerprintManager.ENROLL_FIND_SENSOR) + eq(FingerprintManager.ENROLL_FIND_SENSOR), + any(FingerprintEnrollOptions::class.java), ) enrollCallback.value.onEnrollmentProgress(1) runCurrent() @@ -336,7 +339,8 @@ class FingerprintManagerInteractorTest { any(CancellationSignal::class.java), anyInt(), capture(enrollCallback), - eq(FingerprintManager.ENROLL_FIND_SENSOR) + eq(FingerprintManager.ENROLL_FIND_SENSOR), + any(FingerprintEnrollOptions::class.java), ) enrollCallback.value.onEnrollmentHelp(-1, "help") runCurrent() @@ -360,7 +364,8 @@ class FingerprintManagerInteractorTest { any(CancellationSignal::class.java), anyInt(), capture(enrollCallback), - eq(FingerprintManager.ENROLL_FIND_SENSOR) + eq(FingerprintManager.ENROLL_FIND_SENSOR), + any(FingerprintEnrollOptions::class.java), ) enrollCallback.value.onEnrollmentError(-1, "error") runCurrent() diff --git a/tests/unit/src/com/android/settings/privatespace/HidePrivateSpaceSensitiveNotificationsControllerTest.java b/tests/unit/src/com/android/settings/privatespace/HidePrivateSpaceSensitiveNotificationsControllerTest.java new file mode 100644 index 00000000000..1430dfd1736 --- /dev/null +++ b/tests/unit/src/com/android/settings/privatespace/HidePrivateSpaceSensitiveNotificationsControllerTest.java @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2024 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.privatespace; + +import static com.android.settings.core.BasePreferenceController.AVAILABLE; +import static com.android.settings.core.BasePreferenceController.DISABLED_DEPENDENT_SETTING; +import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE; + +import static com.google.common.truth.Truth.assertThat; + +import static org.junit.Assume.assumeTrue; +import static org.mockito.Mockito.spy; + +import android.content.ContentResolver; +import android.content.Context; +import android.platform.test.flag.junit.SetFlagsRule; +import android.provider.Settings; + +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; + +/** + * Tests for HidePrivateSpaceSensitiveNotificationsController. + * Run as {@code atest SettingsUnitTests:HidePrivateSpaceSensitiveNotificationsControllerTest} + */ +@RunWith(AndroidJUnit4.class) +public class HidePrivateSpaceSensitiveNotificationsControllerTest { + @Rule + public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + + private Context mContext; + private HidePrivateSpaceSensitiveNotificationsController + mHidePrivateSpaceSensitiveNotificationsController; + @Mock + private ContentResolver mContentResolver; + private int mOriginalDeviceSensitiveNotifValue; + private int mOriginalDeviceNotifValue; + private int mOriginalPsSensitiveNotifValue; + private int mPrivateProfileId; + + @Before + public void setUp() { + mContext = spy(ApplicationProvider.getApplicationContext()); + mContentResolver = mContext.getContentResolver(); + assumeTrue(PrivateSpaceMaintainer.getInstance(mContext).doesPrivateSpaceExist()); + + mSetFlagsRule.enableFlags( + android.multiuser.Flags.FLAG_ENABLE_PS_SENSITIVE_NOTIFICATIONS_TOGGLE); + mSetFlagsRule.enableFlags(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE); + + mPrivateProfileId = PrivateSpaceMaintainer.getInstance( + mContext).getPrivateProfileHandle().getIdentifier(); + + mOriginalDeviceSensitiveNotifValue = Settings.Secure.getInt(mContentResolver, + Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1); + mOriginalDeviceNotifValue = Settings.Secure.getInt(mContentResolver, + Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1); + mOriginalPsSensitiveNotifValue = Settings.Secure.getIntForUser(mContentResolver, + Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, mPrivateProfileId); + + final String preferenceKey = "private_space_sensitive_notifications"; + mHidePrivateSpaceSensitiveNotificationsController = + new HidePrivateSpaceSensitiveNotificationsController(mContext, preferenceKey); + } + + @After + public void tearDown() { + Settings.Secure.putInt(mContentResolver, + Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, + mOriginalDeviceSensitiveNotifValue + ); + Settings.Secure.putInt(mContext.getContentResolver(), + Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, mOriginalDeviceNotifValue); + Settings.Secure.putIntForUser(mContext.getContentResolver(), + Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, + mOriginalPsSensitiveNotifValue, mPrivateProfileId); + } + + /** + * Tests that the controller is unavailable if lockscreen sensitive notifications are disabled + * on the device. + */ + @Test + public void getAvailabilityStatus_lockScreenPrivateNotificationsOff() { + Settings.Secure.putInt(mContext.getContentResolver(), + Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0); + assertThat(mHidePrivateSpaceSensitiveNotificationsController.getAvailabilityStatus()) + .isEqualTo(DISABLED_DEPENDENT_SETTING); + } + + /** + * Tests that the controller is unavailable if lockscreen notifications are disabled on the + * device. + */ + @Test + public void getAvailabilityStatus_lockScreenNotificationsOff() { + Settings.Secure.putInt(mContext.getContentResolver(), + Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0); + assertThat(mHidePrivateSpaceSensitiveNotificationsController.getAvailabilityStatus()) + .isEqualTo(DISABLED_DEPENDENT_SETTING); + } + + /** + * Tests that the controller is available if lockscreen notifications and lockscreen private + * notifications are enabled on the device. + */ + @Test + public void getAvailabilityStatus_returnAvailable() { + Settings.Secure.putInt(mContext.getContentResolver(), + Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1); + Settings.Secure.putInt(mContext.getContentResolver(), + Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1); + assertThat(mHidePrivateSpaceSensitiveNotificationsController.getAvailabilityStatus()) + .isEqualTo(AVAILABLE); + } + + + /** + * Tests that toggle is not available if the flag for this feature and MVP flag are disabled. + */ + @Test + public void getAvailabilityStatus_flagDisabled() { + mSetFlagsRule.disableFlags( + android.multiuser.Flags.FLAG_ENABLE_PS_SENSITIVE_NOTIFICATIONS_TOGGLE); + mSetFlagsRule.disableFlags(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE); + Settings.Secure.putInt(mContext.getContentResolver(), + Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1); + Settings.Secure.putInt(mContext.getContentResolver(), + Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1); + assertThat(mHidePrivateSpaceSensitiveNotificationsController.getAvailabilityStatus()) + .isEqualTo(UNSUPPORTED_ON_DEVICE); + } + + @Test + public void testSetChecked() { + assertThat(mHidePrivateSpaceSensitiveNotificationsController.setChecked(true)).isTrue(); + assertThat(mHidePrivateSpaceSensitiveNotificationsController.isChecked()).isEqualTo(true); + assertThat(mHidePrivateSpaceSensitiveNotificationsController.setChecked(false)).isTrue(); + assertThat(mHidePrivateSpaceSensitiveNotificationsController.isChecked()).isEqualTo(false); + } +} diff --git a/tests/unit/src/com/android/settings/privatespace/PrivateSpaceMaintainerTest.java b/tests/unit/src/com/android/settings/privatespace/PrivateSpaceMaintainerTest.java index 4bb5d43b59d..8510b11c9c6 100644 --- a/tests/unit/src/com/android/settings/privatespace/PrivateSpaceMaintainerTest.java +++ b/tests/unit/src/com/android/settings/privatespace/PrivateSpaceMaintainerTest.java @@ -16,6 +16,7 @@ package com.android.settings.privatespace; +import static android.provider.Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS; import static android.provider.Settings.Secure.PRIVATE_SPACE_AUTO_LOCK; import static com.android.settings.privatespace.PrivateSpaceMaintainer.HIDE_PRIVATE_SPACE_ENTRY_POINT_DISABLED_VAL; @@ -139,6 +140,24 @@ public class PrivateSpaceMaintainerTest { .isEqualTo(HIDE_PRIVATE_SPACE_ENTRY_POINT_DISABLED_VAL); } + /** + * Tests that {@link PrivateSpaceMaintainer#createPrivateSpace()} sets the PS sensitive + * notifications to hidden by default. + */ + @Test + public void createPrivateSpace_psDoesNotExist_setsDefaultPsSensitiveNotificationsValue() { + mSetFlagsRule.enableFlags( + Flags.FLAG_ALLOW_PRIVATE_PROFILE, + android.multiuser.Flags.FLAG_ENABLE_PS_SENSITIVE_NOTIFICATIONS_TOGGLE); + PrivateSpaceMaintainer privateSpaceMaintainer = + PrivateSpaceMaintainer.getInstance(mContext); + privateSpaceMaintainer.deletePrivateSpace(); + privateSpaceMaintainer.createPrivateSpace(); + assertThat(privateSpaceMaintainer.doesPrivateSpaceExist()).isTrue(); + assertThat(getPsSensitiveNotificationsValue(privateSpaceMaintainer)) + .isEqualTo(HidePrivateSpaceSensitiveNotificationsController.DISABLED); + } + /** * Tests that {@link PrivateSpaceMaintainer#createPrivateSpace()} when PS exist does not reset * hide PS Settings. @@ -287,4 +306,11 @@ public class PrivateSpaceMaintainerTest { 0, privateSpaceMaintainer.getPrivateProfileHandle().getIdentifier()); } + + private int getPsSensitiveNotificationsValue(PrivateSpaceMaintainer privateSpaceMaintainer) { + return Settings.Secure.getIntForUser(mContentResolver, + LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, + HidePrivateSpaceSensitiveNotificationsController.ENABLED, + privateSpaceMaintainer.getPrivateProfileHandle().getIdentifier()); + } }