diff options
| author | 2020-03-25 14:26:42 -0400 | |
|---|---|---|
| committer | 2020-03-31 16:20:39 -0400 | |
| commit | 239e6cb1df6a932cd05826427369837efab09080 (patch) | |
| tree | ee2d1e6bd316abced01223b7379373d0ad2e2546 | |
| parent | 4fca5e9d5bccc13f4fd12b54ff32ddc24cf05e47 (diff) | |
Add unread count badge to conversation layout
Fixes: 152303800
Test: manual, visual
Change-Id: I9308a15ab223086398ba073b08d60cb7c50d8c30
11 files changed, 245 insertions, 49 deletions
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 9b42fa2012e1..f461a1708373 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -1232,6 +1232,10 @@ public class Notification implements Parcelable /** @hide */ public static final String EXTRA_CONVERSATION_ICON = "android.conversationIcon"; + /** @hide */ + public static final String EXTRA_CONVERSATION_UNREAD_MESSAGE_COUNT = + "android.conversationUnreadMessageCount"; + /** * {@link #extras} key: an array of {@link android.app.Notification.MessagingStyle.Message} * bundles provided by a @@ -7102,6 +7106,7 @@ public class Notification implements Parcelable List<Message> mHistoricMessages = new ArrayList<>(); boolean mIsGroupConversation; @ConversationType int mConversationType = CONVERSATION_TYPE_LEGACY; + int mUnreadMessageCount; MessagingStyle() { } @@ -7247,6 +7252,17 @@ public class Notification implements Parcelable return mConversationType; } + /** @hide */ + public int getUnreadMessageCount() { + return mUnreadMessageCount; + } + + /** @hide */ + public MessagingStyle setUnreadMessageCount(int unreadMessageCount) { + mUnreadMessageCount = unreadMessageCount; + return this; + } + /** * Adds a message for display by this notification. Convenience call for a simple * {@link Message} in {@link #addMessage(Notification.MessagingStyle.Message)}. @@ -7401,6 +7417,7 @@ public class Notification implements Parcelable if (mShortcutIcon != null) { extras.putParcelable(EXTRA_CONVERSATION_ICON, mShortcutIcon); } + extras.putInt(EXTRA_CONVERSATION_UNREAD_MESSAGE_COUNT, mUnreadMessageCount); fixTitleAndTextExtras(extras); extras.putBoolean(EXTRA_IS_GROUP_CONVERSATION, mIsGroupConversation); @@ -7452,6 +7469,7 @@ public class Notification implements Parcelable Parcelable[] histMessages = extras.getParcelableArray(EXTRA_HISTORIC_MESSAGES); mHistoricMessages = Message.getMessagesFromBundleArray(histMessages); mIsGroupConversation = extras.getBoolean(EXTRA_IS_GROUP_CONVERSATION); + mUnreadMessageCount = extras.getInt(EXTRA_CONVERSATION_UNREAD_MESSAGE_COUNT); } /** @@ -7601,6 +7619,7 @@ public class Notification implements Parcelable : mBuilder.getMessagingLayoutResource(), p, bindResult); + addExtras(mBuilder.mN.extras); if (!isConversationLayout) { // also update the end margin if there is an image diff --git a/core/java/com/android/internal/widget/ConversationLayout.java b/core/java/com/android/internal/widget/ConversationLayout.java index 1336ec412cdb..5248ca944c3d 100644 --- a/core/java/com/android/internal/widget/ConversationLayout.java +++ b/core/java/com/android/internal/widget/ConversationLayout.java @@ -62,6 +62,7 @@ import com.android.internal.util.ContrastColorUtil; import java.util.ArrayList; import java.util.List; +import java.util.Locale; import java.util.function.Consumer; import java.util.regex.Pattern; @@ -151,6 +152,7 @@ public class ConversationLayout extends FrameLayout private int mFacePileProtectionWidth; private int mFacePileProtectionWidthExpanded; private boolean mImportantConversation; + private TextView mUnreadBadge; public ConversationLayout(@NonNull Context context) { super(context); @@ -277,6 +279,7 @@ public class ConversationLayout extends FrameLayout mAppName.setOnVisibilityChangedListener((visibility) -> { onAppNameVisibilityChanged(); }); + mUnreadBadge = findViewById(R.id.conversation_unread_count); mConversationContentStart = getResources().getDimensionPixelSize( R.dimen.conversation_content_start); mInternalButtonPadding @@ -354,7 +357,6 @@ public class ConversationLayout extends FrameLayout // mUser now set (would be nice to avoid the side effect but WHATEVER) setUser(extras.getParcelable(Notification.EXTRA_MESSAGING_PERSON)); - // Append remote input history to newMessages (again, side effect is lame but WHATEVS) RemoteInputHistoryItem[] history = (RemoteInputHistoryItem[]) extras.getParcelableArray(Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS); @@ -362,9 +364,11 @@ public class ConversationLayout extends FrameLayout boolean showSpinner = extras.getBoolean(Notification.EXTRA_SHOW_REMOTE_INPUT_SPINNER, false); - // bind it, baby bind(newMessages, newHistoricMessages, showSpinner); + + int unreadCount = extras.getInt(Notification.EXTRA_CONVERSATION_UNREAD_MESSAGE_COUNT); + setUnreadCount(unreadCount); } @Override @@ -372,6 +376,18 @@ public class ConversationLayout extends FrameLayout mImageResolver = resolver; } + /** @hide */ + public void setUnreadCount(int unreadCount) { + mUnreadBadge.setVisibility(mIsCollapsed && unreadCount > 1 ? VISIBLE : GONE); + CharSequence text = unreadCount >= 100 + ? getResources().getString(R.string.unread_convo_overflow, 99) + : String.format(Locale.getDefault(), "%d", unreadCount); + mUnreadBadge.setText(text); + mUnreadBadge.setBackgroundTintList(ColorStateList.valueOf(mLayoutColor)); + boolean needDarkText = ColorUtils.calculateLuminance(mLayoutColor) > 0.5f; + mUnreadBadge.setTextColor(needDarkText ? Color.BLACK : Color.WHITE); + } + private void addRemoteInputHistoryToMessages( List<Notification.MessagingStyle.Message> newMessages, RemoteInputHistoryItem[] remoteInputHistory) { diff --git a/core/res/res/drawable/conversation_unread_bg.xml b/core/res/res/drawable/conversation_unread_bg.xml new file mode 100644 index 000000000000..d3e00cfbf8b1 --- /dev/null +++ b/core/res/res/drawable/conversation_unread_bg.xml @@ -0,0 +1,19 @@ +<!-- + ~ 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. + --> +<shape xmlns:android="http://schemas.android.com/apk/res/android"> + <corners android:radius="20sp" /> + <solid android:color="@android:color/white" /> +</shape>
\ No newline at end of file diff --git a/core/res/res/layout/notification_template_material_conversation.xml b/core/res/res/layout/notification_template_material_conversation.xml index 46d3d1326920..581c53fa44ee 100644 --- a/core/res/res/layout/notification_template_material_conversation.xml +++ b/core/res/res/layout/notification_template_material_conversation.xml @@ -199,10 +199,8 @@ android:clipChildren="false" /> </com.android.internal.widget.RemeasuringLinearLayout> - <!-- Unread Count --> - <!-- <TextView /> --> - <!-- This is where the expand button will be placed when collapsed--> + <!-- This is where the expand button container will be placed when collapsed--> </com.android.internal.widget.RemeasuringLinearLayout> <include layout="@layout/notification_template_smart_reply_container" @@ -238,6 +236,21 @@ android:clipToPadding="false" android:clipChildren="false" /> + <!-- Unread Count --> + <TextView + android:id="@+id/conversation_unread_count" + android:layout_width="33sp" + android:layout_height="wrap_content" + android:layout_marginEnd="11dp" + android:layout_gravity="center" + android:gravity="center" + android:padding="2dp" + android:visibility="gone" + android:textAppearance="@style/TextAppearance.DeviceDefault.Notification" + android:textColor="#FFFFFF" + android:textSize="12sp" + android:background="@drawable/conversation_unread_bg" + /> <com.android.internal.widget.NotificationExpandButton android:id="@+id/expand_button" android:layout_width="@dimen/notification_header_expand_icon_size" @@ -246,6 +259,6 @@ android:drawable="@drawable/ic_expand_notification" android:clickable="false" android:importantForAccessibility="no" - /> + /> </LinearLayout> </com.android.internal.widget.ConversationLayout> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index e2e65dd465ae..c9c498ed9b38 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -5442,6 +5442,9 @@ <!-- Conversation Title fallback if the there is no name provided in a group chat conversation [CHAR LIMIT=40]--> <string name="conversation_title_fallback_group_chat">Group Conversation</string> + <!-- Number of unread messages displayed on a conversation notification, when greater-than-or-equal-to 100 [CHAR LIMIT=3]--> + <string name="unread_convo_overflow"><xliff:g id="max_unread_count" example="99">%1$d</xliff:g>+</string> + <!-- ResolverActivity - profile tabs --> <!-- Label of a tab on a screen. A user can tap this tap to switch to the 'Personal' view (that shows their personal content) if they have a work profile on their device. [CHAR LIMIT=NONE] --> <string name="resolver_personal_tab">Personal</string> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 0fea372ea580..42718cba0fc9 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -3898,6 +3898,8 @@ <java-symbol type="dimen" name="button_padding_horizontal_material" /> <java-symbol type="dimen" name="button_inset_horizontal_material" /> <java-symbol type="layout" name="conversation_face_pile_layout" /> + <java-symbol type="id" name="conversation_unread_count" /> + <java-symbol type="string" name="unread_convo_overflow" /> <!-- Intent resolver and share sheet --> <java-symbol type="string" name="resolver_personal_tab" /> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotificationProcessor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotificationProcessor.kt deleted file mode 100644 index 6be0fff38f2b..000000000000 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotificationProcessor.kt +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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 - } - } - } -}
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt new file mode 100644 index 000000000000..600eb1a9b7eb --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt @@ -0,0 +1,139 @@ +/* + * 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.Context +import android.content.pm.LauncherApps +import com.android.internal.statusbar.NotificationVisibility +import com.android.internal.widget.ConversationLayout +import com.android.systemui.statusbar.notification.collection.NotificationEntry +import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow +import java.util.concurrent.ConcurrentHashMap +import javax.inject.Inject +import javax.inject.Singleton + +class ConversationNotificationProcessor @Inject constructor( + private val launcherApps: LauncherApps, + private val unreadConversationBadgeManager: UnreadConversationBadgeManager +) { + 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 + } + } + messagingStyle.unreadMessageCount = + unreadConversationBadgeManager.getUnreadCount(entry, recoveredBuilder) + } +} + +@Singleton +class UnreadConversationBadgeManager @Inject constructor( + private val notificationEntryManager: NotificationEntryManager, + private val context: Context +) { + // Need this state to be thread safe, since it's accessed from the ui thread + // (NotificationEntryListener) and a bg thread (NotificationContentInflater) + private val states = ConcurrentHashMap<String, ConversationState>() + + private var notifPanelCollapsed = true + + init { + notificationEntryManager.addNotificationEntryListener(object : NotificationEntryListener { + + override fun onEntryInflated(entry: NotificationEntry) { + if (!entry.ranking.isConversation) return + fun updateCount(isExpanded: Boolean) { + if (isExpanded && !notifPanelCollapsed) { + resetCount(entry.key) + entry.row?.let(::resetBadgeUi) + } + } + entry.row?.setOnExpansionChangedListener(::updateCount) + updateCount(entry.row?.isExpanded == true) + } + + override fun onEntryReinflated(entry: NotificationEntry) = onEntryInflated(entry) + + override fun onEntryRemoved( + entry: NotificationEntry, + visibility: NotificationVisibility?, + removedByUser: Boolean, + reason: Int + ) = removeTrackedEntry(entry) + }) + } + + fun getUnreadCount(entry: NotificationEntry, recoveredBuilder: Notification.Builder): Int = + states.compute(entry.key) { _, state -> + val newCount = state?.run { + val old = Notification.Builder.recoverBuilder(context, notification) + val increment = Notification + .areStyledNotificationsVisiblyDifferent(old, recoveredBuilder) + if (increment) unreadCount + 1 else unreadCount + } ?: 1 + ConversationState(newCount, entry.sbn.notification) + }!!.unreadCount + + fun onNotificationPanelExpandStateChanged(isCollapsed: Boolean) { + notifPanelCollapsed = isCollapsed + if (isCollapsed) return + + // When the notification panel is expanded, reset the counters of any expanded + // conversations + val expanded = states + .asSequence() + .mapNotNull { (key, _) -> + notificationEntryManager.getActiveNotificationUnfiltered(key) + ?.let { entry -> + if (entry.row?.isExpanded == true) key to entry + else null + } + } + .toMap() + states.replaceAll { key, state -> + if (expanded.contains(key)) state.copy(unreadCount = 0) + else state + } + // Update UI separate from the replaceAll call, since ConcurrentHashMap may re-run the + // lambda if threads are in contention. + expanded.values.asSequence().mapNotNull { it.row }.forEach(::resetBadgeUi) + } + + private fun resetCount(key: String) { + states.compute(key) { _, state -> state?.copy(unreadCount = 0) } + } + + private fun removeTrackedEntry(entry: NotificationEntry) { + states.remove(entry.key) + } + + private fun resetBadgeUi(row: ExpandableNotificationRow): Unit = + (row.layouts?.asSequence() ?: emptySequence()) + .mapNotNull { layout -> layout.contractedChild as? ConversationLayout } + .forEach { convoLayout -> convoLayout.setUnreadCount(0) } + + private data class ConversationState(val unreadCount: Int, val notification: Notification) +}
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java index 7deabf79a6dd..9792defe0e0b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java @@ -107,6 +107,7 @@ import com.android.systemui.statusbar.policy.InflatedSmartReplies.SmartRepliesAn import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.function.BooleanSupplier; @@ -136,7 +137,11 @@ public class ExpandableNotificationRow extends ActivatableNotificationView */ public interface LayoutListener { void onLayout(); + } + /** Listens for changes to the expansion state of this row. */ + public interface OnExpansionChangedListener { + void onExpansionChanged(boolean isExpanded); } private StatusBarStateController mStatusbarStateController; @@ -323,6 +328,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView private boolean mWasChildInGroupWhenRemoved; private NotificationInlineImageResolver mImageResolver; private NotificationMediaManager mMediaManager; + @Nullable private OnExpansionChangedListener mExpansionChangedListener; private SystemNotificationAsyncTask mSystemNotificationAsyncTask = new SystemNotificationAsyncTask(); @@ -351,6 +357,10 @@ public class ExpandableNotificationRow extends ActivatableNotificationView return isSystemNotification; } + public NotificationContentView[] getLayouts() { + return Arrays.copyOf(mLayouts, mLayouts.length); + } + @Override public boolean isGroupExpansionChanging() { if (isChildInGroup()) { @@ -2911,9 +2921,16 @@ public class ExpandableNotificationRow extends ActivatableNotificationView if (mIsSummaryWithChildren) { mChildrenContainer.onExpansionChanged(); } + if (mExpansionChangedListener != null) { + mExpansionChangedListener.onExpansionChanged(nowExpanded); + } } } + public void setOnExpansionChangedListener(@Nullable OnExpansionChangedListener listener) { + mExpansionChangedListener = listener; + } + @Override public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfoInternal(info); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java index 98ba6e5b88a0..7d09dcacfb46 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java @@ -90,6 +90,7 @@ import com.android.systemui.statusbar.notification.DynamicPrivacyController; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator; import com.android.systemui.statusbar.notification.PropertyAnimator; +import com.android.systemui.statusbar.notification.UnreadConversationBadgeManager; import com.android.systemui.statusbar.notification.ViewGroupFadeHelper; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.row.ActivatableNotificationView; @@ -238,6 +239,7 @@ public class NotificationPanelViewController extends PanelViewController { private final PulseExpansionHandler mPulseExpansionHandler; private final KeyguardBypassController mKeyguardBypassController; private final KeyguardUpdateMonitor mUpdateMonitor; + private final UnreadConversationBadgeManager mUnreadConversationBadgeManager; private KeyguardAffordanceHelper mAffordanceHelper; private KeyguardUserSwitcher mKeyguardUserSwitcher; @@ -451,7 +453,8 @@ public class NotificationPanelViewController extends PanelViewController { ActivityManager activityManager, ZenModeController zenModeController, ConfigurationController configurationController, FlingAnimationUtils.Builder flingAnimationUtilsBuilder, - StatusBarTouchableRegionManager statusBarTouchableRegionManager) { + StatusBarTouchableRegionManager statusBarTouchableRegionManager, + UnreadConversationBadgeManager unreadConversationBadgeManager) { super(view, falsingManager, dozeLog, keyguardStateController, (SysuiStatusBarStateController) statusBarStateController, vibratorHelper, latencyTracker, flingAnimationUtilsBuilder, statusBarTouchableRegionManager); @@ -509,6 +512,7 @@ public class NotificationPanelViewController extends PanelViewController { mShadeController = shadeController; mLockscreenUserManager = notificationLockscreenUserManager; mEntryManager = notificationEntryManager; + mUnreadConversationBadgeManager = unreadConversationBadgeManager; mView.setBackgroundColor(Color.TRANSPARENT); OnAttachStateChangeListener onAttachStateChangeListener = new OnAttachStateChangeListener(); @@ -2143,6 +2147,7 @@ public class NotificationPanelViewController extends PanelViewController { super.onExpandingFinished(); mNotificationStackScroller.onExpansionStopped(); mHeadsUpManager.onExpandingFinished(); + mUnreadConversationBadgeManager.onNotificationPanelExpandStateChanged(isFullyCollapsed()); mIsExpanding = false; if (isFullyCollapsed()) { DejankUtils.postAfterTraversal(new Runnable() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java index 13bf38c7f0f3..5bca946ec1ee 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java @@ -67,6 +67,7 @@ import com.android.systemui.statusbar.VibratorHelper; import com.android.systemui.statusbar.notification.DynamicPrivacyController; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator; +import com.android.systemui.statusbar.notification.UnreadConversationBadgeManager; import com.android.systemui.statusbar.notification.stack.NotificationRoundnessManager; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout; import com.android.systemui.statusbar.policy.ConfigurationController; @@ -169,6 +170,8 @@ public class NotificationPanelViewTest extends SysuiTestCase { private ZenModeController mZenModeController; @Mock private ConfigurationController mConfigurationController; + @Mock + private UnreadConversationBadgeManager mUnreadConversationBadgeManager; private FlingAnimationUtils.Builder mFlingAnimationUtilsBuilder; private NotificationPanelViewController mNotificationPanelViewController; @@ -223,7 +226,8 @@ public class NotificationPanelViewTest extends SysuiTestCase { mDozeParameters, mCommandQueue, mVibratorHelper, mLatencyTracker, mPowerManager, mAccessibilityManager, 0, mUpdateMonitor, mMetricsLogger, mActivityManager, mZenModeController, mConfigurationController, - mFlingAnimationUtilsBuilder, mStatusBarTouchableRegionManager); + mFlingAnimationUtilsBuilder, mStatusBarTouchableRegionManager, + mUnreadConversationBadgeManager); mNotificationPanelViewController.initDependencies(mStatusBar, mGroupManager, mNotificationShelf, mNotificationAreaController, mScrimController); mNotificationPanelViewController.setHeadsUpManager(mHeadsUpManager); |