Merge "Window Manager Flag Migration (3/n)"

This commit is contained in:
Tiger Huang
2019-09-16 16:56:53 +00:00
committed by Android (Google) Code Review
6 changed files with 117 additions and 27 deletions

View File

@@ -26,7 +26,6 @@ import android.annotation.Nullable;
import android.graphics.Insets;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.os.UidProto.Sync;
import android.util.ArraySet;
import android.util.SparseArray;
import android.util.SparseIntArray;
@@ -40,7 +39,6 @@ import android.view.WindowManager.LayoutParams;
import com.android.internal.annotations.VisibleForTesting;
import java.util.ArrayList;
import java.util.function.Function;
import java.util.function.Supplier;
/**
@@ -238,7 +236,12 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
addTranslationToMatrix(side, offset, mTmpMatrix, mTmpFrame);
state.getSource(source.getType()).setFrame(mTmpFrame);
surfaceParams.add(new SurfaceParams(leash, 1f, mTmpMatrix, null, 0, 0f, inset != 0));
// If the system is controlling the insets source, the leash can be null.
if (leash != null) {
surfaceParams.add(new SurfaceParams(leash, 1f /* alpha */, mTmpMatrix,
null /* windowCrop */, 0 /* layer */, 0f /* cornerRadius*/, inset != 0));
}
}
}

View File

@@ -167,7 +167,7 @@ public class InsetsSourceConsumer {
}
private void applyHiddenToControl() {
if (mSourceControl == null) {
if (mSourceControl == null || mSourceControl.getLeash() == null) {
return;
}

View File

@@ -16,6 +16,7 @@
package android.view;
import android.annotation.Nullable;
import android.graphics.Point;
import android.os.Parcel;
import android.os.Parcelable;
@@ -28,10 +29,10 @@ import android.view.InsetsState.InternalInsetType;
public class InsetsSourceControl implements Parcelable {
private final @InternalInsetType int mType;
private final SurfaceControl mLeash;
private final @Nullable SurfaceControl mLeash;
private final Point mSurfacePosition;
public InsetsSourceControl(@InternalInsetType int type, SurfaceControl leash,
public InsetsSourceControl(@InternalInsetType int type, @Nullable SurfaceControl leash,
Point surfacePosition) {
mType = type;
mLeash = leash;
@@ -42,7 +43,13 @@ public class InsetsSourceControl implements Parcelable {
return mType;
}
public SurfaceControl getLeash() {
/**
* Gets the leash for controlling insets source. If the system is controlling the insets source,
* for example, transient bars, the client will receive fake controls without leash in it.
*
* @return the leash.
*/
public @Nullable SurfaceControl getLeash() {
return mLeash;
}

View File

@@ -51,8 +51,11 @@ class InsetsSourceProvider {
private final @NonNull InsetsSource mSource;
private final DisplayContent mDisplayContent;
private final InsetsStateController mStateController;
private final InsetsSourceControl mFakeControl;
private @Nullable InsetsSourceControl mControl;
private @Nullable InsetsControlTarget mControlTarget;
private @Nullable InsetsControlTarget mFakeControlTarget;
private @Nullable ControlAdapter mAdapter;
private WindowState mWin;
private TriConsumer<DisplayFrames, WindowState, Rect> mFrameProvider;
@@ -73,6 +76,8 @@ class InsetsSourceProvider {
mSource = source;
mDisplayContent = displayContent;
mStateController = stateController;
mFakeControl = new InsetsSourceControl(source.getType(), null /* leash */,
new Point());
final int type = source.getType();
if (type == TYPE_TOP_BAR || type == TYPE_NAVIGATION_BAR) {
@@ -150,6 +155,16 @@ class InsetsSourceProvider {
&& !mWin.mGivenInsetsPending);
}
/**
* @see InsetsStateController#onControlFakeTargetChanged(int, InsetsControlTarget)
*/
void updateControlForFakeTarget(@Nullable InsetsControlTarget fakeTarget) {
if (fakeTarget == mFakeControlTarget) {
return;
}
mFakeControlTarget = fakeTarget;
}
void updateControlForTarget(@Nullable InsetsControlTarget target, boolean force) {
if (mWin == null) {
mControlTarget = target;
@@ -199,8 +214,14 @@ class InsetsSourceProvider {
mSource.setVisible(mServerVisible && mClientVisible);
}
InsetsSourceControl getControl() {
return mControl;
InsetsSourceControl getControl(InsetsControlTarget target) {
if (target == mControlTarget) {
return mControl;
}
if (target == mFakeControlTarget) {
return mFakeControl;
}
return null;
}
boolean isClientVisible() {
@@ -257,5 +278,5 @@ class InsetsSourceProvider {
@Override
public void writeToProto(ProtoOutputStream proto) {
}
};
}
}

View File

@@ -20,6 +20,8 @@ import static android.view.InsetsState.InternalInsetType;
import static android.view.InsetsState.TYPE_IME;
import static android.view.InsetsState.TYPE_NAVIGATION_BAR;
import static android.view.InsetsState.TYPE_TOP_BAR;
import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
import static android.view.ViewRootImpl.sNewInsetsMode;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -47,6 +49,10 @@ class InsetsStateController {
private final ArrayMap<InsetsControlTarget, ArrayList<Integer>> mControlTargetTypeMap =
new ArrayMap<>();
private final SparseArray<InsetsControlTarget> mTypeControlTargetMap = new SparseArray<>();
/** @see #onControlFakeTargetChanged */
private final SparseArray<InsetsControlTarget> mTypeFakeControlTargetMap = new SparseArray<>();
private final ArraySet<InsetsControlTarget> mPendingControlChanged = new ArraySet<>();
private final Consumer<WindowState> mDispatchInsetsChanged = w -> {
@@ -93,7 +99,7 @@ class InsetsStateController {
final int size = controlled.size();
final InsetsSourceControl[] result = new InsetsSourceControl[size];
for (int i = 0; i < size; i++) {
result[i] = mProviders.get(controlled.get(i)).getControl();
result[i] = mProviders.get(controlled.get(i)).getControl(target);
}
return result;
}
@@ -157,7 +163,8 @@ class InsetsStateController {
void notifyControlRevoked(@NonNull InsetsControlTarget previousControlTarget,
InsetsSourceProvider provider) {
removeFromControlMaps(previousControlTarget, provider.getSource().getType());
removeFromControlMaps(previousControlTarget, provider.getSource().getType(),
false /* fake */);
}
private void onControlChanged(@InternalInsetType int type,
@@ -175,17 +182,47 @@ class InsetsStateController {
}
provider.updateControlForTarget(target, false /* force */);
if (previous != null) {
removeFromControlMaps(previous, type);
removeFromControlMaps(previous, type, false /* fake */);
mPendingControlChanged.add(previous);
}
if (target != null) {
addToControlMaps(target, type);
addToControlMaps(target, type, false /* fake */);
mPendingControlChanged.add(target);
}
}
/**
* The fake target saved here will be used to pretend to the app that it's still under control
* of the bars while it's not really, but we still need to find out the apps intentions around
* showing/hiding. For example, when the transient bars are showing, and the fake target
* requests to show system bars, the transient state will be aborted.
*/
void onControlFakeTargetChanged(@InternalInsetType int type,
@Nullable InsetsControlTarget fakeTarget) {
if (sNewInsetsMode != NEW_INSETS_MODE_FULL) {
return;
}
final InsetsControlTarget previous = mTypeFakeControlTargetMap.get(type);
if (fakeTarget == previous) {
return;
}
final InsetsSourceProvider provider = mProviders.get(type);
if (provider == null) {
return;
}
provider.updateControlForFakeTarget(fakeTarget);
if (previous != null) {
removeFromControlMaps(previous, type, true /* fake */);
mPendingControlChanged.add(previous);
}
if (fakeTarget != null) {
addToControlMaps(fakeTarget, type, true /* fake */);
mPendingControlChanged.add(fakeTarget);
}
}
private void removeFromControlMaps(@NonNull InsetsControlTarget target,
@InternalInsetType int type) {
@InternalInsetType int type, boolean fake) {
final ArrayList<Integer> array = mControlTargetTypeMap.get(target);
if (array == null) {
return;
@@ -194,15 +231,23 @@ class InsetsStateController {
if (array.isEmpty()) {
mControlTargetTypeMap.remove(target);
}
mTypeControlTargetMap.remove(type);
if (fake) {
mTypeFakeControlTargetMap.remove(type);
} else {
mTypeControlTargetMap.remove(type);
}
}
private void addToControlMaps(@NonNull InsetsControlTarget target,
@InternalInsetType int type) {
@InternalInsetType int type, boolean fake) {
final ArrayList<Integer> array = mControlTargetTypeMap.computeIfAbsent(target,
key -> new ArrayList<>());
array.add(type);
mTypeControlTargetMap.put(type, target);
if (fake) {
mTypeFakeControlTargetMap.put(type, target);
} else {
mTypeControlTargetMap.put(type, target);
}
}
void notifyControlChanged(InsetsControlTarget target) {

View File

@@ -31,14 +31,15 @@ import android.platform.test.annotations.Presubmit;
import android.view.InsetsSource;
import android.view.InsetsState;
import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@SmallTest
@Presubmit
@RunWith(WindowTestRunner.class)
public class InsetsSourceProviderTest extends WindowTestsBase {
private InsetsSource mSource = new InsetsSource(TYPE_TOP_BAR);
@@ -53,7 +54,7 @@ public class InsetsSourceProviderTest extends WindowTestsBase {
@Test
public void testPostLayout() {
final WindowState topBar = createWindow(null, TYPE_APPLICATION, "parentWindow");
final WindowState topBar = createWindow(null, TYPE_APPLICATION, "topBar");
topBar.getFrameLw().set(0, 0, 500, 100);
topBar.mHasSurface = true;
mProvider.setWindow(topBar, null);
@@ -66,7 +67,7 @@ public class InsetsSourceProviderTest extends WindowTestsBase {
@Test
public void testPostLayout_invisible() {
final WindowState topBar = createWindow(null, TYPE_APPLICATION, "parentWindow");
final WindowState topBar = createWindow(null, TYPE_APPLICATION, "topBar");
topBar.getFrameLw().set(0, 0, 500, 100);
mProvider.setWindow(topBar, null);
mProvider.onPostLayout();
@@ -76,7 +77,7 @@ public class InsetsSourceProviderTest extends WindowTestsBase {
@Test
public void testPostLayout_frameProvider() {
final WindowState topBar = createWindow(null, TYPE_APPLICATION, "parentWindow");
final WindowState topBar = createWindow(null, TYPE_APPLICATION, "topBar");
topBar.getFrameLw().set(0, 0, 500, 100);
mProvider.setWindow(topBar,
(displayFrames, windowState, rect) -> {
@@ -88,19 +89,32 @@ public class InsetsSourceProviderTest extends WindowTestsBase {
@Test
public void testUpdateControlForTarget() {
final WindowState topBar = createWindow(null, TYPE_APPLICATION, "parentWindow");
final WindowState topBar = createWindow(null, TYPE_APPLICATION, "topBar");
final WindowState target = createWindow(null, TYPE_APPLICATION, "target");
topBar.getFrameLw().set(0, 0, 500, 100);
mProvider.setWindow(topBar, null);
mProvider.updateControlForTarget(target, false /* force */);
assertNotNull(mProvider.getControl());
assertNotNull(mProvider.getControl(target));
mProvider.updateControlForTarget(null, false /* force */);
assertNull(mProvider.getControl());
assertNull(mProvider.getControl(target));
}
@Test
public void testUpdateControlForFakeTarget() {
final WindowState topBar = createWindow(null, TYPE_APPLICATION, "topBar");
final WindowState target = createWindow(null, TYPE_APPLICATION, "target");
topBar.getFrameLw().set(0, 0, 500, 100);
mProvider.setWindow(topBar, null);
mProvider.updateControlForFakeTarget(target);
assertNotNull(mProvider.getControl(target));
assertNull(mProvider.getControl(target).getLeash());
mProvider.updateControlForFakeTarget(null);
assertNull(mProvider.getControl(target));
}
@Test
public void testInsetsModified() {
final WindowState topBar = createWindow(null, TYPE_APPLICATION, "parentWindow");
final WindowState topBar = createWindow(null, TYPE_APPLICATION, "topBar");
final WindowState target = createWindow(null, TYPE_APPLICATION, "target");
topBar.getFrameLw().set(0, 0, 500, 100);
mProvider.setWindow(topBar, null);
@@ -113,7 +127,7 @@ public class InsetsSourceProviderTest extends WindowTestsBase {
@Test
public void testInsetsModified_noControl() {
final WindowState topBar = createWindow(null, TYPE_APPLICATION, "parentWindow");
final WindowState topBar = createWindow(null, TYPE_APPLICATION, "topBar");
final WindowState target = createWindow(null, TYPE_APPLICATION, "target");
topBar.getFrameLw().set(0, 0, 500, 100);
mProvider.setWindow(topBar, null);