Merge "WindowInsetsController: Address API feedback" into rvc-dev am: 3a4be4a7b1

Change-Id: I252b6aa0fbd784df17d15f89a76d8fda0f6f7a10
This commit is contained in:
Automerger Merge Worker
2020-03-12 16:25:00 +00:00
8 changed files with 86 additions and 78 deletions

View File

@@ -55580,7 +55580,7 @@ package android.view {
public interface WindowInsetsController {
method public void addOnControllableInsetsChangedListener(@NonNull android.view.WindowInsetsController.OnControllableInsetsChangedListener);
method @NonNull public android.os.CancellationSignal controlWindowInsetsAnimation(int, long, @Nullable android.view.animation.Interpolator, @NonNull android.view.WindowInsetsAnimationControlListener);
method public void controlWindowInsetsAnimation(int, long, @Nullable android.view.animation.Interpolator, @Nullable android.os.CancellationSignal, @NonNull android.view.WindowInsetsAnimationControlListener);
method public int getSystemBarsAppearance();
method public int getSystemBarsBehavior();
method public void hide(int);

View File

@@ -52,7 +52,6 @@ import android.view.animation.Interpolator;
import android.view.animation.PathInterpolator;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.Preconditions;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
@@ -494,13 +493,12 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
PendingControlRequest pendingRequest = mPendingImeControlRequest;
mPendingImeControlRequest = null;
mHandler.removeCallbacks(mPendingControlTimeout);
CancellationSignal cancellationSignal = controlAnimationUnchecked(
pendingRequest.types,
controlAnimationUnchecked(
pendingRequest.types, pendingRequest.cancellationSignal,
pendingRequest.listener, mFrame,
true /* fromIme */, pendingRequest.durationMs, pendingRequest.interpolator,
false /* fade */, pendingRequest.animationType,
pendingRequest.layoutInsetsDuringAnimation);
pendingRequest.cancellationSignal.setOnCancelListener(cancellationSignal::cancel);
return;
}
@@ -546,24 +544,26 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
}
@Override
public CancellationSignal controlWindowInsetsAnimation(@InsetsType int types, long durationMs,
public void controlWindowInsetsAnimation(@InsetsType int types, long durationMillis,
@Nullable Interpolator interpolator,
@Nullable CancellationSignal cancellationSignal,
@NonNull WindowInsetsAnimationControlListener listener) {
return controlWindowInsetsAnimation(types, listener, false /* fromIme */, durationMs,
interpolator, ANIMATION_TYPE_USER);
controlWindowInsetsAnimation(types, cancellationSignal, listener,
false /* fromIme */, durationMillis, interpolator, ANIMATION_TYPE_USER);
}
private CancellationSignal controlWindowInsetsAnimation(@InsetsType int types,
WindowInsetsAnimationControlListener listener, boolean fromIme, long durationMs,
@Nullable Interpolator interpolator, @AnimationType int animationType) {
private void controlWindowInsetsAnimation(@InsetsType int types,
@Nullable CancellationSignal cancellationSignal,
WindowInsetsAnimationControlListener listener,
boolean fromIme, long durationMs, @Nullable Interpolator interpolator,
@AnimationType int animationType) {
if (!checkDisplayFramesForControlling()) {
listener.onCancelled();
CancellationSignal cancellationSignal = new CancellationSignal();
cancellationSignal.cancel();
return cancellationSignal;
return;
}
return controlAnimationUnchecked(types, listener, mFrame, fromIme, durationMs, interpolator,
false /* fade */, animationType, getLayoutInsetsDuringAnimationMode(types));
controlAnimationUnchecked(types, cancellationSignal, listener, mFrame, fromIme, durationMs,
interpolator, false /* fade */, animationType,
getLayoutInsetsDuringAnimationMode(types));
}
private boolean checkDisplayFramesForControlling() {
@@ -573,17 +573,16 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
return mState.getDisplayFrame().equals(mFrame);
}
private CancellationSignal controlAnimationUnchecked(@InsetsType int types,
private void controlAnimationUnchecked(@InsetsType int types,
@Nullable CancellationSignal cancellationSignal,
WindowInsetsAnimationControlListener listener, Rect frame, boolean fromIme,
long durationMs, Interpolator interpolator, boolean fade,
@AnimationType int animationType,
@LayoutInsetsDuringAnimation int layoutInsetsDuringAnimation) {
CancellationSignal cancellationSignal = new CancellationSignal();
if (types == 0) {
// nothing to animate.
listener.onCancelled();
cancellationSignal.cancel();
return cancellationSignal;
return;
}
cancelExistingControllers(types);
mLastStartedAnimTypes |= types;
@@ -603,26 +602,28 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
interpolator, animationType, layoutInsetsDuringAnimation, cancellationSignal);
mPendingImeControlRequest = request;
mHandler.postDelayed(mPendingControlTimeout, PENDING_CONTROL_TIMEOUT_MS);
cancellationSignal.setOnCancelListener(() -> {
if (mPendingImeControlRequest == request) {
abortPendingImeControlRequest();
}
});
return cancellationSignal;
if (cancellationSignal != null) {
cancellationSignal.setOnCancelListener(() -> {
if (mPendingImeControlRequest == request) {
abortPendingImeControlRequest();
}
});
}
return;
}
if (typesReady == 0) {
listener.onCancelled();
cancellationSignal.cancel();
return cancellationSignal;
return;
}
final InsetsAnimationControlImpl controller = new InsetsAnimationControlImpl(controls,
frame, mState, listener, typesReady, this, durationMs, interpolator, fade,
layoutInsetsDuringAnimation, animationType);
mRunningAnimations.add(new RunningAnimation(controller, animationType));
cancellationSignal.setOnCancelListener(controller::onCancelled);
return cancellationSignal;
if (cancellationSignal != null) {
cancellationSignal.setOnCancelListener(controller::onCancelled);
}
}
/**
@@ -883,7 +884,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
// Show/hide animations always need to be relative to the display frame, in order that shown
// and hidden state insets are correct.
controlAnimationUnchecked(
types, listener, mState.getDisplayFrame(), fromIme, listener.getDurationMs(),
types, new CancellationSignal(), listener, mState.getDisplayFrame(), fromIme,
listener.getDurationMs(),
INTERPOLATOR, true /* fade */, show ? ANIMATION_TYPE_SHOW : ANIMATION_TYPE_HIDE,
show ? LAYOUT_INSETS_DURING_ANIMATION_SHOWN
: LAYOUT_INSETS_DURING_ANIMATION_HIDDEN);

View File

@@ -16,6 +16,8 @@
package android.view;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.CancellationSignal;
import android.view.WindowInsets.Type.InsetsType;
import android.view.animation.Interpolator;
@@ -59,21 +61,6 @@ public class PendingInsetsController implements WindowInsetsController {
}
}
@Override
public CancellationSignal controlWindowInsetsAnimation(int types, long durationMillis,
Interpolator interpolator,
WindowInsetsAnimationControlListener listener) {
if (mReplayedInsetsController != null) {
return mReplayedInsetsController.controlWindowInsetsAnimation(types, durationMillis,
interpolator, listener);
} else {
listener.onCancelled();
CancellationSignal cancellationSignal = new CancellationSignal();
cancellationSignal.cancel();
return cancellationSignal;
}
}
@Override
public void setSystemBarsAppearance(int appearance, int mask) {
if (mReplayedInsetsController != null) {
@@ -176,6 +163,19 @@ public class PendingInsetsController implements WindowInsetsController {
mReplayedInsetsController = null;
}
@Override
public void controlWindowInsetsAnimation(@InsetsType int types, long durationMillis,
@Nullable Interpolator interpolator,
CancellationSignal cancellationSignal,
@NonNull WindowInsetsAnimationControlListener listener) {
if (mReplayedInsetsController != null) {
mReplayedInsetsController.controlWindowInsetsAnimation(types, durationMillis,
interpolator, cancellationSignal, listener);
} else {
listener.onCancelled();
}
}
private interface PendingRequest {
void replay(InsetsController controller);
}

View File

@@ -16,7 +16,6 @@
package android.view;
import android.annotation.Hide;
import android.annotation.NonNull;
import android.view.WindowInsets.Type.InsetsType;
import android.view.inputmethod.EditorInfo;

View File

@@ -156,16 +156,17 @@ public interface WindowInsetsController {
* calculate {@link WindowInsetsAnimation#getInterpolatedFraction()}.
* @param listener The {@link WindowInsetsAnimationControlListener} that gets called when the
* windows are ready to be controlled, among other callbacks.
* @return A cancellation signal that the caller can use to cancel the request to obtain
* control, or once they have control, to cancel the control.
* @param cancellationSignal A cancellation signal that the caller can use to cancel the
* request to obtain control, or once they have control, to cancel the
* control.
* @see WindowInsetsAnimation#getFraction()
* @see WindowInsetsAnimation#getInterpolatedFraction()
* @see WindowInsetsAnimation#getInterpolator()
* @see WindowInsetsAnimation#getDurationMillis()
*/
@NonNull
CancellationSignal controlWindowInsetsAnimation(@InsetsType int types, long durationMillis,
void controlWindowInsetsAnimation(@InsetsType int types, long durationMillis,
@Nullable Interpolator interpolator,
@Nullable CancellationSignal cancellationSignal,
@NonNull WindowInsetsAnimationControlListener listener);
/**

View File

@@ -56,12 +56,12 @@ import android.view.animation.LinearInterpolator;
import android.view.test.InsetsModeSession;
import android.widget.TextView;
import com.android.server.testutils.OffsettableClock;
import com.android.server.testutils.TestHandler;
import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
import com.android.server.testutils.OffsettableClock;
import com.android.server.testutils.TestHandler;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
@@ -72,7 +72,6 @@ import org.mockito.InOrder;
import org.mockito.Mockito;
import java.util.concurrent.CountDownLatch;
import java.util.function.Supplier;
/**
* Tests for {@link InsetsController}.
@@ -204,7 +203,7 @@ public class InsetsControllerTest {
WindowInsetsAnimationControlListener mockListener =
mock(WindowInsetsAnimationControlListener.class);
mController.controlWindowInsetsAnimation(statusBars(), 10 /* durationMs */,
new LinearInterpolator(), mockListener);
new LinearInterpolator(), new CancellationSignal(), mockListener);
// Ready gets deferred until next predraw
mViewRoot.getView().getViewTreeObserver().dispatchOnPreDraw();
@@ -224,7 +223,7 @@ public class InsetsControllerTest {
WindowInsetsAnimationControlListener controlListener =
mock(WindowInsetsAnimationControlListener.class);
mController.controlWindowInsetsAnimation(0, 0 /* durationMs */, new LinearInterpolator(),
controlListener);
new CancellationSignal(), controlListener);
mController.addOnControllableInsetsChangedListener(
(controller, typeMask) -> assertEquals(0, typeMask));
verify(controlListener).onCancelled();
@@ -515,7 +514,7 @@ public class InsetsControllerTest {
WindowInsetsAnimationControlListener mockListener =
mock(WindowInsetsAnimationControlListener.class);
mController.controlWindowInsetsAnimation(statusBars(), 0 /* durationMs */,
new LinearInterpolator(), mockListener);
new LinearInterpolator(), new CancellationSignal(), mockListener);
ArgumentCaptor<WindowInsetsAnimationController> controllerCaptor =
ArgumentCaptor.forClass(WindowInsetsAnimationController.class);
@@ -542,9 +541,10 @@ public class InsetsControllerTest {
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
WindowInsetsAnimationControlListener mockListener =
mock(WindowInsetsAnimationControlListener.class);
CancellationSignal cancellationSignal = mController.controlWindowInsetsAnimation(
CancellationSignal cancellationSignal = new CancellationSignal();
mController.controlWindowInsetsAnimation(
statusBars(), 0 /* durationMs */,
new LinearInterpolator(), mockListener);
new LinearInterpolator(), cancellationSignal, mockListener);
// Ready gets deferred until next predraw
mViewRoot.getView().getViewTreeObserver().dispatchOnPreDraw();
@@ -567,7 +567,8 @@ public class InsetsControllerTest {
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
WindowInsetsAnimationControlListener listener =
mock(WindowInsetsAnimationControlListener.class);
mController.controlWindowInsetsAnimation(ime(), 0, new LinearInterpolator(), listener);
mController.controlWindowInsetsAnimation(ime(), 0, new LinearInterpolator(),
null /* cancellationSignal */, listener);
// Ready gets deferred until next predraw
mViewRoot.getView().getViewTreeObserver().dispatchOnPreDraw();
@@ -591,7 +592,8 @@ public class InsetsControllerTest {
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
WindowInsetsAnimationControlListener listener =
mock(WindowInsetsAnimationControlListener.class);
mController.controlWindowInsetsAnimation(ime(), 0, new LinearInterpolator(), listener);
mController.controlWindowInsetsAnimation(ime(), 0, new LinearInterpolator(),
null /* cancellationSignal */, listener);
// Ready gets deferred until next predraw
mViewRoot.getView().getViewTreeObserver().dispatchOnPreDraw();
@@ -611,7 +613,8 @@ public class InsetsControllerTest {
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
WindowInsetsAnimationControlListener listener =
mock(WindowInsetsAnimationControlListener.class);
mController.controlWindowInsetsAnimation(ime(), 0, new LinearInterpolator(), listener);
mController.controlWindowInsetsAnimation(ime(), 0, new LinearInterpolator(),
null /* cancellationSignal */, listener);
// Ready gets deferred until next predraw
mViewRoot.getView().getViewTreeObserver().dispatchOnPreDraw();
@@ -632,8 +635,10 @@ public class InsetsControllerTest {
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
WindowInsetsAnimationControlListener listener =
mock(WindowInsetsAnimationControlListener.class);
mController.controlWindowInsetsAnimation(ime(), 0, new LinearInterpolator(), listener)
.cancel();
CancellationSignal cancellationSignal = new CancellationSignal();
mController.controlWindowInsetsAnimation(ime(), 0, new LinearInterpolator(),
cancellationSignal, listener);
cancellationSignal.cancel();
verify(listener).onCancelled();

View File

@@ -20,8 +20,9 @@ import static android.view.WindowInsets.Type.navigationBars;
import static android.view.WindowInsets.Type.systemBars;
import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
@@ -35,12 +36,12 @@ import android.platform.test.annotations.Presubmit;
import android.view.WindowInsetsController.OnControllableInsetsChangedListener;
import android.view.animation.LinearInterpolator;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import androidx.test.runner.AndroidJUnit4;
/**
* Tests for {@link PendingInsetsControllerTest}.
*
@@ -95,10 +96,11 @@ public class PendingInsetsControllerTest {
public void testControl() {
WindowInsetsAnimationControlListener listener =
mock(WindowInsetsAnimationControlListener.class);
CancellationSignal signal = mPendingInsetsController.controlWindowInsetsAnimation(
systemBars(), 0, new LinearInterpolator(), listener);
CancellationSignal cancellationSignal = new CancellationSignal();
mPendingInsetsController.controlWindowInsetsAnimation(
systemBars(), 0, new LinearInterpolator(), cancellationSignal, listener);
verify(listener).onCancelled();
assertTrue(signal.isCanceled());
assertFalse(cancellationSignal.isCanceled());
}
@Test
@@ -106,10 +108,11 @@ public class PendingInsetsControllerTest {
WindowInsetsAnimationControlListener listener =
mock(WindowInsetsAnimationControlListener.class);
mPendingInsetsController.replayAndAttach(mReplayedController);
mPendingInsetsController.controlWindowInsetsAnimation(
systemBars(), 0L, new LinearInterpolator(), listener);
CancellationSignal cancellationSignal = new CancellationSignal();
mPendingInsetsController.controlWindowInsetsAnimation(systemBars(), 0L,
new LinearInterpolator(), cancellationSignal, listener);
verify(mReplayedController).controlWindowInsetsAnimation(eq(systemBars()), eq(0L), any(),
eq(listener));
eq(cancellationSignal), eq(listener));
}
@Test

View File

@@ -34,9 +34,7 @@ import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.Window;
import android.view.WindowInsets;
import android.view.WindowInsets.Type;
import android.view.WindowInsetsAnimation;
import android.view.WindowInsetsAnimation.Callback;
import android.view.WindowInsetsAnimationControlListener;
@@ -101,7 +99,7 @@ public class WindowInsetsActivity extends AppCompatActivity {
&& !mRequestedController) {
mRequestedController = true;
v.getWindowInsetsController().controlWindowInsetsAnimation(ime(),
1000, new LinearInterpolator(),
1000, new LinearInterpolator(), null /* cancellationSignal */,
mCurrentRequest = new WindowInsetsAnimationControlListener() {
@Override
public void onReady(
@@ -208,7 +206,7 @@ public class WindowInsetsActivity extends AppCompatActivity {
if ((types & ime()) != 0 && !hasControl) {
hasControl = true;
controller.controlWindowInsetsAnimation(ime(), -1,
new LinearInterpolator(),
new LinearInterpolator(), null /* cancellationSignal */,
new WindowInsetsAnimationControlListener() {
@Override
public void onReady(