Re-apply local client state when leash changes

When leash changes, we need to re-apply our local state, to ensure
new leash has same state as before and new leash is visible on
screen.

Test: Switch IME while open
Test: SurfaceControlTest
Fixes: 152876819
Change-Id: Ieae1aecdc3ddc427ccb89c4aa7ef7ae9283f39eb
This commit is contained in:
Jorim Jaggi
2020-04-02 21:40:52 +02:00
parent 3bf50bddb3
commit ee54070608
8 changed files with 47 additions and 22 deletions

View File

@@ -4860,7 +4860,9 @@ package android.view {
}
public final class SurfaceControl implements android.os.Parcelable {
ctor public SurfaceControl(@NonNull android.view.SurfaceControl);
method public static long acquireFrameRateFlexibilityToken();
method public boolean isSameSurface(@NonNull android.view.SurfaceControl);
method public static void releaseFrameRateFlexibilityToken(long);
}

View File

@@ -91,6 +91,8 @@ public class InsetsSourceConsumer {
if (mSourceControl == control) {
return;
}
SurfaceControl oldLeash = mSourceControl != null ? mSourceControl.getLeash() : null;
final InsetsSourceControl lastControl = mSourceControl;
mSourceControl = control;
@@ -116,6 +118,12 @@ public class InsetsSourceConsumer {
// However make sure that the leash visibility is still up to date.
if (applyLocalVisibilityOverride()) {
mController.notifyVisibilityChanged();
}
// If we have a new leash, make sure visibility is up-to-date, even though we
// didn't want to run an animation above.
SurfaceControl newLeash = mSourceControl.getLeash();
if (oldLeash == null || newLeash == null || !oldLeash.isSameSurface(newLeash)) {
applyHiddenToControl();
}
}

View File

@@ -44,8 +44,7 @@ public class InsetsSourceControl implements Parcelable {
public InsetsSourceControl(InsetsSourceControl other) {
mType = other.mType;
if (other.mLeash != null) {
mLeash = new SurfaceControl();
mLeash.copyFrom(other.mLeash);
mLeash = new SurfaceControl(other.mLeash);
} else {
mLeash = null;
}

View File

@@ -216,6 +216,7 @@ public final class SurfaceControl implements Parcelable {
private static native void nativeSetFrameRate(
long transactionObj, long nativeObject, float frameRate, int compatibility);
private static native long nativeGetHandle(long nativeObject);
private static native long nativeAcquireFrameRateFlexibilityToken();
private static native void nativeReleaseFrameRateFlexibilityToken(long token);
@@ -226,6 +227,7 @@ public final class SurfaceControl implements Parcelable {
* @hide
*/
public long mNativeObject;
private long mNativeHandle;
// TODO: Move this to native.
private final Object mSizeLock = new Object();
@@ -428,12 +430,13 @@ public final class SurfaceControl implements Parcelable {
mCloseGuard.open("release");
}
mNativeObject = nativeObject;
mNativeHandle = mNativeObject != 0 ? nativeGetHandle(nativeObject) : 0;
}
/**
* @hide
*/
public void copyFrom(SurfaceControl other) {
public void copyFrom(@NonNull SurfaceControl other) {
mName = other.mName;
mWidth = other.mWidth;
mHeight = other.mHeight;
@@ -853,23 +856,19 @@ public final class SurfaceControl implements Parcelable {
throw new OutOfResourcesException(
"Couldn't allocate SurfaceControl native object");
}
mNativeHandle = nativeGetHandle(mNativeObject);
mCloseGuard.open("release");
}
/** This is a transfer constructor, useful for transferring a live SurfaceControl native
* object to another Java wrapper which could have some different behavior, e.g.
* event logging.
/**
* Copy constructor. Creates a new native object pointing to the same surface as {@code other}.
*
* @param other The object to copy the surface from.
* @hide
*/
public SurfaceControl(SurfaceControl other) {
mName = other.mName;
mWidth = other.mWidth;
mHeight = other.mHeight;
mNativeObject = other.mNativeObject;
other.mCloseGuard.close();
other.mNativeObject = 0;
mCloseGuard.open("release");
@TestApi
public SurfaceControl(@NonNull SurfaceControl other) {
copyFrom(other);
}
private SurfaceControl(Parcel in) {
@@ -920,6 +919,18 @@ public final class SurfaceControl implements Parcelable {
}
}
/**
* Checks whether two {@link SurfaceControl} objects represent the same surface.
*
* @param other The other object to check
* @return {@code true} if these two {@link SurfaceControl} objects represent the same surface.
* @hide
*/
@TestApi
public boolean isSameSurface(@NonNull SurfaceControl other) {
return other.mNativeHandle == mNativeHandle;
}
/**
* Write to a protocol buffer output stream. Protocol buffer message definition is at {@link
* android.view.SurfaceControlProto}.
@@ -977,6 +988,7 @@ public final class SurfaceControl implements Parcelable {
if (mNativeObject != 0) {
nativeRelease(mNativeObject);
mNativeObject = 0;
mNativeHandle = 0;
mCloseGuard.close();
}
}

View File

@@ -1430,6 +1430,12 @@ static void nativeSetGlobalShadowSettings(JNIEnv* env, jclass clazz, jfloatArray
client->setGlobalShadowSettings(ambientColor, spotColor, lightPosY, lightPosZ, lightRadius);
}
static jlong nativeGetHandle(JNIEnv* env, jclass clazz, jlong nativeObject) {
SurfaceControl *surfaceControl = reinterpret_cast<SurfaceControl*>(nativeObject);
return reinterpret_cast<jlong>(surfaceControl->getHandle().get());
}
// ----------------------------------------------------------------------------
static const JNINativeMethod sSurfaceControlMethods[] = {
@@ -1606,6 +1612,8 @@ static const JNINativeMethod sSurfaceControlMethods[] = {
(void*)nativeMirrorSurface },
{"nativeSetGlobalShadowSettings", "([F[FFFF)V",
(void*)nativeSetGlobalShadowSettings },
{"nativeGetHandle", "(J)J",
(void*)nativeGetHandle },
};
int register_android_view_SurfaceControl(JNIEnv* env)

View File

@@ -696,8 +696,7 @@ public class InsetsControllerTest {
// Simulate binder behavior by copying SurfaceControl. Otherwise, InsetsController will
// attempt to release mLeash directly.
SurfaceControl copy = new SurfaceControl();
copy.copyFrom(mLeash);
SurfaceControl copy = new SurfaceControl(mLeash);
return new InsetsSourceControl(type, copy, new Point());
}

View File

@@ -1082,8 +1082,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
return null;
}
mShellRoots.put(windowType, root);
SurfaceControl out = new SurfaceControl();
out.copyFrom(rootLeash);
SurfaceControl out = new SurfaceControl(rootLeash);
return out;
}

View File

@@ -2501,9 +2501,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
// We need to copy the SurfaceControl instead of returning the original
// because the Parcel FLAGS PARCELABLE_WRITE_RETURN_VALUE cause SurfaceControls
// to release themselves.
SurfaceControl sc = new SurfaceControl();
sc.copyFrom(wc.getSurfaceControl());
return sc;
return new SurfaceControl(wc.getSurfaceControl());
}
WindowContainerToken toWindowContainerToken() {