summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/Notification.java19
-rw-r--r--core/java/com/android/internal/widget/ConversationLayout.java20
-rw-r--r--core/res/res/drawable/conversation_unread_bg.xml19
-rw-r--r--core/res/res/layout/notification_template_material_conversation.xml21
-rw-r--r--core/res/res/values/strings.xml3
-rw-r--r--core/res/res/values/symbols.xml2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotificationProcessor.kt41
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt139
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java6
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);