Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d9e67678 authored by Alexander Roederer's avatar Alexander Roederer Committed by Android (Google) Code Review
Browse files

Merge "Update lifetime extended notif on second reply" into main

parents f9c767d6 7dd983d3
Loading
Loading
Loading
Loading
+8 −3
Original line number Diff line number Diff line
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,11 +58,16 @@ public class NotificationClickNotifier @Inject constructor(
            } catch (e: RemoteException) {
                // nothing
            }
            if (lifetimeExtensionRefactor()) {
                notifyListenersAboutInteraction(key)
            }
        }
        if (!lifetimeExtensionRefactor()) {
            mainExecutor.execute {
                notifyListenersAboutInteraction(key)
            }
        }
    }

    fun onNotificationClick(
        key: String,
+52 −5
Original line number Diff line number Diff line
@@ -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;
+64 −0
Original line number Diff line number Diff line
@@ -5841,6 +5841,30 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
                mNotificationRecordLogger.event(0));
    }
    @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);
@@ -8506,6 +8530,36 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
        assertThat(r.getStats().hasSmartReplied()).isTrue();
    }
    @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;
@@ -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