Loading core/java/android/app/Notification.java +8 −1 Original line number Original line Diff line number Diff line Loading @@ -7391,7 +7391,14 @@ public class Notification implements Parcelable return messages; return messages; } } static Message getMessageFromBundle(Bundle bundle) { /** * @return The message that is stored in the bundle or null if the message couldn't be * resolved. * * @hide */ @Nullable public static Message getMessageFromBundle(Bundle bundle) { try { try { if (!bundle.containsKey(KEY_TEXT) || !bundle.containsKey(KEY_TIMESTAMP)) { if (!bundle.containsKey(KEY_TEXT) || !bundle.containsKey(KEY_TIMESTAMP)) { return null; return null; Loading packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java +43 −0 Original line number Original line Diff line number Diff line Loading @@ -32,10 +32,13 @@ import android.app.AppGlobals; import android.app.Notification; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.NotificationManager; import android.app.Person; import android.content.Context; import android.content.Context; import android.content.pm.IPackageManager; import android.content.pm.IPackageManager; import android.content.pm.PackageManager; import android.content.pm.PackageManager; import android.graphics.drawable.Icon; import android.graphics.drawable.Icon; import android.os.Bundle; import android.os.Parcelable; import android.os.RemoteException; import android.os.RemoteException; import android.os.SystemClock; import android.os.SystemClock; import android.service.notification.NotificationListenerService.Ranking; import android.service.notification.NotificationListenerService.Ranking; Loading @@ -50,6 +53,7 @@ import android.widget.RemoteViews; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.statusbar.StatusBarIcon; import com.android.internal.statusbar.StatusBarIcon; import com.android.internal.util.ArrayUtils; import com.android.internal.util.NotificationColorUtil; import com.android.internal.util.NotificationColorUtil; import com.android.systemui.Dependency; import com.android.systemui.Dependency; import com.android.systemui.ForegroundServiceController; import com.android.systemui.ForegroundServiceController; Loading Loading @@ -117,6 +121,11 @@ public class NotificationData { */ */ public Boolean mIsSystemNotification; public Boolean mIsSystemNotification; /** * Has the user sent a reply through this Notification. */ private boolean hasSentReply; public Entry(StatusBarNotification n) { public Entry(StatusBarNotification n) { this.key = n.getKey(); this.key = n.getKey(); this.notification = n; this.notification = n; Loading Loading @@ -298,6 +307,40 @@ public class NotificationData { lastRemoteInputSent = NOT_LAUNCHED_YET; lastRemoteInputSent = NOT_LAUNCHED_YET; remoteInputTextWhenReset = null; remoteInputTextWhenReset = null; } } public void setHasSentReply() { hasSentReply = true; } public boolean isLastMessageFromReply() { if (!hasSentReply) { return false; } Bundle extras = notification.getNotification().extras; CharSequence[] replyTexts = extras.getCharSequenceArray( Notification.EXTRA_REMOTE_INPUT_HISTORY); if (!ArrayUtils.isEmpty(replyTexts)) { return true; } Parcelable[] messages = extras.getParcelableArray(Notification.EXTRA_MESSAGES); if (messages != null && messages.length > 0) { Parcelable message = messages[messages.length - 1]; if (message instanceof Bundle) { Notification.MessagingStyle.Message lastMessage = Notification.MessagingStyle.Message.getMessageFromBundle( (Bundle) message); if (lastMessage != null) { Person senderPerson = lastMessage.getSenderPerson(); if (senderPerson == null) { return true; } Person user = extras.getParcelable(Notification.EXTRA_MESSAGING_PERSON); return Objects.equals(user, senderPerson); } } } return false; } } } private final ArrayMap<String, Entry> mEntries = new ArrayMap<>(); private final ArrayMap<String, Entry> mEntries = new ArrayMap<>(); Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java +14 −6 Original line number Original line Diff line number Diff line Loading @@ -141,7 +141,7 @@ public class NotificationIconAreaController implements DarkReceiver { } } protected boolean shouldShowNotificationIcon(NotificationData.Entry entry, protected boolean shouldShowNotificationIcon(NotificationData.Entry entry, boolean showAmbient, boolean hideDismissed) { boolean showAmbient, boolean hideDismissed, boolean hideRepliedMessages) { if (mEntryManager.getNotificationData().isAmbient(entry.key) && !showAmbient) { if (mEntryManager.getNotificationData().isAmbient(entry.key) && !showAmbient) { return false; return false; } } Loading @@ -155,6 +155,10 @@ public class NotificationIconAreaController implements DarkReceiver { return false; return false; } } if (hideRepliedMessages && entry.isLastMessageFromReply()) { return false; } // showAmbient == show in shade but not shelf // showAmbient == show in shade but not shelf if (!showAmbient && mEntryManager.getNotificationData().shouldSuppressStatusBar(entry)) { if (!showAmbient && mEntryManager.getNotificationData().shouldSuppressStatusBar(entry)) { return false; return false; Loading @@ -170,14 +174,15 @@ public class NotificationIconAreaController implements DarkReceiver { updateStatusBarIcons(); updateStatusBarIcons(); updateIconsForLayout(entry -> entry.expandedIcon, mShelfIcons, updateIconsForLayout(entry -> entry.expandedIcon, mShelfIcons, NotificationShelf.SHOW_AMBIENT_ICONS, false /* hideDismissed */); NotificationShelf.SHOW_AMBIENT_ICONS, false /* hideDismissed */, false /* hideRepliedMessages */); applyNotificationIconsTint(); applyNotificationIconsTint(); } } private void updateStatusBarIcons() { public void updateStatusBarIcons() { updateIconsForLayout(entry -> entry.icon, mNotificationIcons, updateIconsForLayout(entry -> entry.icon, mNotificationIcons, false /* showAmbient */, true /* hideDismissed */); false /* showAmbient */, true /* hideDismissed */, true /* hideRepliedMessages */); } } /** /** Loading @@ -187,9 +192,11 @@ public class NotificationIconAreaController implements DarkReceiver { * @param hostLayout which layout should be updated * @param hostLayout which layout should be updated * @param showAmbient should ambient notification icons be shown * @param showAmbient should ambient notification icons be shown * @param hideDismissed should dismissed icons be hidden * @param hideDismissed should dismissed icons be hidden * @param hideRepliedMessages should messages that have been replied to be hidden */ */ private void updateIconsForLayout(Function<NotificationData.Entry, StatusBarIconView> function, private void updateIconsForLayout(Function<NotificationData.Entry, StatusBarIconView> function, NotificationIconContainer hostLayout, boolean showAmbient, boolean hideDismissed) { NotificationIconContainer hostLayout, boolean showAmbient, boolean hideDismissed, boolean hideRepliedMessages) { ArrayList<StatusBarIconView> toShow = new ArrayList<>( ArrayList<StatusBarIconView> toShow = new ArrayList<>( mNotificationScrollLayout.getChildCount()); mNotificationScrollLayout.getChildCount()); Loading @@ -198,7 +205,8 @@ public class NotificationIconAreaController implements DarkReceiver { View view = mNotificationScrollLayout.getChildAt(i); View view = mNotificationScrollLayout.getChildAt(i); if (view instanceof ExpandableNotificationRow) { if (view instanceof ExpandableNotificationRow) { NotificationData.Entry ent = ((ExpandableNotificationRow) view).getEntry(); NotificationData.Entry ent = ((ExpandableNotificationRow) view).getEntry(); if (shouldShowNotificationIcon(ent, showAmbient, hideDismissed)) { if (shouldShowNotificationIcon(ent, showAmbient, hideDismissed, hideRepliedMessages)) { toShow.add(function.apply(ent)); toShow.add(function.apply(ent)); } } } } Loading packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java +1 −0 Original line number Original line Diff line number Diff line Loading @@ -151,6 +151,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene mController.removeRemoteInput(mEntry, mToken); mController.removeRemoteInput(mEntry, mToken); mEditText.mShowImeOnInputConnection = false; mEditText.mShowImeOnInputConnection = false; mController.remoteInputSent(mEntry); mController.remoteInputSent(mEntry); mEntry.setHasSentReply(); // Tell ShortcutManager that this package has been "activated". ShortcutManager // Tell ShortcutManager that this package has been "activated". ShortcutManager // will reset the throttling for this package. // will reset the throttling for this package. Loading packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java +1 −0 Original line number Original line Diff line number Diff line Loading @@ -213,6 +213,7 @@ public class SmartReplyView extends ViewGroup { Intent intent = new Intent().addFlags(Intent.FLAG_RECEIVER_FOREGROUND); Intent intent = new Intent().addFlags(Intent.FLAG_RECEIVER_FOREGROUND); RemoteInput.addResultsToIntent(new RemoteInput[]{remoteInput}, intent, results); RemoteInput.addResultsToIntent(new RemoteInput[]{remoteInput}, intent, results); RemoteInput.setResultsSource(intent, RemoteInput.SOURCE_CHOICE); RemoteInput.setResultsSource(intent, RemoteInput.SOURCE_CHOICE); entry.setHasSentReply(); try { try { pendingIntent.send(context, 0, intent); pendingIntent.send(context, 0, intent); } catch (PendingIntent.CanceledException e) { } catch (PendingIntent.CanceledException e) { Loading Loading
core/java/android/app/Notification.java +8 −1 Original line number Original line Diff line number Diff line Loading @@ -7391,7 +7391,14 @@ public class Notification implements Parcelable return messages; return messages; } } static Message getMessageFromBundle(Bundle bundle) { /** * @return The message that is stored in the bundle or null if the message couldn't be * resolved. * * @hide */ @Nullable public static Message getMessageFromBundle(Bundle bundle) { try { try { if (!bundle.containsKey(KEY_TEXT) || !bundle.containsKey(KEY_TIMESTAMP)) { if (!bundle.containsKey(KEY_TEXT) || !bundle.containsKey(KEY_TIMESTAMP)) { return null; return null; Loading
packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java +43 −0 Original line number Original line Diff line number Diff line Loading @@ -32,10 +32,13 @@ import android.app.AppGlobals; import android.app.Notification; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.NotificationManager; import android.app.Person; import android.content.Context; import android.content.Context; import android.content.pm.IPackageManager; import android.content.pm.IPackageManager; import android.content.pm.PackageManager; import android.content.pm.PackageManager; import android.graphics.drawable.Icon; import android.graphics.drawable.Icon; import android.os.Bundle; import android.os.Parcelable; import android.os.RemoteException; import android.os.RemoteException; import android.os.SystemClock; import android.os.SystemClock; import android.service.notification.NotificationListenerService.Ranking; import android.service.notification.NotificationListenerService.Ranking; Loading @@ -50,6 +53,7 @@ import android.widget.RemoteViews; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.statusbar.StatusBarIcon; import com.android.internal.statusbar.StatusBarIcon; import com.android.internal.util.ArrayUtils; import com.android.internal.util.NotificationColorUtil; import com.android.internal.util.NotificationColorUtil; import com.android.systemui.Dependency; import com.android.systemui.Dependency; import com.android.systemui.ForegroundServiceController; import com.android.systemui.ForegroundServiceController; Loading Loading @@ -117,6 +121,11 @@ public class NotificationData { */ */ public Boolean mIsSystemNotification; public Boolean mIsSystemNotification; /** * Has the user sent a reply through this Notification. */ private boolean hasSentReply; public Entry(StatusBarNotification n) { public Entry(StatusBarNotification n) { this.key = n.getKey(); this.key = n.getKey(); this.notification = n; this.notification = n; Loading Loading @@ -298,6 +307,40 @@ public class NotificationData { lastRemoteInputSent = NOT_LAUNCHED_YET; lastRemoteInputSent = NOT_LAUNCHED_YET; remoteInputTextWhenReset = null; remoteInputTextWhenReset = null; } } public void setHasSentReply() { hasSentReply = true; } public boolean isLastMessageFromReply() { if (!hasSentReply) { return false; } Bundle extras = notification.getNotification().extras; CharSequence[] replyTexts = extras.getCharSequenceArray( Notification.EXTRA_REMOTE_INPUT_HISTORY); if (!ArrayUtils.isEmpty(replyTexts)) { return true; } Parcelable[] messages = extras.getParcelableArray(Notification.EXTRA_MESSAGES); if (messages != null && messages.length > 0) { Parcelable message = messages[messages.length - 1]; if (message instanceof Bundle) { Notification.MessagingStyle.Message lastMessage = Notification.MessagingStyle.Message.getMessageFromBundle( (Bundle) message); if (lastMessage != null) { Person senderPerson = lastMessage.getSenderPerson(); if (senderPerson == null) { return true; } Person user = extras.getParcelable(Notification.EXTRA_MESSAGING_PERSON); return Objects.equals(user, senderPerson); } } } return false; } } } private final ArrayMap<String, Entry> mEntries = new ArrayMap<>(); private final ArrayMap<String, Entry> mEntries = new ArrayMap<>(); Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java +14 −6 Original line number Original line Diff line number Diff line Loading @@ -141,7 +141,7 @@ public class NotificationIconAreaController implements DarkReceiver { } } protected boolean shouldShowNotificationIcon(NotificationData.Entry entry, protected boolean shouldShowNotificationIcon(NotificationData.Entry entry, boolean showAmbient, boolean hideDismissed) { boolean showAmbient, boolean hideDismissed, boolean hideRepliedMessages) { if (mEntryManager.getNotificationData().isAmbient(entry.key) && !showAmbient) { if (mEntryManager.getNotificationData().isAmbient(entry.key) && !showAmbient) { return false; return false; } } Loading @@ -155,6 +155,10 @@ public class NotificationIconAreaController implements DarkReceiver { return false; return false; } } if (hideRepliedMessages && entry.isLastMessageFromReply()) { return false; } // showAmbient == show in shade but not shelf // showAmbient == show in shade but not shelf if (!showAmbient && mEntryManager.getNotificationData().shouldSuppressStatusBar(entry)) { if (!showAmbient && mEntryManager.getNotificationData().shouldSuppressStatusBar(entry)) { return false; return false; Loading @@ -170,14 +174,15 @@ public class NotificationIconAreaController implements DarkReceiver { updateStatusBarIcons(); updateStatusBarIcons(); updateIconsForLayout(entry -> entry.expandedIcon, mShelfIcons, updateIconsForLayout(entry -> entry.expandedIcon, mShelfIcons, NotificationShelf.SHOW_AMBIENT_ICONS, false /* hideDismissed */); NotificationShelf.SHOW_AMBIENT_ICONS, false /* hideDismissed */, false /* hideRepliedMessages */); applyNotificationIconsTint(); applyNotificationIconsTint(); } } private void updateStatusBarIcons() { public void updateStatusBarIcons() { updateIconsForLayout(entry -> entry.icon, mNotificationIcons, updateIconsForLayout(entry -> entry.icon, mNotificationIcons, false /* showAmbient */, true /* hideDismissed */); false /* showAmbient */, true /* hideDismissed */, true /* hideRepliedMessages */); } } /** /** Loading @@ -187,9 +192,11 @@ public class NotificationIconAreaController implements DarkReceiver { * @param hostLayout which layout should be updated * @param hostLayout which layout should be updated * @param showAmbient should ambient notification icons be shown * @param showAmbient should ambient notification icons be shown * @param hideDismissed should dismissed icons be hidden * @param hideDismissed should dismissed icons be hidden * @param hideRepliedMessages should messages that have been replied to be hidden */ */ private void updateIconsForLayout(Function<NotificationData.Entry, StatusBarIconView> function, private void updateIconsForLayout(Function<NotificationData.Entry, StatusBarIconView> function, NotificationIconContainer hostLayout, boolean showAmbient, boolean hideDismissed) { NotificationIconContainer hostLayout, boolean showAmbient, boolean hideDismissed, boolean hideRepliedMessages) { ArrayList<StatusBarIconView> toShow = new ArrayList<>( ArrayList<StatusBarIconView> toShow = new ArrayList<>( mNotificationScrollLayout.getChildCount()); mNotificationScrollLayout.getChildCount()); Loading @@ -198,7 +205,8 @@ public class NotificationIconAreaController implements DarkReceiver { View view = mNotificationScrollLayout.getChildAt(i); View view = mNotificationScrollLayout.getChildAt(i); if (view instanceof ExpandableNotificationRow) { if (view instanceof ExpandableNotificationRow) { NotificationData.Entry ent = ((ExpandableNotificationRow) view).getEntry(); NotificationData.Entry ent = ((ExpandableNotificationRow) view).getEntry(); if (shouldShowNotificationIcon(ent, showAmbient, hideDismissed)) { if (shouldShowNotificationIcon(ent, showAmbient, hideDismissed, hideRepliedMessages)) { toShow.add(function.apply(ent)); toShow.add(function.apply(ent)); } } } } Loading
packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java +1 −0 Original line number Original line Diff line number Diff line Loading @@ -151,6 +151,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene mController.removeRemoteInput(mEntry, mToken); mController.removeRemoteInput(mEntry, mToken); mEditText.mShowImeOnInputConnection = false; mEditText.mShowImeOnInputConnection = false; mController.remoteInputSent(mEntry); mController.remoteInputSent(mEntry); mEntry.setHasSentReply(); // Tell ShortcutManager that this package has been "activated". ShortcutManager // Tell ShortcutManager that this package has been "activated". ShortcutManager // will reset the throttling for this package. // will reset the throttling for this package. Loading
packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java +1 −0 Original line number Original line Diff line number Diff line Loading @@ -213,6 +213,7 @@ public class SmartReplyView extends ViewGroup { Intent intent = new Intent().addFlags(Intent.FLAG_RECEIVER_FOREGROUND); Intent intent = new Intent().addFlags(Intent.FLAG_RECEIVER_FOREGROUND); RemoteInput.addResultsToIntent(new RemoteInput[]{remoteInput}, intent, results); RemoteInput.addResultsToIntent(new RemoteInput[]{remoteInput}, intent, results); RemoteInput.setResultsSource(intent, RemoteInput.SOURCE_CHOICE); RemoteInput.setResultsSource(intent, RemoteInput.SOURCE_CHOICE); entry.setHasSentReply(); try { try { pendingIntent.send(context, 0, intent); pendingIntent.send(context, 0, intent); } catch (PendingIntent.CanceledException e) { } catch (PendingIntent.CanceledException e) { Loading