Merge "WindowInsetsAnimationController: Add state callback and getters" into rvc-dev am: 269b162622 am: 8879718ea2

Change-Id: Ie39482887185b22491a16c7fa827f6efcc007415
This commit is contained in:
Adrian Roos
2020-03-18 16:54:00 +00:00
committed by Automerger Merge Worker
10 changed files with 129 additions and 32 deletions

View File

@@ -55573,7 +55573,8 @@ package android.view {
}
public interface WindowInsetsAnimationControlListener {
method public void onCancelled();
method public void onCancelled(@Nullable android.view.WindowInsetsAnimationController);
method public void onFinished(@NonNull android.view.WindowInsetsAnimationController);
method public void onReady(@NonNull android.view.WindowInsetsAnimationController, int);
}
@@ -55585,6 +55586,9 @@ package android.view {
method @NonNull public android.graphics.Insets getHiddenStateInsets();
method @NonNull public android.graphics.Insets getShownStateInsets();
method public int getTypes();
method public boolean isCancelled();
method public boolean isFinished();
method public default boolean isReady();
method public void setInsetsAndAlpha(@Nullable android.graphics.Insets, @FloatRange(from=0.0f, to=1.0f) float, @FloatRange(from=0.0f, to=1.0f) float);
}

View File

@@ -200,6 +200,7 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
}
setInsetsAndAlpha(shown ? mShownInsets : mHiddenInsets, 1f /* alpha */, 1f /* fraction */);
mFinished = true;
mListener.onFinished(this);
mShownOnFinish = shown;
}
@@ -216,11 +217,17 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
return;
}
mCancelled = true;
mListener.onCancelled();
mListener.onCancelled(this);
releaseLeashes();
}
@Override
public boolean isFinished() {
return mFinished;
}
@Override
public boolean isCancelled() {
return mCancelled;
}

View File

@@ -213,7 +213,11 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
}
@Override
public void onCancelled() {
public void onFinished(WindowInsetsAnimationController controller) {
}
@Override
public void onCancelled(WindowInsetsAnimationController controller) {
// Animator can be null when it is cancelled before onReady() completes.
if (mAnimator != null) {
mAnimator.cancel();
@@ -583,7 +587,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
boolean fromIme, long durationMs, @Nullable Interpolator interpolator,
@AnimationType int animationType) {
if (!checkDisplayFramesForControlling()) {
listener.onCancelled();
listener.onCancelled(null);
return;
}
controlAnimationUnchecked(types, cancellationSignal, listener, mFrame, fromIme, durationMs,
@@ -608,7 +612,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
boolean useInsetsAnimationThread) {
if (types == 0) {
// nothing to animate.
listener.onCancelled();
listener.onCancelled(null);
return;
}
cancelExistingControllers(types);
@@ -641,7 +645,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
}
if (typesReady == 0) {
listener.onCancelled();
listener.onCancelled(null);
return;
}
@@ -756,7 +760,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
private void abortPendingImeControlRequest() {
if (mPendingImeControlRequest != null) {
mPendingImeControlRequest.listener.onCancelled();
mPendingImeControlRequest.listener.onCancelled(null);
mPendingImeControlRequest = null;
mHandler.removeCallbacks(mPendingControlTimeout);
}

View File

@@ -172,7 +172,7 @@ public class PendingInsetsController implements WindowInsetsController {
mReplayedInsetsController.controlWindowInsetsAnimation(types, durationMillis,
interpolator, cancellationSignal, listener);
} else {
listener.onCancelled();
listener.onCancelled(null);
}
}

View File

@@ -17,20 +17,30 @@
package android.view;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.view.WindowInsets.Type.InsetsType;
import android.view.inputmethod.EditorInfo;
/**
* Interface that informs the client about {@link WindowInsetsAnimationController} state changes.
* Listener that encapsulates a request to
* {@link WindowInsetsController#controlWindowInsetsAnimation}.
*
* <p>
* Insets can be controlled with the supplied {@link WindowInsetsAnimationController} from
* {@link #onReady} until either {@link #onFinished} or {@link #onCancelled}.
*
* <p>
* Once the control over insets is finished or cancelled, it will not be regained until a new
* request to {@link WindowInsetsController#controlWindowInsetsAnimation} is made.
*
* <p>
* The request to control insets can fail immediately. In that case {@link #onCancelled} will be
* invoked without a preceding {@link #onReady}.
*
* @see WindowInsetsController#controlWindowInsetsAnimation
*/
public interface WindowInsetsAnimationControlListener {
/**
* @hide
*/
default void onPrepare(int types) {
}
/**
* Called when the animation is ready to be controlled. This may be delayed when the IME needs
* to redraw because of an {@link EditorInfo} change, or when the window is starting up.
@@ -41,14 +51,40 @@ public interface WindowInsetsAnimationControlListener {
* {@link WindowInsetsController#controlWindowInsetsAnimation} in case the window
* wasn't able to gain the controls because it wasn't the IME target or not
* currently the window that's controlling the system bars.
* @see WindowInsetsAnimationController#isReady
*/
void onReady(@NonNull WindowInsetsAnimationController controller, @InsetsType int types);
/**
* Called when the window no longer has control over the requested types. If it loses control
* over one type, the whole control will be cancelled. If none of the requested types were
* available when requesting the control, the animation control will be cancelled immediately
* without {@link #onReady} being called.
* Called when the request for control over the insets has
* {@link WindowInsetsAnimationController#finish finished}.
*
* Once this callback is invoked, the supplied {@link WindowInsetsAnimationController}
* is no longer {@link WindowInsetsAnimationController#isReady() ready}.
*
* Control will not be regained until a new request
* to {@link WindowInsetsController#controlWindowInsetsAnimation} is made.
*
* @param controller the controller which has finished.
* @see WindowInsetsAnimationController#isFinished
*/
void onCancelled();
void onFinished(@NonNull WindowInsetsAnimationController controller);
/**
* Called when the request for control over the insets has been cancelled, either
* because the {@link android.os.CancellationSignal} associated with the
* {@link WindowInsetsController#controlWindowInsetsAnimation request} has been invoked, or
* the window has lost control over the insets (e.g. because it lost focus).
*
* Once this callback is invoked, the supplied {@link WindowInsetsAnimationController}
* is no longer {@link WindowInsetsAnimationController#isReady() ready}.
*
* Control will not be regained until a new request
* to {@link WindowInsetsController#controlWindowInsetsAnimation} is made.
*
* @param controller the controller which has been cancelled, or null if the request
* was cancelled before {@link #onReady} was invoked.
* @see WindowInsetsAnimationController#isCancelled
*/
void onCancelled(@Nullable WindowInsetsAnimationController controller);
}

View File

@@ -139,10 +139,43 @@ public interface WindowInsetsAnimationController {
@FloatRange(from = 0f, to = 1f) float fraction);
/**
* Finishes the animation, and leaves the windows shown or hidden. After invoking
* {@link #finish(boolean)}, this instance is no longer valid.
* Finishes the animation, and leaves the windows shown or hidden.
* <p>
* After invoking {@link #finish(boolean)}, this instance is no longer {@link #isReady ready}.
*
* @param shown if {@code true}, the windows will be shown after finishing the
* animation. Otherwise they will be hidden.
*/
void finish(boolean shown);
/**
* Returns whether this instance is ready to be used to control window insets.
* <p>
* Instances are ready when passed in {@link WindowInsetsAnimationControlListener#onReady}
* and stop being ready when it is either {@link #isFinished() finished} or
* {@link #isCancelled() cancelled}.
*
* @return {@code true} if the instance is ready, {@code false} otherwise.
*/
default boolean isReady() {
return !isFinished() && !isCancelled();
}
/**
* Returns whether this instance has been finished by a call to {@link #finish}.
*
* @see WindowInsetsAnimationControlListener#onFinished
* @return {@code true} if the instance is finished, {@code false} otherwise.
*/
boolean isFinished();
/**
* Returns whether this instance has been cancelled by the system, or by invoking the
* {@link android.os.CancellationSignal} passed into
* {@link WindowInsetsController#controlWindowInsetsAnimation}.
*
* @see WindowInsetsAnimationControlListener#onCancelled
* @return {@code true} if the instance is cancelled, {@code false} otherwise.
*/
boolean isCancelled();
}

View File

@@ -188,7 +188,7 @@ public class InsetsAnimationControlImplTest {
fail("Expected exception to be thrown");
} catch (IllegalStateException ignored) {
}
verify(mMockListener).onCancelled();
verify(mMockListener).onCancelled(mController);
mController.finish(true /* shown */);
}

View File

@@ -204,7 +204,7 @@ public class InsetsControllerTest {
mViewRoot.getView().getViewTreeObserver().dispatchOnPreDraw();
verify(mockListener).onReady(any(), anyInt());
mController.onControlsChanged(new InsetsSourceControl[0]);
verify(mockListener).onCancelled();
verify(mockListener).onCancelled(notNull());
});
}
@@ -221,7 +221,7 @@ public class InsetsControllerTest {
new CancellationSignal(), controlListener);
mController.addOnControllableInsetsChangedListener(
(controller, typeMask) -> assertEquals(0, typeMask));
verify(controlListener).onCancelled();
verify(controlListener).onCancelled(null);
verify(controlListener, never()).onReady(any(), anyInt());
}
@@ -533,7 +533,7 @@ public class InsetsControllerTest {
verify(mockListener).onReady(any(), anyInt());
cancellationSignal.cancel();
verify(mockListener).onCancelled();
verify(mockListener).onCancelled(notNull());
});
waitUntilNextFrame();
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
@@ -584,7 +584,7 @@ public class InsetsControllerTest {
// Pretend that we are losing control
mController.onControlsChanged(new InsetsSourceControl[0]);
verify(listener).onCancelled();
verify(listener).onCancelled(null);
});
}
@@ -606,7 +606,7 @@ public class InsetsControllerTest {
mTestClock.fastForward(2500);
mTestHandler.timeAdvance();
verify(listener).onCancelled();
verify(listener).onCancelled(null);
});
}
@@ -621,7 +621,7 @@ public class InsetsControllerTest {
cancellationSignal, listener);
cancellationSignal.cancel();
verify(listener).onCancelled();
verify(listener).onCancelled(null);
// Ready gets deferred until next predraw
mViewRoot.getView().getViewTreeObserver().dispatchOnPreDraw();

View File

@@ -99,7 +99,7 @@ public class PendingInsetsControllerTest {
CancellationSignal cancellationSignal = new CancellationSignal();
mPendingInsetsController.controlWindowInsetsAnimation(
systemBars(), 0, new LinearInterpolator(), cancellationSignal, listener);
verify(listener).onCancelled();
verify(listener).onCancelled(null);
assertFalse(cancellationSignal.isCanceled());
}

View File

@@ -114,7 +114,14 @@ public class WindowInsetsActivity extends AppCompatActivity {
}
@Override
public void onCancelled() {
public void onFinished(
WindowInsetsAnimationController controller) {
mAnimationController = null;
}
@Override
public void onCancelled(
WindowInsetsAnimationController controller) {
mAnimationController = null;
}
});
@@ -230,7 +237,13 @@ public class WindowInsetsActivity extends AppCompatActivity {
}
@Override
public void onCancelled() {
public void onFinished(
WindowInsetsAnimationController controller) {
}
@Override
public void onCancelled(
WindowInsetsAnimationController controller) {
}
});
}