diff options
| author | 2019-10-28 11:20:24 -0400 | |
|---|---|---|
| committer | 2019-11-05 16:28:32 -0500 | |
| commit | 946b00c4eb01366e38be59a5d0bc38283b433ad8 (patch) | |
| tree | 9d58992da1e3249d5bde0537fb8862fb544e2a9f | |
| parent | 0cf108183435ccaff502726a8ebd1cb3b7f89b5a (diff) | |
PeopleHub swipe-to-dismiss
Test: manual
Change-Id: I9ee003d78f048574e5b9b5b4f297104028eb87a5
9 files changed, 183 insertions, 62 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java index a817f54e77ca..50a20374fee5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java @@ -159,6 +159,8 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView private int mHeadsUpAddStartLocation; private float mHeadsUpLocation; private boolean mIsAppearing; + private boolean mDismissed; + private boolean mRefocusOnDismiss; public ActivatableNotificationView(Context context, AttributeSet attrs) { super(context, attrs); @@ -1048,6 +1050,27 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView return getHeight(); } + /** Mark that this view has been dismissed. */ + public void dismiss(boolean refocusOnDismiss) { + mDismissed = true; + mRefocusOnDismiss = refocusOnDismiss; + } + + /** Mark that this view is no longer dismissed. */ + public void unDismiss() { + mDismissed = false; + } + + /** Is this view marked as dismissed? */ + public boolean isDismissed() { + return mDismissed; + } + + /** Should a re-focus occur upon dismissing this view? */ + public boolean shouldRefocusOnDismiss() { + return mRefocusOnDismiss || isAccessibilityFocused(); + } + public interface OnActivatedListener { void onActivated(ActivatableNotificationView view); void onActivationReset(ActivatableNotificationView view); 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 536db67a8795..f0d07a7ed0bd 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 @@ -95,6 +95,7 @@ import com.android.systemui.statusbar.notification.stack.AnimationProperties; import com.android.systemui.statusbar.notification.stack.ExpandableViewState; import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainer; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout; +import com.android.systemui.statusbar.notification.stack.SwipeableView; import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.phone.NotificationGroupManager; import com.android.systemui.statusbar.phone.StatusBar; @@ -114,7 +115,7 @@ import java.util.function.Consumer; * the group summary (which contains 1 or more child notifications). */ public class ExpandableNotificationRow extends ActivatableNotificationView - implements PluginListener<NotificationMenuRowPlugin> { + implements PluginListener<NotificationMenuRowPlugin>, SwipeableView { private static final boolean DEBUG = false; private static final int DEFAULT_DIVIDER_ALPHA = 0x29; @@ -288,7 +289,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView } }; private boolean mForceUnlocked; - private boolean mDismissed; private boolean mKeepInParent; private boolean mRemoved; private static final Property<ExpandableNotificationRow, Float> TRANSLATE_CONTENT = @@ -307,7 +307,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView private boolean mHeadsupDisappearRunning; private View mChildAfterViewWhenDismissed; private View mGroupParentWhenDismissed; - private boolean mRefocusOnDismiss; private float mContentTransformationAmount; private boolean mIconsVisible = true; private boolean mAboveShelf; @@ -1164,6 +1163,11 @@ public class ExpandableNotificationRow extends ActivatableNotificationView } } + @Override + public boolean hasFinishedInitialization() { + return getEntry().hasFinishedInitialization(); + } + /** * Get a handle to a NotificationMenuRowPlugin whose menu view has been added to our hierarchy, * or null if there is no menu row @@ -1323,11 +1327,11 @@ public class ExpandableNotificationRow extends ActivatableNotificationView } } - public void setDismissed(boolean fromAccessibility) { + @Override + public void dismiss(boolean refocusOnDismiss) { + super.dismiss(refocusOnDismiss); setLongPressListener(null); - mDismissed = true; mGroupParentWhenDismissed = mNotificationParent; - mRefocusOnDismiss = fromAccessibility; mChildAfterViewWhenDismissed = null; mEntry.icon.setDismissed(); if (isChildInGroup()) { @@ -1340,10 +1344,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView } } - public boolean isDismissed() { - return mDismissed; - } - public boolean keepInParent() { return mKeepInParent; } @@ -1445,7 +1445,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView groupSummary.getRow().performDismiss(fromAccessibility); } } - setDismissed(fromAccessibility); + dismiss(fromAccessibility); if (mEntry.isClearable()) { // TODO: beverlyt, log dismissal // TODO: track dismiss sentiment @@ -3021,10 +3021,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView return false; } - public boolean shouldRefocusOnDismiss() { - return mRefocusOnDismiss || isAccessibilityFocused(); - } - public interface OnExpandClickListener { void onExpandClicked(NotificationEntry clickedEntry, boolean nowExpanded); } 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 54d406615ae0..fdd51e9e7790 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 @@ -23,7 +23,6 @@ import static java.lang.annotation.RetentionPolicy.SOURCE; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.app.PendingIntent; import android.content.Intent; import android.provider.Settings; import android.view.LayoutInflater; @@ -310,6 +309,8 @@ public class NotificationSectionsManager implements StackScrollAlgorithm.Section mParent.removeView(mPeopleHubView); } } else { + mPeopleHubView.unDismiss(); + mPeopleHubView.resetTranslation(); if (!currentlyVisible) { if (mPeopleHubView.getTransientContainer() != null) { mPeopleHubView.getTransientContainer().removeTransientView(mPeopleHubView); @@ -419,8 +420,9 @@ public class NotificationSectionsManager implements StackScrollAlgorithm.Section } } - private void handlePeopleHubClick(PendingIntent pendingIntent) { - mActivityStarter.startPendingIntentDismissingKeyguard(pendingIntent, null, mPeopleHubView); + void hidePeopleRow() { + mPeopleHubVisible = false; + updateSectionBoundaries(); } /** 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 6dca7ee9e872..2b9912ce055d 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 @@ -4920,7 +4920,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd } else { child.setMinClipTopAmount(0); } - previousChildWillBeDismissed = StackScrollAlgorithm.canChildBeDismissed(child); + previousChildWillBeDismissed = canChildBeDismissed(child); } } @@ -5523,7 +5523,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd performDismissAllAnimations(viewsToHide, closeShade, () -> { for (ExpandableNotificationRow rowToRemove : viewsToRemove) { - if (StackScrollAlgorithm.canChildBeDismissed(rowToRemove)) { + if (canChildBeDismissed(rowToRemove)) { if (selection == ROWS_ALL) { // TODO: This is a listener method; we shouldn't be calling it. Can we just // call performRemoveNotification as below? @@ -5552,7 +5552,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd private boolean includeChildInDismissAll( ExpandableNotificationRow row, @SelectedRows int selection) { - return StackScrollAlgorithm.canChildBeDismissed(row) && matchesSelection(row, selection); + return canChildBeDismissed(row) && matchesSelection(row, selection); } /** @@ -6223,7 +6223,10 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd */ @Override public void onChildDismissed(View view) { - ExpandableNotificationRow row = (ExpandableNotificationRow) view; + if (!(view instanceof ActivatableNotificationView)) { + return; + } + ActivatableNotificationView row = (ActivatableNotificationView) view; if (!row.isDismissed()) { handleChildViewDismissed(view); } @@ -6261,6 +6264,12 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd row.performDismissWithBlockingHelper(false /* fromAccessibility */); } + if (view instanceof PeopleHubView) { + PeopleHubView row = (PeopleHubView) view; + row.dismiss(false); + mSectionsManager.hidePeopleRow(); + } + if (!isBlockingHelperShown) { mSwipedOutViews.add(view); } @@ -6349,9 +6358,9 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd return 0; } - @Override + @Override public boolean canChildBeDismissed(View v) { - return StackScrollAlgorithm.canChildBeDismissed(v); + return NotificationStackScrollLayout.canChildBeDismissed(v); } @Override @@ -6361,6 +6370,23 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd } }; + private static boolean canChildBeDismissed(View v) { + if (v instanceof ExpandableNotificationRow) { + ExpandableNotificationRow row = (ExpandableNotificationRow) v; + if (row.isBlockingHelperShowingAndTranslationFinished()) { + return true; + } + if (row.areGutsExposed() || !row.getEntry().hasFinishedInitialization()) { + return false; + } + return row.canViewBeDismissed(); + } + if (v instanceof PeopleHubView) { + return true; + } + return false; + } + // ---------------------- DragDownHelper.OnDragDownListener ------------------------------------ @ShadeViewRefactor(RefactorComponent.INPUT) 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 0968674d31cc..6d0fcc386281 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,11 +31,10 @@ 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 { +class NotificationSwipeHelper extends SwipeHelper implements NotificationSwipeActionHelper { + @VisibleForTesting protected static final long COVER_MENU_DELAY = 4000; private static final String TAG = "NotificationSwipeHelper"; @@ -58,12 +57,7 @@ class NotificationSwipeHelper extends SwipeHelper super(swipeDirection, callback, context, falsingManager); mMenuListener = menuListener; mCallback = callback; - mFalsingCheck = new Runnable() { - @Override - public void run() { - resetExposedMenuView(true /* animate */, true /* force */); - } - }; + mFalsingCheck = () -> resetExposedMenuView(true /* animate */, true /* force */); } public View getTranslatingParentView() { @@ -126,14 +120,14 @@ class NotificationSwipeHelper extends SwipeHelper // Slide back any notifications that might be showing a menu resetExposedMenuView(true /* animate */, false /* force */); - if (currView instanceof ExpandableNotificationRow) { - initializeRow((ExpandableNotificationRow) currView); + if (currView instanceof SwipeableView) { + initializeRow((SwipeableView) currView); } } @VisibleForTesting - protected void initializeRow(ExpandableNotificationRow row) { - if (row.getEntry().hasFinishedInitialization()) { + protected void initializeRow(SwipeableView row) { + if (row.hasFinishedInitialization()) { mCurrMenuRow = row.createMenu(); if (mCurrMenuRow != null) { mCurrMenuRow.setMenuClickListener(mMenuListener); @@ -304,8 +298,8 @@ class NotificationSwipeHelper extends SwipeHelper @Override public Animator getViewTranslationAnimator(View v, float target, ValueAnimator.AnimatorUpdateListener listener) { - if (v instanceof ExpandableNotificationRow) { - return ((ExpandableNotificationRow) v).getTranslateViewAnimator(target, listener); + if (v instanceof SwipeableView) { + return ((SwipeableView) v).getTranslateViewAnimator(target, listener); } else { return superGetViewTranslationAnimator(v, target, listener); } @@ -313,15 +307,15 @@ class NotificationSwipeHelper extends SwipeHelper @Override public void setTranslation(View v, float translate) { - if (v instanceof ExpandableNotificationRow) { - ((ExpandableNotificationRow) v).setTranslation(translate); + if (v instanceof SwipeableView) { + ((SwipeableView) v).setTranslation(translate); } } @Override public float getTranslation(View v) { - if (v instanceof ExpandableNotificationRow) { - return ((ExpandableNotificationRow) v).getTranslation(); + if (v instanceof SwipeableView) { + return ((SwipeableView) v).getTranslation(); } else { return 0f; @@ -410,8 +404,8 @@ class NotificationSwipeHelper extends SwipeHelper if (anim != null) { anim.start(); } - } else if (prevMenuExposedView instanceof ExpandableNotificationRow) { - ExpandableNotificationRow row = (ExpandableNotificationRow) prevMenuExposedView; + } else if (prevMenuExposedView instanceof SwipeableView) { + SwipeableView row = (SwipeableView) prevMenuExposedView; if (!row.isRemoved()) { row.resetTranslation(); } 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 e31ee024fa36..a0796060e9d8 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,23 +16,39 @@ 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.statusbar.notification.people.PersonViewModel +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<PeopleHubView>("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) { + ActivatableNotificationView(context, attrs), SwipeableView { private lateinit var contents: ViewGroup private lateinit var personControllers: List<PersonDataListenerImpl> + private var translateAnim: ObjectAnimator? = null + val personViewAdapters: Sequence<DataListener<PersonViewModel?>> get() = personControllers.asSequence() @@ -49,6 +65,34 @@ class PeopleHubView(context: Context, attrs: AttributeSet) : override fun getContentView(): View = contents + override fun hasFinishedInitialization(): Boolean = true + + 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) : DataListener<PersonViewModel?> { 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 4b61064f4a54..9646c01c8c41 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 @@ -195,20 +195,6 @@ public class StackScrollAlgorithm { } } - public static boolean canChildBeDismissed(View v) { - if (!(v instanceof ExpandableNotificationRow)) { - return false; - } - ExpandableNotificationRow row = (ExpandableNotificationRow) v; - if (row.isBlockingHelperShowingAndTranslationFinished()) { - return true; - } - if (row.areGutsExposed() || !row.getEntry().hasFinishedInitialization()) { - return false; - } - return row.canViewBeDismissed(); - } - /** * Updates the dimmed, activated and hiding sensitive states of the children. */ 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 new file mode 100644 index 000000000000..6c6ef61cfdaf --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/SwipeableView.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2019 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.stack; + +import android.animation.Animator; +import android.animation.ValueAnimator; + +import androidx.annotation.Nullable; + +import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; + +/** A View that is swipeable inside of the notification shade. */ +public interface SwipeableView { + + /** Has this view finished initializing? */ + boolean hasFinishedInitialization(); + + /** 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); + + /** Gets the current translation amount. */ + float getTranslation(); + + /** Has this view been removed? */ + boolean isRemoved(); + + /** Resets the swipe translation back to zero state. */ + void resetTranslation(); +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java index 5e6c96313d36..d17c573515f5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java @@ -226,7 +226,7 @@ public class ExpandableNotificationRowTest extends SysuiTestCase { any(NotificationMenuRowPlugin.MenuItem.class)); reset(listener); - mGroupRow.setDismissed(true); + mGroupRow.dismiss(true); mGroupRow.doLongClickCallback(0,0); verify(listener, times(0)).onLongPress(eq(mGroupRow), eq(0), eq(0), any(NotificationMenuRowPlugin.MenuItem.class)); |