Snap for 9957928 from 4d5ac5a89f to udc-release
Change-Id: I51bcde837f4e9b986fdc3958ab4544c41c2c85f2
This commit is contained in:
@@ -716,4 +716,9 @@
|
||||
<string name="battery_tip_incompatible_charging_message" product="default">Battery charging slowly or won\'t charge. Check if the cable and power adapter work with your phone</string>
|
||||
<string name="battery_tip_incompatible_charging_message" product="device">Battery charging slowly or won\'t charge. Check if the cable and power adapter work with your device</string>
|
||||
<string name="battery_tip_incompatible_charging_message" product="tablet">Battery charging slowly or won\'t charge. Check if the cable and power adapter work with your tablet</string>
|
||||
|
||||
<!-- Description for using device controls feature with a locked phone [CHAR LIMIT=NONE] -->
|
||||
<string name="lockscreen_trivial_controls_summary" product="default">Without unlocking your phone</string>
|
||||
<!-- Description for using device controls feature with a locked tablet [CHAR LIMIT=NONE] -->
|
||||
<string name="lockscreen_trivial_controls_summary" product="tabled">Without unlocking your tablet</string>
|
||||
</resources>
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
android:id="@+id/card_preference_buttons"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="24dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_below="@android:id/summary"
|
||||
android:visibility="gone">
|
||||
<Button
|
||||
@@ -105,4 +105,4 @@
|
||||
android:paddingEnd="0dp"
|
||||
android:orientation="vertical"/>
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
@@ -746,6 +746,8 @@
|
||||
|
||||
<!-- Fingerprint enrollment and settings --><skip />
|
||||
<!-- Note: Update FingerprintEnrollParentalConsent.CONSENT_STRING_RESOURCES when any _consent_ strings are added or removed. -->
|
||||
<!-- Title shown for choose lock options [CHAR LIMIT=22] -->
|
||||
<string name="security_settings_fingerprint">Fingerprint</string>
|
||||
<!-- Title shown for menu item that launches fingerprint settings or enrollment [CHAR LIMIT=22] -->
|
||||
<string name="security_settings_fingerprint_preference_title">Fingerprint</string>
|
||||
<!-- Title for a category shown for the fingerprint settings page, followed by items that the user can toggle on/off to require/disable. [CHAR LIMIT=50] -->
|
||||
@@ -10282,13 +10284,10 @@
|
||||
<string name="credman_confirmation_message">Saved info like addresses or payment methods won\'t be filled in when you sign in. To keep your saved info filled in, set enable a password, passkey and data/or service.</string>
|
||||
|
||||
<!-- Title of the warning dialog for enabling the credential provider. [CHAR_LIMIT=NONE] -->
|
||||
<string name="credman_enable_confirmation_message_title">Turn on %1$s\?</string>
|
||||
<string name="credman_enable_confirmation_message_title">Use %1$s\?</string>
|
||||
|
||||
<!-- Message of the warning dialog for enabling the credential provider. [CHAR_LIMIT=NONE] -->
|
||||
<string name="credman_enable_confirmation_message">Saved info like addresses or payment methods will be shared with this provider.</string>
|
||||
|
||||
<!-- Positive button to turn on credential manager provider (confirmation). [CHAR LIMIT=60] -->
|
||||
<string name="credman_enable_confirmation_message_positive_button">Turn on</string>
|
||||
<string name="credman_enable_confirmation_message">%1$s uses what\'s on your screen to determine what can be autofilled.</string>
|
||||
|
||||
<!-- Title of the error dialog when too many credential providers are selected. [CHAR_LIMIT=NONE] -->
|
||||
<string name="credman_error_message_title">Passwords, passkeys and data services limit</string>
|
||||
@@ -11238,11 +11237,9 @@
|
||||
<!-- Device controls toggle name [CHAR LIMIT=60] -->
|
||||
<string name="lockscreen_privacy_controls_setting_toggle">Show device controls</string>
|
||||
<!-- Device controls summary [CHAR LIMIT=NONE] -->
|
||||
<string name="lockscreen_privacy_controls_summary">Show controls for external devices from the lock screen</string>
|
||||
<string name="lockscreen_privacy_controls_summary">From the lockscreen</string>
|
||||
<!-- Trivial Device controls toggle name [CHAR LIMIT=60] -->
|
||||
<string name="lockscreen_trivial_controls_setting_toggle">Control from locked device</string>
|
||||
<!-- Trivial Device controls summary [CHAR LIMIT=NONE] -->
|
||||
<string name="lockscreen_trivial_controls_summary">Control external devices without unlocking your phone or tablet if allowed by the device controls app</string>
|
||||
<string name="lockscreen_trivial_controls_setting_toggle">Use device controls</string>
|
||||
<!-- Trivial Device disabled controls summary [CHAR LIMIT=NONE] -->
|
||||
<string name="lockscreen_trivial_disabled_controls_summary">To use, first turn on \u0022Show device controls\u0022</string>
|
||||
<!-- Lockscreen double-line clock summary [CHAR LIMIT=NONE] -->
|
||||
|
||||
@@ -153,8 +153,7 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
|
||||
}
|
||||
|
||||
final String action = launchIntent.getAction();
|
||||
final boolean isCredProviderAction =
|
||||
TextUtils.equals(action, PRIMARY_INTENT);
|
||||
final boolean isCredProviderAction = TextUtils.equals(action, PRIMARY_INTENT);
|
||||
final boolean isExistingAction = TextUtils.equals(action, ALTERNATE_INTENT);
|
||||
final boolean isValid = isCredProviderAction || isExistingAction;
|
||||
|
||||
@@ -226,7 +225,8 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
|
||||
}
|
||||
|
||||
NewProviderConfirmationDialogFragment fragment =
|
||||
newNewProviderConfirmationDialogFragment(serviceInfo.packageName, appName);
|
||||
newNewProviderConfirmationDialogFragment(
|
||||
serviceInfo.packageName, appName, /* setActivityResult= */ true);
|
||||
if (fragment == null || mFragmentManager == null) {
|
||||
return;
|
||||
}
|
||||
@@ -482,20 +482,17 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
|
||||
boolean isChecked = pref.isChecked();
|
||||
|
||||
if (isChecked) {
|
||||
// Show the error if too many enabled.
|
||||
if (!togglePackageNameEnabled(packageName)) {
|
||||
final DialogFragment fragment = newErrorDialogFragment();
|
||||
|
||||
if (fragment == null || mFragmentManager == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
fragment.show(mFragmentManager, ErrorDialogFragment.TAG);
|
||||
|
||||
// The user set the check to true so we need to set it back.
|
||||
pref.setChecked(false);
|
||||
// Since we are enabling it we should confirm the user decision with a
|
||||
// dialog box.
|
||||
NewProviderConfirmationDialogFragment fragment =
|
||||
newNewProviderConfirmationDialogFragment(
|
||||
packageName, title, /* setActivityResult= */ false);
|
||||
if (fragment == null || mFragmentManager == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
fragment.show(mFragmentManager, NewProviderConfirmationDialogFragment.TAG);
|
||||
|
||||
return true;
|
||||
} else {
|
||||
// If we are disabling the last enabled provider then show a warning.
|
||||
@@ -546,12 +543,15 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
|
||||
/** Create the new provider confirmation dialog. */
|
||||
private @Nullable NewProviderConfirmationDialogFragment
|
||||
newNewProviderConfirmationDialogFragment(
|
||||
@NonNull String packageName, @NonNull CharSequence appName) {
|
||||
@NonNull String packageName,
|
||||
@NonNull CharSequence appName,
|
||||
boolean setActivityResult) {
|
||||
DialogHost host =
|
||||
new DialogHost() {
|
||||
@Override
|
||||
public void onDialogClick(int whichButton) {
|
||||
completeEnableProviderDialogBox(whichButton, packageName);
|
||||
completeEnableProviderDialogBox(
|
||||
whichButton, packageName, setActivityResult);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -559,17 +559,19 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void completeEnableProviderDialogBox(int whichButton, String packageName) {
|
||||
void completeEnableProviderDialogBox(
|
||||
int whichButton, String packageName, boolean setActivityResult) {
|
||||
int activityResult = -1;
|
||||
if (whichButton == DialogInterface.BUTTON_POSITIVE) {
|
||||
if (togglePackageNameEnabled(packageName)) {
|
||||
// Enable all prefs.
|
||||
if (mPrefs.containsKey(packageName)) {
|
||||
mPrefs.get(packageName).setChecked(true);
|
||||
}
|
||||
setActivityResult(Activity.RESULT_OK);
|
||||
activityResult = Activity.RESULT_OK;
|
||||
} else {
|
||||
// There are too many providers so set the result as cancelled.
|
||||
setActivityResult(Activity.RESULT_CANCELED);
|
||||
activityResult = Activity.RESULT_CANCELED;
|
||||
|
||||
// Show the error if too many enabled.
|
||||
final DialogFragment fragment = newErrorDialogFragment();
|
||||
@@ -582,7 +584,13 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
|
||||
}
|
||||
} else {
|
||||
// The user clicked the cancel button so send that result back.
|
||||
setActivityResult(Activity.RESULT_CANCELED);
|
||||
activityResult = Activity.RESULT_CANCELED;
|
||||
}
|
||||
|
||||
// If the dialog is being shown because of the intent we should
|
||||
// return a result.
|
||||
if (activityResult == -1 || !setActivityResult) {
|
||||
setActivityResult(activityResult);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -735,16 +743,17 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
final Bundle bundle = getArguments();
|
||||
final Context context = getContext();
|
||||
final CharSequence appName =
|
||||
bundle.getCharSequence(CredentialManagerDialogFragment.APP_NAME_KEY);
|
||||
final String title =
|
||||
context.getString(
|
||||
R.string.credman_enable_confirmation_message_title,
|
||||
bundle.getCharSequence(CredentialManagerDialogFragment.APP_NAME_KEY));
|
||||
context.getString(R.string.credman_enable_confirmation_message_title, appName);
|
||||
final String message =
|
||||
context.getString(R.string.credman_enable_confirmation_message, appName);
|
||||
|
||||
return new AlertDialog.Builder(getActivity())
|
||||
.setTitle(title)
|
||||
.setMessage(context.getString(R.string.credman_enable_confirmation_message))
|
||||
.setPositiveButton(
|
||||
R.string.credman_enable_confirmation_message_positive_button, this)
|
||||
.setMessage(message)
|
||||
.setPositiveButton(android.R.string.ok, this)
|
||||
.setNegativeButton(android.R.string.cancel, this)
|
||||
.create();
|
||||
}
|
||||
|
||||
@@ -237,20 +237,7 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mHasFeatureFingerprint) {
|
||||
final FingerprintManager fpManager = getSystemService(FingerprintManager.class);
|
||||
final List<FingerprintSensorPropertiesInternal> fpProperties =
|
||||
fpManager.getSensorPropertiesInternal();
|
||||
final int maxFingerprintsEnrollableIfSUW = getApplicationContext().getResources()
|
||||
.getInteger(R.integer.suw_max_fingerprints_enrollable);
|
||||
if (!fpProperties.isEmpty()) {
|
||||
final int maxEnrolls =
|
||||
isSetupWizard ? maxFingerprintsEnrollableIfSUW
|
||||
: fpProperties.get(0).maxEnrollmentsPerUser;
|
||||
mIsFingerprintEnrollable =
|
||||
fpManager.getEnrolledFingerprints(mUserId).size() < maxEnrolls;
|
||||
}
|
||||
}
|
||||
updateFingerprintEnrollable(isSetupWizard);
|
||||
|
||||
// TODO(b/195128094): remove this restriction
|
||||
// Consent can only be recorded when this activity is launched directly from the kids
|
||||
@@ -289,6 +276,23 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
|
||||
}
|
||||
}
|
||||
|
||||
private void updateFingerprintEnrollable(boolean isSetupWizard) {
|
||||
if (mHasFeatureFingerprint) {
|
||||
final FingerprintManager fpManager = getSystemService(FingerprintManager.class);
|
||||
final List<FingerprintSensorPropertiesInternal> fpProperties =
|
||||
fpManager.getSensorPropertiesInternal();
|
||||
final int maxFingerprintsEnrollableIfSUW = getApplicationContext().getResources()
|
||||
.getInteger(R.integer.suw_max_fingerprints_enrollable);
|
||||
if (!fpProperties.isEmpty()) {
|
||||
final int maxEnrolls =
|
||||
isSetupWizard ? maxFingerprintsEnrollableIfSUW
|
||||
: fpProperties.get(0).maxEnrollmentsPerUser;
|
||||
mIsFingerprintEnrollable =
|
||||
fpManager.getEnrolledFingerprints(mUserId).size() < maxEnrolls;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void startEnrollWith(@Authenticators.Types int authenticators, boolean setupWizard) {
|
||||
// If the caller is not setup wizard, and the user has something enrolled, finish.
|
||||
// Allow parental consent flow to skip this check, since one modality could be consented
|
||||
@@ -464,12 +468,12 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
|
||||
mConfirmingCredentials = false;
|
||||
final boolean isOk =
|
||||
isSuccessfulConfirmOrChooseCredential(requestCode, resultCode);
|
||||
if (isOk && (mHasFeatureFace || mHasFeatureFingerprint)) {
|
||||
if (isOk && (mIsFaceEnrollable || mIsFingerprintEnrollable)) {
|
||||
// Apply forward animation during the transition from ChooseLock/ConfirmLock to
|
||||
// SetupFingerprintEnrollIntroduction/FingerprintEnrollmentActivity
|
||||
TransitionHelper.applyForwardTransition(this, TRANSITION_FADE_THROUGH);
|
||||
updateGatekeeperPasswordHandle(data);
|
||||
if (mHasFeatureFingerprint) {
|
||||
if (mIsFingerprintEnrollable) {
|
||||
launchFingerprintOnlyEnroll();
|
||||
} else {
|
||||
launchFaceOnlyEnroll();
|
||||
@@ -482,8 +486,15 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
|
||||
break;
|
||||
case REQUEST_SINGLE_ENROLL_FINGERPRINT:
|
||||
mIsSingleEnrolling = false;
|
||||
if (resultCode == BiometricEnrollBase.RESULT_FINISHED) {
|
||||
// FingerprintEnrollIntroduction's visibility is determined by
|
||||
// mIsFingerprintEnrollable. Keep this value up-to-date after a successful
|
||||
// enrollment.
|
||||
updateFingerprintEnrollable(WizardManagerHelper.isAnySetupWizard(getIntent()));
|
||||
}
|
||||
if ((resultCode == BiometricEnrollBase.RESULT_SKIP
|
||||
|| resultCode == BiometricEnrollBase.RESULT_FINISHED) && mHasFeatureFace) {
|
||||
|| resultCode == BiometricEnrollBase.RESULT_FINISHED)
|
||||
&& mIsFaceEnrollable) {
|
||||
// Apply forward animation during the transition from
|
||||
// SetupFingerprintEnroll*/FingerprintEnrollmentActivity to
|
||||
// SetupFaceEnrollIntroduction
|
||||
@@ -495,7 +506,7 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
|
||||
break;
|
||||
case REQUEST_SINGLE_ENROLL_FACE:
|
||||
mIsSingleEnrolling = false;
|
||||
if (resultCode == Activity.RESULT_CANCELED && mHasFeatureFingerprint) {
|
||||
if (resultCode == Activity.RESULT_CANCELED && mIsFingerprintEnrollable) {
|
||||
launchFingerprintOnlyEnroll();
|
||||
} else {
|
||||
finishOrLaunchHandToParent(resultCode);
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.settings.biometrics.face;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.hardware.biometrics.SensorProperties;
|
||||
import android.hardware.face.FaceManager;
|
||||
import android.hardware.face.FaceSensorPropertiesInternal;
|
||||
@@ -49,32 +50,17 @@ public class FaceSettingsFooterPreferenceController extends BasePreferenceContro
|
||||
public FaceSettingsFooterPreferenceController(Context context, String preferenceKey) {
|
||||
super(context, preferenceKey);
|
||||
mProvider = FeatureFactory.getFactory(context).getFaceFeatureProvider();
|
||||
FaceManager faceManager = context.getSystemService(FaceManager.class);
|
||||
faceManager.addAuthenticatorsRegisteredCallback(
|
||||
new IFaceAuthenticatorsRegisteredCallback.Stub() {
|
||||
@Override
|
||||
public void onAllAuthenticatorsRegistered(
|
||||
@NonNull List<FaceSensorPropertiesInternal> sensors) {
|
||||
if (sensors.isEmpty()) {
|
||||
Log.e(TAG, "No sensors");
|
||||
return;
|
||||
}
|
||||
|
||||
boolean isFaceStrong = sensors.get(0).sensorStrength
|
||||
== SensorProperties.STRENGTH_STRONG;
|
||||
if (mIsFaceStrong == isFaceStrong) {
|
||||
return;
|
||||
}
|
||||
mIsFaceStrong = isFaceStrong;
|
||||
updateState(mPreference);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
mPreference = screen.findPreference(mPreferenceKey);
|
||||
if (screen.getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_FACE)) {
|
||||
addAuthenticatorsRegisteredCallback(screen.getContext());
|
||||
} else {
|
||||
Log.w(TAG, "Not support FEATURE_FACE");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -105,4 +91,27 @@ public class FaceSettingsFooterPreferenceController extends BasePreferenceContro
|
||||
preference.setTitle(AnnotationSpan.linkify(
|
||||
mContext.getText(footerRes), linkInfo));
|
||||
}
|
||||
|
||||
private void addAuthenticatorsRegisteredCallback(Context context) {
|
||||
final FaceManager faceManager = context.getSystemService(FaceManager.class);
|
||||
faceManager.addAuthenticatorsRegisteredCallback(
|
||||
new IFaceAuthenticatorsRegisteredCallback.Stub() {
|
||||
@Override
|
||||
public void onAllAuthenticatorsRegistered(
|
||||
@NonNull List<FaceSensorPropertiesInternal> sensors) {
|
||||
if (sensors.isEmpty()) {
|
||||
Log.e(TAG, "No sensors");
|
||||
return;
|
||||
}
|
||||
|
||||
boolean isFaceStrong = sensors.get(0).sensorStrength
|
||||
== SensorProperties.STRENGTH_STRONG;
|
||||
if (mIsFaceStrong == isFaceStrong) {
|
||||
return;
|
||||
}
|
||||
mIsFaceStrong = isFaceStrong;
|
||||
updateState(mPreference);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,6 +48,8 @@ import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.os.storage.StorageManager;
|
||||
import android.service.persistentdata.PersistentDataBlockManager;
|
||||
import android.text.BidiFormatter;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.TextUtils;
|
||||
import android.util.EventLog;
|
||||
import android.util.Log;
|
||||
@@ -56,6 +58,7 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
@@ -76,6 +79,7 @@ import com.android.settings.biometrics.BiometricEnrollActivity;
|
||||
import com.android.settings.biometrics.BiometricEnrollBase;
|
||||
import com.android.settings.core.SubSettingLauncher;
|
||||
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settings.safetycenter.LockScreenSafetySource;
|
||||
import com.android.settings.search.SearchFeatureProvider;
|
||||
import com.android.settingslib.RestrictedPreference;
|
||||
@@ -139,6 +143,9 @@ public class ChooseLockGeneric extends SettingsActivity {
|
||||
*/
|
||||
public static final String EXTRA_CHOOSE_LOCK_GENERIC_EXTRAS = "choose_lock_generic_extras";
|
||||
|
||||
/** The character ' • ' to separate the setup choose options */
|
||||
public static final String SEPARATOR = " \u2022 ";
|
||||
|
||||
@VisibleForTesting
|
||||
static final int CONFIRM_EXISTING_REQUEST = 100;
|
||||
@VisibleForTesting
|
||||
@@ -628,10 +635,11 @@ public class ChooseLockGeneric extends SettingsActivity {
|
||||
R.string.face_unlock_set_unlock_password);
|
||||
} else if (mForBiometrics) {
|
||||
setPreferenceTitle(ScreenLockType.PATTERN,
|
||||
R.string.biometrics_unlock_set_unlock_pattern);
|
||||
setPreferenceTitle(ScreenLockType.PIN, R.string.biometrics_unlock_set_unlock_pin);
|
||||
getBiometricsPreferenceTitle(ScreenLockType.PATTERN));
|
||||
setPreferenceTitle(ScreenLockType.PIN,
|
||||
getBiometricsPreferenceTitle(ScreenLockType.PIN));
|
||||
setPreferenceTitle(ScreenLockType.PASSWORD,
|
||||
R.string.biometrics_unlock_set_unlock_password);
|
||||
getBiometricsPreferenceTitle(ScreenLockType.PASSWORD));
|
||||
}
|
||||
|
||||
if (mManagedPasswordProvider.isSettingManagedPasswordSupported()) {
|
||||
@@ -652,6 +660,36 @@ public class ChooseLockGeneric extends SettingsActivity {
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
String getBiometricsPreferenceTitle(@NonNull ScreenLockType secureType) {
|
||||
SpannableStringBuilder ssb = new SpannableStringBuilder();
|
||||
BidiFormatter bidi = BidiFormatter.getInstance();
|
||||
// Assume the flow is "Screen Lock" + "Face" + "Fingerprint"
|
||||
if (mController != null) {
|
||||
ssb.append(bidi.unicodeWrap(mController.getTitle(secureType)));
|
||||
} else {
|
||||
Log.e(TAG, "ChooseLockGenericController is null!");
|
||||
}
|
||||
|
||||
if (mFaceManager != null && mFaceManager.isHardwareDetected() && isFaceSupported()) {
|
||||
ssb.append(bidi.unicodeWrap(SEPARATOR));
|
||||
ssb.append(bidi.unicodeWrap(
|
||||
getResources().getString(R.string.keywords_face_settings)));
|
||||
}
|
||||
if (mFingerprintManager != null && mFingerprintManager.isHardwareDetected()) {
|
||||
ssb.append(bidi.unicodeWrap(SEPARATOR));
|
||||
ssb.append(bidi.unicodeWrap(
|
||||
getResources().getString(R.string.security_settings_fingerprint)));
|
||||
}
|
||||
return ssb.toString();
|
||||
}
|
||||
|
||||
private boolean isFaceSupported() {
|
||||
return FeatureFactory.getFactory(getContext().getApplicationContext())
|
||||
.getFaceFeatureProvider()
|
||||
.isSetupWizardSupported(getContext().getApplicationContext());
|
||||
}
|
||||
|
||||
private void setPreferenceTitle(ScreenLockType lock, @StringRes int title) {
|
||||
Preference preference = findPreference(lock.preferenceKey);
|
||||
if (preference != null) {
|
||||
@@ -815,6 +853,14 @@ public class ChooseLockGeneric extends SettingsActivity {
|
||||
return intent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
if (!getActivity().isChangingConfigurations() && !mWaitingForConfirmation) {
|
||||
getActivity().finish();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.settings.privacy;
|
||||
import static android.safetylabel.SafetyLabelConstants.SAFETY_LABEL_CHANGE_NOTIFICATIONS_ENABLED;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.provider.DeviceConfig;
|
||||
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
@@ -28,7 +29,6 @@ import com.android.settings.core.BasePreferenceController;
|
||||
* TODO b/264939792: Add tests
|
||||
*/
|
||||
public class AppDataSharingUpdatesPreferenceController extends BasePreferenceController {
|
||||
|
||||
public AppDataSharingUpdatesPreferenceController(Context context,
|
||||
String preferenceKey) {
|
||||
super(context, preferenceKey);
|
||||
@@ -36,8 +36,16 @@ public class AppDataSharingUpdatesPreferenceController extends BasePreferenceCon
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_PRIVACY,
|
||||
SAFETY_LABEL_CHANGE_NOTIFICATIONS_ENABLED, false)
|
||||
return isPrivacySafetyLabelChangeNotificationsEnabled(mContext)
|
||||
? AVAILABLE : UNSUPPORTED_ON_DEVICE;
|
||||
}
|
||||
|
||||
private boolean isPrivacySafetyLabelChangeNotificationsEnabled(Context context) {
|
||||
PackageManager packageManager = context.getPackageManager();
|
||||
return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_PRIVACY,
|
||||
SAFETY_LABEL_CHANGE_NOTIFICATIONS_ENABLED, false)
|
||||
&& !packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)
|
||||
&& !packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK)
|
||||
&& !packageManager.hasSystemFeature(PackageManager.FEATURE_WATCH);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,10 +18,14 @@ package com.android.settings.biometrics.face;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.hardware.face.FaceManager;
|
||||
import android.hardware.face.FaceSensorProperties;
|
||||
import android.hardware.face.FaceSensorPropertiesInternal;
|
||||
@@ -59,6 +63,8 @@ public class FaceSettingsFooterPreferenceControllerTest {
|
||||
private static final String PREF_KEY = "security_face_footer";
|
||||
@Mock
|
||||
private FaceManager mFaceManager;
|
||||
@Mock
|
||||
PackageManager mPackageManager;
|
||||
@Captor
|
||||
private ArgumentCaptor<IFaceAuthenticatorsRegisteredCallback> mCaptor;
|
||||
private Preference mPreference;
|
||||
@@ -71,8 +77,20 @@ public class FaceSettingsFooterPreferenceControllerTest {
|
||||
if (Looper.myLooper() == null) {
|
||||
Looper.prepare(); // needed to create the preference screen
|
||||
}
|
||||
ShadowApplication.getInstance().setSystemService(Context.FACE_SERVICE, mFaceManager);
|
||||
when(mContext.getPackageManager()).thenReturn(mPackageManager);
|
||||
when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)).thenReturn(true);
|
||||
}
|
||||
|
||||
private void setupHasFaceFeature() {
|
||||
when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FACE)).thenReturn(true);
|
||||
}
|
||||
|
||||
private void setupNoFaceFeature() {
|
||||
when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FACE)).thenReturn(false);
|
||||
}
|
||||
|
||||
private void displayFaceSettingsFooterPreferenceController() {
|
||||
ShadowApplication.getInstance().setSystemService(Context.FACE_SERVICE, mFaceManager);
|
||||
mController = new FaceSettingsFooterPreferenceController(mContext, PREF_KEY);
|
||||
PreferenceScreen screen = new PreferenceManager(mContext).createPreferenceScreen(mContext);
|
||||
mPreference = new FooterPreference(mContext);
|
||||
@@ -82,13 +100,24 @@ public class FaceSettingsFooterPreferenceControllerTest {
|
||||
mController.displayPreference(screen);
|
||||
}
|
||||
|
||||
private void createFaceSettingsFooterPreferenceController() {
|
||||
ShadowApplication.getInstance().setSystemService(Context.FACE_SERVICE, mFaceManager);
|
||||
mController = new FaceSettingsFooterPreferenceController(mContext, PREF_KEY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSliceable_returnFalse() {
|
||||
setupHasFaceFeature();
|
||||
displayFaceSettingsFooterPreferenceController();
|
||||
|
||||
assertThat(mController.isSliceable()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testString_faceNotClass3() throws RemoteException {
|
||||
setupHasFaceFeature();
|
||||
displayFaceSettingsFooterPreferenceController();
|
||||
|
||||
verify(mFaceManager).addAuthenticatorsRegisteredCallback(mCaptor.capture());
|
||||
mController.updateState(mPreference);
|
||||
|
||||
@@ -112,6 +141,9 @@ public class FaceSettingsFooterPreferenceControllerTest {
|
||||
|
||||
@Test
|
||||
public void testString_faceClass3() throws RemoteException {
|
||||
setupHasFaceFeature();
|
||||
displayFaceSettingsFooterPreferenceController();
|
||||
|
||||
verify(mFaceManager).addAuthenticatorsRegisteredCallback(mCaptor.capture());
|
||||
mController.updateState(mPreference);
|
||||
|
||||
@@ -132,4 +164,30 @@ public class FaceSettingsFooterPreferenceControllerTest {
|
||||
assertThat(mPreference.getTitle().toString()).isEqualTo(
|
||||
mContext.getString(R.string.security_settings_face_settings_footer_class3));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSupportFaceFeature_shouldAddAuthenticatorsRegisteredCallback() {
|
||||
setupHasFaceFeature();
|
||||
displayFaceSettingsFooterPreferenceController();
|
||||
|
||||
verify(mFaceManager).addAuthenticatorsRegisteredCallback(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoFaceFeature_shouldNotAddAuthenticatorsRegisteredCallback() {
|
||||
setupNoFaceFeature();
|
||||
displayFaceSettingsFooterPreferenceController();
|
||||
|
||||
verify(mContext, never()).getSystemService(FaceManager.class);
|
||||
verify(mFaceManager, never()).addAuthenticatorsRegisteredCallback(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHasFaceFeature_shouldNotAddAuthenticatorsRegisteredCallback_inCtor() {
|
||||
setupHasFaceFeature();
|
||||
createFaceSettingsFooterPreferenceController();
|
||||
|
||||
verify(mContext, never()).getSystemService(FaceManager.class);
|
||||
verify(mFaceManager, never()).addAuthenticatorsRegisteredCallback(any());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,11 +29,14 @@ import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE;
|
||||
import static com.android.settings.password.ChooseLockGeneric.ChooseLockGenericFragment.KEY_LOCK_SETTINGS_FOOTER;
|
||||
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_CALLER_APP_NAME;
|
||||
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_DEVICE_PASSWORD_REQUIREMENT_ONLY;
|
||||
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_FOR_BIOMETRICS;
|
||||
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_IS_CALLING_APP_ADMIN;
|
||||
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_REQUESTED_MIN_COMPLEXITY;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.robolectric.RuntimeEnvironment.application;
|
||||
import static org.robolectric.Shadows.shadowOf;
|
||||
|
||||
@@ -43,6 +46,8 @@ import android.app.admin.PasswordMetrics;
|
||||
import android.app.admin.PasswordPolicy;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.hardware.face.FaceManager;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings.Global;
|
||||
|
||||
@@ -55,6 +60,7 @@ import com.android.settings.R;
|
||||
import com.android.settings.biometrics.BiometricEnrollBase;
|
||||
import com.android.settings.password.ChooseLockGeneric.ChooseLockGenericFragment;
|
||||
import com.android.settings.search.SearchFeatureProvider;
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
import com.android.settings.testutils.shadow.ShadowInteractionJankMonitor;
|
||||
import com.android.settings.testutils.shadow.ShadowLockPatternUtils;
|
||||
import com.android.settings.testutils.shadow.ShadowStorageManager;
|
||||
@@ -65,8 +71,12 @@ import com.android.settingslib.widget.FooterPreference;
|
||||
import org.junit.After;
|
||||
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.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
@@ -86,13 +96,33 @@ import org.robolectric.shadows.ShadowPersistentDataBlockManager;
|
||||
@Ignore("b/179136903: Tests failed with collapsing toolbar, plan to figure out root cause later.")
|
||||
public class ChooseLockGenericTest {
|
||||
|
||||
@Rule
|
||||
public final MockitoRule mMockitoRule = MockitoJUnit.rule();
|
||||
private FakeFeatureFactory mFakeFeatureFactory;
|
||||
private ChooseLockGenericFragment mFragment;
|
||||
private ChooseLockGeneric mActivity;
|
||||
@Mock
|
||||
private FingerprintManager mFingerprintManager;
|
||||
@Mock
|
||||
private FaceManager mFaceManager;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
|
||||
mActivity = Robolectric.buildActivity(ChooseLockGeneric.class)
|
||||
.create()
|
||||
.start()
|
||||
.postCreate(null)
|
||||
.resume()
|
||||
.get();
|
||||
|
||||
Global.putInt(application.getContentResolver(), Global.DEVICE_PROVISIONED, 1);
|
||||
mFragment = new ChooseLockGenericFragment();
|
||||
|
||||
when(mFaceManager.isHardwareDetected()).thenReturn(true);
|
||||
when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
|
||||
when(mFakeFeatureFactory.mFaceFeatureProvider.isSetupWizardSupported(any())).thenReturn(
|
||||
false);
|
||||
}
|
||||
|
||||
@After
|
||||
@@ -490,13 +520,47 @@ public class ChooseLockGenericTest {
|
||||
new PasswordMetrics(CREDENTIAL_TYPE_NONE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updatePreferenceText_supportBiometrics_showFaceAndFingerprint() {
|
||||
ShadowLockPatternUtils.setRequiredPasswordComplexity(PASSWORD_COMPLEXITY_LOW);
|
||||
final PasswordPolicy policy = new PasswordPolicy();
|
||||
policy.quality = PASSWORD_QUALITY_ALPHABETIC;
|
||||
ShadowLockPatternUtils.setRequestedProfilePasswordMetrics(policy.getMinMetrics());
|
||||
|
||||
final Intent intent = new Intent().putExtra(EXTRA_KEY_FOR_BIOMETRICS, true);
|
||||
initActivity(intent);
|
||||
|
||||
final Intent passwordIntent = mFragment.getLockPatternIntent();
|
||||
assertThat(passwordIntent.getIntExtra(ChooseLockPassword.EXTRA_KEY_MIN_COMPLEXITY,
|
||||
PASSWORD_COMPLEXITY_NONE)).isEqualTo(PASSWORD_COMPLEXITY_LOW);
|
||||
|
||||
final String supportFingerprint = mActivity.getResources().getString(
|
||||
R.string.security_settings_fingerprint);
|
||||
final String supportFace = mActivity.getResources().getString(
|
||||
R.string.keywords_face_settings);
|
||||
|
||||
assertThat(mFragment.getBiometricsPreferenceTitle(ScreenLockType.PIN)).contains(
|
||||
supportFingerprint);
|
||||
assertThat(mFragment.getBiometricsPreferenceTitle(ScreenLockType.PIN)).contains(
|
||||
supportFace);
|
||||
assertThat(mFragment.getBiometricsPreferenceTitle(ScreenLockType.PATTERN)).contains(
|
||||
supportFingerprint);
|
||||
assertThat(mFragment.getBiometricsPreferenceTitle(ScreenLockType.PATTERN)).contains(
|
||||
supportFace);
|
||||
assertThat(mFragment.getBiometricsPreferenceTitle(ScreenLockType.PASSWORD)).contains(
|
||||
supportFingerprint);
|
||||
assertThat(mFragment.getBiometricsPreferenceTitle(ScreenLockType.PASSWORD)).contains(
|
||||
supportFace);
|
||||
}
|
||||
|
||||
private void initActivity(@Nullable Intent intent) {
|
||||
if (intent == null) {
|
||||
intent = new Intent();
|
||||
}
|
||||
intent.putExtra(ChooseLockGeneric.CONFIRM_CREDENTIALS, false);
|
||||
// TODO(b/275023433) This presents the activity from being made 'visible` is workaround
|
||||
mActivity = Robolectric.buildActivity(ChooseLockGeneric.InternalActivity.class, intent)
|
||||
.setup().get();
|
||||
.create().start().postCreate(null).resume().get();
|
||||
mActivity.getSupportFragmentManager().beginTransaction().add(mFragment, null).commitNow();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,13 +23,22 @@ import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_R
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.robolectric.RuntimeEnvironment.application;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.hardware.face.FaceManager;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.password.SetupChooseLockGeneric.SetupChooseLockGenericFragment;
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
import com.android.settings.testutils.shadow.ShadowLockPatternUtils;
|
||||
import com.android.settings.testutils.shadow.ShadowPasswordUtils;
|
||||
import com.android.settings.testutils.shadow.ShadowUserManager;
|
||||
@@ -38,8 +47,13 @@ import com.android.settings.testutils.shadow.ShadowUtils;
|
||||
import com.google.android.setupdesign.GlifPreferenceLayout;
|
||||
|
||||
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;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.Shadows;
|
||||
@@ -56,6 +70,28 @@ import java.util.List;
|
||||
})
|
||||
public class SetupChooseLockGenericTest {
|
||||
|
||||
@Rule
|
||||
public final MockitoRule mMockitoRule = MockitoJUnit.rule();
|
||||
@Mock
|
||||
private FakeFeatureFactory mFakeFeatureFactory;
|
||||
@Mock
|
||||
private FingerprintManager mFingerprintManager;
|
||||
@Mock
|
||||
private FaceManager mFaceManager;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
ShadowUtils.setFingerprintManager(mFingerprintManager);
|
||||
ShadowUtils.setFaceManager(mFaceManager);
|
||||
mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
|
||||
|
||||
Settings.Global.putInt(application.getContentResolver(), Settings.Global.DEVICE_PROVISIONED,
|
||||
0);
|
||||
|
||||
when(mFaceManager.isHardwareDetected()).thenReturn(true);
|
||||
when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
ShadowPasswordUtils.reset();
|
||||
@@ -102,13 +138,91 @@ public class SetupChooseLockGenericTest {
|
||||
assertThat(view.getDescriptionText().toString()).isEqualTo(fragment.loadDescriptionText());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updatePreferenceTextShowScreenLockAndFingerprint() {
|
||||
when(mFakeFeatureFactory.mFaceFeatureProvider.isSetupWizardSupported(any())).thenReturn(
|
||||
false);
|
||||
SetupChooseLockGenericFragment fragment = getFragmentOfSetupChooseLockGeneric(true);
|
||||
|
||||
final String supportFingerprint = fragment.getResources().getString(
|
||||
R.string.security_settings_fingerprint);
|
||||
final String supportFace = fragment.getResources().getString(
|
||||
R.string.keywords_face_settings);
|
||||
|
||||
assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PIN)).contains(
|
||||
supportFingerprint);
|
||||
assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PIN)).doesNotContain(
|
||||
supportFace);
|
||||
assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PATTERN)).contains(
|
||||
supportFingerprint);
|
||||
assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PATTERN)).doesNotContain(
|
||||
supportFace);
|
||||
assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PASSWORD)).contains(
|
||||
supportFingerprint);
|
||||
assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PASSWORD)).doesNotContain(
|
||||
supportFace);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updatePreferenceTextShowScreenLockAndShowFaceAndShowFingerprint() {
|
||||
when(mFakeFeatureFactory.mFaceFeatureProvider.isSetupWizardSupported(any())).thenReturn(
|
||||
true);
|
||||
SetupChooseLockGenericFragment fragment = getFragmentOfSetupChooseLockGeneric(true);
|
||||
|
||||
final String supportFingerprint = fragment.getResources().getString(
|
||||
R.string.security_settings_fingerprint);
|
||||
final String supportFace = fragment.getResources().getString(
|
||||
R.string.keywords_face_settings);
|
||||
|
||||
assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PIN)).contains(
|
||||
supportFingerprint);
|
||||
assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PIN)).contains(
|
||||
supportFace);
|
||||
assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PATTERN)).contains(
|
||||
supportFingerprint);
|
||||
assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PATTERN)).contains(
|
||||
supportFace);
|
||||
assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PASSWORD)).contains(
|
||||
supportFingerprint);
|
||||
assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PASSWORD)).contains(
|
||||
supportFace);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updatePreferenceTextShowScreenLockAndShowFingerprint() {
|
||||
when(mFakeFeatureFactory.mFaceFeatureProvider.isSetupWizardSupported(any())).thenReturn(
|
||||
false);
|
||||
SetupChooseLockGenericFragment fragment = getFragmentOfSetupChooseLockGeneric(true);
|
||||
|
||||
final String supportFingerprint = fragment.getResources().getString(
|
||||
R.string.security_settings_fingerprint);
|
||||
final String supportFace = fragment.getResources().getString(
|
||||
R.string.keywords_face_settings);
|
||||
|
||||
assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PIN)).contains(
|
||||
supportFingerprint);
|
||||
assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PIN)).doesNotContain(
|
||||
supportFace);
|
||||
assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PATTERN)).contains(
|
||||
supportFingerprint);
|
||||
assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PATTERN)).doesNotContain(
|
||||
supportFace);
|
||||
assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PASSWORD)).contains(
|
||||
supportFingerprint);
|
||||
assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PASSWORD)).doesNotContain(
|
||||
supportFace);
|
||||
}
|
||||
|
||||
private SetupChooseLockGenericFragment getFragmentOfSetupChooseLockGeneric(boolean biometric) {
|
||||
ShadowPasswordUtils.addGrantedPermission(REQUEST_PASSWORD_COMPLEXITY);
|
||||
Intent intent = new Intent("com.android.settings.SETUP_LOCK_SCREEN");
|
||||
intent.putExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY, PASSWORD_COMPLEXITY_HIGH);
|
||||
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, biometric);
|
||||
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FACE, biometric);
|
||||
// TODO(b/275023433) This presents the activity from being made 'visible` is workaround
|
||||
SetupChooseLockGeneric activity =
|
||||
Robolectric.buildActivity(SetupChooseLockGeneric.class, intent).setup().get();
|
||||
Robolectric.buildActivity(SetupChooseLockGeneric.class,
|
||||
intent).create().start().postCreate(null).resume().get();
|
||||
|
||||
List<Fragment> fragments = activity.getSupportFragmentManager().getFragments();
|
||||
assertThat(fragments).isNotNull();
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.privacy;
|
||||
|
||||
import static android.content.pm.PackageManager.FEATURE_AUTOMOTIVE;
|
||||
import static android.content.pm.PackageManager.FEATURE_LEANBACK;
|
||||
import static android.content.pm.PackageManager.FEATURE_WATCH;
|
||||
|
||||
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
|
||||
import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.provider.DeviceConfig;
|
||||
import android.provider.Settings;
|
||||
import android.safetylabel.SafetyLabelConstants;
|
||||
|
||||
import com.android.settings.testutils.shadow.ShadowDeviceConfig;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.MockitoSession;
|
||||
import org.mockito.quality.Strictness;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(shadows = {ShadowDeviceConfig.class})
|
||||
public class AppDataSharingUpdatesPreferenceControllerTest {
|
||||
|
||||
public static final String PREFERENCE_KEY = "PREFERENCE_KEY";
|
||||
private static final List<String> sUnsupportedFormFactors =
|
||||
Arrays.asList(FEATURE_AUTOMOTIVE, FEATURE_LEANBACK, FEATURE_WATCH);
|
||||
private MockitoSession mMockitoSession;
|
||||
@Mock
|
||||
private PackageManager mPackageManager;
|
||||
@Mock
|
||||
private Context mContext;
|
||||
private AppDataSharingUpdatesPreferenceController mController;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mMockitoSession = Mockito.mockitoSession()
|
||||
.initMocks(this)
|
||||
.strictness(Strictness.WARN)
|
||||
.startMocking();
|
||||
doReturn(mPackageManager).when(mContext).getPackageManager();
|
||||
mController = new AppDataSharingUpdatesPreferenceController(mContext, PREFERENCE_KEY);
|
||||
for (String formFactor : sUnsupportedFormFactors) {
|
||||
doReturn(false).when(mPackageManager).hasSystemFeature(eq(formFactor));
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
mMockitoSession.finishMocking();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSafetyLabelsDisabled_thenPreferenceUnavailable()
|
||||
throws Exception {
|
||||
setSafetyLabelsDeviceConfigEnabled(false);
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSafetyLabelsEnabled_andSupportedFormFactor_thenPreferenceAvailable()
|
||||
throws Exception {
|
||||
setSafetyLabelsDeviceConfigEnabled(true);
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSafetyLabelsEnabled_andUnsupportedFormFactor_thenPreferenceUnavailable()
|
||||
throws Exception {
|
||||
setSafetyLabelsDeviceConfigEnabled(true);
|
||||
for (String formFactor : sUnsupportedFormFactors) {
|
||||
doReturn(true).when(mPackageManager).hasSystemFeature(eq(formFactor));
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
|
||||
doReturn(false).when(mPackageManager).hasSystemFeature(eq(formFactor));
|
||||
}
|
||||
}
|
||||
|
||||
private void setSafetyLabelsDeviceConfigEnabled(boolean newValue)
|
||||
throws Settings.SettingNotFoundException {
|
||||
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_PRIVACY,
|
||||
SafetyLabelConstants.SAFETY_LABEL_CHANGE_NOTIFICATIONS_ENABLED,
|
||||
((Boolean) newValue).toString(), /* makeDefault */ false);
|
||||
}
|
||||
}
|
||||
@@ -389,7 +389,7 @@ public class CredentialManagerPreferenceControllerTest {
|
||||
Intent intent = new Intent(PRIMARY_INTENT);
|
||||
intent.setData(Uri.parse("package:" + packageName));
|
||||
assertThat(controller.verifyReceivedIntent(intent)).isTrue();
|
||||
controller.completeEnableProviderDialogBox(DialogInterface.BUTTON_POSITIVE, packageName);
|
||||
controller.completeEnableProviderDialogBox(DialogInterface.BUTTON_POSITIVE, packageName, true);
|
||||
assertThat(mReceivedResultCode.get()).isEqualTo(Activity.RESULT_OK);
|
||||
}
|
||||
|
||||
@@ -404,7 +404,7 @@ public class CredentialManagerPreferenceControllerTest {
|
||||
Intent intent = new Intent(PRIMARY_INTENT);
|
||||
intent.setData(Uri.parse("package:" + packageName));
|
||||
assertThat(controller.verifyReceivedIntent(intent)).isTrue();
|
||||
controller.completeEnableProviderDialogBox(DialogInterface.BUTTON_NEGATIVE, packageName);
|
||||
controller.completeEnableProviderDialogBox(DialogInterface.BUTTON_NEGATIVE, packageName, true);
|
||||
assertThat(mReceivedResultCode.get()).isEqualTo(Activity.RESULT_CANCELED);
|
||||
}
|
||||
|
||||
@@ -430,7 +430,7 @@ public class CredentialManagerPreferenceControllerTest {
|
||||
Intent intent = new Intent(ALTERNATE_INTENT);
|
||||
intent.setData(Uri.parse("package:" + packageName));
|
||||
assertThat(controller.verifyReceivedIntent(intent)).isTrue();
|
||||
controller.completeEnableProviderDialogBox(DialogInterface.BUTTON_POSITIVE, packageName);
|
||||
controller.completeEnableProviderDialogBox(DialogInterface.BUTTON_POSITIVE, packageName, true);
|
||||
assertThat(mReceivedResultCode.get()).isEqualTo(Activity.RESULT_OK);
|
||||
}
|
||||
|
||||
@@ -445,7 +445,7 @@ public class CredentialManagerPreferenceControllerTest {
|
||||
Intent intent = new Intent(ALTERNATE_INTENT);
|
||||
intent.setData(Uri.parse("package:" + packageName));
|
||||
assertThat(controller.verifyReceivedIntent(intent)).isTrue();
|
||||
controller.completeEnableProviderDialogBox(DialogInterface.BUTTON_NEGATIVE, packageName);
|
||||
controller.completeEnableProviderDialogBox(DialogInterface.BUTTON_NEGATIVE, packageName, true);
|
||||
assertThat(mReceivedResultCode.get()).isEqualTo(Activity.RESULT_CANCELED);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user