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 requires you to change the roundness of the current View targets and reset 75 // the roundness of the old View targets (if any) to 0f. 76 // To avoid conflicts, it generates a set of old Views and removes the current Views 77 // from this set. 78 HashSet<Roundable> oldViews = new HashSet<>(); 79 if (mViewBeforeSwipedView != null) oldViews.add(mViewBeforeSwipedView); 80 if (mSwipedView != null) oldViews.add(mSwipedView); 81 if (mViewAfterSwipedView != null) oldViews.add(mViewAfterSwipedView); 82 83 mViewBeforeSwipedView = viewBefore; 84 if (viewBefore != null) { 85 oldViews.remove(viewBefore); 86 viewBefore.requestRoundness(/* top = */ 0f, /* bottom = */ 1f, DISMISS_ANIMATION); 87 } 88 89 mSwipedView = viewSwiped; 90 if (viewSwiped != null) { 91 oldViews.remove(viewSwiped); 92 viewSwiped.requestRoundness(/* top = */ 1f, /* bottom = */ 1f, DISMISS_ANIMATION); 93 } 94 95 mViewAfterSwipedView = viewAfter; 96 if (viewAfter != null) { 97 oldViews.remove(viewAfter); 98 viewAfter.requestRoundness(/* top = */ 1f, /* bottom = */ 0f, DISMISS_ANIMATION); 99 } 100 101 // After setting the current Views, reset the views that are still present in the set. 102 for (Roundable oldView : oldViews) { 103 oldView.requestRoundnessReset(DISMISS_ANIMATION); 104 } 105 } 106 setClearAllInProgress(boolean isClearingAll)107 void setClearAllInProgress(boolean isClearingAll) { 108 mIsClearAllInProgress = isClearingAll; 109 } 110 111 /** 112 * Check if "Clear all" notifications is in progress. 113 */ isClearAllInProgress()114 public boolean isClearAllInProgress() { 115 return mIsClearAllInProgress; 116 } 117 118 /** 119 * Check if we can request the `Pulsing` roundness for notification. 120 */ shouldRoundNotificationPulsing()121 public boolean shouldRoundNotificationPulsing() { 122 return mRoundForPulsingViews; 123 } 124 setAnimatedChildren(HashSet<ExpandableView> animatedChildren)125 public void setAnimatedChildren(HashSet<ExpandableView> animatedChildren) { 126 mAnimatedChildren = animatedChildren; 127 } 128 129 /** 130 * Check if the view should be animated 131 * @param view target view 132 * @return true, if is in the AnimatedChildren set 133 */ isAnimatedChild(ExpandableView view)134 public boolean isAnimatedChild(ExpandableView view) { 135 return mAnimatedChildren.contains(view); 136 } 137 setShouldRoundPulsingViews(boolean shouldRoundPulsingViews)138 public void setShouldRoundPulsingViews(boolean shouldRoundPulsingViews) { 139 mRoundForPulsingViews = shouldRoundPulsingViews; 140 } 141 } 142