Merge "Populate conversation notifs from shortcut info" into rvc-dev

This commit is contained in:
Steve Elliott
2020-03-19 15:18:33 +00:00
committed by Android (Google) Code Review
12 changed files with 228 additions and 40 deletions

View File

@@ -21,7 +21,6 @@ import static android.graphics.drawable.Icon.TYPE_URI;
import static android.graphics.drawable.Icon.TYPE_URI_ADAPTIVE_BITMAP;
import static com.android.internal.util.ContrastColorUtil.satisfiesTextContrast;
import static com.android.internal.widget.ConversationLayout.CONVERSATION_LAYOUT_ENABLED;
import android.annotation.ColorInt;
import android.annotation.DimenRes;
@@ -1229,6 +1228,9 @@ public class Notification implements Parcelable
*/
public static final String EXTRA_CONVERSATION_TITLE = "android.conversationTitle";
/** @hide */
public static final String EXTRA_CONVERSATION_ICON = "android.conversationIcon";
/**
* {@link #extras} key: an array of {@link android.app.Notification.MessagingStyle.Message}
* bundles provided by a
@@ -3576,7 +3578,6 @@ public class Notification implements Parcelable
}
}
}
}
}
@@ -6118,9 +6119,11 @@ public class Notification implements Parcelable
}
private int getMessagingLayoutResource() {
return CONVERSATION_LAYOUT_ENABLED
? R.layout.notification_template_material_conversation
: R.layout.notification_template_material_messaging;
return R.layout.notification_template_material_messaging;
}
private int getConversationLayoutResource() {
return R.layout.notification_template_material_conversation;
}
private int getActionLayoutResource() {
@@ -7078,11 +7081,28 @@ public class Notification implements Parcelable
*/
public static final int MAXIMUM_RETAINED_MESSAGES = 25;
/** @hide */
public static final int CONVERSATION_TYPE_LEGACY = 0;
/** @hide */
public static final int CONVERSATION_TYPE_NORMAL = 1;
/** @hide */
public static final int CONVERSATION_TYPE_IMPORTANT = 2;
/** @hide */
@IntDef(prefix = {"CONVERSATION_TYPE_"}, value = {
CONVERSATION_TYPE_LEGACY, CONVERSATION_TYPE_NORMAL, CONVERSATION_TYPE_IMPORTANT
})
@Retention(RetentionPolicy.SOURCE)
public @interface ConversationType {}
@NonNull Person mUser;
@Nullable CharSequence mConversationTitle;
@Nullable Icon mShortcutIcon;
List<Message> mMessages = new ArrayList<>();
List<Message> mHistoricMessages = new ArrayList<>();
boolean mIsGroupConversation;
@ConversationType int mConversationType = CONVERSATION_TYPE_LEGACY;
MessagingStyle() {
}
@@ -7160,6 +7180,11 @@ public class Notification implements Parcelable
/**
* Sets the title to be displayed on this conversation. May be set to {@code null}.
*
* <p>Starting in {@link Build.VERSION_CODES#R, this conversation title will be ignored if a
* valid shortcutId is added via {@link Notification.Builder#setShortcutId(String)}. In this
* case, {@link ShortcutInfo#getShortLabel()} will be shown as the conversation title
* instead.
*
* <p>This API's behavior was changed in SDK version {@link Build.VERSION_CODES#P}. If your
* application's target version is less than {@link Build.VERSION_CODES#P}, setting a
* conversation title to a non-null value will make {@link #isGroupConversation()} return
@@ -7183,6 +7208,46 @@ public class Notification implements Parcelable
return mConversationTitle;
}
/**
* Sets the icon to be displayed on the conversation, derived from the shortcutId.
*
* @hide
*/
public MessagingStyle setShortcutIcon(@Nullable Icon conversationIcon) {
mShortcutIcon = conversationIcon;
return this;
}
/**
* Return the icon to be displayed on this conversation, derived from the shortcutId. May
* return {@code null}.
*
* @hide
*/
@Nullable
public Icon getShortcutIcon() {
return mShortcutIcon;
}
/**
* Sets the conversation type of this MessageStyle notification.
* {@link #CONVERSATION_TYPE_LEGACY} will use the "older" layout from pre-R,
* {@link #CONVERSATION_TYPE_NORMAL} will use the new "conversation" layout, and
* {@link #CONVERSATION_TYPE_IMPORTANT} will add additional "important" treatments.
*
* @hide
*/
public MessagingStyle setConversationType(@ConversationType int conversationType) {
mConversationType = conversationType;
return this;
}
/** @hide */
@ConversationType
public int getConversationType() {
return mConversationType;
}
/**
* Adds a message for display by this notification. Convenience call for a simple
* {@link Message} in {@link #addMessage(Notification.MessagingStyle.Message)}.
@@ -7334,6 +7399,9 @@ public class Notification implements Parcelable
if (!mHistoricMessages.isEmpty()) { extras.putParcelableArray(EXTRA_HISTORIC_MESSAGES,
Message.getBundleArrayForMessages(mHistoricMessages));
}
if (mShortcutIcon != null) {
extras.putParcelable(EXTRA_CONVERSATION_ICON, mShortcutIcon);
}
fixTitleAndTextExtras(extras);
extras.putBoolean(EXTRA_IS_GROUP_CONVERSATION, mIsGroupConversation);
@@ -7515,24 +7583,31 @@ public class Notification implements Parcelable
} else {
isOneToOne = !isGroupConversation();
}
boolean isConversationLayout = mConversationType != CONVERSATION_TYPE_LEGACY;
Icon largeIcon = isConversationLayout ? mShortcutIcon : mBuilder.mN.mLargeIcon;
TemplateBindResult bindResult = new TemplateBindResult();
StandardTemplateParams p = mBuilder.mParams.reset().hasProgress(false).title(
conversationTitle).text(null)
StandardTemplateParams p = mBuilder.mParams.reset()
.hasProgress(false)
.title(conversationTitle)
.text(null)
.hideLargeIcon(hideRightIcons || isOneToOne)
.hideReplyIcon(hideRightIcons)
.headerTextSecondary(conversationTitle);
RemoteViews contentView = mBuilder.applyStandardTemplateWithActions(
mBuilder.getMessagingLayoutResource(),
isConversationLayout
? mBuilder.getConversationLayoutResource()
: mBuilder.getMessagingLayoutResource(),
p,
bindResult);
addExtras(mBuilder.mN.extras);
if (!CONVERSATION_LAYOUT_ENABLED) {
if (!isConversationLayout) {
// also update the end margin if there is an image
contentView.setViewLayoutMarginEnd(R.id.notification_messaging,
bindResult.getIconMarginEnd());
}
contentView.setInt(R.id.status_bar_latest_event_content, "setLayoutColor",
mBuilder.isColorized(p) ? mBuilder.getPrimaryTextColor(p)
mBuilder.isColorized(p)
? mBuilder.getPrimaryTextColor(p)
: mBuilder.resolveContrastColor(p));
contentView.setInt(R.id.status_bar_latest_event_content, "setSenderTextColor",
mBuilder.getPrimaryTextColor(p));
@@ -7552,7 +7627,7 @@ public class Notification implements Parcelable
contentView.setCharSequence(R.id.status_bar_latest_event_content,
"setConversationTitle", conversationTitle);
contentView.setIcon(R.id.status_bar_latest_event_content, "setLargeIcon",
mBuilder.mN.mLargeIcon);
largeIcon);
contentView.setBundle(R.id.status_bar_latest_event_content, "setData",
mBuilder.mN.extras);
return contentView;
@@ -7615,7 +7690,7 @@ public class Notification implements Parcelable
public RemoteViews makeHeadsUpContentView(boolean increasedHeight) {
RemoteViews remoteViews = makeMessagingView(true /* isCollapsed */,
true /* hideLargeIcon */);
if (!CONVERSATION_LAYOUT_ENABLED) {
if (mConversationType == CONVERSATION_TYPE_LEGACY) {
remoteViews.setInt(R.id.notification_messaging, "setMaxDisplayedLines", 1);
}
return remoteViews;

View File

@@ -1299,6 +1299,38 @@ public class LauncherApps {
}
}
/**
* @hide
*/
public Icon getShortcutIcon(@NonNull ShortcutInfo shortcut) {
if (shortcut.hasIconFile()) {
final ParcelFileDescriptor pfd = getShortcutIconFd(shortcut);
if (pfd == null) {
return null;
}
try {
final Bitmap bmp = BitmapFactory.decodeFileDescriptor(pfd.getFileDescriptor());
if (bmp != null) {
if (shortcut.hasAdaptiveBitmap()) {
return Icon.createWithAdaptiveBitmap(bmp);
} else {
return Icon.createWithBitmap(bmp);
}
}
return null;
} finally {
try {
pfd.close();
} catch (IOException ignore) {
}
}
} else if (shortcut.hasIconResource()) {
return Icon.createWithResource(shortcut.getPackage(), shortcut.getIconResourceId());
} else {
return shortcut.getIcon();
}
}
private Drawable loadDrawableResourceFromPackage(String packageName, int resId,
UserHandle user, int density) {
try {

View File

@@ -66,7 +66,6 @@ import java.util.regex.Pattern;
public class ConversationLayout extends FrameLayout
implements ImageMessageConsumer, IMessagingLayout {
public static final boolean CONVERSATION_LAYOUT_ENABLED = true;
private static final float COLOR_SHIFT_AMOUNT = 60;
/**
* Pattren for filter some ingonable characters.

View File

@@ -32,6 +32,7 @@ import android.content.Context;
import android.content.pm.IPackageManager;
import android.content.pm.LauncherApps;
import android.content.pm.PackageManager;
import android.content.pm.ShortcutManager;
import android.content.res.Resources;
import android.hardware.SensorPrivacyManager;
import android.media.AudioManager;
@@ -139,6 +140,12 @@ public class SystemServicesModule {
ServiceManager.checkService(DreamService.DREAM_SERVICE));
}
@Provides
@Singleton
static IPackageManager provideIPackageManager() {
return IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
}
@Singleton
@Provides
static IStatusBarService provideIStatusBarService() {
@@ -159,13 +166,6 @@ public class SystemServicesModule {
return WindowManagerGlobal.getWindowManagerService();
}
/** */
@Singleton
@Provides
public IPackageManager provideIPackageManager() {
return IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
}
@Singleton
@Provides
static KeyguardManager provideKeyguardManager(Context context) {
@@ -230,6 +230,12 @@ public class SystemServicesModule {
return context.getSystemService(SensorPrivacyManager.class);
}
@Singleton
@Provides
static ShortcutManager provideShortcutManager(Context context) {
return context.getSystemService(ShortcutManager.class);
}
@Provides
@Singleton
@Nullable

View File

@@ -0,0 +1,41 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.statusbar.notification
import android.app.Notification
import android.content.pm.LauncherApps
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import javax.inject.Inject
class ConversationNotificationProcessor @Inject constructor(
private val launcherApps: LauncherApps
) {
fun processNotification(entry: NotificationEntry, recoveredBuilder: Notification.Builder) {
val messagingStyle = recoveredBuilder.style as? Notification.MessagingStyle ?: return
messagingStyle.conversationType =
if (entry.ranking.channel.isImportantConversation)
Notification.MessagingStyle.CONVERSATION_TYPE_IMPORTANT
else
Notification.MessagingStyle.CONVERSATION_TYPE_NORMAL
entry.ranking.shortcutInfo?.let { shortcutInfo ->
messagingStyle.shortcutIcon = launcherApps.getShortcutIcon(shortcutInfo)
shortcutInfo.shortLabel?.let { shortLabel ->
messagingStyle.conversationTitle = shortLabel
}
}
}
}

View File

@@ -16,7 +16,10 @@
package com.android.systemui.statusbar.notification.dagger;
import android.app.INotificationManager;
import android.content.Context;
import android.content.pm.LauncherApps;
import android.content.pm.ShortcutManager;
import android.os.Handler;
import android.view.accessibility.AccessibilityManager;
@@ -103,14 +106,20 @@ public interface NotificationsModule {
Lazy<StatusBar> statusBarLazy,
@Main Handler mainHandler,
AccessibilityManager accessibilityManager,
HighPriorityProvider highPriorityProvider) {
HighPriorityProvider highPriorityProvider,
INotificationManager notificationManager,
LauncherApps launcherApps,
ShortcutManager shortcutManager) {
return new NotificationGutsManager(
context,
visualStabilityManager,
statusBarLazy,
mainHandler,
accessibilityManager,
highPriorityProvider);
highPriorityProvider,
notificationManager,
launcherApps,
shortcutManager);
}
/** Provides an instance of {@link VisualStabilityManager} */

View File

@@ -39,6 +39,7 @@ import com.android.internal.widget.ImageMessageConsumer;
import com.android.systemui.statusbar.InflationTask;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.SmartReplyController;
import com.android.systemui.statusbar.notification.ConversationNotificationProcessor;
import com.android.systemui.statusbar.notification.InflationException;
import com.android.systemui.statusbar.notification.MediaNotificationProcessor;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -72,17 +73,20 @@ public class NotificationContentInflater implements NotificationRowContentBinder
private final NotifRemoteViewCache mRemoteViewCache;
private final Lazy<SmartReplyConstants> mSmartReplyConstants;
private final Lazy<SmartReplyController> mSmartReplyController;
private final ConversationNotificationProcessor mConversationProcessor;
@Inject
NotificationContentInflater(
NotifRemoteViewCache remoteViewCache,
NotificationRemoteInputManager remoteInputManager,
Lazy<SmartReplyConstants> smartReplyConstants,
Lazy<SmartReplyController> smartReplyController) {
Lazy<SmartReplyController> smartReplyController,
ConversationNotificationProcessor conversationProcessor) {
mRemoteViewCache = remoteViewCache;
mRemoteInputManager = remoteInputManager;
mSmartReplyConstants = smartReplyConstants;
mSmartReplyController = smartReplyController;
mConversationProcessor = conversationProcessor;
}
@Override
@@ -116,6 +120,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder
entry,
mSmartReplyConstants.get(),
mSmartReplyController.get(),
mConversationProcessor,
row,
bindParams.isLowPriority,
bindParams.isChildInGroup,
@@ -671,6 +676,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder
private Exception mError;
private RemoteViews.OnClickHandler mRemoteViewClickHandler;
private CancellationSignal mCancellationSignal;
private final ConversationNotificationProcessor mConversationProcessor;
private AsyncInflationTask(
boolean inflateSynchronously,
@@ -679,6 +685,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder
NotificationEntry entry,
SmartReplyConstants smartReplyConstants,
SmartReplyController smartReplyController,
ConversationNotificationProcessor conversationProcessor,
ExpandableNotificationRow row,
boolean isLowPriority,
boolean isChildInGroup,
@@ -700,6 +707,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder
mUsesIncreasedHeadsUpHeight = usesIncreasedHeadsUpHeight;
mRemoteViewClickHandler = remoteViewClickHandler;
mCallback = callback;
mConversationProcessor = conversationProcessor;
entry.setInflationTask(this);
}
@@ -728,6 +736,9 @@ public class NotificationContentInflater implements NotificationRowContentBinder
packageContext);
processor.processNotification(notification, recoveredBuilder);
}
if (mEntry.getRanking().isConversation()) {
mConversationProcessor.processNotification(mEntry, recoveredBuilder);
}
InflationProgress inflationProgress = createRemoteViews(mReInflateFlags,
recoveredBuilder, mIsLowPriority, mIsChildInGroup, mUsesIncreasedHeight,
mUsesIncreasedHeadsUpHeight, packageContext);

View File

@@ -29,7 +29,6 @@ import android.content.pm.ShortcutManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.provider.Settings;
import android.service.notification.StatusBarNotification;
@@ -109,6 +108,9 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
private final Lazy<StatusBar> mStatusBarLazy;
private final Handler mMainHandler;
private Runnable mOpenRunnable;
private final INotificationManager mNotificationManager;
private final LauncherApps mLauncherApps;
private final ShortcutManager mShortcutManager;
/**
* Injected constructor. See {@link NotificationsModule}.
@@ -116,13 +118,19 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
public NotificationGutsManager(Context context, VisualStabilityManager visualStabilityManager,
Lazy<StatusBar> statusBarLazy, @Main Handler mainHandler,
AccessibilityManager accessibilityManager,
HighPriorityProvider highPriorityProvider) {
HighPriorityProvider highPriorityProvider,
INotificationManager notificationManager,
LauncherApps launcherApps,
ShortcutManager shortcutManager) {
mContext = context;
mVisualStabilityManager = visualStabilityManager;
mStatusBarLazy = statusBarLazy;
mMainHandler = mainHandler;
mAccessibilityManager = accessibilityManager;
mHighPriorityProvider = highPriorityProvider;
mNotificationManager = notificationManager;
mLauncherApps = launcherApps;
mShortcutManager = shortcutManager;
}
public void setUpWithPresenter(NotificationPresenter presenter,
@@ -306,8 +314,6 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
UserHandle userHandle = sbn.getUser();
PackageManager pmUser = StatusBar.getPackageManagerForUser(
mContext, userHandle.getIdentifier());
INotificationManager iNotificationManager = INotificationManager.Stub.asInterface(
ServiceManager.getService(Context.NOTIFICATION_SERVICE));
final NotificationInfo.OnAppSettingsClickListener onAppSettingsClick =
(View v, Intent intent) -> {
mMetricsLogger.action(MetricsProto.MetricsEvent.ACTION_APP_NOTE_SETTINGS);
@@ -328,7 +334,7 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
notificationInfoView.bindNotification(
pmUser,
iNotificationManager,
mNotificationManager,
mVisualStabilityManager,
packageName,
row.getEntry().getChannel(),
@@ -358,10 +364,6 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
UserHandle userHandle = sbn.getUser();
PackageManager pmUser = StatusBar.getPackageManagerForUser(
mContext, userHandle.getIdentifier());
LauncherApps launcherApps = mContext.getSystemService(LauncherApps.class);
ShortcutManager shortcutManager = mContext.getSystemService(ShortcutManager.class);
INotificationManager iNotificationManager = INotificationManager.Stub.asInterface(
ServiceManager.getService(Context.NOTIFICATION_SERVICE));
final NotificationConversationInfo.OnAppSettingsClickListener onAppSettingsClick =
(View v, Intent intent) -> {
mMetricsLogger.action(MetricsProto.MetricsEvent.ACTION_APP_NOTE_SETTINGS);
@@ -386,15 +388,15 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
};
}
ConversationIconFactory iconFactoryLoader = new ConversationIconFactory(mContext,
launcherApps, pmUser, IconDrawableFactory.newInstance(mContext, false),
mLauncherApps, pmUser, IconDrawableFactory.newInstance(mContext, false),
mContext.getResources().getDimensionPixelSize(
R.dimen.notification_guts_conversation_icon_size));
notificationInfoView.bindNotification(
shortcutManager,
launcherApps,
mShortcutManager,
mLauncherApps,
pmUser,
iNotificationManager,
mNotificationManager,
mVisualStabilityManager,
packageName,
row.getEntry().getChannel(),

View File

@@ -51,6 +51,7 @@ import androidx.test.filters.Suppress;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.SmartReplyController;
import com.android.systemui.statusbar.notification.ConversationNotificationProcessor;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.BindParams;
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationCallback;
@@ -82,6 +83,7 @@ public class NotificationContentInflaterTest extends SysuiTestCase {
private ExpandableNotificationRow mRow;
@Mock private NotifRemoteViewCache mCache;
@Mock private ConversationNotificationProcessor mConversationNotificationProcessor;
@Before
public void setUp() throws Exception {
@@ -101,7 +103,8 @@ public class NotificationContentInflaterTest extends SysuiTestCase {
mCache,
mock(NotificationRemoteInputManager.class),
() -> smartReplyConstants,
() -> smartReplyController);
() -> smartReplyController,
mConversationNotificationProcessor);
}
@Test

View File

@@ -51,6 +51,7 @@ import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.SbnBuilder;
import com.android.systemui.statusbar.SmartReplyController;
import com.android.systemui.statusbar.notification.ConversationNotificationProcessor;
import com.android.systemui.statusbar.notification.ForegroundServiceDismissalFeatureController;
import com.android.systemui.statusbar.notification.NotificationClicker;
import com.android.systemui.statusbar.notification.NotificationEntryListener;
@@ -183,7 +184,8 @@ public class NotificationEntryManagerInflationTest extends SysuiTestCase {
cache,
mRemoteInputManager,
() -> mock(SmartReplyConstants.class),
() -> mock(SmartReplyController.class));
() -> mock(SmartReplyController.class),
mock(ConversationNotificationProcessor.class));
RowContentBindStage stage = new RowContentBindStage(
binder,
mock(NotifInflationErrorManager.class),

View File

@@ -48,7 +48,9 @@ import android.app.INotificationManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.content.Intent;
import android.content.pm.LauncherApps;
import android.content.pm.PackageManager;
import android.content.pm.ShortcutManager;
import android.os.Binder;
import android.os.Handler;
import android.provider.Settings;
@@ -113,6 +115,9 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
@Mock private StatusBar mStatusBar;
@Mock private AccessibilityManager mAccessibilityManager;
@Mock private HighPriorityProvider mHighPriorityProvider;
@Mock private INotificationManager mINotificationManager;
@Mock private LauncherApps mLauncherApps;
@Mock private ShortcutManager mShortcutManager;
@Before
public void setUp() {
@@ -128,7 +133,8 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(false);
mGutsManager = new NotificationGutsManager(mContext, mVisualStabilityManager,
() -> mStatusBar, mHandler, mAccessibilityManager, mHighPriorityProvider);
() -> mStatusBar, mHandler, mAccessibilityManager, mHighPriorityProvider,
mINotificationManager, mLauncherApps, mShortcutManager);
mGutsManager.setUpWithPresenter(mPresenter, mStackScroller,
mCheckSaveListener, mOnSettingsClickListener);
mGutsManager.setNotificationActivityStarter(mNotificationActivityStarter);

View File

@@ -50,6 +50,7 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.NotificationMediaManager;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.SmartReplyController;
import com.android.systemui.statusbar.notification.ConversationNotificationProcessor;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
@@ -119,7 +120,8 @@ public class NotificationTestHelper {
mock(NotifRemoteViewCache.class),
mock(NotificationRemoteInputManager.class),
() -> mock(SmartReplyConstants.class),
() -> mock(SmartReplyController.class));
() -> mock(SmartReplyController.class),
mock(ConversationNotificationProcessor.class));
contentBinder.setInflateSynchronously(true);
mBindStage = new RowContentBindStage(contentBinder,
mock(NotifInflationErrorManager.class),