Merge "Remove Bubbles from the WM, only after all bubbles finish animating out." into rvc-dev am: e7b00f678c
Change-Id: I313d0a46da6e621a6bb3a931355c11eeae63a498
This commit is contained in:
@@ -185,9 +185,10 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
|
|||||||
// Used to post to main UI thread
|
// Used to post to main UI thread
|
||||||
private Handler mHandler = new Handler();
|
private Handler mHandler = new Handler();
|
||||||
|
|
||||||
/** LayoutParams used to add the BubbleStackView to the window maanger. */
|
/** LayoutParams used to add the BubbleStackView to the window manager. */
|
||||||
private WindowManager.LayoutParams mWmLayoutParams;
|
private WindowManager.LayoutParams mWmLayoutParams;
|
||||||
|
/** Whether or not the BubbleStackView has been added to the WindowManager. */
|
||||||
|
private boolean mAddedToWindowManager = false;
|
||||||
|
|
||||||
// Used for determining view rect for touch interaction
|
// Used for determining view rect for touch interaction
|
||||||
private Rect mTempRect = new Rect();
|
private Rect mTempRect = new Rect();
|
||||||
@@ -595,9 +596,8 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
|
|||||||
if (mStackView == null) {
|
if (mStackView == null) {
|
||||||
mStackView = new BubbleStackView(
|
mStackView = new BubbleStackView(
|
||||||
mContext, mBubbleData, mSurfaceSynchronizer, mFloatingContentCoordinator,
|
mContext, mBubbleData, mSurfaceSynchronizer, mFloatingContentCoordinator,
|
||||||
mSysUiState, mNotificationShadeWindowController);
|
mSysUiState, mNotificationShadeWindowController, this::onAllBubblesAnimatedOut);
|
||||||
mStackView.addView(mBubbleScrim);
|
mStackView.addView(mBubbleScrim);
|
||||||
addToWindowManager();
|
|
||||||
if (mExpandListener != null) {
|
if (mExpandListener != null) {
|
||||||
mStackView.setExpandListener(mExpandListener);
|
mStackView.setExpandListener(mExpandListener);
|
||||||
}
|
}
|
||||||
@@ -605,10 +605,17 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
|
|||||||
mStackView.setUnbubbleConversationCallback(notificationEntry ->
|
mStackView.setUnbubbleConversationCallback(notificationEntry ->
|
||||||
onUserChangedBubble(notificationEntry, false /* shouldBubble */));
|
onUserChangedBubble(notificationEntry, false /* shouldBubble */));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addToWindowManagerMaybe();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Adds the BubbleStackView to the WindowManager. */
|
/** Adds the BubbleStackView to the WindowManager if it's not already there. */
|
||||||
private void addToWindowManager() {
|
private void addToWindowManagerMaybe() {
|
||||||
|
// If the stack is null, or already added, don't add it.
|
||||||
|
if (mStackView == null || mAddedToWindowManager) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
mWmLayoutParams = new WindowManager.LayoutParams(
|
mWmLayoutParams = new WindowManager.LayoutParams(
|
||||||
// Fill the screen so we can use translation animations to position the bubble
|
// Fill the screen so we can use translation animations to position the bubble
|
||||||
// stack. We'll use touchable regions to ignore touches that are not on the bubbles
|
// stack. We'll use touchable regions to ignore touches that are not on the bubbles
|
||||||
@@ -629,9 +636,37 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
|
|||||||
mWmLayoutParams.packageName = mContext.getPackageName();
|
mWmLayoutParams.packageName = mContext.getPackageName();
|
||||||
mWmLayoutParams.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
|
mWmLayoutParams.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
|
||||||
|
|
||||||
mWindowManager.addView(mStackView, mWmLayoutParams);
|
try {
|
||||||
|
mAddedToWindowManager = true;
|
||||||
|
mWindowManager.addView(mStackView, mWmLayoutParams);
|
||||||
|
} catch (IllegalStateException e) {
|
||||||
|
// This means the stack has already been added. This shouldn't happen, since we keep
|
||||||
|
// track of that, but just in case, update the previously added view's layout params.
|
||||||
|
e.printStackTrace();
|
||||||
|
updateWmFlags();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Removes the BubbleStackView from the WindowManager if it's there. */
|
||||||
|
private void removeFromWindowManagerMaybe() {
|
||||||
|
if (!mAddedToWindowManager) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
mAddedToWindowManager = false;
|
||||||
|
mWindowManager.removeView(mStackView);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
// This means the stack has already been removed - it shouldn't happen, but ignore if it
|
||||||
|
// does, since we wanted it removed anyway.
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the BubbleStackView's WindowManager.LayoutParams, and updates the WindowManager with
|
||||||
|
* the new params if the stack has been added.
|
||||||
|
*/
|
||||||
private void updateWmFlags() {
|
private void updateWmFlags() {
|
||||||
if (isStackExpanded()) {
|
if (isStackExpanded()) {
|
||||||
// If we're expanded, we want to be focusable so that the ActivityView can receive focus
|
// If we're expanded, we want to be focusable so that the ActivityView can receive focus
|
||||||
@@ -643,7 +678,25 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
|
|||||||
mWmLayoutParams.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
|
mWmLayoutParams.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
mWindowManager.updateViewLayout(mStackView, mWmLayoutParams);
|
if (mStackView != null && mAddedToWindowManager) {
|
||||||
|
try {
|
||||||
|
mWindowManager.updateViewLayout(mStackView, mWmLayoutParams);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
// If the stack is somehow not there, ignore the attempt to update it.
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called by the BubbleStackView and whenever all bubbles have animated out, and none have been
|
||||||
|
* added in the meantime.
|
||||||
|
*/
|
||||||
|
private void onAllBubblesAnimatedOut() {
|
||||||
|
if (mStackView != null) {
|
||||||
|
mStackView.setVisibility(INVISIBLE);
|
||||||
|
removeFromWindowManagerMaybe();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -833,10 +886,9 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
|
|||||||
}
|
}
|
||||||
|
|
||||||
void updateBubble(NotificationEntry notif, boolean suppressFlyout, boolean showInShade) {
|
void updateBubble(NotificationEntry notif, boolean suppressFlyout, boolean showInShade) {
|
||||||
if (mStackView == null) {
|
// Lazy init stack view when a bubble is created
|
||||||
// Lazy init stack view when a bubble is created
|
ensureStackViewCreated();
|
||||||
ensureStackViewCreated();
|
|
||||||
}
|
|
||||||
// If this is an interruptive notif, mark that it's interrupted
|
// If this is an interruptive notif, mark that it's interrupted
|
||||||
if (notif.getImportance() >= NotificationManager.IMPORTANCE_HIGH) {
|
if (notif.getImportance() >= NotificationManager.IMPORTANCE_HIGH) {
|
||||||
notif.setInterruption();
|
notif.setInterruption();
|
||||||
@@ -1196,11 +1248,15 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
|
|||||||
if (mStackView == null) {
|
if (mStackView == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (mStatusBarStateListener.getCurrentState() == SHADE && hasBubbles()) {
|
|
||||||
// Bubbles only appear in unlocked shade
|
if (mStatusBarStateListener.getCurrentState() != SHADE) {
|
||||||
mStackView.setVisibility(hasBubbles() ? VISIBLE : INVISIBLE);
|
// Bubbles don't appear over the locked shade.
|
||||||
} else if (mStackView != null) {
|
|
||||||
mStackView.setVisibility(INVISIBLE);
|
mStackView.setVisibility(INVISIBLE);
|
||||||
|
} else if (hasBubbles()) {
|
||||||
|
// If we're unlocked, show the stack if we have bubbles. If we don't have bubbles, the
|
||||||
|
// stack will be set to INVISIBLE in onAllBubblesAnimatedOut after the bubbles animate
|
||||||
|
// out.
|
||||||
|
mStackView.setVisibility(VISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
mStackView.updateContentDescription();
|
mStackView.updateContentDescription();
|
||||||
|
|||||||
@@ -656,7 +656,8 @@ public class BubbleStackView extends FrameLayout
|
|||||||
@Nullable SurfaceSynchronizer synchronizer,
|
@Nullable SurfaceSynchronizer synchronizer,
|
||||||
FloatingContentCoordinator floatingContentCoordinator,
|
FloatingContentCoordinator floatingContentCoordinator,
|
||||||
SysUiState sysUiState,
|
SysUiState sysUiState,
|
||||||
NotificationShadeWindowController notificationShadeWindowController) {
|
NotificationShadeWindowController notificationShadeWindowController,
|
||||||
|
Runnable allBubblesAnimatedOutAction) {
|
||||||
super(context);
|
super(context);
|
||||||
|
|
||||||
mBubbleData = data;
|
mBubbleData = data;
|
||||||
@@ -691,11 +692,18 @@ public class BubbleStackView extends FrameLayout
|
|||||||
mExpandedViewPadding = res.getDimensionPixelSize(R.dimen.bubble_expanded_view_padding);
|
mExpandedViewPadding = res.getDimensionPixelSize(R.dimen.bubble_expanded_view_padding);
|
||||||
int elevation = res.getDimensionPixelSize(R.dimen.bubble_elevation);
|
int elevation = res.getDimensionPixelSize(R.dimen.bubble_elevation);
|
||||||
|
|
||||||
|
final Runnable onBubbleAnimatedOut = () -> {
|
||||||
|
if (getBubbleCount() == 0) {
|
||||||
|
allBubblesAnimatedOutAction.run();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
mStackAnimationController = new StackAnimationController(
|
mStackAnimationController = new StackAnimationController(
|
||||||
floatingContentCoordinator, this::getBubbleCount);
|
floatingContentCoordinator, this::getBubbleCount, onBubbleAnimatedOut);
|
||||||
|
|
||||||
mExpandedAnimationController = new ExpandedAnimationController(
|
mExpandedAnimationController = new ExpandedAnimationController(
|
||||||
mDisplaySize, mExpandedViewPadding, res.getConfiguration().orientation);
|
mDisplaySize, mExpandedViewPadding, res.getConfiguration().orientation,
|
||||||
|
onBubbleAnimatedOut);
|
||||||
mSurfaceSynchronizer = synchronizer != null ? synchronizer : DEFAULT_SURFACE_SYNCHRONIZER;
|
mSurfaceSynchronizer = synchronizer != null ? synchronizer : DEFAULT_SURFACE_SYNCHRONIZER;
|
||||||
|
|
||||||
setUpUserEducation();
|
setUpUserEducation();
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import androidx.dynamicanimation.animation.SpringForce;
|
|||||||
|
|
||||||
import com.android.systemui.Interpolators;
|
import com.android.systemui.Interpolators;
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
|
import com.android.systemui.util.animation.PhysicsAnimator;
|
||||||
import com.android.systemui.util.magnetictarget.MagnetizedObject;
|
import com.android.systemui.util.magnetictarget.MagnetizedObject;
|
||||||
|
|
||||||
import com.google.android.collect.Sets;
|
import com.google.android.collect.Sets;
|
||||||
@@ -69,6 +70,10 @@ public class ExpandedAnimationController
|
|||||||
*/
|
*/
|
||||||
private static final float FLING_TO_DISMISS_MIN_VELOCITY = 6000f;
|
private static final float FLING_TO_DISMISS_MIN_VELOCITY = 6000f;
|
||||||
|
|
||||||
|
private final PhysicsAnimator.SpringConfig mAnimateOutSpringConfig =
|
||||||
|
new PhysicsAnimator.SpringConfig(
|
||||||
|
EXPAND_COLLAPSE_ANIM_STIFFNESS, SpringForce.DAMPING_RATIO_NO_BOUNCY);
|
||||||
|
|
||||||
/** Horizontal offset between bubbles, which we need to know to re-stack them. */
|
/** Horizontal offset between bubbles, which we need to know to re-stack them. */
|
||||||
private float mStackOffsetPx;
|
private float mStackOffsetPx;
|
||||||
/** Space between status bar and bubbles in the expanded state. */
|
/** Space between status bar and bubbles in the expanded state. */
|
||||||
@@ -116,10 +121,17 @@ public class ExpandedAnimationController
|
|||||||
|
|
||||||
private int mExpandedViewPadding;
|
private int mExpandedViewPadding;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback to run whenever any bubble is animated out. The BubbleStackView will check if the
|
||||||
|
* end of this animation means we have no bubbles left, and notify the BubbleController.
|
||||||
|
*/
|
||||||
|
private Runnable mOnBubbleAnimatedOutAction;
|
||||||
|
|
||||||
public ExpandedAnimationController(Point displaySize, int expandedViewPadding,
|
public ExpandedAnimationController(Point displaySize, int expandedViewPadding,
|
||||||
int orientation) {
|
int orientation, Runnable onBubbleAnimatedOutAction) {
|
||||||
updateResources(orientation, displaySize);
|
updateResources(orientation, displaySize);
|
||||||
mExpandedViewPadding = expandedViewPadding;
|
mExpandedViewPadding = expandedViewPadding;
|
||||||
|
mOnBubbleAnimatedOutAction = onBubbleAnimatedOutAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -355,8 +367,8 @@ public class ExpandedAnimationController
|
|||||||
}
|
}
|
||||||
animationForChild(bubble)
|
animationForChild(bubble)
|
||||||
.withStiffness(SpringForce.STIFFNESS_HIGH)
|
.withStiffness(SpringForce.STIFFNESS_HIGH)
|
||||||
.scaleX(1.1f)
|
.scaleX(0f)
|
||||||
.scaleY(1.1f)
|
.scaleY(0f)
|
||||||
.translationY(bubble.getTranslationY() + translationYBy)
|
.translationY(bubble.getTranslationY() + translationYBy)
|
||||||
.alpha(0f, after)
|
.alpha(0f, after)
|
||||||
.start();
|
.start();
|
||||||
@@ -500,18 +512,17 @@ public class ExpandedAnimationController
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
void onChildRemoved(View child, int index, Runnable finishRemoval) {
|
void onChildRemoved(View child, int index, Runnable finishRemoval) {
|
||||||
final PhysicsAnimationLayout.PhysicsPropertyAnimator animator = animationForChild(child);
|
|
||||||
|
|
||||||
// If we're removing the dragged-out bubble, that means it got dismissed.
|
// If we're removing the dragged-out bubble, that means it got dismissed.
|
||||||
if (child.equals(getDraggedOutBubble())) {
|
if (child.equals(getDraggedOutBubble())) {
|
||||||
mMagnetizedBubbleDraggingOut = null;
|
mMagnetizedBubbleDraggingOut = null;
|
||||||
finishRemoval.run();
|
finishRemoval.run();
|
||||||
|
mOnBubbleAnimatedOutAction.run();
|
||||||
} else {
|
} else {
|
||||||
animator.alpha(0f, finishRemoval /* endAction */)
|
PhysicsAnimator.getInstance(child)
|
||||||
.withStiffness(SpringForce.STIFFNESS_HIGH)
|
.spring(DynamicAnimation.ALPHA, 0f)
|
||||||
.withDampingRatio(SpringForce.DAMPING_RATIO_NO_BOUNCY)
|
.spring(DynamicAnimation.SCALE_X, 0f, mAnimateOutSpringConfig)
|
||||||
.scaleX(1.1f)
|
.spring(DynamicAnimation.SCALE_Y, 0f, mAnimateOutSpringConfig)
|
||||||
.scaleY(1.1f)
|
.withEndActions(finishRemoval, mOnBubbleAnimatedOutAction)
|
||||||
.start();
|
.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -74,6 +74,10 @@ public class StackAnimationController extends
|
|||||||
private static final int FLING_FOLLOW_STIFFNESS = 20000;
|
private static final int FLING_FOLLOW_STIFFNESS = 20000;
|
||||||
public static final float DEFAULT_BOUNCINESS = 0.9f;
|
public static final float DEFAULT_BOUNCINESS = 0.9f;
|
||||||
|
|
||||||
|
private final PhysicsAnimator.SpringConfig mAnimateOutSpringConfig =
|
||||||
|
new PhysicsAnimator.SpringConfig(
|
||||||
|
ANIMATE_IN_STIFFNESS, SpringForce.DAMPING_RATIO_NO_BOUNCY);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Friction applied to fling animations. Since the stack must land on one of the sides of the
|
* Friction applied to fling animations. Since the stack must land on one of the sides of the
|
||||||
* screen, we want less friction horizontally so that the stack has a better chance of making it
|
* screen, we want less friction horizontally so that the stack has a better chance of making it
|
||||||
@@ -248,12 +252,19 @@ public class StackAnimationController extends
|
|||||||
/** Returns the number of 'real' bubbles (excluding the overflow bubble). */
|
/** Returns the number of 'real' bubbles (excluding the overflow bubble). */
|
||||||
private IntSupplier mBubbleCountSupplier;
|
private IntSupplier mBubbleCountSupplier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback to run whenever any bubble is animated out. The BubbleStackView will check if the
|
||||||
|
* end of this animation means we have no bubbles left, and notify the BubbleController.
|
||||||
|
*/
|
||||||
|
private Runnable mOnBubbleAnimatedOutAction;
|
||||||
|
|
||||||
public StackAnimationController(
|
public StackAnimationController(
|
||||||
FloatingContentCoordinator floatingContentCoordinator,
|
FloatingContentCoordinator floatingContentCoordinator,
|
||||||
IntSupplier bubbleCountSupplier) {
|
IntSupplier bubbleCountSupplier,
|
||||||
|
Runnable onBubbleAnimatedOutAction) {
|
||||||
mFloatingContentCoordinator = floatingContentCoordinator;
|
mFloatingContentCoordinator = floatingContentCoordinator;
|
||||||
mBubbleCountSupplier = bubbleCountSupplier;
|
mBubbleCountSupplier = bubbleCountSupplier;
|
||||||
|
mOnBubbleAnimatedOutAction = onBubbleAnimatedOutAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -652,8 +663,8 @@ public class StackAnimationController extends
|
|||||||
public void animateStackDismissal(float translationYBy, Runnable after) {
|
public void animateStackDismissal(float translationYBy, Runnable after) {
|
||||||
animationsForChildrenFromIndex(0, (index, animation) ->
|
animationsForChildrenFromIndex(0, (index, animation) ->
|
||||||
animation
|
animation
|
||||||
.scaleX(0.5f)
|
.scaleX(0f)
|
||||||
.scaleY(0.5f)
|
.scaleY(0f)
|
||||||
.alpha(0f)
|
.alpha(0f)
|
||||||
.translationY(
|
.translationY(
|
||||||
mLayout.getChildAt(index).getTranslationY() + translationYBy)
|
mLayout.getChildAt(index).getTranslationY() + translationYBy)
|
||||||
@@ -760,13 +771,11 @@ public class StackAnimationController extends
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
void onChildRemoved(View child, int index, Runnable finishRemoval) {
|
void onChildRemoved(View child, int index, Runnable finishRemoval) {
|
||||||
// Animate the removing view in the opposite direction of the stack.
|
PhysicsAnimator.getInstance(child)
|
||||||
final float xOffset = getOffsetForChainedPropertyAnimation(DynamicAnimation.TRANSLATION_X);
|
.spring(DynamicAnimation.ALPHA, 0f)
|
||||||
animationForChild(child)
|
.spring(DynamicAnimation.SCALE_X, 0f, mAnimateOutSpringConfig)
|
||||||
.alpha(0f, finishRemoval /* after */)
|
.spring(DynamicAnimation.SCALE_Y, 0f, mAnimateOutSpringConfig)
|
||||||
.scaleX(ANIMATE_IN_STARTING_SCALE)
|
.withEndActions(finishRemoval, mOnBubbleAnimatedOutAction)
|
||||||
.scaleY(ANIMATE_IN_STARTING_SCALE)
|
|
||||||
.translationX(mStackPosition.x - (-xOffset * ANIMATE_TRANSLATION_FACTOR))
|
|
||||||
.start();
|
.start();
|
||||||
|
|
||||||
// If there are other bubbles, pull them into the correct position.
|
// If there are other bubbles, pull them into the correct position.
|
||||||
|
|||||||
@@ -49,11 +49,13 @@ public class ExpandedAnimationControllerTest extends PhysicsAnimationLayoutTestC
|
|||||||
private int mOrientation = Configuration.ORIENTATION_PORTRAIT;
|
private int mOrientation = Configuration.ORIENTATION_PORTRAIT;
|
||||||
private float mLauncherGridDiff = 30f;
|
private float mLauncherGridDiff = 30f;
|
||||||
|
|
||||||
|
private Runnable mOnBubbleAnimatedOutAction = Mockito.mock(Runnable.class);
|
||||||
|
|
||||||
@Spy
|
@Spy
|
||||||
private ExpandedAnimationController mExpandedController =
|
private ExpandedAnimationController mExpandedController =
|
||||||
new ExpandedAnimationController(
|
new ExpandedAnimationController(
|
||||||
new Point(mDisplayWidth, mDisplayHeight) /* displaySize */,
|
new Point(mDisplayWidth, mDisplayHeight) /* displaySize */,
|
||||||
mExpandedViewPadding, mOrientation);
|
mExpandedViewPadding, mOrientation, mOnBubbleAnimatedOutAction);
|
||||||
|
|
||||||
private int mStackOffset;
|
private int mStackOffset;
|
||||||
private float mBubblePaddingTop;
|
private float mBubblePaddingTop;
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ import org.junit.Ignore;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
@@ -66,7 +67,7 @@ public class StackAnimationControllerTest extends PhysicsAnimationLayoutTestCase
|
|||||||
public int getAsInt() {
|
public int getAsInt() {
|
||||||
return mLayout.getChildCount();
|
return mLayout.getChildCount();
|
||||||
}
|
}
|
||||||
}));
|
}, Mockito.mock(Runnable.class)));
|
||||||
mLayout.setActiveController(mStackController);
|
mLayout.setActiveController(mStackController);
|
||||||
addOneMoreThanBubbleLimitBubbles();
|
addOneMoreThanBubbleLimitBubbles();
|
||||||
mStackOffset = mLayout.getResources().getDimensionPixelSize(R.dimen.bubble_stack_offset);
|
mStackOffset = mLayout.getResources().getDimensionPixelSize(R.dimen.bubble_stack_offset);
|
||||||
@@ -303,8 +304,9 @@ public class StackAnimationControllerTest extends PhysicsAnimationLayoutTestCase
|
|||||||
private class TestableStackController extends StackAnimationController {
|
private class TestableStackController extends StackAnimationController {
|
||||||
TestableStackController(
|
TestableStackController(
|
||||||
FloatingContentCoordinator floatingContentCoordinator,
|
FloatingContentCoordinator floatingContentCoordinator,
|
||||||
IntSupplier bubbleCountSupplier) {
|
IntSupplier bubbleCountSupplier,
|
||||||
super(floatingContentCoordinator, bubbleCountSupplier);
|
Runnable onBubbleAnimatedOutAction) {
|
||||||
|
super(floatingContentCoordinator, bubbleCountSupplier, onBubbleAnimatedOutAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Reference in New Issue
Block a user