Merge cherrypicks of ['googleplex-android-review.googlesource.com/33629809', 'googleplex-android-review.googlesource.com/33629810', 'googleplex-android-review.googlesource.com/33646576', 'googleplex-android-review.googlesource.com/33607203', 'googleplex-android-review.googlesource.com/33909851', 'googleplex-android-review.googlesource.com/33751637', 'googleplex-android-review.googlesource.com/33923313', 'googleplex-android-review.googlesource.com/34044915'] into 25Q2-release.
Change-Id: I5f332baa008006699a4c3386d544e38d68db3a31
This commit is contained in:
@@ -265,7 +265,14 @@ public class AccountTypePreferenceLoader {
|
||||
try {
|
||||
// Allows to launch only authenticator owned activities.
|
||||
ApplicationInfo authenticatorAppInf = pm.getApplicationInfo(authDesc.packageName, 0);
|
||||
return resolvedAppInfo.uid == authenticatorAppInf.uid;
|
||||
if (resolvedAppInfo.uid == authenticatorAppInf.uid) {
|
||||
// Explicitly set the component to be same as authenticator to
|
||||
// prevent launching arbitrary activities.
|
||||
intent.setComponent(resolvedActivityInfo.getComponentName());
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} catch (NameNotFoundException e) {
|
||||
Log.e(TAG,
|
||||
"Intent considered unsafe due to exception.",
|
||||
|
||||
@@ -50,6 +50,8 @@ import com.google.android.setupdesign.span.LinkSpan;
|
||||
import com.google.android.setupdesign.template.RequireScrollMixin;
|
||||
import com.google.android.setupdesign.util.DynamicColorPalette;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Abstract base class for the intro onboarding activity for biometric enrollment.
|
||||
*/
|
||||
@@ -249,6 +251,19 @@ public abstract class BiometricEnrollIntroduction extends BiometricEnrollBase
|
||||
!isScrollNeeded && !enrollmentCompleted ? View.VISIBLE : View.INVISIBLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
|
||||
if (!getPackageName().equals(getCallingPackage())) {
|
||||
for (String key : List.of(MultiBiometricEnrollHelper.EXTRA_SKIP_PENDING_ENROLL,
|
||||
MultiBiometricEnrollHelper.EXTRA_ENROLL_AFTER_FACE,
|
||||
MultiBiometricEnrollHelper.EXTRA_ENROLL_AFTER_FINGERPRINT)) {
|
||||
getIntent().removeExtra(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
@@ -497,14 +512,15 @@ public abstract class BiometricEnrollIntroduction extends BiometricEnrollBase
|
||||
getIntent().removeExtra(MultiBiometricEnrollHelper.EXTRA_ENROLL_AFTER_FINGERPRINT);
|
||||
}
|
||||
|
||||
protected void removeEnrollNextBiometricIfSkipEnroll(@Nullable Intent data) {
|
||||
private void removeEnrollNextBiometricIfSkipEnroll(@Nullable Intent data) {
|
||||
if (data != null
|
||||
&& data.getBooleanExtra(
|
||||
MultiBiometricEnrollHelper.EXTRA_SKIP_PENDING_ENROLL, false)) {
|
||||
removeEnrollNextBiometric();
|
||||
}
|
||||
}
|
||||
protected void handleBiometricResultSkipOrFinished(int resultCode, @Nullable Intent data) {
|
||||
|
||||
private void handleBiometricResultSkipOrFinished(int resultCode, @Nullable Intent data) {
|
||||
removeEnrollNextBiometricIfSkipEnroll(data);
|
||||
if (resultCode == RESULT_SKIP) {
|
||||
onEnrollmentSkipped(data);
|
||||
|
||||
@@ -95,8 +95,8 @@ public class FaceSettings extends DashboardFragment {
|
||||
private FaceManager mFaceManager;
|
||||
private DevicePolicyManager mDevicePolicyManager;
|
||||
private int mUserId;
|
||||
private int mSensorId;
|
||||
private long mChallenge;
|
||||
private int mSensorId = -1;
|
||||
private long mChallenge = 0;
|
||||
private byte[] mToken;
|
||||
private FaceSettingsAttentionPreferenceController mAttentionController;
|
||||
private FaceSettingsRemoveButtonPreferenceController mRemoveController;
|
||||
@@ -181,12 +181,19 @@ public class FaceSettings extends DashboardFragment {
|
||||
mUserManager = context.getSystemService(UserManager.class);
|
||||
mFaceManager = context.getSystemService(FaceManager.class);
|
||||
mDevicePolicyManager = context.getSystemService(DevicePolicyManager.class);
|
||||
mToken = getIntent().getByteArrayExtra(KEY_TOKEN);
|
||||
mSensorId = getIntent().getIntExtra(BiometricEnrollBase.EXTRA_KEY_SENSOR_ID, -1);
|
||||
mChallenge = getIntent().getLongExtra(BiometricEnrollBase.EXTRA_KEY_CHALLENGE, 0L);
|
||||
|
||||
mUserId = getActivity().getIntent().getIntExtra(
|
||||
Intent.EXTRA_USER_ID, UserHandle.myUserId());
|
||||
final SettingsActivity activity = (SettingsActivity) requireActivity();
|
||||
final String callingPackage = activity.getInitialCallingPackage();
|
||||
if (callingPackage == null || !callingPackage.equals(activity.getPackageName())) {
|
||||
mUserId = UserHandle.myUserId();
|
||||
} else {
|
||||
// only allow these extras when called internally by Settings
|
||||
mToken = getIntent().getByteArrayExtra(KEY_TOKEN);
|
||||
mSensorId = getIntent().getIntExtra(BiometricEnrollBase.EXTRA_KEY_SENSOR_ID, -1);
|
||||
mChallenge = getIntent().getLongExtra(BiometricEnrollBase.EXTRA_KEY_CHALLENGE, 0L);
|
||||
mUserId = getIntent().getIntExtra(Intent.EXTRA_USER_ID, UserHandle.myUserId());
|
||||
}
|
||||
|
||||
mFaceFeatureProvider = FeatureFactory.getFeatureFactory().getFaceFeatureProvider();
|
||||
|
||||
if (mUserManager.getUserInfo(mUserId).isManagedProfile()) {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.settings.notification.history;
|
||||
|
||||
import static android.provider.Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS;
|
||||
import static android.provider.Settings.Secure.NOTIFICATION_HISTORY_ENABLED;
|
||||
import static android.view.View.GONE;
|
||||
import static android.view.View.VISIBLE;
|
||||
@@ -28,9 +29,11 @@ import android.annotation.DrawableRes;
|
||||
import android.app.ActionBar;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.INotificationManager;
|
||||
import android.app.KeyguardManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.os.Bundle;
|
||||
@@ -58,6 +61,7 @@ import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.android.internal.logging.UiEvent;
|
||||
import com.android.internal.logging.UiEventLogger;
|
||||
import com.android.internal.logging.UiEventLoggerImpl;
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.internal.widget.NotificationExpandButton;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.notification.NotificationBackend;
|
||||
@@ -68,6 +72,7 @@ import com.android.settingslib.widget.MainSwitchBar;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@@ -98,6 +103,8 @@ public class NotificationHistoryActivity extends CollapsingToolbarBaseActivity {
|
||||
|
||||
private UiEventLogger mUiEventLogger = new UiEventLoggerImpl();
|
||||
|
||||
private ArrayList<Integer> mContentRestrictedUsers = new ArrayList<>();
|
||||
|
||||
enum NotificationHistoryEvent implements UiEventLogger.UiEventEnum {
|
||||
@UiEvent(doc = "User turned on notification history")
|
||||
NOTIFICATION_HISTORY_ON(504),
|
||||
@@ -205,14 +212,14 @@ public class NotificationHistoryActivity extends CollapsingToolbarBaseActivity {
|
||||
|
||||
final NotificationHistoryRecyclerView rv =
|
||||
viewForPackage.findViewById(R.id.notification_list);
|
||||
rv.setAdapter(new NotificationHistoryAdapter(mNm, rv,
|
||||
rv.setAdapter(new NotificationHistoryAdapter(NotificationHistoryActivity.this, mNm, rv,
|
||||
newCount -> {
|
||||
count.setText(StringUtil.getIcuPluralsString(this, newCount,
|
||||
R.string.notification_history_count));
|
||||
if (newCount == 0) {
|
||||
viewForPackage.setVisibility(GONE);
|
||||
}
|
||||
}, mUiEventLogger));
|
||||
}, mUiEventLogger, mContentRestrictedUsers));
|
||||
((NotificationHistoryAdapter) rv.getAdapter()).onRebuildComplete(
|
||||
new ArrayList<>(nhp.notifications));
|
||||
|
||||
@@ -249,6 +256,19 @@ public class NotificationHistoryActivity extends CollapsingToolbarBaseActivity {
|
||||
|
||||
mPm = getPackageManager();
|
||||
mUm = getSystemService(UserManager.class);
|
||||
|
||||
List<UserInfo> users = mUm.getProfiles(getUserId());
|
||||
for (UserInfo user : users) {
|
||||
if (Settings.Secure.getIntForUser(getContentResolver(),
|
||||
LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, user.id) == 0) {
|
||||
LockPatternUtils lpu = new LockPatternUtils(this);
|
||||
KeyguardManager km = getSystemService(KeyguardManager.class);
|
||||
if (lpu.isSecure(user.id) && km.isDeviceLocked(user.id)) {
|
||||
mContentRestrictedUsers.add(user.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// wait for history loading and recent/snooze loading
|
||||
mCountdownLatch = new CountDownLatch(2);
|
||||
|
||||
@@ -419,7 +439,7 @@ public class NotificationHistoryActivity extends CollapsingToolbarBaseActivity {
|
||||
mSnoozedRv.setLayoutManager(lm);
|
||||
mSnoozedRv.setAdapter(
|
||||
new NotificationSbnAdapter(NotificationHistoryActivity.this, mPm, mUm,
|
||||
true, mUiEventLogger));
|
||||
true, mUiEventLogger, mContentRestrictedUsers));
|
||||
mSnoozedRv.setNestedScrollingEnabled(false);
|
||||
|
||||
if (snoozed == null || snoozed.length == 0) {
|
||||
@@ -435,7 +455,7 @@ public class NotificationHistoryActivity extends CollapsingToolbarBaseActivity {
|
||||
mDismissedRv.setLayoutManager(dismissLm);
|
||||
mDismissedRv.setAdapter(
|
||||
new NotificationSbnAdapter(NotificationHistoryActivity.this, mPm, mUm,
|
||||
false, mUiEventLogger));
|
||||
false, mUiEventLogger, mContentRestrictedUsers));
|
||||
mDismissedRv.setNestedScrollingEnabled(false);
|
||||
|
||||
if (dismissed == null || dismissed.length == 0) {
|
||||
|
||||
@@ -22,6 +22,7 @@ import static android.provider.Settings.EXTRA_CONVERSATION_ID;
|
||||
|
||||
import android.app.INotificationManager;
|
||||
import android.app.NotificationHistory.HistoricalNotification;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.RemoteException;
|
||||
@@ -53,16 +54,23 @@ public class NotificationHistoryAdapter extends
|
||||
private List<HistoricalNotification> mValues;
|
||||
private OnItemDeletedListener mListener;
|
||||
private UiEventLogger mUiEventLogger;
|
||||
public NotificationHistoryAdapter(INotificationManager nm,
|
||||
private ArrayList<Integer> mContentRestrictedUsers = new ArrayList<>();
|
||||
Context mContext;
|
||||
|
||||
public NotificationHistoryAdapter(Context context,
|
||||
INotificationManager nm,
|
||||
NotificationHistoryRecyclerView listView,
|
||||
OnItemDeletedListener listener,
|
||||
UiEventLogger uiEventLogger) {
|
||||
UiEventLogger uiEventLogger,
|
||||
ArrayList<Integer> contentRestrictedUsers) {
|
||||
mContext = context;
|
||||
mValues = new ArrayList<>();
|
||||
setHasStableIds(true);
|
||||
listView.setOnItemSwipeDeleteListener(this);
|
||||
mNm = nm;
|
||||
mListener = listener;
|
||||
mUiEventLogger = uiEventLogger;
|
||||
mContentRestrictedUsers = contentRestrictedUsers;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -81,8 +89,13 @@ public class NotificationHistoryAdapter extends
|
||||
public void onBindViewHolder(final @NonNull NotificationHistoryViewHolder holder,
|
||||
int position) {
|
||||
final HistoricalNotification hn = mValues.get(position);
|
||||
holder.setTitle(hn.getTitle());
|
||||
holder.setSummary(hn.getText());
|
||||
if (mContentRestrictedUsers.contains(hn.getUserId())) {
|
||||
holder.setSummary(mContext.getString(
|
||||
com.android.internal.R.string.notification_hidden_text));
|
||||
} else {
|
||||
holder.setTitle(hn.getTitle());
|
||||
holder.setSummary(hn.getText());
|
||||
}
|
||||
holder.setPostedTime(hn.getPostedTimeMs());
|
||||
final View.OnClickListener onClick = v -> {
|
||||
mUiEventLogger.logWithPosition(NotificationHistoryActivity.NotificationHistoryEvent
|
||||
|
||||
@@ -78,9 +78,11 @@ public class NotificationSbnAdapter extends
|
||||
private List<Integer> mEnabledProfiles = new ArrayList<>();
|
||||
private boolean mIsSnoozed;
|
||||
private UiEventLogger mUiEventLogger;
|
||||
private ArrayList<Integer> mContentRestrictedUsers = new ArrayList<>();
|
||||
|
||||
public NotificationSbnAdapter(Context context, PackageManager pm, UserManager um,
|
||||
boolean isSnoozed, UiEventLogger uiEventLogger) {
|
||||
boolean isSnoozed, UiEventLogger uiEventLogger,
|
||||
ArrayList<Integer> contentRestrictedUsers) {
|
||||
mContext = context;
|
||||
mPm = pm;
|
||||
mUserBadgeCache = new HashMap<>();
|
||||
@@ -101,6 +103,7 @@ public class NotificationSbnAdapter extends
|
||||
// If true, this is the panel for snoozed notifs, otherwise the one for dismissed notifs.
|
||||
mIsSnoozed = isSnoozed;
|
||||
mUiEventLogger = uiEventLogger;
|
||||
mContentRestrictedUsers = contentRestrictedUsers;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -128,8 +131,13 @@ public class NotificationSbnAdapter extends
|
||||
holder.setIconBackground(loadBackground(sbn));
|
||||
holder.setIcon(loadIcon(sbn));
|
||||
holder.setPackageLabel(loadPackageLabel(sbn.getPackageName()).toString());
|
||||
holder.setTitle(getTitleString(sbn.getNotification()));
|
||||
holder.setSummary(getTextString(mContext, sbn.getNotification()));
|
||||
if (mContentRestrictedUsers.contains(sbn.getNormalizedUserId())) {
|
||||
holder.setSummary(mContext.getString(
|
||||
com.android.internal.R.string.notification_hidden_text));
|
||||
} else {
|
||||
holder.setTitle(getTitleString(sbn.getNotification()));
|
||||
holder.setSummary(getTextString(mContext, sbn.getNotification()));
|
||||
}
|
||||
holder.setPostedTime(sbn.getPostTime());
|
||||
int userId = normalizeUserId(sbn);
|
||||
if (!mUserBadgeCache.containsKey(userId)) {
|
||||
|
||||
@@ -132,7 +132,7 @@ public class ContentProtectionTogglePreferenceController extends TogglePreferenc
|
||||
|
||||
UserManager userManager = mContext.getSystemService(UserManager.class);
|
||||
if (userManager != null
|
||||
&& userManager.isGuestUser()
|
||||
&& !userManager.isAdminUser()
|
||||
&& mSwitchBar != null) {
|
||||
mSwitchBar.setEnabled(false);
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.settings.security;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
@@ -322,15 +323,25 @@ public final class CredentialStorage extends FragmentActivity {
|
||||
}
|
||||
}
|
||||
|
||||
private String getCallingPackageName() {
|
||||
try {
|
||||
return ActivityManager.getService().getLaunchedFromPackage(getActivityToken());
|
||||
} catch (RemoteException re) {
|
||||
// Error talking to ActivityManager, just give up
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the caller is either certinstaller or Settings running in a profile of this user.
|
||||
*/
|
||||
private boolean checkCallerIsCertInstallerOrSelfInProfile() {
|
||||
if (TextUtils.equals("com.android.certinstaller", getCallingPackage())) {
|
||||
String callingPackage = getCallingPackageName();
|
||||
if (TextUtils.equals("com.android.certinstaller", callingPackage)) {
|
||||
// CertInstaller is allowed to install credentials if it has the same signature as
|
||||
// Settings package.
|
||||
return getPackageManager().checkSignatures(
|
||||
getCallingPackage(), getPackageName()) == PackageManager.SIGNATURE_MATCH;
|
||||
callingPackage, getPackageName()) == PackageManager.SIGNATURE_MATCH;
|
||||
}
|
||||
|
||||
final int launchedFromUserId;
|
||||
|
||||
@@ -639,8 +639,11 @@ public class AppRestrictionsFragment extends SettingsPreferenceFragment implemen
|
||||
} else if (restrictionsIntent != null) {
|
||||
preference.setRestrictions(restrictions);
|
||||
if (invokeIfCustom && AppRestrictionsFragment.this.isResumed()) {
|
||||
// We don't necessarily trust the given intent to launch its component.
|
||||
// We will first check it, and only use parts of it that were indeed checked.
|
||||
final Intent vettedIntent;
|
||||
try {
|
||||
assertSafeToStartCustomActivity(restrictionsIntent);
|
||||
vettedIntent = assertSafeToStartCustomActivity(restrictionsIntent);
|
||||
} catch (ActivityNotFoundException | SecurityException e) {
|
||||
// return without startActivity
|
||||
Log.e(TAG, "Cannot start restrictionsIntent " + e);
|
||||
@@ -651,15 +654,20 @@ public class AppRestrictionsFragment extends SettingsPreferenceFragment implemen
|
||||
int requestCode = generateCustomActivityRequestCode(
|
||||
RestrictionsResultReceiver.this.preference);
|
||||
AppRestrictionsFragment.this.startActivityForResult(
|
||||
new Intent(restrictionsIntent), requestCode);
|
||||
vettedIntent, requestCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void assertSafeToStartCustomActivity(Intent intent) {
|
||||
/**
|
||||
* Checks that it is safe to start the custom activity, and, if so, returns a copy of the
|
||||
* Intent using its vetted components.
|
||||
*/
|
||||
private Intent assertSafeToStartCustomActivity(Intent intent) {
|
||||
EventLog.writeEvent(0x534e4554, "223578534", -1 /* UID */, "");
|
||||
final Intent vettedIntent = new Intent(intent);
|
||||
ResolveInfo resolveInfo = mPackageManager.resolveActivity(
|
||||
intent, PackageManager.MATCH_DEFAULT_ONLY);
|
||||
vettedIntent, PackageManager.MATCH_DEFAULT_ONLY);
|
||||
|
||||
if (resolveInfo == null) {
|
||||
throw new ActivityNotFoundException("No result for resolving " + intent);
|
||||
@@ -670,6 +678,12 @@ public class AppRestrictionsFragment extends SettingsPreferenceFragment implemen
|
||||
throw new SecurityException("Application " + packageName
|
||||
+ " is not allowed to start activity " + intent);
|
||||
}
|
||||
|
||||
// We were able to vet the given intent this time. Make a copy using the components
|
||||
// that were used to do the vetting, since that's as much as we've verified is safe.
|
||||
vettedIntent.setComponent(activityInfo.getComponentName());
|
||||
vettedIntent.setPackage(activityInfo.packageName);
|
||||
return vettedIntent;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,11 +32,13 @@ import static com.google.common.truth.Truth.assertWithMessage;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
@@ -64,6 +66,7 @@ import com.android.settings.R;
|
||||
import com.android.settings.Settings;
|
||||
import com.android.settings.biometrics.BiometricEnrollBase;
|
||||
import com.android.settings.biometrics.BiometricUtils;
|
||||
import com.android.settings.biometrics.MultiBiometricEnrollHelper;
|
||||
import com.android.settings.password.ChooseLockSettingsHelper;
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
import com.android.settings.testutils.shadow.SettingsShadowResources;
|
||||
@@ -206,6 +209,12 @@ public class FaceEnrollIntroductionTest {
|
||||
testIntent.putExtra(BiometricUtils.EXTRA_ENROLL_REASON,
|
||||
FaceEnrollOptions.ENROLL_REASON_SETTINGS);
|
||||
|
||||
testIntent.putExtra(MultiBiometricEnrollHelper.EXTRA_ENROLL_AFTER_FACE,
|
||||
mock(PendingIntent.class));
|
||||
testIntent.putExtra(MultiBiometricEnrollHelper.EXTRA_ENROLL_AFTER_FINGERPRINT,
|
||||
mock(PendingIntent.class));
|
||||
testIntent.putExtra(MultiBiometricEnrollHelper.EXTRA_SKIP_PENDING_ENROLL, false);
|
||||
|
||||
when(mFakeFeatureFactory.mFaceFeatureProvider.getPostureGuidanceIntent(any())).thenReturn(
|
||||
null /* Simulate no posture intent */);
|
||||
mContext = spy(ApplicationProvider.getApplicationContext());
|
||||
@@ -690,4 +699,16 @@ public class FaceEnrollIntroductionTest {
|
||||
.isEqualTo(FaceEnrollOptions.ENROLL_REASON_SETTINGS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void drops_pendingIntents() {
|
||||
setupActivity();
|
||||
|
||||
mController.start();
|
||||
Shadows.shadowOf(Looper.getMainLooper()).idle();
|
||||
|
||||
final Intent intent = mActivity.getIntent();
|
||||
assertThat(intent.hasExtra(MultiBiometricEnrollHelper.EXTRA_SKIP_PENDING_ENROLL)).isFalse();
|
||||
assertThat(intent.hasExtra(MultiBiometricEnrollHelper.EXTRA_ENROLL_AFTER_FACE)).isFalse();
|
||||
assertThat(intent.hasExtra(MultiBiometricEnrollHelper.EXTRA_ENROLL_AFTER_FINGERPRINT)).isFalse();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
@@ -44,6 +45,7 @@ import android.hardware.fingerprint.FingerprintEnrollOptions;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.hardware.fingerprint.FingerprintSensorProperties;
|
||||
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
|
||||
import android.os.Looper;
|
||||
import android.os.UserManager;
|
||||
import android.view.View;
|
||||
|
||||
@@ -55,6 +57,7 @@ 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.android.settings.biometrics.MultiBiometricEnrollHelper;
|
||||
|
||||
import com.google.android.setupcompat.util.WizardManagerHelper;
|
||||
import com.google.android.setupdesign.GlifLayout;
|
||||
@@ -70,6 +73,7 @@ import org.mockito.stubbing.Answer;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.Shadows;
|
||||
import org.robolectric.android.controller.ActivityController;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -353,7 +357,19 @@ public class FingerprintEnrollIntroductionTest {
|
||||
false);
|
||||
Assert.assertEquals(View.INVISIBLE,
|
||||
mFingerprintEnrollIntroduction.getSecondaryFooterButton().getVisibility());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void drops_pendingIntents() {
|
||||
setupFingerprintEnrollIntroWith(newExternalPendingIntent());
|
||||
|
||||
mController.start();
|
||||
Shadows.shadowOf(Looper.getMainLooper()).idle();
|
||||
|
||||
final Intent intent = mFingerprintEnrollIntroduction.getIntent();
|
||||
assertThat(intent.hasExtra(MultiBiometricEnrollHelper.EXTRA_SKIP_PENDING_ENROLL)).isFalse();
|
||||
assertThat(intent.hasExtra(MultiBiometricEnrollHelper.EXTRA_ENROLL_AFTER_FACE)).isFalse();
|
||||
assertThat(intent.hasExtra(MultiBiometricEnrollHelper.EXTRA_ENROLL_AFTER_FINGERPRINT)).isFalse();
|
||||
}
|
||||
|
||||
private Intent newTokenOnlyIntent() {
|
||||
@@ -383,6 +399,15 @@ public class FingerprintEnrollIntroductionTest {
|
||||
.putExtra(EXTRA_KEY_GK_PW_HANDLE, 1L);
|
||||
}
|
||||
|
||||
private Intent newExternalPendingIntent() {
|
||||
return newTokenOnlyIntent()
|
||||
.putExtra(MultiBiometricEnrollHelper.EXTRA_ENROLL_AFTER_FACE,
|
||||
mock(PendingIntent.class))
|
||||
.putExtra(MultiBiometricEnrollHelper.EXTRA_ENROLL_AFTER_FINGERPRINT,
|
||||
mock(PendingIntent.class))
|
||||
.putExtra(MultiBiometricEnrollHelper.EXTRA_SKIP_PENDING_ENROLL, false);
|
||||
}
|
||||
|
||||
private VerifyCredentialResponse newGoodCredential(long gkPwHandle, @NonNull byte[] hat) {
|
||||
return new VerifyCredentialResponse.Builder()
|
||||
.setGatekeeperPasswordHandle(gkPwHandle)
|
||||
|
||||
@@ -85,7 +85,7 @@ public class ContentProtectionTogglePreferenceControllerTest {
|
||||
@Before
|
||||
public void setUp() {
|
||||
mShadowUserManager = ShadowUserManager.getShadow();
|
||||
mShadowUserManager.setGuestUser(false);
|
||||
mShadowUserManager.setIsAdminUser(true);
|
||||
mController = new TestContentProtectionTogglePreferenceController();
|
||||
SettingsMainSwitchPreference switchPreference = new SettingsMainSwitchPreference(mContext);
|
||||
when(mMockPreferenceScreen.findPreference(mController.getPreferenceKey()))
|
||||
@@ -277,8 +277,8 @@ public class ContentProtectionTogglePreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_flagEnabled_noEnforcedAdmin_guestUser_switchBarDisabled() {
|
||||
mShadowUserManager.setGuestUser(true);
|
||||
public void updateState_flagEnabled_noEnforcedAdmin_nonAdminUser_switchBarDisabled() {
|
||||
mShadowUserManager.setIsAdminUser(false);
|
||||
mSetFlagsRule.enableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED);
|
||||
mContentProtectionPolicy = DevicePolicyManager.CONTENT_PROTECTION_ENABLED;
|
||||
setupForUpdateState();
|
||||
@@ -289,13 +289,15 @@ public class ContentProtectionTogglePreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_flagEnabled_noEnforcedAdmin_nonGuestUser_switchBarEnabled() {
|
||||
public void updateState_flagEnabled_noEnforcedAdmin_adminUser_switchBarEnabled() {
|
||||
mShadowUserManager.setIsAdminUser(true);
|
||||
mSetFlagsRule.enableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED);
|
||||
mContentProtectionPolicy = DevicePolicyManager.CONTENT_PROTECTION_ENABLED;
|
||||
setupForUpdateState();
|
||||
|
||||
mController.updateState(mMockSwitchPreference);
|
||||
|
||||
// Verify that the switch bar is *not* set to disabled.
|
||||
verify(mMockSwitchPreference, never()).setEnabled(false);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user