1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17 package com.android.systemui.statusbar.notification.stack; 18 19 import androidx.annotation.NonNull; 20 21 import com.android.systemui.Dumpable; 22 import com.android.systemui.dagger.SysUISingleton; 23 import com.android.systemui.dump.DumpManager; 24 import com.android.systemui.statusbar.notification.Roundable; 25 import com.android.systemui.statusbar.notification.SourceType; 26 import com.android.systemui.statusbar.notification.row.ExpandableView; 27 28 import java.io.PrintWriter; 29 import java.util.HashSet; 30 31 import javax.inject.Inject; 32 33 /** 34 * A class that manages the roundness for notification views 35 */ 36 @SysUISingleton 37 public class NotificationRoundnessManager implements Dumpable { 38 39 private static final String TAG = "NotificationRoundnessManager"; 40 private static final SourceType DISMISS_ANIMATION = SourceType.from("DismissAnimation"); 41 42 private final DumpManager mDumpManager; 43 private HashSet<ExpandableView> mAnimatedChildren; 44 private boolean mRoundForPulsingViews; 45 private boolean mIsClearAllInProgress; 46 47 private ExpandableView mSwipedView = null; 48 private Roundable mViewBeforeSwipedView = null; 49 private Roundable mViewAfterSwipedView = null; 50 51 @Inject NotificationRoundnessManager(DumpManager dumpManager)52 NotificationRoundnessManager(DumpManager dumpManager) { 53 mDumpManager = dumpManager; 54 mDumpManager.registerDumpable(TAG, this); 55 } 56 57 @Override dump(@onNull PrintWriter pw, @NonNull String[] args)58 public void dump(@NonNull PrintWriter pw, @NonNull String[] args) { 59 pw.println("roundForPulsingViews=" + mRoundForPulsingViews); 60 pw.println("isClearAllInProgress=" + mIsClearAllInProgress); 61 } 62 isViewAffectedBySwipe(ExpandableView expandableView)63 public boolean isViewAffectedBySwipe(ExpandableView expandableView) { 64 return expandableView != null 65 && (expandableView == mSwipedView 66 || expandableView == mViewBeforeSwipedView 67 || expandableView == mViewAfterSwipedView); 68 } 69 setViewsAffectedBySwipe( Roundable viewBefore, ExpandableView viewSwiped, Roundable viewAfter)70 void setViewsAffectedBySwipe( 71 Roundable viewBefore, 72 ExpandableView viewSwiped, 73 Roundable viewAfter) { 74 // This method caches a new set of current View targets and reset the roundness of the old 75 // View targets (if any) to 0f. 76 HashSet<Roundable> oldViews = new HashSet<>(); 77 if (mViewBeforeSwipedView != null) oldViews.add(mViewBeforeSwipedView); 78 if (mSwipedView != null) oldViews.add(mSwipedView); 79 if (mViewAfterSwipedView != null) oldViews.add(mViewAfterSwipedView); 80 81 mViewBeforeSwipedView = viewBefore; 82 if (viewBefore != null) { 83 oldViews.remove(viewBefore); 84 } 85 86 mSwipedView = viewSwiped; 87 if (viewSwiped != null) { 88 oldViews.remove(viewSwiped); 89 } 90 91 mViewAfterSwipedView = viewAfter; 92 if (viewAfter != null) { 93 oldViews.remove(viewAfter); 94 } 95 96 // After setting the current Views, reset the views that are still present in the set. 97 for (Roundable oldView : oldViews) { 98 oldView.requestRoundnessReset(DISMISS_ANIMATION); 99 } 100 } 101 setRoundnessForAffectedViews(float roundness)102 void setRoundnessForAffectedViews(float roundness) { 103 if (mViewBeforeSwipedView != null) { 104 mViewBeforeSwipedView.requestBottomRoundness(roundness, DISMISS_ANIMATION); 105 } 106 107 if (mSwipedView != null) { 108 mSwipedView.requestRoundness(roundness, roundness, DISMISS_ANIMATION); 109 } 110 111 if (mViewAfterSwipedView != null) { 112 mViewAfterSwipedView.requestTopRoundness(roundness, DISMISS_ANIMATION); 113 } 114 } 115 setRoundnessForAffectedViews(float roundness, boolean animate)116 void setRoundnessForAffectedViews(float roundness, boolean animate) { 117 if (mViewBeforeSwipedView != null) { 118 mViewBeforeSwipedView.requestBottomRoundness(roundness, DISMISS_ANIMATION, animate); 119 } 120 121 if (mSwipedView != null) { 122 mSwipedView.requestRoundness(roundness, roundness, DISMISS_ANIMATION, animate); 123 } 124 125 if (mViewAfterSwipedView != null) { 126 mViewAfterSwipedView.requestTopRoundness(roundness, DISMISS_ANIMATION, animate); 127 } 128 } 129 setClearAllInProgress(boolean isClearingAll)130 void setClearAllInProgress(boolean isClearingAll) { 131 mIsClearAllInProgress = isClearingAll; 132 } 133 134 /** 135 * Check if "Clear all" notifications is in progress. 136 */ isClearAllInProgress()137 public boolean isClearAllInProgress() { 138 return mIsClearAllInProgress; 139 } 140 141 /** 142 * Check if we can request the `Pulsing` roundness for notification. 143 */ shouldRoundNotificationPulsing()144 public boolean shouldRoundNotificationPulsing() { 145 return mRoundForPulsingViews; 146 } 147 setAnimatedChildren(HashSet<ExpandableView> animatedChildren)148 public void setAnimatedChildren(HashSet<ExpandableView> animatedChildren) { 149 mAnimatedChildren = animatedChildren; 150 } 151 152 /** 153 * Check if the view should be animated 154 * @param view target view 155 * @return true, if is in the AnimatedChildren set 156 */ isAnimatedChild(ExpandableView view)157 public boolean isAnimatedChild(ExpandableView view) { 158 return mAnimatedChildren.contains(view); 159 } 160 setShouldRoundPulsingViews(boolean shouldRoundPulsingViews)161 public void setShouldRoundPulsingViews(boolean shouldRoundPulsingViews) { 162 mRoundForPulsingViews = shouldRoundPulsingViews; 163 } 164 isSwipedViewSet()165 public boolean isSwipedViewSet() { 166 return mSwipedView != null; 167 } 168 } 169