Loading libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewTest.kt +93 −4 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.wm.shell.bubbles.bar import android.app.ActivityManager import android.content.ComponentName import android.content.Context import android.content.pm.ShortcutInfo import android.graphics.Insets Loading @@ -24,6 +25,7 @@ import android.graphics.Rect import android.view.LayoutInflater import android.view.View import android.view.WindowManager import android.widget.FrameLayout import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest Loading Loading @@ -110,9 +112,9 @@ class BubbleBarExpandedViewTest { regionSamplingProvider = TestRegionSamplingProvider() bubbleExpandedView = (inflater.inflate( bubbleExpandedView = inflater.inflate( R.layout.bubble_bar_expanded_view, null, false /* attachToRoot */ ) as BubbleBarExpandedView) ) as BubbleBarExpandedView bubbleExpandedView.initialize( expandedViewManager, positioner, Loading @@ -124,11 +126,11 @@ class BubbleBarExpandedViewTest { regionSamplingProvider, ) getInstrumentation().runOnMainSync(Runnable { getInstrumentation().runOnMainSync { bubbleExpandedView.onAttachedToWindow() // Helper should be created once attached to window testableRegionSamplingHelper = regionSamplingProvider!!.helper }) } bubble = Bubble( "key", Loading Loading @@ -254,6 +256,93 @@ class BubbleBarExpandedViewTest { assertThat(uiEventLoggerFake.logs[0]).hasBubbleInfo(bubble) } @Test fun animateExpansion_waitsUntilTaskCreated() { var animated = false bubbleExpandedView.animateExpansionWhenTaskViewVisible { animated = true } assertThat(animated).isFalse() bubbleExpandedView.onTaskCreated() assertThat(animated).isTrue() } @Test fun animateExpansion_taskViewAttachedAndVisible() { val inflater = LayoutInflater.from(context) val expandedView = inflater.inflate( R.layout.bubble_bar_expanded_view, null, false /* attachToRoot */ ) as BubbleBarExpandedView val taskView = FakeBubbleTaskViewFactory().create() val taskViewParent = FrameLayout(context) taskViewParent.addView(taskView.taskView) taskView.listener.onTaskCreated(666, ComponentName(context, "BubbleBarExpandedViewTest")) assertThat(taskView.isVisible).isTrue() expandedView.initialize( expandedViewManager, positioner, BubbleLogger(uiEventLoggerFake), false /* isOverflow */, taskView, mainExecutor, bgExecutor, regionSamplingProvider, ) // the task view should be removed from its parent assertThat(taskView.taskView.parent).isNull() var animated = false expandedView.animateExpansionWhenTaskViewVisible { animated = true } assertThat(animated).isFalse() // send an invisible signal to simulate the surface getting destroyed expandedView.onContentVisibilityChanged(false) // send a visible signal to simulate a new surface getting created expandedView.onContentVisibilityChanged(true) assertThat(taskView.taskView.parent).isEqualTo(expandedView) assertThat(animated).isTrue() } @Test fun animateExpansion_taskViewAttachedAndInvisible() { val inflater = LayoutInflater.from(context) val expandedView = inflater.inflate( R.layout.bubble_bar_expanded_view, null, false /* attachToRoot */ ) as BubbleBarExpandedView val taskView = FakeBubbleTaskViewFactory().create() val taskViewParent = FrameLayout(context) taskViewParent.addView(taskView.taskView) taskView.listener.onTaskCreated(666, ComponentName(context, "BubbleBarExpandedViewTest")) assertThat(taskView.isVisible).isTrue() taskView.listener.onTaskVisibilityChanged(666, false) assertThat(taskView.isVisible).isFalse() expandedView.initialize( expandedViewManager, positioner, BubbleLogger(uiEventLoggerFake), false /* isOverflow */, taskView, mainExecutor, bgExecutor, regionSamplingProvider, ) // the task view should be added to the expanded view assertThat(taskView.taskView.parent).isEqualTo(expandedView) var animated = false expandedView.animateExpansionWhenTaskViewVisible { animated = true } assertThat(animated).isFalse() // send a visible signal to simulate a new surface getting created expandedView.onContentVisibilityChanged(true) assertThat(animated).isTrue() } private fun BubbleBarExpandedView.menuView(): BubbleBarMenuView { return findViewByPredicate { it is BubbleBarMenuView } } Loading libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerViewTest.kt +2 −0 Original line number Diff line number Diff line Loading @@ -253,6 +253,7 @@ class BubbleBarLayerViewTest { getInstrumentation().runOnMainSync { bubbleBarLayerView.showExpandedView(bubble) bubble.bubbleBarExpandedView!!.onContentVisibilityChanged(true) } waitForExpandedViewAnimation() Loading @@ -276,6 +277,7 @@ class BubbleBarLayerViewTest { getInstrumentation().runOnMainSync { bubbleBarLayerView.showExpandedView(bubble) bubble.bubbleBarExpandedView!!.onContentVisibilityChanged(true) } waitForExpandedViewAnimation() Loading libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTaskView.kt +13 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,16 @@ class BubbleTaskView(val taskView: TaskView, executor: Executor) { var componentName: ComponentName? = null private set /** * Whether the task view is visible and has a surface. Note that this does not check the alpha * value of the task view. * * When this is `true` it is safe to start showing the task view. Otherwise if this is `false` * callers should wait for it to be visible which will be indicated either by a call to * [TaskView.Listener.onTaskCreated] or [TaskView.Listener.onTaskVisibilityChanged]. */ var isVisible = false private set /** [TaskView.Listener] for users of this class. */ var delegateListener: TaskView.Listener? = null Loading @@ -61,9 +71,12 @@ class BubbleTaskView(val taskView: TaskView, executor: Executor) { this@BubbleTaskView.taskId = taskId isCreated = true componentName = name // when the task is created it is visible isVisible = true } override fun onTaskVisibilityChanged(taskId: Int, visible: Boolean) { this@BubbleTaskView.isVisible = visible delegateListener?.onTaskVisibilityChanged(taskId, visible) } Loading libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java +24 −22 Original line number Diff line number Diff line Loading @@ -161,6 +161,7 @@ public class BubbleBarAnimationHelper { updateExpandedView(); bbev.setAnimating(true); bbev.setSurfaceZOrderedOnTop(true); bbev.setContentVisibility(false); bbev.setAlpha(0f); bbev.setTaskViewAlpha(0f); Loading @@ -171,6 +172,7 @@ public class BubbleBarAnimationHelper { bbev.setAnimationMatrix(mExpandedViewContainerMatrix); bbev.animateExpansionWhenTaskViewVisible(() -> { mExpandedViewAlphaAnimator.start(); PhysicsAnimator.getInstance(mExpandedViewContainerMatrix).cancel(); Loading @@ -187,12 +189,12 @@ public class BubbleBarAnimationHelper { .withEndActions(() -> { bbev.setAnimationMatrix(null); updateExpandedView(); bbev.setSurfaceZOrderedOnTop(false); if (afterAnimation != null) { afterAnimation.run(); } }) .start(); }); } /** Loading libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java +79 −9 Original line number Diff line number Diff line Loading @@ -131,6 +131,11 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView /** Current corner radius */ private float mCurrentCornerRadius = 0f; /** A runnable to start the expansion animation as soon as the task view is made visible. */ @Nullable private Runnable mAnimateExpansion = null; private TaskViewVisibilityState mVisibilityState = TaskViewVisibilityState.INVISIBLE; /** * Whether we want the {@code TaskView}'s content to be visible (alpha = 1f). If * {@link #mIsAnimating} is true, this may not reflect the {@code TaskView}'s actual alpha Loading @@ -140,6 +145,18 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView private boolean mIsAnimating; private boolean mIsDragging; /** An enum value that tracks the visibility state of the task view */ private enum TaskViewVisibilityState { /** The task view is going away, and we're waiting for the surface to be destroyed. */ PENDING_INVISIBLE, /** The task view is invisible and does not have a surface. */ INVISIBLE, /** The task view is in the process of being added to a surface. */ PENDING_VISIBLE, /** The task view is visible and has a surface. */ VISIBLE } public BubbleBarExpandedView(Context context) { this(context, null); } Loading Loading @@ -206,16 +223,27 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView mBubbleTaskViewHelper = new BubbleTaskViewHelper(mContext, expandedViewManager, /* listener= */ this, bubbleTaskView, /* viewParent= */ this); // if the task view is already attached to a parent we need to remove it if (mTaskView.getParent() != null) { // it's possible that the task view is visible, e.g. if we're unfolding, in which // case removing it will trigger a visibility change. we have to wait for that // signal before we can add it to this expanded view, otherwise the signal will be // incorrect because the task view will have a surface. // if the task view is not visible, then it has no surface and removing it will not // trigger any visibility change signals. if (bubbleTaskView.isVisible()) { mVisibilityState = TaskViewVisibilityState.PENDING_INVISIBLE; } ((ViewGroup) mTaskView.getParent()).removeView(mTaskView); } FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT); addView(mTaskView, lp); mTaskView.setEnableSurfaceClipping(true); mTaskView.setCornerRadius(mCurrentCornerRadius); mTaskView.setVisibility(VISIBLE); mTaskView.setCaptionInsets(Insets.of(0, mCaptionHeight, 0, 0)); // if we're invisible it's safe to setup the task view and then await on the visibility // signal. if (mVisibilityState == TaskViewVisibilityState.INVISIBLE) { mVisibilityState = TaskViewVisibilityState.PENDING_VISIBLE; setupTaskView(); } // Handle view needs to draw on top of task view. bringChildToFront(mHandleView); Loading Loading @@ -269,6 +297,16 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView }); } private void setupTaskView() { FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT); addView(mTaskView, lp); mTaskView.setEnableSurfaceClipping(true); mTaskView.setCornerRadius(mCurrentCornerRadius); mTaskView.setVisibility(VISIBLE); mTaskView.setCaptionInsets(Insets.of(0, mCaptionHeight, 0, 0)); } public BubbleBarHandleView getHandleView() { return mHandleView; } Loading Loading @@ -326,15 +364,28 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView @Override public void onTaskCreated() { setContentVisibility(true); if (mTaskView != null) { mTaskView.setAlpha(0); } if (mListener != null) { mListener.onTaskCreated(); } // when the task is created we're visible onTaskViewVisible(); } @Override public void onContentVisibilityChanged(boolean visible) { setContentVisibility(visible); if (mVisibilityState == TaskViewVisibilityState.PENDING_INVISIBLE && !visible) { // the surface is now destroyed. set up the task view and wait for the visibility // signal. mVisibilityState = TaskViewVisibilityState.PENDING_VISIBLE; setupTaskView(); return; } if (visible) { onTaskViewVisible(); } } @Override Loading @@ -350,6 +401,25 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView mListener.onBackPressed(); } void animateExpansionWhenTaskViewVisible(Runnable animateExpansion) { if (mVisibilityState == TaskViewVisibilityState.VISIBLE) { animateExpansion.run(); } else { mAnimateExpansion = animateExpansion; } } private void onTaskViewVisible() { // if we're waiting to be visible, start the expansion animation if it's pending. if (mVisibilityState == TaskViewVisibilityState.PENDING_VISIBLE) { mVisibilityState = TaskViewVisibilityState.VISIBLE; if (mAnimateExpansion != null) { mAnimateExpansion.run(); mAnimateExpansion = null; } } } /** * Set whether this view is currently being dragged. * Loading Loading
libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewTest.kt +93 −4 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.wm.shell.bubbles.bar import android.app.ActivityManager import android.content.ComponentName import android.content.Context import android.content.pm.ShortcutInfo import android.graphics.Insets Loading @@ -24,6 +25,7 @@ import android.graphics.Rect import android.view.LayoutInflater import android.view.View import android.view.WindowManager import android.widget.FrameLayout import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest Loading Loading @@ -110,9 +112,9 @@ class BubbleBarExpandedViewTest { regionSamplingProvider = TestRegionSamplingProvider() bubbleExpandedView = (inflater.inflate( bubbleExpandedView = inflater.inflate( R.layout.bubble_bar_expanded_view, null, false /* attachToRoot */ ) as BubbleBarExpandedView) ) as BubbleBarExpandedView bubbleExpandedView.initialize( expandedViewManager, positioner, Loading @@ -124,11 +126,11 @@ class BubbleBarExpandedViewTest { regionSamplingProvider, ) getInstrumentation().runOnMainSync(Runnable { getInstrumentation().runOnMainSync { bubbleExpandedView.onAttachedToWindow() // Helper should be created once attached to window testableRegionSamplingHelper = regionSamplingProvider!!.helper }) } bubble = Bubble( "key", Loading Loading @@ -254,6 +256,93 @@ class BubbleBarExpandedViewTest { assertThat(uiEventLoggerFake.logs[0]).hasBubbleInfo(bubble) } @Test fun animateExpansion_waitsUntilTaskCreated() { var animated = false bubbleExpandedView.animateExpansionWhenTaskViewVisible { animated = true } assertThat(animated).isFalse() bubbleExpandedView.onTaskCreated() assertThat(animated).isTrue() } @Test fun animateExpansion_taskViewAttachedAndVisible() { val inflater = LayoutInflater.from(context) val expandedView = inflater.inflate( R.layout.bubble_bar_expanded_view, null, false /* attachToRoot */ ) as BubbleBarExpandedView val taskView = FakeBubbleTaskViewFactory().create() val taskViewParent = FrameLayout(context) taskViewParent.addView(taskView.taskView) taskView.listener.onTaskCreated(666, ComponentName(context, "BubbleBarExpandedViewTest")) assertThat(taskView.isVisible).isTrue() expandedView.initialize( expandedViewManager, positioner, BubbleLogger(uiEventLoggerFake), false /* isOverflow */, taskView, mainExecutor, bgExecutor, regionSamplingProvider, ) // the task view should be removed from its parent assertThat(taskView.taskView.parent).isNull() var animated = false expandedView.animateExpansionWhenTaskViewVisible { animated = true } assertThat(animated).isFalse() // send an invisible signal to simulate the surface getting destroyed expandedView.onContentVisibilityChanged(false) // send a visible signal to simulate a new surface getting created expandedView.onContentVisibilityChanged(true) assertThat(taskView.taskView.parent).isEqualTo(expandedView) assertThat(animated).isTrue() } @Test fun animateExpansion_taskViewAttachedAndInvisible() { val inflater = LayoutInflater.from(context) val expandedView = inflater.inflate( R.layout.bubble_bar_expanded_view, null, false /* attachToRoot */ ) as BubbleBarExpandedView val taskView = FakeBubbleTaskViewFactory().create() val taskViewParent = FrameLayout(context) taskViewParent.addView(taskView.taskView) taskView.listener.onTaskCreated(666, ComponentName(context, "BubbleBarExpandedViewTest")) assertThat(taskView.isVisible).isTrue() taskView.listener.onTaskVisibilityChanged(666, false) assertThat(taskView.isVisible).isFalse() expandedView.initialize( expandedViewManager, positioner, BubbleLogger(uiEventLoggerFake), false /* isOverflow */, taskView, mainExecutor, bgExecutor, regionSamplingProvider, ) // the task view should be added to the expanded view assertThat(taskView.taskView.parent).isEqualTo(expandedView) var animated = false expandedView.animateExpansionWhenTaskViewVisible { animated = true } assertThat(animated).isFalse() // send a visible signal to simulate a new surface getting created expandedView.onContentVisibilityChanged(true) assertThat(animated).isTrue() } private fun BubbleBarExpandedView.menuView(): BubbleBarMenuView { return findViewByPredicate { it is BubbleBarMenuView } } Loading
libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerViewTest.kt +2 −0 Original line number Diff line number Diff line Loading @@ -253,6 +253,7 @@ class BubbleBarLayerViewTest { getInstrumentation().runOnMainSync { bubbleBarLayerView.showExpandedView(bubble) bubble.bubbleBarExpandedView!!.onContentVisibilityChanged(true) } waitForExpandedViewAnimation() Loading @@ -276,6 +277,7 @@ class BubbleBarLayerViewTest { getInstrumentation().runOnMainSync { bubbleBarLayerView.showExpandedView(bubble) bubble.bubbleBarExpandedView!!.onContentVisibilityChanged(true) } waitForExpandedViewAnimation() Loading
libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTaskView.kt +13 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,16 @@ class BubbleTaskView(val taskView: TaskView, executor: Executor) { var componentName: ComponentName? = null private set /** * Whether the task view is visible and has a surface. Note that this does not check the alpha * value of the task view. * * When this is `true` it is safe to start showing the task view. Otherwise if this is `false` * callers should wait for it to be visible which will be indicated either by a call to * [TaskView.Listener.onTaskCreated] or [TaskView.Listener.onTaskVisibilityChanged]. */ var isVisible = false private set /** [TaskView.Listener] for users of this class. */ var delegateListener: TaskView.Listener? = null Loading @@ -61,9 +71,12 @@ class BubbleTaskView(val taskView: TaskView, executor: Executor) { this@BubbleTaskView.taskId = taskId isCreated = true componentName = name // when the task is created it is visible isVisible = true } override fun onTaskVisibilityChanged(taskId: Int, visible: Boolean) { this@BubbleTaskView.isVisible = visible delegateListener?.onTaskVisibilityChanged(taskId, visible) } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java +24 −22 Original line number Diff line number Diff line Loading @@ -161,6 +161,7 @@ public class BubbleBarAnimationHelper { updateExpandedView(); bbev.setAnimating(true); bbev.setSurfaceZOrderedOnTop(true); bbev.setContentVisibility(false); bbev.setAlpha(0f); bbev.setTaskViewAlpha(0f); Loading @@ -171,6 +172,7 @@ public class BubbleBarAnimationHelper { bbev.setAnimationMatrix(mExpandedViewContainerMatrix); bbev.animateExpansionWhenTaskViewVisible(() -> { mExpandedViewAlphaAnimator.start(); PhysicsAnimator.getInstance(mExpandedViewContainerMatrix).cancel(); Loading @@ -187,12 +189,12 @@ public class BubbleBarAnimationHelper { .withEndActions(() -> { bbev.setAnimationMatrix(null); updateExpandedView(); bbev.setSurfaceZOrderedOnTop(false); if (afterAnimation != null) { afterAnimation.run(); } }) .start(); }); } /** Loading
libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java +79 −9 Original line number Diff line number Diff line Loading @@ -131,6 +131,11 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView /** Current corner radius */ private float mCurrentCornerRadius = 0f; /** A runnable to start the expansion animation as soon as the task view is made visible. */ @Nullable private Runnable mAnimateExpansion = null; private TaskViewVisibilityState mVisibilityState = TaskViewVisibilityState.INVISIBLE; /** * Whether we want the {@code TaskView}'s content to be visible (alpha = 1f). If * {@link #mIsAnimating} is true, this may not reflect the {@code TaskView}'s actual alpha Loading @@ -140,6 +145,18 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView private boolean mIsAnimating; private boolean mIsDragging; /** An enum value that tracks the visibility state of the task view */ private enum TaskViewVisibilityState { /** The task view is going away, and we're waiting for the surface to be destroyed. */ PENDING_INVISIBLE, /** The task view is invisible and does not have a surface. */ INVISIBLE, /** The task view is in the process of being added to a surface. */ PENDING_VISIBLE, /** The task view is visible and has a surface. */ VISIBLE } public BubbleBarExpandedView(Context context) { this(context, null); } Loading Loading @@ -206,16 +223,27 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView mBubbleTaskViewHelper = new BubbleTaskViewHelper(mContext, expandedViewManager, /* listener= */ this, bubbleTaskView, /* viewParent= */ this); // if the task view is already attached to a parent we need to remove it if (mTaskView.getParent() != null) { // it's possible that the task view is visible, e.g. if we're unfolding, in which // case removing it will trigger a visibility change. we have to wait for that // signal before we can add it to this expanded view, otherwise the signal will be // incorrect because the task view will have a surface. // if the task view is not visible, then it has no surface and removing it will not // trigger any visibility change signals. if (bubbleTaskView.isVisible()) { mVisibilityState = TaskViewVisibilityState.PENDING_INVISIBLE; } ((ViewGroup) mTaskView.getParent()).removeView(mTaskView); } FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT); addView(mTaskView, lp); mTaskView.setEnableSurfaceClipping(true); mTaskView.setCornerRadius(mCurrentCornerRadius); mTaskView.setVisibility(VISIBLE); mTaskView.setCaptionInsets(Insets.of(0, mCaptionHeight, 0, 0)); // if we're invisible it's safe to setup the task view and then await on the visibility // signal. if (mVisibilityState == TaskViewVisibilityState.INVISIBLE) { mVisibilityState = TaskViewVisibilityState.PENDING_VISIBLE; setupTaskView(); } // Handle view needs to draw on top of task view. bringChildToFront(mHandleView); Loading Loading @@ -269,6 +297,16 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView }); } private void setupTaskView() { FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT); addView(mTaskView, lp); mTaskView.setEnableSurfaceClipping(true); mTaskView.setCornerRadius(mCurrentCornerRadius); mTaskView.setVisibility(VISIBLE); mTaskView.setCaptionInsets(Insets.of(0, mCaptionHeight, 0, 0)); } public BubbleBarHandleView getHandleView() { return mHandleView; } Loading Loading @@ -326,15 +364,28 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView @Override public void onTaskCreated() { setContentVisibility(true); if (mTaskView != null) { mTaskView.setAlpha(0); } if (mListener != null) { mListener.onTaskCreated(); } // when the task is created we're visible onTaskViewVisible(); } @Override public void onContentVisibilityChanged(boolean visible) { setContentVisibility(visible); if (mVisibilityState == TaskViewVisibilityState.PENDING_INVISIBLE && !visible) { // the surface is now destroyed. set up the task view and wait for the visibility // signal. mVisibilityState = TaskViewVisibilityState.PENDING_VISIBLE; setupTaskView(); return; } if (visible) { onTaskViewVisible(); } } @Override Loading @@ -350,6 +401,25 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView mListener.onBackPressed(); } void animateExpansionWhenTaskViewVisible(Runnable animateExpansion) { if (mVisibilityState == TaskViewVisibilityState.VISIBLE) { animateExpansion.run(); } else { mAnimateExpansion = animateExpansion; } } private void onTaskViewVisible() { // if we're waiting to be visible, start the expansion animation if it's pending. if (mVisibilityState == TaskViewVisibilityState.PENDING_VISIBLE) { mVisibilityState = TaskViewVisibilityState.VISIBLE; if (mAnimateExpansion != null) { mAnimateExpansion.run(); mAnimateExpansion = null; } } } /** * Set whether this view is currently being dragged. * Loading