diff options
13 files changed, 383 insertions, 55 deletions
diff --git a/Android.bp b/Android.bp index 5250dc5895c8..a1061681358f 100644 --- a/Android.bp +++ b/Android.bp @@ -426,7 +426,7 @@ java_library { java_library { name: "framework-annotation-proc", - defaults: ["framework-defaults"], + defaults: ["framework-aidl-export-defaults"], srcs: [":framework-all-sources"], installable: false, plugins: [ diff --git a/cmds/statsd/src/metrics/CountMetricProducer.cpp b/cmds/statsd/src/metrics/CountMetricProducer.cpp index 23d025f82c26..1d0d2fb70a9d 100644 --- a/cmds/statsd/src/metrics/CountMetricProducer.cpp +++ b/cmds/statsd/src/metrics/CountMetricProducer.cpp @@ -251,6 +251,7 @@ bool CountMetricProducer::hitGuardRailLocked(const MetricDimensionKey& newKey) { if (newTupleCount > StatsdStats::kDimensionKeySizeHardLimit) { ALOGE("CountMetric %lld dropping data for dimension key %s", (long long)mMetricId, newKey.toString().c_str()); + StatsdStats::getInstance().noteHardDimensionLimitReached(mMetricId); return true; } } diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.cpp b/cmds/statsd/src/metrics/DurationMetricProducer.cpp index cca793b2146a..d7b46d1858cc 100644 --- a/cmds/statsd/src/metrics/DurationMetricProducer.cpp +++ b/cmds/statsd/src/metrics/DurationMetricProducer.cpp @@ -491,6 +491,7 @@ bool DurationMetricProducer::hitGuardRailLocked(const MetricDimensionKey& newKey if (newTupleCount > StatsdStats::kDimensionKeySizeHardLimit) { ALOGE("DurationMetric %lld dropping data for condition dimension key %s", (long long)mMetricId, newKey.getDimensionKeyInCondition().toString().c_str()); + StatsdStats::getInstance().noteHardDimensionLimitReached(mMetricId); return true; } } @@ -504,6 +505,7 @@ bool DurationMetricProducer::hitGuardRailLocked(const MetricDimensionKey& newKey if (newTupleCount > StatsdStats::kDimensionKeySizeHardLimit) { ALOGE("DurationMetric %lld dropping data for what dimension key %s", (long long)mMetricId, newKey.getDimensionKeyInWhat().toString().c_str()); + StatsdStats::getInstance().noteHardDimensionLimitReached(mMetricId); return true; } } diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp index 1f423cd384ef..efd05dcb04f1 100644 --- a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp +++ b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp @@ -439,6 +439,7 @@ bool GaugeMetricProducer::hitGuardRailLocked(const MetricDimensionKey& newKey) { if (newTupleCount > mDimensionHardLimit) { ALOGE("GaugeMetric %lld dropping data for dimension key %s", (long long)mMetricId, newKey.toString().c_str()); + StatsdStats::getInstance().noteHardDimensionLimitReached(mMetricId); return true; } } diff --git a/core/java/android/content/pm/AndroidTestBaseUpdater.java b/core/java/android/content/pm/AndroidTestBaseUpdater.java index da1a693b13c3..8fcfe711a882 100644 --- a/core/java/android/content/pm/AndroidTestBaseUpdater.java +++ b/core/java/android/content/pm/AndroidTestBaseUpdater.java @@ -18,10 +18,17 @@ package android.content.pm; import static android.content.pm.SharedLibraryNames.ANDROID_TEST_BASE; import static android.content.pm.SharedLibraryNames.ANDROID_TEST_RUNNER; +import android.compat.annotation.ChangeId; +import android.compat.annotation.EnabledAfter; +import android.content.Context; import android.content.pm.PackageParser.Package; import android.os.Build; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.util.Log; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.compat.IPlatformCompat; /** * Updates a package to ensure that if it targets <= Q that the android.test.base library is @@ -37,10 +44,26 @@ import com.android.internal.annotations.VisibleForTesting; */ @VisibleForTesting public class AndroidTestBaseUpdater extends PackageSharedLibraryUpdater { + private static final String TAG = "AndroidTestBaseUpdater"; - private static boolean apkTargetsApiLevelLessThanOrEqualToQ(Package pkg) { - int targetSdkVersion = pkg.applicationInfo.targetSdkVersion; - return targetSdkVersion <= Build.VERSION_CODES.Q; + /** + * Remove android.test.base library for apps that target SDK R or more and do not depend on + * android.test.runner (as it depends on classes from the android.test.base library). + */ + @ChangeId + @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q) + private static final long REMOVE_ANDROID_TEST_BASE = 133396946L; + + private static boolean isChangeEnabled(Package pkg) { + IPlatformCompat platformCompat = IPlatformCompat.Stub.asInterface( + ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE)); + try { + return platformCompat.isChangeEnabled(REMOVE_ANDROID_TEST_BASE, pkg.applicationInfo); + } catch (RemoteException | NullPointerException e) { + Log.e(TAG, "Failed to get a response from PLATFORM_COMPAT_SERVICE", e); + } + // Fall back to previous behaviour. + return pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.Q; } @Override @@ -48,7 +71,7 @@ public class AndroidTestBaseUpdater extends PackageSharedLibraryUpdater { // Packages targeted at <= Q expect the classes in the android.test.base library // to be accessible so this maintains backward compatibility by adding the // android.test.base library to those packages. - if (apkTargetsApiLevelLessThanOrEqualToQ(pkg)) { + if (!isChangeEnabled(pkg)) { prefixRequiredLibrary(pkg, ANDROID_TEST_BASE); } else { // If a package already depends on android.test.runner then add a dependency on diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index fe88a9140b37..6d60366dc72d 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -2569,7 +2569,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te if (isItemClickable(view)) { addAccessibilityActionIfEnabled(info, isItemEnabled, AccessibilityAction.ACTION_CLICK); - info.setClickable(true); + // A disabled item is a separator which should not be clickable. + info.setClickable(isItemEnabled); } if (isLongClickable()) { diff --git a/core/java/com/android/internal/app/ResolverListController.java b/core/java/com/android/internal/app/ResolverListController.java index 5f92cddbaa38..a390611be20b 100644 --- a/core/java/com/android/internal/app/ResolverListController.java +++ b/core/java/com/android/internal/app/ResolverListController.java @@ -115,14 +115,6 @@ public class ResolverListController { flags |= PackageManager.MATCH_INSTANT; } final List<ResolveInfo> infos = mpm.queryIntentActivities(intent, flags); - // Remove any activities that are not exported. - int totalSize = infos.size(); - for (int j = totalSize - 1; j >= 0 ; j--) { - ResolveInfo info = infos.get(j); - if (info.activityInfo != null && !info.activityInfo.exported) { - infos.remove(j); - } - } if (infos != null) { if (resolvedComponents == null) { resolvedComponents = new ArrayList<>(); diff --git a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java index 1e0a9f157ff5..176676fcb9b3 100644 --- a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java +++ b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java @@ -152,6 +152,20 @@ public class BrightnessController implements ToggleSlider.Listener { private final Runnable mStartListeningRunnable = new Runnable() { @Override public void run() { + if (mListening) { + return; + } + mListening = true; + + if (mVrManager != null) { + try { + mVrManager.registerListener(mVrStateCallbacks); + mIsVrModeEnabled = mVrManager.getVrModeState(); + } catch (RemoteException e) { + Log.e(TAG, "Failed to register VR mode state listener: ", e); + } + } + mBrightnessObserver.startObserving(); mUserTracker.startTracking(); @@ -167,6 +181,19 @@ public class BrightnessController implements ToggleSlider.Listener { private final Runnable mStopListeningRunnable = new Runnable() { @Override public void run() { + if (!mListening) { + return; + } + mListening = false; + + if (mVrManager != null) { + try { + mVrManager.unregisterListener(mVrStateCallbacks); + } catch (RemoteException e) { + Log.e(TAG, "Failed to unregister VR mode state listener: ", e); + } + } + mBrightnessObserver.stopObserving(); mUserTracker.stopTracking(); @@ -297,39 +324,12 @@ public class BrightnessController implements ToggleSlider.Listener { } public void registerCallbacks() { - if (mListening) { - return; - } - - if (mVrManager != null) { - try { - mVrManager.registerListener(mVrStateCallbacks); - mIsVrModeEnabled = mVrManager.getVrModeState(); - } catch (RemoteException e) { - Log.e(TAG, "Failed to register VR mode state listener: ", e); - } - } - mBackgroundHandler.post(mStartListeningRunnable); - mListening = true; } /** Unregister all call backs, both to and from the controller */ public void unregisterCallbacks() { - if (!mListening) { - return; - } - - if (mVrManager != null) { - try { - mVrManager.unregisterListener(mVrStateCallbacks); - } catch (RemoteException e) { - Log.e(TAG, "Failed to unregister VR mode state listener: ", e); - } - } - mBackgroundHandler.post(mStopListeningRunnable); - mListening = false; mControlValueInitialized = false; } diff --git a/services/core/java/com/android/server/notification/GroupHelper.java b/services/core/java/com/android/server/notification/GroupHelper.java index b1cd62788073..9cb8a0105286 100644 --- a/services/core/java/com/android/server/notification/GroupHelper.java +++ b/services/core/java/com/android/server/notification/GroupHelper.java @@ -16,9 +16,13 @@ package com.android.server.notification; import android.service.notification.StatusBarNotification; +import android.util.ArrayMap; +import android.util.ArraySet; import android.util.Log; import android.util.Slog; +import com.android.internal.annotations.VisibleForTesting; + import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashSet; @@ -37,6 +41,11 @@ public class GroupHelper { private final Callback mCallback; private final int mAutoGroupAtCount; + // count the number of ongoing notifications per group + // userId -> (package name -> (group Id -> (set of notification keys))) + final ArrayMap<String, ArraySet<String>> + mOngoingGroupCount = new ArrayMap<>(); + // Map of user : <Map of package : notification keys>. Only contains notifications that are not // grouped by the app (aka no group or sort key). Map<Integer, Map<String, LinkedHashSet<String>>> mUngroupedNotifications = new HashMap<>(); @@ -46,10 +55,52 @@ public class GroupHelper { mCallback = callback; } + private String generatePackageGroupKey(int userId, String pkg, String group) { + return userId + "|" + pkg + "|" + group; + } + + @VisibleForTesting + protected int getOngoingGroupCount(int userId, String pkg, String group) { + String key = generatePackageGroupKey(userId, pkg, group); + return mOngoingGroupCount.getOrDefault(key, new ArraySet<>(0)).size(); + } + + private void addToOngoingGroupCount(StatusBarNotification sbn, boolean add) { + if (sbn.getNotification().isGroupSummary()) return; + if (!sbn.isOngoing() && add) return; + String group = sbn.getGroup(); + if (group == null) return; + int userId = sbn.getUser().getIdentifier(); + String key = generatePackageGroupKey(userId, sbn.getPackageName(), group); + ArraySet<String> notifications = mOngoingGroupCount.getOrDefault(key, new ArraySet<>(0)); + if (add) { + notifications.add(sbn.getKey()); + mOngoingGroupCount.put(key, notifications); + } else { + notifications.remove(sbn.getKey()); + // we dont need to put it back if it is default + } + String combinedKey = generatePackageGroupKey(userId, sbn.getPackageName(), group); + boolean needsOngoingFlag = notifications.size() > 0; + mCallback.updateAutogroupSummary(sbn.getKey(), needsOngoingFlag); + } + + public void onNotificationUpdated(StatusBarNotification childSbn, + boolean autogroupSummaryExists) { + if (childSbn.getGroup() != AUTOGROUP_KEY + || childSbn.getNotification().isGroupSummary()) return; + if (childSbn.isOngoing()) { + addToOngoingGroupCount(childSbn, true); + } else { + addToOngoingGroupCount(childSbn, false); + } + } + public void onNotificationPosted(StatusBarNotification sbn, boolean autogroupSummaryExists) { if (DEBUG) Log.i(TAG, "POSTED " + sbn.getKey()); try { List<String> notificationsToGroup = new ArrayList<>(); + if (autogroupSummaryExists) addToOngoingGroupCount(sbn, true); if (!sbn.isAppGroup()) { // Not grouped by the app, add to the list of notifications for the app; // send grouping update if app exceeds the autogrouping limit. @@ -90,6 +141,7 @@ public class GroupHelper { public void onNotificationRemoved(StatusBarNotification sbn) { try { + addToOngoingGroupCount(sbn, false); maybeUngroup(sbn, true, sbn.getUserId()); } catch (Exception e) { Slog.e(TAG, "Error processing canceled notification", e); @@ -159,5 +211,6 @@ public class GroupHelper { void removeAutoGroup(String key); void addAutoGroupSummary(int userId, String pkg, String triggeringKey); void removeAutoGroupSummary(int user, String pkg); + void updateAutogroupSummary(String key, boolean needsOngoingFlag); } } diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 503956617e6e..d7efa1b733fd 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -601,6 +601,40 @@ public class NotificationManagerService extends SystemService { } } + /** + * This method will update the flags of the summary. + * It will set it to FLAG_ONGOING_EVENT if any of its group members + * has the same flag. It will delete the flag otherwise + * @param userId user id of the autogroup summary + * @param pkg package of the autogroup summary + * @param needsOngoingFlag true if the group has at least one ongoing notification + */ + @GuardedBy("mNotificationLock") + protected void updateAutobundledSummaryFlags(int userId, String pkg, boolean needsOngoingFlag) { + ArrayMap<String, String> summaries = mAutobundledSummaries.get(userId); + if (summaries == null) { + return; + } + String summaryKey = summaries.get(pkg); + if (summaryKey == null) { + return; + } + NotificationRecord summary = mNotificationsByKey.get(summaryKey); + if (summary == null) { + return; + } + int oldFlags = summary.sbn.getNotification().flags; + if (needsOngoingFlag) { + summary.sbn.getNotification().flags |= FLAG_ONGOING_EVENT; + } else { + summary.sbn.getNotification().flags &= ~FLAG_ONGOING_EVENT; + } + + if (summary.sbn.getNotification().flags != oldFlags) { + mHandler.post(new EnqueueNotificationRunnable(userId, summary)); + } + } + private void allowDndPackage(String packageName) { try { getBinderService().setNotificationPolicyAccessGranted(packageName, true); @@ -1917,7 +1951,6 @@ public class NotificationManagerService extends SystemService { }); } - private GroupHelper getGroupHelper() { mAutoGroupAtCount = getContext().getResources().getInteger(R.integer.config_autoGroupAtCount); @@ -1947,6 +1980,15 @@ public class NotificationManagerService extends SystemService { clearAutogroupSummaryLocked(userId, pkg); } } + + @Override + public void updateAutogroupSummary(String key, boolean needsOngoingFlag) { + synchronized (mNotificationLock) { + NotificationRecord r = mNotificationsByKey.get(key); + updateAutobundledSummaryFlags(r.getUser().getIdentifier(), + r.sbn.getPackageName(), needsOngoingFlag); + } + } }); } @@ -5762,6 +5804,10 @@ public class NotificationManagerService extends SystemService { n, hasAutoGroupSummaryLocked(n)); } }); + } else if (oldSbn != null) { + final NotificationRecord finalRecord = r; + mHandler.post(() -> mGroupHelper.onNotificationUpdated( + finalRecord.sbn, hasAutoGroupSummaryLocked(n))); } } else { Slog.e(TAG, "Not posting notification without small icon: " + notification); diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index b85009b8eac1..01ea6868aff6 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -15080,19 +15080,6 @@ public class PackageManagerService extends IPackageManager.Stub return disabled; } - @GuardedBy("mLock") - private void setInstallerPackageNameLPw(PackageParser.Package pkg, - String installerPackageName) { - // Enable the parent package - mSettings.setInstallerPackageName(pkg.packageName, installerPackageName); - // Enable the child packages - final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; - for (int i = 0; i < childCount; i++) { - PackageParser.Package childPkg = pkg.childPackages.get(i); - mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName); - } - } - private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName, int[] allUsers, PackageInstalledInfo res, UserHandle user, int installReason) { // Update the parent package setting diff --git a/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java index f652c5afd203..721641a7a8c8 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java @@ -15,6 +15,8 @@ */ package com.android.server.notification; +import static com.android.server.notification.GroupHelper.AUTOGROUP_KEY; + import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertNotNull; @@ -155,6 +157,196 @@ public class GroupHelperTest extends UiServiceTestCase { } @Test + public void testAutoGroupCount_addingNoGroupSBN() { + final String pkg = "package"; + ArrayList<StatusBarNotification> notifications = new ArrayList<>(); + for (int i = 0; i < AUTOGROUP_AT_COUNT + 1; i++) { + notifications.add(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM)); + } + + for (StatusBarNotification sbn: notifications) { + sbn.getNotification().flags |= Notification.FLAG_ONGOING_EVENT; + sbn.setOverrideGroupKey(AUTOGROUP_KEY); + } + + for (StatusBarNotification sbn: notifications) { + mGroupHelper.onNotificationPosted(sbn, true); + } + + verify(mCallback, times(AUTOGROUP_AT_COUNT + 1)) + .updateAutogroupSummary(anyString(), eq(true)); + + int userId = UserHandle.SYSTEM.getIdentifier(); + assertEquals(mGroupHelper.getOngoingGroupCount( + userId, pkg, AUTOGROUP_KEY), AUTOGROUP_AT_COUNT + 1); + } + + @Test + public void testAutoGroupCount_UpdateNotification() { + final String pkg = "package"; + ArrayList<StatusBarNotification> notifications = new ArrayList<>(); + for (int i = 0; i < AUTOGROUP_AT_COUNT + 1; i++) { + notifications.add(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM)); + } + + for (StatusBarNotification sbn: notifications) { + sbn.getNotification().flags |= Notification.FLAG_ONGOING_EVENT; + sbn.setOverrideGroupKey(AUTOGROUP_KEY); + } + + for (StatusBarNotification sbn: notifications) { + mGroupHelper.onNotificationPosted(sbn, true); + } + + notifications.get(0).getNotification().flags &= ~Notification.FLAG_ONGOING_EVENT; + + mGroupHelper.onNotificationUpdated(notifications.get(0), true); + + verify(mCallback, times(AUTOGROUP_AT_COUNT + 2)) + .updateAutogroupSummary(anyString(), eq(true)); + + int userId = UserHandle.SYSTEM.getIdentifier(); + assertEquals(mGroupHelper.getOngoingGroupCount( + userId, pkg, AUTOGROUP_KEY), AUTOGROUP_AT_COUNT); + } + + @Test + public void testAutoGroupCount_UpdateNotificationAfterChanges() { + final String pkg = "package"; + ArrayList<StatusBarNotification> notifications = new ArrayList<>(); + for (int i = 0; i < AUTOGROUP_AT_COUNT + 1; i++) { + notifications.add(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM)); + } + + for (StatusBarNotification sbn: notifications) { + sbn.getNotification().flags |= Notification.FLAG_ONGOING_EVENT; + sbn.setOverrideGroupKey(AUTOGROUP_KEY); + } + + for (StatusBarNotification sbn: notifications) { + mGroupHelper.onNotificationPosted(sbn, true); + } + + notifications.get(0).getNotification().flags &= ~Notification.FLAG_ONGOING_EVENT; + + mGroupHelper.onNotificationUpdated(notifications.get(0), true); + + notifications.get(0).getNotification().flags |= Notification.FLAG_ONGOING_EVENT; + + mGroupHelper.onNotificationUpdated(notifications.get(0), true); + + verify(mCallback, times(AUTOGROUP_AT_COUNT + 3)) + .updateAutogroupSummary(anyString(), eq(true)); + + int userId = UserHandle.SYSTEM.getIdentifier(); + assertEquals(mGroupHelper.getOngoingGroupCount( + userId, pkg, AUTOGROUP_KEY), AUTOGROUP_AT_COUNT + 1); + } + + @Test + public void testAutoGroupCount_RemoveNotification() { + final String pkg = "package"; + ArrayList<StatusBarNotification> notifications = new ArrayList<>(); + for (int i = 0; i < AUTOGROUP_AT_COUNT + 1; i++) { + notifications.add(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM)); + } + + for (StatusBarNotification sbn: notifications) { + sbn.getNotification().flags |= Notification.FLAG_ONGOING_EVENT; + sbn.setOverrideGroupKey(AUTOGROUP_KEY); + } + + for (StatusBarNotification sbn: notifications) { + mGroupHelper.onNotificationPosted(sbn, true); + } + + mGroupHelper.onNotificationRemoved(notifications.get(0)); + + verify(mCallback, times(AUTOGROUP_AT_COUNT + 2)) + .updateAutogroupSummary(anyString(), eq(true)); + + int userId = UserHandle.SYSTEM.getIdentifier(); + assertEquals(mGroupHelper.getOngoingGroupCount( + userId, pkg, AUTOGROUP_KEY), AUTOGROUP_AT_COUNT); + } + + + @Test + public void testAutoGroupCount_UpdateToNoneOngoingNotification() { + final String pkg = "package"; + ArrayList<StatusBarNotification> notifications = new ArrayList<>(); + for (int i = 0; i < AUTOGROUP_AT_COUNT + 1; i++) { + notifications.add(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM)); + } + + for (StatusBarNotification sbn: notifications) { + sbn.setOverrideGroupKey(AUTOGROUP_KEY); + } + + for (StatusBarNotification sbn: notifications) { + mGroupHelper.onNotificationPosted(sbn, true); + } + + notifications.get(0).getNotification().flags |= Notification.FLAG_ONGOING_EVENT; + mGroupHelper.onNotificationUpdated(notifications.get(0), true); + + verify(mCallback, times(1)) + .updateAutogroupSummary(anyString(), eq(true)); + + int userId = UserHandle.SYSTEM.getIdentifier(); + assertEquals(mGroupHelper.getOngoingGroupCount( + userId, pkg, AUTOGROUP_KEY), 1); + } + + @Test + public void testAutoGroupCount_AddOneOngoingNotification() { + final String pkg = "package"; + ArrayList<StatusBarNotification> notifications = new ArrayList<>(); + for (int i = 0; i < AUTOGROUP_AT_COUNT + 1; i++) { + notifications.add(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM)); + } + StatusBarNotification sbn = notifications.get(0); + sbn.getNotification().flags |= Notification.FLAG_ONGOING_EVENT; + sbn.setOverrideGroupKey(AUTOGROUP_KEY); + + + for (StatusBarNotification current: notifications) { + mGroupHelper.onNotificationPosted(current, true); + } + + verify(mCallback, times(1)) + .updateAutogroupSummary(anyString(), eq(true)); + + int userId = UserHandle.SYSTEM.getIdentifier(); + assertEquals(mGroupHelper.getOngoingGroupCount( + userId, pkg, AUTOGROUP_KEY), 1); + } + + @Test + public void testAutoGroupCount_UpdateNoneOngoing() { + final String pkg = "package"; + ArrayList<StatusBarNotification> notifications = new ArrayList<>(); + for (int i = 0; i < AUTOGROUP_AT_COUNT + 1; i++) { + notifications.add(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM)); + } + + for (StatusBarNotification sbn: notifications) { + sbn.setOverrideGroupKey(AUTOGROUP_KEY); + } + + for (StatusBarNotification sbn: notifications) { + mGroupHelper.onNotificationPosted(sbn, true); + } + + verify(mCallback, times(0)) + .updateAutogroupSummary(anyString(), eq(true)); + + int userId = UserHandle.SYSTEM.getIdentifier(); + assertEquals(mGroupHelper.getOngoingGroupCount(userId, pkg, AUTOGROUP_KEY), 0); + } + + + @Test public void testDropToZeroRemoveGroup() throws Exception { final String pkg = "package"; List<StatusBarNotification> posted = new ArrayList<>(); 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 2072ee538fdd..4ea2fc0d398e 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -1182,6 +1182,36 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } @Test + public void testAutobundledSummary_notificationAdded() { + NotificationRecord summary = + generateNotificationRecord(mTestNotificationChannel, 0, "pkg", true); + summary.getNotification().flags |= Notification.FLAG_AUTOGROUP_SUMMARY; + mService.addNotification(summary); + mService.mSummaryByGroupKey.put("pkg", summary); + mService.mAutobundledSummaries.put(0, new ArrayMap<>()); + mService.mAutobundledSummaries.get(0).put("pkg", summary.getKey()); + mService.updateAutobundledSummaryFlags(0, "pkg", true); + + assertTrue(summary.sbn.isOngoing()); + } + + @Test + public void testAutobundledSummary_notificationRemoved() { + NotificationRecord summary = + generateNotificationRecord(mTestNotificationChannel, 0, "pkg", true); + summary.getNotification().flags |= Notification.FLAG_AUTOGROUP_SUMMARY; + summary.getNotification().flags |= Notification.FLAG_ONGOING_EVENT; + mService.addNotification(summary); + mService.mAutobundledSummaries.put(0, new ArrayMap<>()); + mService.mAutobundledSummaries.get(0).put("pkg", summary.getKey()); + mService.mSummaryByGroupKey.put("pkg", summary); + + mService.updateAutobundledSummaryFlags(0, "pkg", false); + + assertFalse(summary.sbn.isOngoing()); + } + + @Test public void testCancelAllNotifications_IgnoreForegroundService() throws Exception { final StatusBarNotification sbn = generateNotificationRecord(null).sbn; sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE; |