diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-08-17 01:09:55 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-08-17 01:09:55 +0000 |
commit | cfd7b2133d9508f5f6b5b56b93182f3dc1791d58 (patch) | |
tree | 642eb83ab4ccda4340d65dbd8be688f3cddd97f4 | |
parent | fdac2c77ca20cda9728b286ef6292262f17b3dd0 (diff) | |
parent | cb5c454398b4cc54eee5047bb2371246cf94f594 (diff) | |
download | base-cfd7b2133d9508f5f6b5b56b93182f3dc1791d58.tar.gz |
Merge cherrypicks of [19205945, 19344104, 19459069, 17325442, 19537073, 19117574] into sc-platform-release.android-platform-12.0.0_r12
Change-Id: Ibfa60e7b46e4d4b8fe04d2cf1d0d93c83d28b83f
14 files changed, 418 insertions, 35 deletions
diff --git a/core/java/android/accounts/Account.java b/core/java/android/accounts/Account.java index e6cdcc0ee742..0d6a07938e95 100644 --- a/core/java/android/accounts/Account.java +++ b/core/java/android/accounts/Account.java @@ -31,7 +31,6 @@ import android.util.Log; import com.android.internal.annotations.GuardedBy; -import java.util.Objects; import java.util.Set; /** @@ -87,12 +86,6 @@ public class Account implements Parcelable { if (TextUtils.isEmpty(type)) { throw new IllegalArgumentException("the type must not be empty: " + type); } - if (name.length() > 200) { - throw new IllegalArgumentException("account name is longer than 200 characters"); - } - if (type.length() > 200) { - throw new IllegalArgumentException("account type is longer than 200 characters"); - } this.name = name; this.type = type; this.accessId = accessId; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java index 433d5e19ed6b..8313299cef32 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java @@ -175,9 +175,86 @@ public class NotificationInterruptStateProviderImpl implements NotificationInter */ @Override public boolean shouldLaunchFullScreenIntentWhenAdded(NotificationEntry entry) { - return entry.getSbn().getNotification().fullScreenIntent != null - && (!shouldHeadsUp(entry) - || mStatusBarStateController.getState() == StatusBarState.KEYGUARD); + if (entry.getSbn().getNotification().fullScreenIntent == null) { + return false; + } + + // Never show FSI when suppressed by DND + if (entry.shouldSuppressFullScreenIntent()) { + if (DEBUG) { + Log.d(TAG, "No FullScreenIntent: Suppressed by DND: " + entry.getKey()); + } + return false; + } + + // Never show FSI if importance is not HIGH + if (entry.getImportance() < NotificationManager.IMPORTANCE_HIGH) { + if (DEBUG) { + Log.d(TAG, "No FullScreenIntent: Not important enough: " + entry.getKey()); + } + return false; + } + + // If the notification has suppressive GroupAlertBehavior, block FSI and warn. + StatusBarNotification sbn = entry.getSbn(); + if (sbn.isGroup() && sbn.getNotification().suppressAlertingDueToGrouping()) { + // b/231322873: Detect and report an event when a notification has both an FSI and a + // suppressive groupAlertBehavior, and now correctly block the FSI from firing. + final int uid = entry.getSbn().getUid(); + android.util.EventLog.writeEvent(0x534e4554, "231322873", uid, "groupAlertBehavior"); + if (DEBUG) { + Log.w(TAG, "No FullScreenIntent: WARNING: GroupAlertBehavior will prevent HUN: " + + entry.getKey()); + } + return false; + } + + // If the screen is off, then launch the FullScreenIntent + if (!mPowerManager.isInteractive()) { + if (DEBUG) { + Log.d(TAG, "FullScreenIntent: Device is not interactive: " + entry.getKey()); + } + return true; + } + + // If the device is currently dreaming, then launch the FullScreenIntent + if (isDreaming()) { + if (DEBUG) { + Log.d(TAG, "FullScreenIntent: Device is dreaming: " + entry.getKey()); + } + return true; + } + + // If the keyguard is showing, then launch the FullScreenIntent + if (mStatusBarStateController.getState() == StatusBarState.KEYGUARD) { + if (DEBUG) { + Log.d(TAG, "FullScreenIntent: Keyguard is showing: " + entry.getKey()); + } + return true; + } + + // If the notification should HUN, then we don't need FSI + if (shouldHeadsUp(entry)) { + if (DEBUG) { + Log.d(TAG, "No FullScreenIntent: Expected to HUN: " + entry.getKey()); + } + return false; + } + + // If the notification won't HUN for some other reason (DND/snooze/etc), launch FSI. + if (DEBUG) { + Log.d(TAG, "FullScreenIntent: Expected not to HUN: " + entry.getKey()); + } + return true; + } + + private boolean isDreaming() { + try { + return mDreamManager.isDreaming(); + } catch (RemoteException e) { + Log.e(TAG, "Failed to query dream manager.", e); + return false; + } } private boolean shouldHeadsUpWhenAwake(NotificationEntry entry) { @@ -228,13 +305,7 @@ public class NotificationInterruptStateProviderImpl implements NotificationInter return false; } - boolean isDreaming = false; - try { - isDreaming = mDreamManager.isDreaming(); - } catch (RemoteException e) { - Log.e(TAG, "Failed to query dream manager.", e); - } - boolean inUse = mPowerManager.isScreenOn() && !isDreaming; + boolean inUse = mPowerManager.isScreenOn() && !isDreaming(); if (!inUse) { if (DEBUG_HEADS_UP) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java index 1e92ca9862f7..31a2b5b28dd0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java @@ -330,6 +330,13 @@ public class NotificationStackScrollLayoutController { }; /** + * Recalculate sensitiveness without animation; called when waking up while keyguard occluded. + */ + public void updateSensitivenessForOccludedWakeup() { + mView.updateSensitiveness(false, mLockscreenUserManager.isAnyProfilePublicMode()); + } + + /** * Set the overexpansion of the panel to be applied to the view. */ public void setOverExpansion(float overExpansion) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index 88434cc214be..9ebc2f58f421 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -4159,6 +4159,17 @@ public class StatusBar extends SystemUI implements DemoMode, mWakeUpCoordinator.setFullyAwake(true); mBypassHeadsUpNotifier.setFullyAwake(true); mWakeUpCoordinator.setWakingUp(false); + if (isOccluded() && !mDozeParameters.canControlUnlockedScreenOff()) { + // When the keyguard is occluded we don't use the KEYGUARD state which would + // normally cause these redaction updates. If AOD is on, the KEYGUARD state is used + // to show the doze, AND UnlockedScreenOffAnimationController.onFinishedWakingUp() + // would force a KEYGUARD state that would take care of recalculating redaction. + // So if AOD is off or unsupported we need to trigger these updates at screen on + // when the keyguard is occluded. + mLockscreenUserManager.updatePublicMode(); + mNotificationPanelViewController.getNotificationStackScrollLayoutController() + .updateSensitivenessForOccludedWakeup(); + } if (mLaunchCameraWhenFinishedWaking) { mNotificationPanelViewController.launchCamera( false /* animate */, mLastCameraLaunchSource); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java index 60c3bc874235..440f76af2af4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java @@ -24,6 +24,7 @@ import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_AMBIENT; import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK; import static com.android.systemui.statusbar.NotificationEntryHelper.modifyRanking; +import static com.android.systemui.statusbar.StatusBarState.KEYGUARD; import static com.android.systemui.statusbar.StatusBarState.SHADE; import static com.google.common.truth.Truth.assertThat; @@ -84,6 +85,8 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase { BatteryController mBatteryController; @Mock Handler mMockHandler; + @Mock + PendingIntent mPendingIntent; private NotificationInterruptStateProviderImpl mNotifInterruptionStateProvider; @@ -399,6 +402,97 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase { assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isFalse(); } + @Test + public void testShouldNotFullScreen_notPendingIntent() throws RemoteException { + NotificationEntry entry = createNotification(IMPORTANCE_HIGH); + when(mPowerManager.isInteractive()).thenReturn(true); + when(mDreamManager.isDreaming()).thenReturn(false); + when(mStatusBarStateController.getState()).thenReturn(SHADE); + + assertThat(mNotifInterruptionStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry)) + .isFalse(); + } + + @Test + public void testShouldNotFullScreen_notHighImportance() throws RemoteException { + NotificationEntry entry = createFsiNotification(IMPORTANCE_DEFAULT, /* silenced */ false); + when(mPowerManager.isInteractive()).thenReturn(true); + when(mDreamManager.isDreaming()).thenReturn(false); + when(mStatusBarStateController.getState()).thenReturn(SHADE); + + assertThat(mNotifInterruptionStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry)) + .isFalse(); + } + + @Test + public void testShouldNotFullScreen_isGroupAlertSilenced() throws RemoteException { + NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ true); + when(mPowerManager.isInteractive()).thenReturn(false); + when(mDreamManager.isDreaming()).thenReturn(true); + when(mStatusBarStateController.getState()).thenReturn(KEYGUARD); + + assertThat(mNotifInterruptionStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry)) + .isFalse(); + } + + @Test + public void testShouldFullScreen_notInteractive() throws RemoteException { + NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ false); + when(mPowerManager.isInteractive()).thenReturn(false); + when(mDreamManager.isDreaming()).thenReturn(false); + when(mStatusBarStateController.getState()).thenReturn(SHADE); + + assertThat(mNotifInterruptionStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry)) + .isTrue(); + } + + @Test + public void testShouldFullScreen_isDreaming() throws RemoteException { + NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ false); + when(mPowerManager.isInteractive()).thenReturn(true); + when(mDreamManager.isDreaming()).thenReturn(true); + when(mStatusBarStateController.getState()).thenReturn(SHADE); + + assertThat(mNotifInterruptionStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry)) + .isTrue(); + } + + @Test + public void testShouldFullScreen_onKeyguard() throws RemoteException { + NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ false); + when(mPowerManager.isInteractive()).thenReturn(true); + when(mDreamManager.isDreaming()).thenReturn(false); + when(mStatusBarStateController.getState()).thenReturn(KEYGUARD); + + assertThat(mNotifInterruptionStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry)) + .isTrue(); + } + + @Test + public void testShouldNotFullScreen_willHun() throws RemoteException { + NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ false); + when(mPowerManager.isInteractive()).thenReturn(true); + when(mPowerManager.isScreenOn()).thenReturn(true); + when(mDreamManager.isDreaming()).thenReturn(false); + when(mStatusBarStateController.getState()).thenReturn(SHADE); + + assertThat(mNotifInterruptionStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry)) + .isFalse(); + } + + @Test + public void testShouldFullScreen_packageSnoozed() throws RemoteException { + NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ false); + when(mPowerManager.isInteractive()).thenReturn(true); + when(mPowerManager.isScreenOn()).thenReturn(true); + when(mDreamManager.isDreaming()).thenReturn(false); + when(mStatusBarStateController.getState()).thenReturn(SHADE); + when(mHeadsUpManager.isSnoozed("a")).thenReturn(true); + + assertThat(mNotifInterruptionStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry)) + .isTrue(); + } + /** * Bubbles can happen. */ @@ -503,6 +597,10 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase { .setContentText("content text") .build(); + return createNotification(importance, n); + } + + private NotificationEntry createNotification(int importance, Notification n) { return new NotificationEntryBuilder() .setPkg("a") .setOpPkg("a") @@ -512,6 +610,20 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase { .build(); } + private NotificationEntry createFsiNotification(int importance, boolean silent) { + Notification n = new Notification.Builder(getContext(), "a") + .setContentTitle("title") + .setContentText("content text") + .setFullScreenIntent(mPendingIntent, true) + .setGroup("fsi") + .setGroupAlertBehavior(silent + ? Notification.GROUP_ALERT_SUMMARY + : Notification.GROUP_ALERT_ALL) + .build(); + + return createNotification(importance, n); + } + private final NotificationInterruptSuppressor mSuppressAwakeHeadsUp = new NotificationInterruptSuppressor() { diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java index 400b084ee966..ae2f93449c86 100644 --- a/services/core/java/com/android/server/accounts/AccountManagerService.java +++ b/services/core/java/com/android/server/accounts/AccountManagerService.java @@ -1819,6 +1819,14 @@ public class AccountManagerService if (account == null) { return false; } + if (account.name != null && account.name.length() > 200) { + Log.w(TAG, "Account cannot be added - Name longer than 200 chars"); + return false; + } + if (account.type != null && account.type.length() > 200) { + Log.w(TAG, "Account cannot be added - Name longer than 200 chars"); + return false; + } if (!isLocalUnlockedUser(accounts.userId)) { Log.w(TAG, "Account " + account.toSafeString() + " cannot be added - user " + accounts.userId + " is locked. callingUid=" + callingUid); @@ -2064,6 +2072,10 @@ public class AccountManagerService + ", pid " + Binder.getCallingPid()); } if (accountToRename == null) throw new IllegalArgumentException("account is null"); + if (newName != null && newName.length() > 200) { + Log.e(TAG, "renameAccount failed - account name longer than 200"); + throw new IllegalArgumentException("account name longer than 200"); + } int userId = UserHandle.getCallingUserId(); if (!isAccountManagedByCaller(accountToRename.type, callingUid, userId)) { String msg = String.format( diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 97424640984b..89c86b67acbc 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -6817,6 +6817,7 @@ public class NotificationManagerService extends SystemService { @GuardedBy("mNotificationLock") void snoozeLocked(NotificationRecord r) { + final List<NotificationRecord> recordsToSnooze = new ArrayList<>(); if (r.getSbn().isGroup()) { final List<NotificationRecord> groupNotifications = findCurrentAndSnoozedGroupNotificationsLocked( @@ -6825,8 +6826,8 @@ public class NotificationManagerService extends SystemService { if (r.getNotification().isGroupSummary()) { // snooze all children for (int i = 0; i < groupNotifications.size(); i++) { - if (mKey != groupNotifications.get(i).getKey()) { - snoozeNotificationLocked(groupNotifications.get(i)); + if (!mKey.equals(groupNotifications.get(i).getKey())) { + recordsToSnooze.add(groupNotifications.get(i)); } } } else { @@ -6836,8 +6837,8 @@ public class NotificationManagerService extends SystemService { if (groupNotifications.size() == 2) { // snooze summary and the one child for (int i = 0; i < groupNotifications.size(); i++) { - if (mKey != groupNotifications.get(i).getKey()) { - snoozeNotificationLocked(groupNotifications.get(i)); + if (!mKey.equals(groupNotifications.get(i).getKey())) { + recordsToSnooze.add(groupNotifications.get(i)); } } } @@ -6845,7 +6846,15 @@ public class NotificationManagerService extends SystemService { } } // snooze the notification - snoozeNotificationLocked(r); + recordsToSnooze.add(r); + + if (mSnoozeHelper.canSnooze(recordsToSnooze.size())) { + for (int i = 0; i < recordsToSnooze.size(); i++) { + snoozeNotificationLocked(recordsToSnooze.get(i)); + } + } else { + Log.w(TAG, "Cannot snooze " + r.getKey() + ": too many snoozed notifications"); + } } diff --git a/services/core/java/com/android/server/notification/SnoozeHelper.java b/services/core/java/com/android/server/notification/SnoozeHelper.java index 4500bbcd250f..2e08a9cbf844 100644 --- a/services/core/java/com/android/server/notification/SnoozeHelper.java +++ b/services/core/java/com/android/server/notification/SnoozeHelper.java @@ -62,6 +62,8 @@ import java.util.Set; public class SnoozeHelper { public static final int XML_SNOOZED_NOTIFICATION_VERSION = 1; + static final int CONCURRENT_SNOOZE_LIMIT = 500; + protected static final String XML_TAG_NAME = "snoozed-notifications"; private static final String XML_SNOOZED_NOTIFICATION = "notification"; @@ -134,6 +136,15 @@ public class SnoozeHelper { } } + protected boolean canSnooze(int numberToSnooze) { + synchronized (mLock) { + if ((mPackages.size() + numberToSnooze) > CONCURRENT_SNOOZE_LIMIT) { + return false; + } + } + return true; + } + @NonNull protected Long getSnoozeTimeForUnpostedNotification(int userId, String pkg, String key) { Long time = null; diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java index c11116c827cb..5e62496d5cca 100644 --- a/services/core/java/com/android/server/notification/ZenModeHelper.java +++ b/services/core/java/com/android/server/notification/ZenModeHelper.java @@ -326,7 +326,8 @@ public class ZenModeHelper { int newRuleInstanceCount = getCurrentInstanceCount(automaticZenRule.getOwner()) + getCurrentInstanceCount(automaticZenRule.getConfigurationActivity()) + 1; - if (newRuleInstanceCount > RULE_LIMIT_PER_PACKAGE + int newPackageRuleCount = getPackageRuleCount(pkg) + 1; + if (newPackageRuleCount > RULE_LIMIT_PER_PACKAGE || (ruleInstanceLimit > 0 && ruleInstanceLimit < newRuleInstanceCount)) { throw new IllegalArgumentException("Rule instance limit exceeded"); } @@ -507,6 +508,23 @@ public class ZenModeHelper { return count; } + // Equivalent method to getCurrentInstanceCount, but for all rules associated with a specific + // package rather than a condition provider service or activity. + private int getPackageRuleCount(String pkg) { + if (pkg == null) { + return 0; + } + int count = 0; + synchronized (mConfig) { + for (ZenRule rule : mConfig.automaticRules.values()) { + if (pkg.equals(rule.getPkg())) { + count++; + } + } + } + return count; + } + public boolean canManageAutomaticZenRule(ZenRule rule) { final int callingUid = Binder.getCallingUid(); if (callingUid == 0 || callingUid == Process.SYSTEM_UID) { diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 0af6a29fad10..d1e89279ce3e 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -3532,7 +3532,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } // Exclude toast because legacy apps may show toast window by themselves, so the misused // apps won't always be considered as foreground state. - if (mAttrs.type >= FIRST_SYSTEM_WINDOW && mAttrs.type != TYPE_TOAST) { + // Exclude private presentations as they can only be shown on private virtual displays and + // shouldn't be the cause of an app be considered foreground. + if (mAttrs.type >= FIRST_SYSTEM_WINDOW && mAttrs.type != TYPE_TOAST + && mAttrs.type != TYPE_PRIVATE_PRESENTATION) { mWmService.mAtmService.mActiveUids.onNonAppSurfaceVisibilityChanged(mOwnerUid, shown); } if (mIsImWindow && mWmService.mAccessibilityController != null) { diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java index 2690948ca449..491626281c69 100644 --- a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java @@ -36,6 +36,7 @@ import android.accounts.CantAddAccountActivity; import android.accounts.IAccountManagerResponse; import android.app.AppOpsManager; import android.app.INotificationManager; +import android.app.PropertyInvalidatedCache; import android.app.admin.DevicePolicyManager; import android.app.admin.DevicePolicyManagerInternal; import android.content.BroadcastReceiver; @@ -132,6 +133,8 @@ public class AccountManagerServiceTest extends AndroidTestCase { protected void setUp() throws Exception { MockitoAnnotations.initMocks(this); + PropertyInvalidatedCache.disableForTestMode(); + when(mMockPackageManager.checkSignatures(anyInt(), anyInt())) .thenReturn(PackageManager.SIGNATURE_MATCH); final UserInfo ui = new UserInfo(UserHandle.USER_SYSTEM, "user0", 0); @@ -248,6 +251,26 @@ public class AccountManagerServiceTest extends AndroidTestCase { } @SmallTest + public void testCheckAddAccountLongName() throws Exception { + unlockSystemUser(); + String longString = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + + "aaaaa"; + Account a11 = new Account(longString, AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1); + + mAms.addAccountExplicitly( + a11, /* password= */ "p11", /* extras= */ null, /* callerPackage= */ null); + + String[] list = new String[]{AccountManagerServiceTestFixtures.CALLER_PACKAGE}; + when(mMockPackageManager.getPackagesForUid(anyInt())).thenReturn(list); + Account[] accounts = mAms.getAccountsAsUser(null, + UserHandle.getCallingUserId(), mContext.getOpPackageName()); + assertEquals(0, accounts.length); + } + + + @SmallTest public void testPasswords() throws Exception { unlockSystemUser(); Account a11 = new Account("account1", AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1); 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 e20efbbe044e..564ace201658 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -2815,19 +2815,80 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } @Test + public void testSnoozeRunnable_tooManySnoozed_singleNotification() { + final NotificationRecord notification = generateNotificationRecord( + mTestNotificationChannel, 1, null, true); + mService.addNotification(notification); + + when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true); + when(mSnoozeHelper.canSnooze(1)).thenReturn(false); + + NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable = + mService.new SnoozeNotificationRunnable( + notification.getKey(), 100, null); + snoozeNotificationRunnable.run(); + + verify(mSnoozeHelper, never()).snooze(any(NotificationRecord.class), anyLong()); + assertThat(mService.getNotificationRecordCount()).isEqualTo(1); + } + + @Test + public void testSnoozeRunnable_tooManySnoozed_singleGroupChildNotification() { + final NotificationRecord notification = generateNotificationRecord( + mTestNotificationChannel, 1, "group", true); + final NotificationRecord notificationChild = generateNotificationRecord( + mTestNotificationChannel, 1, "group", false); + mService.addNotification(notification); + mService.addNotification(notificationChild); + + when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true); + when(mSnoozeHelper.canSnooze(2)).thenReturn(false); + + NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable = + mService.new SnoozeNotificationRunnable( + notificationChild.getKey(), 100, null); + snoozeNotificationRunnable.run(); + + verify(mSnoozeHelper, never()).snooze(any(NotificationRecord.class), anyLong()); + assertThat(mService.getNotificationRecordCount()).isEqualTo(2); + } + + @Test + public void testSnoozeRunnable_tooManySnoozed_summaryNotification() { + final NotificationRecord notification = generateNotificationRecord( + mTestNotificationChannel, 1, "group", true); + final NotificationRecord notificationChild = generateNotificationRecord( + mTestNotificationChannel, 12, "group", false); + final NotificationRecord notificationChild2 = generateNotificationRecord( + mTestNotificationChannel, 13, "group", false); + mService.addNotification(notification); + mService.addNotification(notificationChild); + mService.addNotification(notificationChild2); + + when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true); + when(mSnoozeHelper.canSnooze(3)).thenReturn(false); + + NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable = + mService.new SnoozeNotificationRunnable( + notification.getKey(), 100, null); + snoozeNotificationRunnable.run(); + + verify(mSnoozeHelper, never()).snooze(any(NotificationRecord.class), anyLong()); + assertThat(mService.getNotificationRecordCount()).isEqualTo(3); + } + + @Test public void testSnoozeRunnable_reSnoozeASingleSnoozedNotification() throws Exception { final NotificationRecord notification = generateNotificationRecord( mTestNotificationChannel, 1, null, true); mService.addNotification(notification); when(mSnoozeHelper.getNotification(any())).thenReturn(notification); + when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true); NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable = mService.new SnoozeNotificationRunnable( notification.getKey(), 100, null); snoozeNotificationRunnable.run(); - NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable2 = - mService.new SnoozeNotificationRunnable( - notification.getKey(), 100, null); snoozeNotificationRunnable.run(); // snooze twice @@ -2835,19 +2896,17 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } @Test - public void testSnoozeRunnable_reSnoozeASnoozedNotificationWithGroupKey() throws Exception { + public void testSnoozeRunnable_reSnoozeASnoozedNotificationWithGroupKey() { final NotificationRecord notification = generateNotificationRecord( mTestNotificationChannel, 1, "group", true); mService.addNotification(notification); when(mSnoozeHelper.getNotification(any())).thenReturn(notification); + when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true); NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable = mService.new SnoozeNotificationRunnable( notification.getKey(), 100, null); snoozeNotificationRunnable.run(); - NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable2 = - mService.new SnoozeNotificationRunnable( - notification.getKey(), 100, null); snoozeNotificationRunnable.run(); // snooze twice @@ -2865,6 +2924,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { when(mSnoozeHelper.getNotification(any())).thenReturn(notification); when(mSnoozeHelper.getNotifications( anyString(), anyString(), anyInt())).thenReturn(new ArrayList<>()); + when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true); NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable = mService.new SnoozeNotificationRunnable( @@ -2874,8 +2934,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { .thenReturn(new ArrayList<>(Arrays.asList(notification, notification2))); NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable2 = mService.new SnoozeNotificationRunnable( - notification.getKey(), 100, null); - snoozeNotificationRunnable.run(); + notification2.getKey(), 100, null); + snoozeNotificationRunnable2.run(); // snooze twice verify(mSnoozeHelper, times(4)).snooze(any(NotificationRecord.class), anyLong()); @@ -2889,6 +2949,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mTestNotificationChannel, 2, "group", false); mService.addNotification(grouped); mService.addNotification(nonGrouped); + when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true); NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable = mService.new SnoozeNotificationRunnable( @@ -2918,6 +2979,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mService.addNotification(parent); mService.addNotification(child); mService.addNotification(child2); + when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true); NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable = mService.new SnoozeNotificationRunnable( @@ -2939,6 +3001,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mService.addNotification(parent); mService.addNotification(child); mService.addNotification(child2); + when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true); NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable = mService.new SnoozeNotificationRunnable( @@ -2964,6 +3027,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mTestNotificationChannel, 2, "group", false); mService.addNotification(parent); mService.addNotification(child); + when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true); NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable = mService.new SnoozeNotificationRunnable( @@ -2991,6 +3055,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { final NotificationRecord child = generateNotificationRecord( mTestNotificationChannel, 2, "group", false); mService.addNotification(child); + when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true); NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable = mService.new SnoozeNotificationRunnable( diff --git a/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java index 2ae2ef7162a5..8bead5774548 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java @@ -15,6 +15,7 @@ */ package com.android.server.notification; +import static com.android.server.notification.SnoozeHelper.CONCURRENT_SNOOZE_LIMIT; import static com.android.server.notification.SnoozeHelper.EXTRA_KEY; import static junit.framework.Assert.assertEquals; @@ -281,6 +282,22 @@ public class SnoozeHelperTest extends UiServiceTestCase { } @Test + public void testSnoozeLimit() { + for (int i = 0; i < CONCURRENT_SNOOZE_LIMIT; i++ ) { + NotificationRecord r = getNotificationRecord("pkg", i, i+"", UserHandle.SYSTEM); + + assertTrue("cannot snooze record " + i, mSnoozeHelper.canSnooze(1)); + + if (i % 2 == 0) { + mSnoozeHelper.snooze(r, null); + } else { + mSnoozeHelper.snooze(r, 9000); + } + } + assertFalse(mSnoozeHelper.canSnooze(1)); + } + + @Test public void testCancelByApp() throws Exception { NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM); NotificationRecord r2 = getNotificationRecord("pkg", 2, "two", UserHandle.SYSTEM); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java index e03cf1cd83a3..c0fb39c41676 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java @@ -1618,7 +1618,9 @@ public class ZenModeHelperTest extends UiServiceTestCase { ZenModeConfig.toScheduleConditionId(si), new ZenPolicy.Builder().build(), NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); - String id = mZenModeHelperSpy.addAutomaticZenRule("android", zenRule, "test"); + // We need the package name to be something that's not "android" so there aren't any + // existing rules under that package. + String id = mZenModeHelperSpy.addAutomaticZenRule("pkgname", zenRule, "test"); assertNotNull(id); } try { @@ -1628,12 +1630,41 @@ public class ZenModeHelperTest extends UiServiceTestCase { ZenModeConfig.toScheduleConditionId(new ScheduleInfo()), new ZenPolicy.Builder().build(), NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); - String id = mZenModeHelperSpy.addAutomaticZenRule("android", zenRule, "test"); + String id = mZenModeHelperSpy.addAutomaticZenRule("pkgname", zenRule, "test"); fail("allowed too many rules to be created"); } catch (IllegalArgumentException e) { // yay } + } + @Test + public void testAddAutomaticZenRule_beyondSystemLimit_differentComponents() { + // Make sure the system limit is enforced per-package even with different component provider + // names. + for (int i = 0; i < RULE_LIMIT_PER_PACKAGE; i++) { + ScheduleInfo si = new ScheduleInfo(); + si.startHour = i; + AutomaticZenRule zenRule = new AutomaticZenRule("name" + i, + null, + new ComponentName("android", "ScheduleConditionProvider" + i), + ZenModeConfig.toScheduleConditionId(si), + new ZenPolicy.Builder().build(), + NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); + String id = mZenModeHelperSpy.addAutomaticZenRule("pkgname", zenRule, "test"); + assertNotNull(id); + } + try { + AutomaticZenRule zenRule = new AutomaticZenRule("name", + null, + new ComponentName("android", "ScheduleConditionProviderFinal"), + ZenModeConfig.toScheduleConditionId(new ScheduleInfo()), + new ZenPolicy.Builder().build(), + NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); + String id = mZenModeHelperSpy.addAutomaticZenRule("pkgname", zenRule, "test"); + fail("allowed too many rules to be created"); + } catch (IllegalArgumentException e) { + // yay + } } @Test |