From d991c048bc7b0732aa566036a24d2f7172daec46 Mon Sep 17 00:00:00 2001 From: Steve Elliott Date: Thu, 19 Dec 2019 12:40:29 -0500 Subject: [PATCH] Minified people row Bug: 146664602 Test: manual, atest Change-Id: Id007cc64a6d37dea51bbdd5d70d7eac4df7556ac --- packages/SystemUI/res/layout/people_strip.xml | 222 ++++-------------- packages/SystemUI/res/values/strings.xml | 3 + .../people/PeopleHubNotificationListener.kt | 78 +----- .../stack/NotificationSectionsManager.java | 55 +++-- .../stack/NotificationSwipeHelper.java | 5 +- .../notification/stack/PeopleHubView.kt | 64 ++--- .../notification/stack/SwipeableView.java | 7 - 7 files changed, 108 insertions(+), 326 deletions(-) diff --git a/packages/SystemUI/res/layout/people_strip.xml b/packages/SystemUI/res/layout/people_strip.xml index f0ac08bdad376..982aa8ef6d16d 100644 --- a/packages/SystemUI/res/layout/people_strip.xml +++ b/packages/SystemUI/res/layout/people_strip.xml @@ -18,7 +18,10 @@ + android:layout_height="@dimen/notification_section_header_height" + android:focusable="true" + android:clickable="true" +> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -236,4 +96,4 @@ android:layout_width="match_parent" android:layout_height="match_parent" /> - \ No newline at end of file + diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 380dcfd63585b..6d5c658fd1370 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -1163,6 +1163,9 @@ Silent notifications + + Conversations + Clear all silent notifications diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleHubNotificationListener.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleHubNotificationListener.kt index 45d8c9705b0df..88b41471a063c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleHubNotificationListener.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleHubNotificationListener.kt @@ -17,24 +17,16 @@ package com.android.systemui.statusbar.notification.people import android.app.Notification -import android.content.Context import android.content.pm.UserInfo -import android.graphics.Canvas -import android.graphics.ColorFilter -import android.graphics.PixelFormat -import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.Drawable -import android.os.UserHandle import android.os.UserManager import android.service.notification.StatusBarNotification import android.util.SparseArray -import android.util.TypedValue import android.view.View import android.view.ViewGroup import android.widget.ImageView import com.android.internal.statusbar.NotificationVisibility import com.android.internal.widget.MessagingGroup -import com.android.launcher3.icons.BaseIconFactory import com.android.systemui.R import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.dagger.qualifiers.Main @@ -59,8 +51,7 @@ interface NotificationPersonExtractor { @Singleton class NotificationPersonExtractorPluginBoundary @Inject constructor( - extensionController: ExtensionController, - private val context: Context + extensionController: ExtensionController ) : NotificationPersonExtractor { private var plugin: NotificationPersonExtractorPlugin? = null @@ -77,9 +68,8 @@ class NotificationPersonExtractorPluginBoundary @Inject constructor( } override fun extractPerson(sbn: StatusBarNotification) = - plugin?.extractPerson(sbn)?.let { data -> - val badged = addBadgeToDrawable(data.avatar, context, sbn.packageName, sbn.user) - PersonModel(data.key, data.name, badged, data.clickIntent, sbn.user.identifier) + plugin?.extractPerson(sbn)?.run { + PersonModel(key, name, avatar, clickIntent, sbn.user.identifier) } override fun extractPersonKey(sbn: StatusBarNotification) = plugin?.extractPersonKey(sbn) @@ -214,7 +204,7 @@ class PeopleHubManager { if (inactivePeople.size >= MAX_STORED_INACTIVE_PEOPLE) { inactivePeople.removeLast() } - inactivePeople.push(data) + inactivePeople.add(data) return true } return false @@ -247,63 +237,7 @@ private fun NotificationEntry.extractPerson(): PersonModel? { ?: extras.getString(Notification.EXTRA_TITLE) ?: return null val drawable = extractAvatarFromRow(this) ?: return null - val badgedAvatar = addBadgeToDrawable(drawable, row.context, sbn.packageName, sbn.user) - return PersonModel(key, name, badgedAvatar, clickIntent, sbn.user.identifier) -} - -private fun addBadgeToDrawable( - drawable: Drawable, - context: Context, - packageName: String, - user: UserHandle -): Drawable { - val pm = context.packageManager - val appInfo = pm.getApplicationInfoAsUser(packageName, 0, user) - return object : Drawable() { - override fun draw(canvas: Canvas) { - val iconBounds = getBounds() - val factory = object : BaseIconFactory( - context, - 0 /* unused */, - iconBounds.width(), - true) {} - val badge = factory.createBadgedIconBitmap( - appInfo.loadIcon(pm), - user, - true, - appInfo.isInstantApp, - null) - val badgeDrawable = BitmapDrawable(context.resources, badge.icon) - .apply { - alpha = drawable.alpha - colorFilter = drawable.colorFilter - val badgeWidth = TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_DIP, - 15f, - context.resources.displayMetrics - ).toInt() - setBounds( - iconBounds.left + (iconBounds.width() - badgeWidth), - iconBounds.top + (iconBounds.height() - badgeWidth), - iconBounds.right, - iconBounds.bottom) - } - drawable.bounds = iconBounds - drawable.draw(canvas) - badgeDrawable.draw(canvas) - } - - override fun setAlpha(alpha: Int) { - drawable.alpha = alpha - } - - override fun setColorFilter(colorFilter: ColorFilter?) { - drawable.colorFilter = colorFilter - } - - @PixelFormat.Opacity - override fun getOpacity(): Int = PixelFormat.OPAQUE - } + return PersonModel(key, name, drawable, clickIntent, sbn.user.identifier) } fun extractAvatarFromRow(entry: NotificationEntry): Drawable? = @@ -329,4 +263,4 @@ private fun NotificationEntry.extractPersonKey(): PersonKey? = if (isMessagingNotification()) key else null private fun NotificationEntry.isMessagingNotification() = - sbn.notification.notificationStyle == Notification.MessagingStyle::class.java \ No newline at end of file + sbn.notification.notificationStyle == Notification.MessagingStyle::class.java diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.java index 2761689ec4096..09c1fad423d33 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.java @@ -187,18 +187,18 @@ public class NotificationSectionsManager implements StackScrollAlgorithm.Section @Override public boolean beginsSection(@NonNull View view, @Nullable View previous) { boolean begin = false; - if (view instanceof ExpandableNotificationRow) { - if (previous instanceof ExpandableNotificationRow) { + if (view instanceof ActivatableNotificationView) { + if (previous instanceof ActivatableNotificationView) { // If we're drawing the first non-person notification, break out a section - ExpandableNotificationRow curr = (ExpandableNotificationRow) view; - ExpandableNotificationRow prev = (ExpandableNotificationRow) previous; + ActivatableNotificationView curr = (ActivatableNotificationView) view; + ActivatableNotificationView prev = (ActivatableNotificationView) previous; - begin = curr.getEntry().getBucket() != prev.getEntry().getBucket(); + begin = getBucket(curr) != getBucket(prev); } } if (!begin) { - begin = view == mGentleHeader || previous == mPeopleHubView; + begin = view == mGentleHeader || view == mPeopleHubView; } return begin; @@ -230,29 +230,42 @@ public class NotificationSectionsManager implements StackScrollAlgorithm.Section return; } - int lastPersonIndex = -1; - int firstGentleNotifIndex = -1; + boolean peopleNotificationsPresent = false; + int firstNonHeadsUpIndex = -1; + int firstGentleIndex = -1; + int notifCount = 0; final int n = mParent.getChildCount(); for (int i = 0; i < n; i++) { View child = mParent.getChildAt(i); - if (child instanceof ExpandableNotificationRow - && child.getVisibility() != View.GONE) { + if (child instanceof ExpandableNotificationRow && child.getVisibility() != View.GONE) { + notifCount++; ExpandableNotificationRow row = (ExpandableNotificationRow) child; + if (firstNonHeadsUpIndex == -1 && !row.isHeadsUp()) { + firstNonHeadsUpIndex = i; + } if (row.getEntry().getBucket() == BUCKET_PEOPLE) { - lastPersonIndex = i; + peopleNotificationsPresent = true; } if (row.getEntry().getBucket() == BUCKET_SILENT) { - firstGentleNotifIndex = i; + firstGentleIndex = i; break; } } } - // make room for peopleHub - firstGentleNotifIndex += adjustPeopleHubVisibilityAndPosition(lastPersonIndex); + if (firstNonHeadsUpIndex == -1) { + firstNonHeadsUpIndex = firstGentleIndex != -1 ? firstGentleIndex : notifCount; + } - adjustGentleHeaderVisibilityAndPosition(firstGentleNotifIndex); + // make room for peopleHub + int offset = adjustPeopleHubVisibilityAndPosition( + firstNonHeadsUpIndex, peopleNotificationsPresent); + if (firstGentleIndex != -1) { + firstGentleIndex += offset; + } + + adjustGentleHeaderVisibilityAndPosition(firstGentleIndex); mGentleHeader.setAreThereDismissableGentleNotifs( mParent.hasActiveClearableNotifications(ROWS_GENTLE)); @@ -294,13 +307,15 @@ public class NotificationSectionsManager implements StackScrollAlgorithm.Section } } - private int adjustPeopleHubVisibilityAndPosition(int lastPersonIndex) { - final boolean showPeopleHeader = mPeopleHubVisible - && mNumberOfSections > 2 - && mStatusBarStateController.getState() != StatusBarState.KEYGUARD; + private int adjustPeopleHubVisibilityAndPosition( + int targetIndex, boolean peopleNotificationsPresent) { + final boolean showPeopleHeader = mNumberOfSections > 2 + && mStatusBarStateController.getState() != StatusBarState.KEYGUARD + && (peopleNotificationsPresent || mPeopleHubVisible); final int currentHubIndex = mParent.indexOfChild(mPeopleHubView); final boolean currentlyVisible = currentHubIndex >= 0; - int targetIndex = lastPersonIndex + 1; + + mPeopleHubView.setCanSwipe(showPeopleHeader && !peopleNotificationsPresent); if (!showPeopleHeader) { if (currentlyVisible) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java index 6d0fcc3862815..4845ea16020bf 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java @@ -31,6 +31,7 @@ import com.android.systemui.SwipeHelper; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper; +import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.row.ExpandableView; class NotificationSwipeHelper extends SwipeHelper implements NotificationSwipeActionHelper { @@ -298,8 +299,8 @@ class NotificationSwipeHelper extends SwipeHelper implements NotificationSwipeAc @Override public Animator getViewTranslationAnimator(View v, float target, ValueAnimator.AnimatorUpdateListener listener) { - if (v instanceof SwipeableView) { - return ((SwipeableView) v).getTranslateViewAnimator(target, listener); + if (v instanceof ExpandableNotificationRow) { + return ((ExpandableNotificationRow) v).getTranslateViewAnimator(target, listener); } else { return superGetViewTranslationAnimator(v, target, listener); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/PeopleHubView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/PeopleHubView.kt index a0796060e9d87..e5717aeefdcbd 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/PeopleHubView.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/PeopleHubView.kt @@ -16,38 +16,22 @@ package com.android.systemui.statusbar.notification.stack -import android.animation.Animator -import android.animation.AnimatorListenerAdapter -import android.animation.ObjectAnimator -import android.animation.ValueAnimator import android.content.Context import android.util.AttributeSet -import android.util.FloatProperty import android.view.View import android.view.ViewGroup import android.widget.ImageView -import android.widget.LinearLayout -import android.widget.TextView import com.android.systemui.R import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin import com.android.systemui.statusbar.notification.people.DataListener import com.android.systemui.statusbar.notification.people.PersonViewModel import com.android.systemui.statusbar.notification.row.ActivatableNotificationView -private val TRANSLATE_CONTENT = object : FloatProperty("translate") { - override fun setValue(view: PeopleHubView, value: Float) { - view.translation = value - } - - override fun get(view: PeopleHubView) = view.translation -} - class PeopleHubView(context: Context, attrs: AttributeSet) : ActivatableNotificationView(context, attrs), SwipeableView { private lateinit var contents: ViewGroup private lateinit var personControllers: List - private var translateAnim: ObjectAnimator? = null val personViewAdapters: Sequence> get() = personControllers.asSequence() @@ -56,9 +40,10 @@ class PeopleHubView(context: Context, attrs: AttributeSet) : super.onFinishInflate() contents = requireViewById(R.id.people_list) personControllers = (0 until contents.childCount) + .reversed() .asSequence() .mapNotNull { idx -> - (contents.getChildAt(idx) as? LinearLayout)?.let(::PersonDataListenerImpl) + (contents.getChildAt(idx) as? ImageView)?.let(::PersonDataListenerImpl) } .toList() } @@ -69,41 +54,32 @@ class PeopleHubView(context: Context, attrs: AttributeSet) : override fun createMenu(): NotificationMenuRowPlugin? = null - override fun getTranslateViewAnimator( - leftTarget: Float, - listener: ValueAnimator.AnimatorUpdateListener? - ): Animator = - ObjectAnimator - .ofFloat(this, TRANSLATE_CONTENT, leftTarget) - .apply { - listener?.let { addUpdateListener(listener) } - addListener(object : AnimatorListenerAdapter() { - override fun onAnimationEnd(anim: Animator) { - translateAnim = null - } - }) - } - .also { - translateAnim?.cancel() - translateAnim = it - } - override fun resetTranslation() { - translateAnim?.cancel() translationX = 0f } - private inner class PersonDataListenerImpl(val viewGroup: ViewGroup) : + override fun setTranslation(translation: Float) { + if (canSwipe) { + super.setTranslation(translation) + } + } + + var canSwipe: Boolean = true + set(value) { + if (field != value) { + if (field) { + resetTranslation() + } + field = value + } + } + + private inner class PersonDataListenerImpl(val avatarView: ImageView) : DataListener { - val nameView = viewGroup.requireViewById(R.id.person_name) - val avatarView = viewGroup.requireViewById(R.id.person_icon) - override fun onDataChanged(data: PersonViewModel?) { - viewGroup.visibility = data?.let { View.VISIBLE } ?: View.INVISIBLE - nameView.text = data?.name avatarView.setImageDrawable(data?.icon) - viewGroup.setOnClickListener { data?.onClick?.invoke() } + avatarView.setOnClickListener { data?.onClick?.invoke() } } } } \ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/SwipeableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/SwipeableView.java index 6c6ef61cfdaf4..49e59a2e7200e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/SwipeableView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/SwipeableView.java @@ -16,9 +16,6 @@ package com.android.systemui.statusbar.notification.stack; -import android.animation.Animator; -import android.animation.ValueAnimator; - import androidx.annotation.Nullable; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; @@ -32,10 +29,6 @@ public interface SwipeableView { /** Optionally creates a menu for this view. */ @Nullable NotificationMenuRowPlugin createMenu(); - /** Animator for translating the view, simulating a swipe. */ - Animator getTranslateViewAnimator( - float leftTarget, ValueAnimator.AnimatorUpdateListener listener); - /** Sets the translation amount for an in-progress swipe. */ void setTranslation(float translate);