From 6597f16fcb83ad7e27076dcc6e03ad662aed8955 Mon Sep 17 00:00:00 2001 From: Beth Thibodeau Date: Thu, 25 Jul 2019 16:42:51 -0400 Subject: [PATCH 1/3] Stop timer when notification isn't visible Fixes: 138261464 Test: manual, atest com.android.systemui.statusbar.notification.row.wrapper.NotificationMediaTemplateViewWrapperTest Change-Id: Id7b1b586f3ab258fad8670070240ef951080c969 (cherry picked from commit 3c4a8e48d404649bd03ee8e6e377dcf9a65afee9) --- .../widget/MediaNotificationView.java | 47 +++++++++++++++++++ .../NotificationMediaTemplateViewWrapper.java | 47 +++++++++++++++---- 2 files changed, 86 insertions(+), 8 deletions(-) diff --git a/core/java/com/android/internal/widget/MediaNotificationView.java b/core/java/com/android/internal/widget/MediaNotificationView.java index e7d240a1035e6..0d87afa42e3eb 100644 --- a/core/java/com/android/internal/widget/MediaNotificationView.java +++ b/core/java/com/android/internal/widget/MediaNotificationView.java @@ -26,6 +26,8 @@ import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.RemoteViews; +import java.util.ArrayList; + /** * A TextView that can float around an image on the end. * @@ -42,6 +44,7 @@ public class MediaNotificationView extends FrameLayout { private View mMainColumn; private View mMediaContent; private int mImagePushIn; + private ArrayList mListeners; public MediaNotificationView(Context context) { this(context, null); @@ -168,4 +171,48 @@ public class MediaNotificationView extends FrameLayout { mMainColumn = findViewById(com.android.internal.R.id.notification_main_column); mMediaContent = findViewById(com.android.internal.R.id.notification_media_content); } + + @Override + public void onVisibilityAggregated(boolean isVisible) { + super.onVisibilityAggregated(isVisible); + for (int i = 0; i < mListeners.size(); i++) { + mListeners.get(i).onAggregatedVisibilityChanged(isVisible); + } + } + + /** + * Add a listener to receive updates on the visibility of this view + * + * @param listener The listener to add. + */ + public void addVisibilityListener(VisibilityChangeListener listener) { + if (mListeners == null) { + mListeners = new ArrayList<>(); + } + if (!mListeners.contains(listener)) { + mListeners.add(listener); + } + } + + /** + * Remove the specified listener + * + * @param listener The listener to remove. + */ + public void removeVisibilityListener(VisibilityChangeListener listener) { + if (mListeners != null) { + mListeners.remove(listener); + } + } + + /** + * Interface for receiving updates when the view's visibility changes + */ + public interface VisibilityChangeListener { + /** + * Method called when the visibility of this view has changed + * @param isVisible true if the view is now visible + */ + void onAggregatedVisibilityChanged(boolean isVisible); + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java index 20e8b733ce6ab..38f9bff2a63f9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java @@ -39,6 +39,7 @@ import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; +import com.android.internal.widget.MediaNotificationView; import com.android.systemui.Dependency; import com.android.systemui.statusbar.NotificationMediaManager; import com.android.systemui.statusbar.TransformableView; @@ -67,6 +68,7 @@ public class NotificationMediaTemplateViewWrapper extends NotificationTemplateVi private View mSeekBarView; private Context mContext; private MetricsLogger mMetricsLogger; + private boolean mIsViewVisible; @VisibleForTesting protected SeekBar.OnSeekBarChangeListener mSeekListener = @@ -88,11 +90,33 @@ public class NotificationMediaTemplateViewWrapper extends NotificationTemplateVi } }; + MediaNotificationView.VisibilityChangeListener mVisibilityListener = + new MediaNotificationView.VisibilityChangeListener() { + @Override + public void onAggregatedVisibilityChanged(boolean isVisible) { + mIsViewVisible = isVisible; + if (isVisible) { + // Restart timer if we're currently playing and didn't already have one going + PlaybackState state = mMediaController.getPlaybackState(); + if (state != null && state.getState() == PlaybackState.STATE_PLAYING + && mSeekBarTimer == null && mSeekBarView != null + && mSeekBarView.getVisibility() != View.GONE) { + startTimer(); + } + } else { + clearTimer(); + } + } + }; + private MediaController.Callback mMediaCallback = new MediaController.Callback() { @Override public void onSessionDestroyed() { clearTimer(); mMediaController.unregisterCallback(this); + if (mView instanceof MediaNotificationView) { + ((MediaNotificationView) mView).removeVisibilityListener(mVisibilityListener); + } } @Override @@ -126,10 +150,16 @@ public class NotificationMediaTemplateViewWrapper extends NotificationTemplateVi mContext = ctx; mMediaManager = Dependency.get(NotificationMediaManager.class); mMetricsLogger = Dependency.get(MetricsLogger.class); + + if (mView instanceof MediaNotificationView) { + MediaNotificationView mediaView = (MediaNotificationView) mView; + mediaView.addVisibilityListener(mVisibilityListener); + } } private void resolveViews() { mActions = mView.findViewById(com.android.internal.R.id.media_actions); + mIsViewVisible = mView.isShown(); final MediaSession.Token token = mRow.getEntry().notification.getNotification().extras .getParcelable(Notification.EXTRA_MEDIA_SESSION); @@ -208,18 +238,19 @@ public class NotificationMediaTemplateViewWrapper extends NotificationTemplateVi private void startTimer() { clearTimer(); - mSeekBarTimer = new Timer(true /* isDaemon */); - mSeekBarTimer.schedule(new TimerTask() { - @Override - public void run() { - mHandler.post(mOnUpdateTimerTick); - } - }, 0, PROGRESS_UPDATE_INTERVAL); + if (mIsViewVisible) { + mSeekBarTimer = new Timer(true /* isDaemon */); + mSeekBarTimer.schedule(new TimerTask() { + @Override + public void run() { + mHandler.post(mOnUpdateTimerTick); + } + }, 0, PROGRESS_UPDATE_INTERVAL); + } } private void clearTimer() { if (mSeekBarTimer != null) { - // TODO: also trigger this when the notification panel is collapsed mSeekBarTimer.cancel(); mSeekBarTimer.purge(); mSeekBarTimer = null; From 65dd52bb2b40b61f2b98cb9e2479c95df3b5a12c Mon Sep 17 00:00:00 2001 From: Selim Cinek Date: Thu, 25 Jul 2019 20:41:29 -0700 Subject: [PATCH 2/3] Showing the notification icon properly now when the pulse is suppressed Previously the notification would be hidden so if the user would pull out the phone from the pocket, they might not see what notification actually alerted. Bug: 138336424 Test: add notification while on AOD, block prox sensor, see icon Change-Id: I101640c9d0226948e44a4bf36a7ca91dd135fe66 Merged-In: I8f7bd7a6a0562942ed3e12f28705043722d177e8 (cherry picked from commit 15803b51e3ec5e3335f54cab12bdd7697df865d9) --- .../com/android/systemui/statusbar/NotificationShelf.java | 7 ++++--- .../notification/stack/NotificationStackScrollLayout.java | 3 ++- .../statusbar/notification/stack/StackScrollAlgorithm.java | 3 ++- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java index 312ea473d9e66..165c64e7a6a45 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java @@ -512,7 +512,7 @@ public class NotificationShelf extends ActivatableNotificationView implements float viewEnd = row.getTranslationY() + row.getActualHeight(); boolean isPinned = (row.isPinned() || row.isHeadsUpAnimatingAway()) && !mAmbientState.isDozingAndNotPulsing(row); - boolean shouldClipOwnTop = row.showingAmbientPulsing() + boolean shouldClipOwnTop = row.showingAmbientPulsing() && !mAmbientState.isFullyDark() || (mAmbientState.isPulseExpanding() && childIndex == 0); if (viewEnd > notificationClipEnd && !shouldClipOwnTop && (mAmbientState.isShadeExpanded() || !isPinned)) { @@ -752,8 +752,9 @@ public class NotificationShelf extends ActivatableNotificationView implements iconState.scaleY = 1.0f; iconState.hidden = false; } - if (row.isAboveShelf() || (!row.isInShelf() && (isLastChild && row.areGutsExposed() - || row.getTranslationZ() > mAmbientState.getBaseZHeight()))) { + if ((row.isAboveShelf() || (!row.isInShelf() && (isLastChild && row.areGutsExposed() + || row.getTranslationZ() > mAmbientState.getBaseZHeight()))) + && !mAmbientState.isFullyDark()) { iconState.hidden = true; } int backgroundColor = getBackgroundColorWithoutTint(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java index 09352cfd17a36..237825e44b978 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java @@ -1355,7 +1355,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd mIsClipped = clipped; } - if (!mAmbientPulseManager.hasNotifications() && mAmbientState.isFullyDark()) { + if (!mPulsing && mAmbientState.isFullyDark()) { setClipBounds(null); } else if (mAmbientState.isDarkAtAll()) { clipToOutline = true; @@ -5169,6 +5169,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd return; } mPulsing = pulsing; + updateClipping(); mAmbientState.setPulsing(pulsing); mSwipeHelper.setPulsing(pulsing); updateNotificationAnimationStates(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java index 60061c6a9ad2a..d9f8c88e0d135 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java @@ -501,7 +501,8 @@ public class StackScrollAlgorithm { continue; } ExpandableNotificationRow row = (ExpandableNotificationRow) child; - if (!row.showingAmbientPulsing() || (i == 0 && ambientState.isPulseExpanding())) { + if (!row.showingAmbientPulsing() || ambientState.isFullyDark() + || (i == 0 && ambientState.isPulseExpanding())) { continue; } ExpandableViewState viewState = row.getViewState(); From 67dd6142d71ba8d6c5eb8228b964a01e0743bef9 Mon Sep 17 00:00:00 2001 From: Selim Cinek Date: Fri, 26 Jul 2019 21:47:19 -0700 Subject: [PATCH 3/3] Fixed an issue where the notification wouldn't collapse When clicking on a notification with an activity that wouldn't start an opening animation, the panel could remain open. We're now closing it in that case. Fixes: 138468703 Test: follow test on bug and observe normal closing Change-Id: I0b867302d616c017d82f944ee983d4ba4356701a (cherry picked from commit 7c236e9ca79ac7ea50449f77709bbc1f5dcd4b79) --- .../systemui/statusbar/notification/ActivityLaunchAnimator.java | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java index 0d9f4e7b909d4..91d47077fc312 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java @@ -153,6 +153,7 @@ public class ActivityLaunchAnimator { if (primary == null) { setAnimationPending(false); invokeCallback(iRemoteAnimationFinishedCallback); + mNotificationPanel.collapse(false /* delayed */, 1.0f /* speedUpFactor */); return; }