summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationClickNotifier.kt11
-rwxr-xr-xservices/core/java/com/android/server/notification/NotificationManagerService.java57
-rwxr-xr-xservices/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java64
3 files changed, 124 insertions, 8 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationClickNotifier.kt b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationClickNotifier.kt
index 692a9977c364..4ab78aab372d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationClickNotifier.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationClickNotifier.kt
@@ -1,8 +1,8 @@
package com.android.systemui.statusbar
+import android.app.Flags.lifetimeExtensionRefactor
import android.app.Notification
import android.os.RemoteException
-import android.util.Log
import com.android.internal.statusbar.IStatusBarService
import com.android.internal.statusbar.NotificationVisibility
import com.android.systemui.dagger.SysUISingleton
@@ -58,9 +58,14 @@ public class NotificationClickNotifier @Inject constructor(
} catch (e: RemoteException) {
// nothing
}
+ if (lifetimeExtensionRefactor()) {
+ notifyListenersAboutInteraction(key)
+ }
}
- mainExecutor.execute {
- notifyListenersAboutInteraction(key)
+ if (!lifetimeExtensionRefactor()) {
+ mainExecutor.execute {
+ notifyListenersAboutInteraction(key)
+ }
}
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 7455fe0043f8..fc7b87317344 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1355,7 +1355,8 @@ public class NotificationManagerService extends SystemService {
nv.recycle();
reportUserInteraction(r);
mAssistants.notifyAssistantActionClicked(r, action, generatedByAssistant);
- // Notifications that have been interacted with don't need to be lifetime extended.
+ // Notifications that have been interacted with should no longer be lifetime
+ // extended.
if (lifetimeExtensionRefactor()) {
r.getSbn().getNotification().flags &= ~FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY;
}
@@ -1524,9 +1525,32 @@ public class NotificationManagerService extends SystemService {
@Override
public void onNotificationDirectReplied(String key) {
exitIdle();
+ String packageName = null;
+ final int packageImportance;
synchronized (mNotificationLock) {
NotificationRecord r = mNotificationsByKey.get(key);
if (r != null) {
+ packageName = r.getSbn().getPackageName();
+ }
+ }
+ if (lifetimeExtensionRefactor() && packageName != null) {
+ packageImportance = getPackageImportanceWithIdentity(packageName);
+ } else {
+ packageImportance = IMPORTANCE_NONE;
+ }
+ synchronized (mNotificationLock) {
+ NotificationRecord r = mNotificationsByKey.get(key);
+ if (r != null) {
+ // If the notification is already marked as lifetime extended before we record
+ // the new direct reply, there must have been a previous lifetime extension
+ // event, and the app has already cancelled the notification, or does not
+ // respond to direct replies with updates. So we need to update System UI
+ // immediately.
+ if (lifetimeExtensionRefactor()) {
+ maybeNotifySystemUiListenerLifetimeExtendedLocked(r,
+ r.getSbn().getPackageName(), packageImportance);
+ }
+
r.recordDirectReplied();
mMetricsLogger.write(r.getLogMaker()
.setCategory(MetricsEvent.NOTIFICATION_DIRECT_REPLY_ACTION)
@@ -1557,10 +1581,31 @@ public class NotificationManagerService extends SystemService {
@Override
public void onNotificationSmartReplySent(String key, int replyIndex, CharSequence reply,
int notificationLocation, boolean modifiedBeforeSending) {
-
+ String packageName = null;
+ final int packageImportance;
synchronized (mNotificationLock) {
NotificationRecord r = mNotificationsByKey.get(key);
if (r != null) {
+ packageName = r.getSbn().getPackageName();
+ }
+ }
+ if (lifetimeExtensionRefactor() && packageName != null) {
+ packageImportance = getPackageImportanceWithIdentity(packageName);
+ } else {
+ packageImportance = IMPORTANCE_NONE;
+ }
+ synchronized (mNotificationLock) {
+ NotificationRecord r = mNotificationsByKey.get(key);
+ if (r != null) {
+ // If the notification is already marked as lifetime extended before we record
+ // the new direct reply, there must have been a previous lifetime extension
+ // event, and the app has already cancelled the notification, or does not
+ // respond to direct replies with updates. So we need to update System UI
+ // immediately.
+ if (lifetimeExtensionRefactor()) {
+ maybeNotifySystemUiListenerLifetimeExtendedLocked(r,
+ r.getSbn().getPackageName(), packageImportance);
+ }
r.recordSmartReplied();
LogMaker logMaker = r.getLogMaker()
.setCategory(MetricsEvent.SMART_REPLY_ACTION)
@@ -7735,7 +7780,7 @@ public class NotificationManagerService extends SystemService {
notification.flags &= ~FLAG_FSI_REQUESTED_BUT_DENIED;
- // Apps should not create notifications that are lifetime extended.
+ // Apps cannot post notifications that are lifetime extended.
if (lifetimeExtensionRefactor()) {
notification.flags &= ~FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY;
}
@@ -12005,8 +12050,10 @@ public class NotificationManagerService extends SystemService {
@Override
public void onServiceAdded(ManagedServiceInfo info) {
if (lifetimeExtensionRefactor()) {
- // Only System or System UI can call registerSystemService, so if the caller is not
- // system, we know it's system UI.
+ // Generally, only System or System UI should have the permissions to call
+ // registerSystemService.
+ // isCallerSystemorPhone tells us whether the caller is System. Then, if it's not
+ // the system, we know it's system UI.
info.isSystemUi = !isCallerSystemOrPhone();
}
final INotificationListener listener = (INotificationListener) info.service;
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 92dad2598538..cff7f460feb5 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -5842,6 +5842,30 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
}
@Test
+ public void testStats_DirectReplyLifetimeExtendedPostsUpdate() throws Exception {
+ mSetFlagsRule.enableFlags(android.app.Flags.FLAG_LIFETIME_EXTENSION_REFACTOR);
+ final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
+ r.getSbn().getNotification().flags |= FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY;
+ mService.addNotification(r);
+
+ mService.mNotificationDelegate.onNotificationDirectReplied(r.getKey());
+ waitForIdle();
+
+ assertThat(mService.getNotificationRecord(r.getKey()).getStats().hasDirectReplied())
+ .isTrue();
+ // Checks that a post update is sent.
+ verify(mWorkerHandler, times(1))
+ .post(any(NotificationManagerService.PostNotificationRunnable.class));
+ ArgumentCaptor<NotificationRecord> captor =
+ ArgumentCaptor.forClass(NotificationRecord.class);
+ verify(mListeners, times(1)).prepareNotifyPostedLocked(captor.capture(), any(),
+ anyBoolean());
+ assertThat(captor.getValue().getNotification().flags
+ & FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY).isEqualTo(
+ FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY);
+ }
+
+ @Test
public void testStats_updatedOnUserExpansion() throws Exception {
NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
mService.addNotification(r);
@@ -8507,6 +8531,36 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
}
@Test
+ public void testStats_SmartReplyAlreadyLifetimeExtendedPostsUpdate() throws Exception {
+ mSetFlagsRule.enableFlags(android.app.Flags.FLAG_LIFETIME_EXTENSION_REFACTOR);
+ final int replyIndex = 2;
+ final String reply = "Hello";
+ final boolean modifiedBeforeSending = true;
+ final boolean generatedByAssistant = true;
+
+ NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
+ r.getSbn().getNotification().flags |= FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY;
+ r.setSuggestionsGeneratedByAssistant(generatedByAssistant);
+ mService.addNotification(r);
+
+ mService.mNotificationDelegate.onNotificationSmartReplySent(
+ r.getKey(), replyIndex, reply, NOTIFICATION_LOCATION_UNKNOWN,
+ modifiedBeforeSending);
+ waitForIdle();
+
+ // Checks that a post update is sent.
+ verify(mWorkerHandler, times(1))
+ .post(any(NotificationManagerService.PostNotificationRunnable.class));
+ ArgumentCaptor<NotificationRecord> captor =
+ ArgumentCaptor.forClass(NotificationRecord.class);
+ verify(mListeners, times(1)).prepareNotifyPostedLocked(captor.capture(), any(),
+ anyBoolean());
+ assertThat(captor.getValue().getNotification().flags
+ & FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY).isEqualTo(
+ FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY);
+ }
+
+ @Test
public void testOnNotificationActionClick() {
final int actionIndex = 2;
final Notification.Action action =
@@ -8537,6 +8591,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
final Notification.Action action =
new Notification.Action.Builder(null, "text", PendingIntent.getActivity(
mContext, 0, new Intent(), PendingIntent.FLAG_IMMUTABLE)).build();
+ final boolean generatedByAssistant = false;
+
// Creates a notification marked as being lifetime extended.
NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
r.getSbn().getNotification().flags |= FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY;
@@ -8550,6 +8606,14 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
// The flag is removed, so the notification is no longer lifetime extended.
assertThat(r.getSbn().getNotification().flags
& FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY).isEqualTo(0);
+
+ // The record is sent out without the flag.
+ ArgumentCaptor<NotificationRecord> captor =
+ ArgumentCaptor.forClass(NotificationRecord.class);
+ verify(mAssistants, times(1)).notifyAssistantActionClicked(
+ captor.capture(), eq(action), eq(generatedByAssistant));
+ assertThat(captor.getValue().getNotification().flags
+ & FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY).isEqualTo(0);
}
@Test