diff options
6 files changed, 116 insertions, 10 deletions
diff --git a/core/java/android/content/pm/parsing/component/ParsedAttribution.java b/core/java/android/content/pm/parsing/component/ParsedAttribution.java index 4ec2e73a0b83..bd44120f58b5 100644 --- a/core/java/android/content/pm/parsing/component/ParsedAttribution.java +++ b/core/java/android/content/pm/parsing/component/ParsedAttribution.java @@ -40,7 +40,7 @@ public class ParsedAttribution implements Parcelable { public static final int MAX_ATTRIBUTION_TAG_LEN = 50; /** Maximum amount of attributions per package */ - private static final int MAX_NUM_ATTRIBUTIONS = 10000; + private static final int MAX_NUM_ATTRIBUTIONS = 1000; /** Tag of the attribution */ public final @NonNull String tag; diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java index cd1bbb6bc6fe..b5f3191c3826 100644 --- a/core/java/com/android/internal/widget/LockPatternUtils.java +++ b/core/java/com/android/internal/widget/LockPatternUtils.java @@ -1295,8 +1295,8 @@ public class LockPatternUtils { } public boolean isUserInLockdown(int userId) { - return getStrongAuthForUser(userId) - == StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN; + return (getStrongAuthForUser(userId) + & StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN) != 0; } private static class WrappedCallback extends ICheckCredentialProgressCallback.Stub { diff --git a/core/tests/utiltests/src/com/android/internal/util/LockPatternUtilsTest.java b/core/tests/utiltests/src/com/android/internal/util/LockPatternUtilsTest.java index 50e8474e8d52..01494a7659a5 100644 --- a/core/tests/utiltests/src/com/android/internal/util/LockPatternUtilsTest.java +++ b/core/tests/utiltests/src/com/android/internal/util/LockPatternUtilsTest.java @@ -19,6 +19,10 @@ package com.android.internal.util; import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_MANAGED; import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; +import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED; +import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT; +import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN; + import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.doReturn; @@ -48,12 +52,15 @@ import org.mockito.Mockito; @SmallTest public class LockPatternUtilsTest { + private ILockSettings mLockSettings; + private static final int USER_ID = 1; private static final int DEMO_USER_ID = 5; private LockPatternUtils mLockPatternUtils; private void configureTest(boolean isSecure, boolean isDemoUser, int deviceDemoMode) throws Exception { + mLockSettings = Mockito.mock(ILockSettings.class); final Context context = spy(new ContextWrapper(InstrumentationRegistry.getTargetContext())); final MockContentResolver cr = new MockContentResolver(context); @@ -61,15 +68,14 @@ public class LockPatternUtilsTest { when(context.getContentResolver()).thenReturn(cr); Settings.Global.putInt(cr, Settings.Global.DEVICE_DEMO_MODE, deviceDemoMode); - final ILockSettings ils = Mockito.mock(ILockSettings.class); - when(ils.getCredentialType(DEMO_USER_ID)).thenReturn( + when(mLockSettings.getCredentialType(DEMO_USER_ID)).thenReturn( isSecure ? LockPatternUtils.CREDENTIAL_TYPE_PASSWORD : LockPatternUtils.CREDENTIAL_TYPE_NONE); - when(ils.getLong("lockscreen.password_type", PASSWORD_QUALITY_UNSPECIFIED, DEMO_USER_ID)) - .thenReturn((long) PASSWORD_QUALITY_MANAGED); + when(mLockSettings.getLong("lockscreen.password_type", PASSWORD_QUALITY_UNSPECIFIED, + DEMO_USER_ID)).thenReturn((long) PASSWORD_QUALITY_MANAGED); // TODO(b/63758238): stop spying the class under test mLockPatternUtils = spy(new LockPatternUtils(context)); - when(mLockPatternUtils.getLockSettings()).thenReturn(ils); + when(mLockPatternUtils.getLockSettings()).thenReturn(mLockSettings); doReturn(true).when(mLockPatternUtils).hasSecureLockScreen(); final UserInfo userInfo = Mockito.mock(UserInfo.class); @@ -80,6 +86,31 @@ public class LockPatternUtilsTest { } @Test + public void isUserInLockDown() throws Exception { + configureTest(true, false, 2); + + // GIVEN strong auth not required + when(mLockSettings.getStrongAuthForUser(USER_ID)).thenReturn(STRONG_AUTH_NOT_REQUIRED); + + // THEN user isn't in lockdown + assertFalse(mLockPatternUtils.isUserInLockdown(USER_ID)); + + // GIVEN lockdown + when(mLockSettings.getStrongAuthForUser(USER_ID)).thenReturn( + STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN); + + // THEN user is in lockdown + assertTrue(mLockPatternUtils.isUserInLockdown(USER_ID)); + + // GIVEN lockdown and lockout + when(mLockSettings.getStrongAuthForUser(USER_ID)).thenReturn( + STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN | STRONG_AUTH_REQUIRED_AFTER_LOCKOUT); + + // THEN user is in lockdown + assertTrue(mLockPatternUtils.isUserInLockdown(USER_ID)); + } + + @Test public void isLockScreenDisabled_isDemoUser_true() throws Exception { configureTest(false, true, 2); assertTrue(mLockPatternUtils.isLockScreenDisabled(DEMO_USER_ID)); diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java index 759099f89b76..cb7b15e17133 100644 --- a/services/core/java/com/android/server/appop/AppOpsService.java +++ b/services/core/java/com/android/server/appop/AppOpsService.java @@ -3436,6 +3436,10 @@ public class AppOpsService extends IAppOpsService.Stub { return new SyncNotedAppOp(AppOpsManager.MODE_ERRORED, code, attributionTag, packageName); } + if (proxyAttributionTag != null + && !isAttributionTagDefined(packageName, proxyPackageName, proxyAttributionTag)) { + proxyAttributionTag = null; + } synchronized (this) { final Ops ops = getOpsLocked(uid, packageName, attributionTag, @@ -3950,6 +3954,10 @@ public class AppOpsService extends IAppOpsService.Stub { return new SyncNotedAppOp(AppOpsManager.MODE_ERRORED, code, attributionTag, packageName); } + if (proxyAttributionTag != null + && !isAttributionTagDefined(packageName, proxyPackageName, proxyAttributionTag)) { + proxyAttributionTag = null; + } boolean isRestricted = false; int startType = START_TYPE_FAILED; @@ -4645,6 +4653,36 @@ public class AppOpsService extends IAppOpsService.Stub { } /** + * Checks to see if the attribution tag is defined in either package or proxyPackage. + * This method is intended for ProxyAttributionTag validation and returns false + * if it does not exist in either one of them. + * + * @param packageName Name of the package + * @param proxyPackageName Name of the proxy package + * @param attributionTag attribution tag to be checked + * + * @return boolean specifying if attribution tag is valid or not + */ + private boolean isAttributionTagDefined(@Nullable String packageName, + @Nullable String proxyPackageName, + @Nullable String attributionTag) { + if (packageName == null) { + return false; + } else if (attributionTag == null) { + return true; + } + PackageManagerInternal pmInt = LocalServices.getService(PackageManagerInternal.class); + if (proxyPackageName != null) { + AndroidPackage proxyPkg = pmInt.getPackage(proxyPackageName); + if (proxyPkg != null && isAttributionInPackage(proxyPkg, attributionTag)) { + return true; + } + } + AndroidPackage pkg = pmInt.getPackage(packageName); + return isAttributionInPackage(pkg, attributionTag); + } + + /** * Get (and potentially create) ops. * * @param uid The uid the package belongs to diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 0e537cc1af31..bf7efc05540c 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -4534,8 +4534,10 @@ public class NotificationManagerService extends SystemService { for (int userId : mUm.getProfileIds(info.userid, false)) { try { int uid = getUidForPackageAndUser(pkg, UserHandle.of(userId)); - VersionedPackage vp = new VersionedPackage(pkg, uid); - nlf.addPackage(vp); + if (uid != INVALID_UID) { + VersionedPackage vp = new VersionedPackage(pkg, uid); + nlf.addPackage(vp); + } } catch (Exception e) { // pkg doesn't exist on that user; skip } diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java index 4b908564ef6b..0784c2644175 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -74,6 +74,7 @@ import static junit.framework.Assert.assertNull; import static junit.framework.Assert.assertTrue; import static junit.framework.Assert.fail; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertThrows; import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.Matchers.anyBoolean; @@ -8649,6 +8650,40 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } @Test + public void testMigrateNotificationFilter_invalidPackage() throws Exception { + int[] userIds = new int[] {UserHandle.getUserId(mUid), 1000}; + when(mUm.getProfileIds(anyInt(), anyBoolean())).thenReturn(userIds); + List<String> disallowedApps = ImmutableList.of("apples", "bananas", "cherries"); + for (int userId : userIds) { + when(mPackageManager.getPackageUid("apples", 0, userId)).thenThrow( + new RemoteException("")); + when(mPackageManager.getPackageUid("bananas", 0, userId)).thenReturn(9000); + when(mPackageManager.getPackageUid("cherries", 0, userId)).thenReturn(9001); + } + + when(mListeners.getNotificationListenerFilter(any())).thenReturn( + new NotificationListenerFilter()); + + mBinderService.migrateNotificationFilter(null, + FLAG_FILTER_TYPE_CONVERSATIONS | FLAG_FILTER_TYPE_ONGOING, + disallowedApps); + + ArgumentCaptor<NotificationListenerFilter> captor = + ArgumentCaptor.forClass(NotificationListenerFilter.class); + verify(mListeners).setNotificationListenerFilter(any(), captor.capture()); + + assertEquals(FLAG_FILTER_TYPE_CONVERSATIONS | FLAG_FILTER_TYPE_ONGOING, + captor.getValue().getTypes()); + // valid values stay + assertFalse(captor.getValue().isPackageAllowed(new VersionedPackage("bananas", 9000))); + assertFalse(captor.getValue().isPackageAllowed(new VersionedPackage("cherries", 9001))); + // don't store invalid values + for (VersionedPackage vp : captor.getValue().getDisallowedPackages()) { + assertNotEquals("apples", vp.getPackageName()); + } + } + + @Test public void testMigrateNotificationFilter_noPreexistingFilter() throws Exception { int[] userIds = new int[] {UserHandle.getUserId(mUid)}; when(mUm.getProfileIds(anyInt(), anyBoolean())).thenReturn(userIds); |