blob: 55eae8c358580ae5065ee742caee205c16826b76 [file] [log] [blame]
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.server.wm;
import static android.server.wm.app.Components.KEEP_CLEAR_RECTS_ACTIVITY;
import static android.server.wm.app.Components.KEEP_CLEAR_RECTS_ACTIVITY2;
import static android.server.wm.app.Components.KeepClearRectsActivity.EXTRA_KEEP_CLEAR_RECTS;
import static android.view.Display.DEFAULT_DISPLAY;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
import static java.util.Collections.EMPTY_LIST;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Rect;
import android.os.Bundle;
import android.platform.test.annotations.Presubmit;
import android.server.wm.cts.R;
import android.view.Gravity;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.RelativeLayout;
import android.widget.RelativeLayout.LayoutParams;
import androidx.test.filters.FlakyTest;
import com.android.compatibility.common.util.PollingCheck;
import org.junit.Before;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Callable;
@Presubmit
@FlakyTest(detail = "Promote once confirmed non-flaky")
public class KeepClearRectsTests extends WindowManagerTestBase {
private static final long SAME_ELEMENT_ASSERTION_TIMEOUT = 3000;
private static final List<Rect> TEST_KEEP_CLEAR_RECTS =
Arrays.asList(new Rect(0, 0, 25, 25),
new Rect(30, 0, 50, 25),
new Rect(25, 25, 50, 50),
new Rect(10, 30, 20, 50));
private static final List<Rect> TEST_KEEP_CLEAR_RECTS_2 =
Arrays.asList(new Rect(55, 0, 75, 15),
new Rect(50, 15, 60, 25),
new Rect(75, 25, 90, 50),
new Rect(90, 0, 100, 10));
private static final Rect TEST_VIEW_BOUNDS = new Rect(0, 0, 100, 100);
private static final String USE_KEEP_CLEAR_ATTR_LAYOUT = "use_keep_clear_attr_layout";
private TestActivitySession<TestActivity> mTestSession;
@Before
public void setUp() throws Exception {
super.setUp();
mTestSession = createManagedTestActivitySession();
}
@Test
public void testSetPreferKeepClearAttr() throws Exception {
final Intent intent = new Intent(mContext, TestActivity.class);
intent.putExtra(USE_KEEP_CLEAR_ATTR_LAYOUT, true);
mTestSession.launchTestActivityOnDisplaySync(null, intent, DEFAULT_DISPLAY);
final TestActivity activity = mTestSession.getActivity();
// To be kept in sync with res/layout/keep_clear_attr_activity
final Rect keepClearRect = new Rect(0, 0, 25, 25);
assertSameElementsEventually(Arrays.asList(keepClearRect),
() -> getKeepClearRectsForActivity(activity));
}
@Test
public void testSetPreferKeepClearSingleView() throws Exception {
mTestSession.launchTestActivityOnDisplaySync(TestActivity.class, DEFAULT_DISPLAY);
final TestActivity activity = mTestSession.getActivity();
final Rect keepClearRect = new Rect(0, 0, 25, 25);
final View v = createTestViewInActivity(activity, keepClearRect);
mTestSession.runOnMainSyncAndWait(() -> v.setPreferKeepClear(true));
assertSameElementsEventually(Arrays.asList(keepClearRect),
() -> getKeepClearRectsForActivity(activity));
}
@Test
public void testSetPreferKeepClearTwoViews() throws Exception {
mTestSession.launchTestActivityOnDisplaySync(TestActivity.class, DEFAULT_DISPLAY);
final TestActivity activity = mTestSession.getActivity();
final Rect keepClearRect = new Rect(0, 0, 25, 25);
final View v = createTestViewInActivity(activity, keepClearRect);
mTestSession.runOnMainSyncAndWait(() -> v.setPreferKeepClear(true));
final List<Rect> expected = new ArrayList(Arrays.asList(keepClearRect));
assertSameElementsEventually(expected, () -> getKeepClearRectsForActivity(activity));
final Rect keepClearRect2 = new Rect(25, 25, 50, 50);
final View v2 = createTestViewInActivity(activity, keepClearRect2);
mTestSession.runOnMainSyncAndWait(() -> v2.setPreferKeepClear(true));
expected.addAll(Arrays.asList(keepClearRect2));
assertSameElementsEventually(expected, () -> getKeepClearRectsForActivity(activity));
}
@Test
public void testSetMultipleKeepClearRectsSingleView() throws Exception {
mTestSession.launchTestActivityOnDisplaySync(TestActivity.class, DEFAULT_DISPLAY);
final TestActivity activity = mTestSession.getActivity();
final View v = createTestViewInActivity(activity);
mTestSession.runOnMainSyncAndWait(() -> v.setPreferKeepClearRects(TEST_KEEP_CLEAR_RECTS));
assertSameElementsEventually(TEST_KEEP_CLEAR_RECTS,
() -> getKeepClearRectsForActivity(activity));
}
@Test
public void testSetMultipleKeepClearRectsTwoViews() throws Exception {
mTestSession.launchTestActivityOnDisplaySync(TestActivity.class, DEFAULT_DISPLAY);
final TestActivity activity = mTestSession.getActivity();
final View v1 = createTestViewInActivity(activity);
final View v2 = createTestViewInActivity(activity);
mTestSession.runOnMainSyncAndWait(() -> {
v1.setPreferKeepClearRects(TEST_KEEP_CLEAR_RECTS);
v2.setPreferKeepClearRects(TEST_KEEP_CLEAR_RECTS_2);
});
final List<Rect> expected = new ArrayList(TEST_KEEP_CLEAR_RECTS);
expected.addAll(TEST_KEEP_CLEAR_RECTS_2);
assertSameElementsEventually(expected, () -> getKeepClearRectsForActivity(activity));
}
@Test
public void testIsPreferKeepClearSingleView() {
mTestSession.launchTestActivityOnDisplaySync(TestActivity.class, DEFAULT_DISPLAY);
final TestActivity activity = mTestSession.getActivity();
final Rect viewBounds = new Rect(0, 0, 60, 60);
final View v = createTestViewInActivity(activity, viewBounds);
assertFalse(v.isPreferKeepClear());
mTestSession.runOnMainSyncAndWait(() -> v.setPreferKeepClear(true));
assertTrue(v.isPreferKeepClear());
mTestSession.runOnMainSyncAndWait(() -> v.setPreferKeepClear(false));
assertFalse(v.isPreferKeepClear());
}
@Test
public void testGetPreferKeepClearRectsSingleView() throws Exception {
mTestSession.launchTestActivityOnDisplaySync(TestActivity.class, DEFAULT_DISPLAY);
final TestActivity activity = mTestSession.getActivity();
final Rect viewBounds = new Rect(0, 0, 60, 60);
final View v = createTestViewInActivity(activity, viewBounds);
assertSameElementsEventually(EMPTY_LIST, () -> v.getPreferKeepClearRects());
mTestSession.runOnMainSyncAndWait(() -> v.setPreferKeepClearRects(TEST_KEEP_CLEAR_RECTS));
assertSameElementsEventually(TEST_KEEP_CLEAR_RECTS, () -> v.getPreferKeepClearRects());
mTestSession.runOnMainSyncAndWait(() -> v.setPreferKeepClearRects(TEST_KEEP_CLEAR_RECTS_2));
assertSameElementsEventually(TEST_KEEP_CLEAR_RECTS_2, () -> v.getPreferKeepClearRects());
mTestSession.runOnMainSyncAndWait(() -> v.setPreferKeepClearRects(EMPTY_LIST));
assertSameElementsEventually(EMPTY_LIST, () -> v.getPreferKeepClearRects());
}
@Test
public void testGettersPreferKeepClearRectsTwoViews() throws Exception {
mTestSession.launchTestActivityOnDisplaySync(TestActivity.class, DEFAULT_DISPLAY);
final TestActivity activity = mTestSession.getActivity();
final Rect viewBounds1 = new Rect(0, 0, 60, 60);
final Rect viewBounds2 = new Rect(0, 0, 90, 90);
final View v1 = createTestViewInActivity(activity, viewBounds1);
final View v2 = createTestViewInActivity(activity, viewBounds2);
mTestSession.runOnMainSyncAndWait(() -> {
v1.setPreferKeepClear(true);
v2.setPreferKeepClearRects(TEST_KEEP_CLEAR_RECTS);
});
assertTrue(v1.isPreferKeepClear());
assertSameElementsEventually(TEST_KEEP_CLEAR_RECTS, () -> v2.getPreferKeepClearRects());
mTestSession.runOnMainSyncAndWait(() -> v1.setPreferKeepClear(false));
assertFalse(v1.isPreferKeepClear());
assertSameElementsEventually(TEST_KEEP_CLEAR_RECTS, () -> v2.getPreferKeepClearRects());
mTestSession.runOnMainSyncAndWait(() -> {
v1.setPreferKeepClear(true);
v2.setPreferKeepClearRects(EMPTY_LIST);
});
assertTrue(v1.isPreferKeepClear());
assertSameElementsEventually(EMPTY_LIST, () -> v2.getPreferKeepClearRects());
}
@Test
public void testSetPreferKeepClearCombinesWithMultipleRects() throws Exception {
mTestSession.launchTestActivityOnDisplaySync(TestActivity.class, DEFAULT_DISPLAY);
final TestActivity activity = mTestSession.getActivity();
final Rect viewBounds = new Rect(0, 0, 60, 60);
final View v = createTestViewInActivity(activity, viewBounds);
mTestSession.runOnMainSyncAndWait(() -> v.setPreferKeepClearRects(TEST_KEEP_CLEAR_RECTS));
assertSameElementsEventually(TEST_KEEP_CLEAR_RECTS,
() -> getKeepClearRectsForActivity(activity));
mTestSession.runOnMainSyncAndWait(() -> v.setPreferKeepClear(true));
final List<Rect> combinedRects = new ArrayList<>(TEST_KEEP_CLEAR_RECTS);
combinedRects.add(viewBounds);
assertSameElementsEventually(combinedRects, () -> getKeepClearRectsForActivity(activity));
mTestSession.runOnMainSyncAndWait(() -> v.setPreferKeepClear(false));
assertSameElementsEventually(TEST_KEEP_CLEAR_RECTS,
() -> getKeepClearRectsForActivity(activity));
}
@Test
public void testIgnoreKeepClearRectsFromGoneViews() throws Exception {
mTestSession.launchTestActivityOnDisplaySync(TestActivity.class, DEFAULT_DISPLAY);
final TestActivity activity = mTestSession.getActivity();
final Rect viewBounds = new Rect(0, 0, 60, 60);
final View v = createTestViewInActivity(activity, viewBounds);
mTestSession.runOnMainSyncAndWait(() -> v.setPreferKeepClear(true));
assertSameElementsEventually(Arrays.asList(viewBounds),
() -> getKeepClearRectsForActivity(activity));
mTestSession.runOnMainSyncAndWait(() -> v.setVisibility(View.GONE));
assertSameElementsEventually(EMPTY_LIST, () -> getKeepClearRectsForActivity(activity));
mTestSession.runOnMainSyncAndWait(() -> v.setVisibility(View.VISIBLE));
assertSameElementsEventually(Arrays.asList(viewBounds),
() -> getKeepClearRectsForActivity(activity));
mTestSession.runOnMainSyncAndWait(() -> {
v.setPreferKeepClear(false);
v.setPreferKeepClearRects(TEST_KEEP_CLEAR_RECTS);
});
assertSameElementsEventually(TEST_KEEP_CLEAR_RECTS,
() -> getKeepClearRectsForActivity(activity));
mTestSession.runOnMainSyncAndWait(() -> v.setVisibility(View.GONE));
assertSameElementsEventually(EMPTY_LIST, () -> getKeepClearRectsForActivity(activity));
mTestSession.runOnMainSyncAndWait(() -> v.setVisibility(View.VISIBLE));
assertSameElementsEventually(TEST_KEEP_CLEAR_RECTS,
() -> getKeepClearRectsForActivity(activity));
final Rect viewBounds2 = new Rect(60, 60, 90, 90);
final View v2 = createTestViewInActivity(activity, viewBounds2);
mTestSession.runOnMainSyncAndWait(() -> v2.setPreferKeepClear(true));
final List<Rect> expected = new ArrayList(TEST_KEEP_CLEAR_RECTS);
expected.add(viewBounds2);
assertSameElementsEventually(expected, () -> getKeepClearRectsForActivity(activity));
mTestSession.runOnMainSyncAndWait(() -> v.setVisibility(View.GONE));
assertSameElementsEventually(Arrays.asList(viewBounds2),
() -> getKeepClearRectsForActivity(activity));
mTestSession.runOnMainSyncAndWait(() -> {
v.setVisibility(View.VISIBLE);
v2.setVisibility(View.GONE);
});
assertSameElementsEventually(TEST_KEEP_CLEAR_RECTS,
() -> getKeepClearRectsForActivity(activity));
mTestSession.runOnMainSyncAndWait(() -> {
v.setVisibility(View.VISIBLE);
v2.setVisibility(View.VISIBLE);
});
assertSameElementsEventually(expected, () -> getKeepClearRectsForActivity(activity));
}
@Test
public void testIgnoreKeepClearRectsFromDetachedViews() throws Exception {
mTestSession.launchTestActivityOnDisplaySync(TestActivity.class, DEFAULT_DISPLAY);
final TestActivity activity = mTestSession.getActivity();
final Rect viewBounds = new Rect(0, 0, 60, 60);
final View v = createTestViewInActivity(activity, viewBounds);
mTestSession.runOnMainSyncAndWait(() -> v.setPreferKeepClear(true));
assertSameElementsEventually(Arrays.asList(viewBounds),
() -> getKeepClearRectsForActivity(activity));
mTestSession.runOnMainSyncAndWait(() -> ((ViewGroup) v.getParent()).removeView(v));
assertSameElementsEventually(EMPTY_LIST, () -> getKeepClearRectsForActivity(activity));
}
@Test
public void testFocusedViewDeclaredAsKeepClearArea() throws Exception {
assumeTrue(ViewConfiguration.get(mContext).isPreferKeepClearForFocusEnabled());
mTestSession.launchTestActivityOnDisplaySync(TestActivity.class, DEFAULT_DISPLAY);
final TestActivity activity = mTestSession.getActivity();
final Rect viewBounds = new Rect(0, 0, 60, 60);
final View v = createTestViewInActivity(activity, viewBounds);
assertSameElementsEventually(EMPTY_LIST, () -> getKeepClearRectsForActivity(activity));
mTestSession.runOnMainSyncAndWait(() -> {
v.setFocusableInTouchMode(true);
v.setFocusable(true);
v.requestFocus();
});
assertSameElementsEventually(Arrays.asList(viewBounds),
() -> getKeepClearRectsForActivity(activity));
mTestSession.runOnMainSyncAndWait(() -> v.setFocusable(false));
assertSameElementsEventually(EMPTY_LIST, () -> getKeepClearRectsForActivity(activity));
}
@Test
public void testKeepClearRectsGetTranslatedToWindowSpace() throws Exception {
mTestSession.launchTestActivityOnDisplaySync(TestActivity.class, DEFAULT_DISPLAY);
final TestActivity activity = mTestSession.getActivity();
final Rect viewBounds = new Rect(30, 30, 60, 60);
final View v = createTestViewInActivity(activity, viewBounds);
mTestSession.runOnMainSyncAndWait(() -> v.setPreferKeepClearRects(TEST_KEEP_CLEAR_RECTS));
final List<Rect> expected = new ArrayList();
for (Rect r : TEST_KEEP_CLEAR_RECTS) {
Rect newRect = new Rect(r);
newRect.offset(viewBounds.left, viewBounds.top);
expected.add(newRect);
}
assertSameElementsEventually(expected, () -> getKeepClearRectsForActivity(activity));
}
@Test
public void testSetKeepClearRectsOnDisplaySingleWindow() throws Exception {
mTestSession.launchTestActivityOnDisplaySync(TestActivity.class, DEFAULT_DISPLAY);
final TestActivity activity = mTestSession.getActivity();
final Rect keepClearRect = new Rect(0, 0, 25, 25);
final View v = createTestViewInActivity(activity, keepClearRect);
mTestSession.runOnMainSyncAndWait(() -> v.setPreferKeepClear(true));
assertSameElementsEventually(Arrays.asList(keepClearRect),
() -> getKeepClearRectsForActivity(activity));
mTestSession.runOnMainSyncAndWait(() -> {
v.setPreferKeepClear(false);
v.setPreferKeepClearRects(TEST_KEEP_CLEAR_RECTS);
});
assertSameElementsEventually(TEST_KEEP_CLEAR_RECTS,
() -> getKeepClearRectsForActivity(activity));
final List<Rect> expectedRectsInScreenSpace =
getRectsInScreenSpace(TEST_KEEP_CLEAR_RECTS, activity.getComponentName());
assertSameElementsEventually(expectedRectsInScreenSpace,
() -> getKeepClearRectsOnDefaultDisplay());
activity.finishAndRemoveTask();
assertTrue(Collections.disjoint(
expectedRectsInScreenSpace,
getKeepClearRectsOnDefaultDisplay()));
}
@Test
public void testKeepClearRectsOnDisplayTwoWindows() throws Exception {
mTestSession.launchTestActivityOnDisplaySync(TestActivity.class, DEFAULT_DISPLAY);
final TestActivity activity = mTestSession.getActivity();
final Rect viewBounds = new Rect(0, 0, 25, 25);
final View v1 = createTestViewInActivity(activity, viewBounds);
mTestSession.runOnMainSyncAndWait(() -> v1.setPreferKeepClear(true));
assertSameElementsEventually(Arrays.asList(viewBounds),
() -> getKeepClearRectsForActivity(activity));
final String title = "KeepClearRectsTestWindow";
mTestSession.runOnMainSyncAndWait(() -> {
final View testView = new View(activity);
testView.setPreferKeepClear(true);
testView.setBackgroundColor(Color.argb(20, 255, 0, 0));
WindowManager.LayoutParams params = new WindowManager.LayoutParams();
params.gravity = Gravity.TOP | Gravity.START;
params.width = 50;
params.height = 50;
params.setTitle(title);
activity.getWindowManager().addView(testView, params);
});
mWmState.waitAndAssertWindowSurfaceShown(title, true);
assertSameElementsEventually(Arrays.asList(viewBounds),
() -> getKeepClearRectsForActivity(activity));
}
@Test
public void testKeepClearRectsOnDisplayTwoFullscreenActivities() throws Exception {
mTestSession.launchTestActivityOnDisplaySync(TestActivity.class, DEFAULT_DISPLAY);
final TestActivity activity1 = mTestSession.getActivity();
final Rect viewBounds = new Rect(0, 0, 25, 25);
final View v1 = createTestViewInActivity(activity1, viewBounds);
mTestSession.runOnMainSyncAndWait(() -> v1.setPreferKeepClear(true));
assertSameElementsEventually(Arrays.asList(viewBounds),
() -> getKeepClearRectsForActivity(activity1));
final TestActivitySession<TranslucentTestActivity> translucentTestSession =
createManagedTestActivitySession();
translucentTestSession.launchTestActivityOnDisplaySync(
TranslucentTestActivity.class, DEFAULT_DISPLAY);
final TestActivity activity2 = translucentTestSession.getActivity();
final View v2 = createTestViewInActivity(activity2);
mTestSession.runOnMainSyncAndWait(() -> v2.setPreferKeepClearRects(TEST_KEEP_CLEAR_RECTS));
assertSameElementsEventually(TEST_KEEP_CLEAR_RECTS,
() -> getKeepClearRectsForActivity(activity2));
mWmState.assertVisibility(activity1.getComponentName(), true);
mWmState.assertVisibility(activity2.getComponentName(), true);
// Since both activities are fullscreen, WM only takes the keep clear areas from the top one
assertSameElementsEventually(getRectsInScreenSpace(TEST_KEEP_CLEAR_RECTS,
activity2.getComponentName()), () -> getKeepClearRectsOnDefaultDisplay());
}
@Test
public void testDisplayHasKeepClearRectsOnlyFromVisibleWindows() throws Exception {
final TestActivitySession<TranslucentTestActivity> translucentTestSession =
createManagedTestActivitySession();
translucentTestSession.launchTestActivityOnDisplaySync(
TranslucentTestActivity.class, DEFAULT_DISPLAY);
final TestActivity activity1 = translucentTestSession.getActivity();
final Rect viewBounds = new Rect(0, 0, 25, 25);
final View v1 = createTestViewInActivity(activity1, viewBounds);
translucentTestSession.runOnMainSyncAndWait(() -> v1.setPreferKeepClear(true));
assertSameElementsEventually(getRectsInScreenSpace(Arrays.asList(viewBounds),
activity1.getComponentName()), () -> getKeepClearRectsOnDefaultDisplay());
mTestSession.launchTestActivityOnDisplaySync(TestActivity.class, DEFAULT_DISPLAY);
final TestActivity activity2 = mTestSession.getActivity();
final View v2 = createTestViewInActivity(activity2);
mTestSession.runOnMainSyncAndWait(() -> v2.setPreferKeepClearRects(TEST_KEEP_CLEAR_RECTS));
assertSameElementsEventually(TEST_KEEP_CLEAR_RECTS,
() -> getKeepClearRectsForActivity(activity2));
mWmState.waitAndAssertVisibilityGone(activity1.getComponentName());
mWmState.assertVisibility(activity2.getComponentName(), true);
assertSameElementsEventually(TEST_KEEP_CLEAR_RECTS,
() -> getKeepClearRectsForActivity(activity2));
}
@Test
public void testDisplayHasKeepClearAreasFromTwoActivitiesInSplitscreen() throws Exception {
assumeTrue("Skipping test: no split multi-window support",
supportsSplitScreenMultiWindow());
final LaunchActivityBuilder activityBuilder1 = getLaunchActivityBuilder()
.setUseInstrumentation()
.setIntentExtra(extra -> {
extra.putParcelableArrayList(EXTRA_KEEP_CLEAR_RECTS,
new ArrayList(TEST_KEEP_CLEAR_RECTS));
})
.setTargetActivity(KEEP_CLEAR_RECTS_ACTIVITY);
final LaunchActivityBuilder activityBuilder2 = getLaunchActivityBuilder()
.setUseInstrumentation()
.setIntentExtra(extra -> {
extra.putParcelableArrayList(EXTRA_KEEP_CLEAR_RECTS,
new ArrayList(TEST_KEEP_CLEAR_RECTS_2));
})
.setTargetActivity(KEEP_CLEAR_RECTS_ACTIVITY2);
launchActivitiesInSplitScreen(activityBuilder1, activityBuilder2);
waitAndAssertResumedActivity(KEEP_CLEAR_RECTS_ACTIVITY, KEEP_CLEAR_RECTS_ACTIVITY
+ " must be resumed");
waitAndAssertResumedActivity(KEEP_CLEAR_RECTS_ACTIVITY2, KEEP_CLEAR_RECTS_ACTIVITY2
+ " must be resumed");
mWmState.assertVisibility(KEEP_CLEAR_RECTS_ACTIVITY, true);
mWmState.assertVisibility(KEEP_CLEAR_RECTS_ACTIVITY2, true);
assertSameElementsEventually(TEST_KEEP_CLEAR_RECTS,
() -> getKeepClearRectsForActivity(KEEP_CLEAR_RECTS_ACTIVITY));
assertSameElementsEventually(TEST_KEEP_CLEAR_RECTS_2,
() -> getKeepClearRectsForActivity(KEEP_CLEAR_RECTS_ACTIVITY2));
final List<Rect> expected = new ArrayList();
expected.addAll(getRectsInScreenSpace(TEST_KEEP_CLEAR_RECTS, KEEP_CLEAR_RECTS_ACTIVITY));
expected.addAll(getRectsInScreenSpace(TEST_KEEP_CLEAR_RECTS_2, KEEP_CLEAR_RECTS_ACTIVITY2));
assertSameElementsEventually(expected, () -> getKeepClearRectsOnDefaultDisplay());
}
@Test
public void testUnrestrictedKeepClearRects() throws Exception {
mTestSession.launchTestActivityOnDisplaySync(TestActivity.class, DEFAULT_DISPLAY);
final TestActivity activity = mTestSession.getActivity();
final View v = createTestViewInActivity(activity);
mTestSession.runOnMainSyncAndWait(() -> {
v.setUnrestrictedPreferKeepClearRects(TEST_KEEP_CLEAR_RECTS);
});
assertSameElementsEventually(EMPTY_LIST, () -> getKeepClearRectsForActivity(activity));
assertSameElementsEventually(EMPTY_LIST,
() -> getUnrestrictedKeepClearRectsForActivity(activity));
mTestSession.runOnMainSyncAndWait(() -> {
v.setPreferKeepClearRects(TEST_KEEP_CLEAR_RECTS);
});
assertSameElementsEventually(TEST_KEEP_CLEAR_RECTS,
() -> getKeepClearRectsForActivity(activity));
assertSameElementsEventually(EMPTY_LIST,
() -> getUnrestrictedKeepClearRectsForActivity(activity));
}
private View createTestViewInActivity(TestActivity activity) {
return createTestViewInActivity(activity, new Rect(0, 0, 100, 100));
}
private View createTestViewInActivity(TestActivity activity, Rect viewBounds) {
final View newView = new View(activity);
final LayoutParams params = new LayoutParams(viewBounds.width(), viewBounds.height());
params.leftMargin = viewBounds.left;
params.topMargin = viewBounds.top;
mTestSession.runOnMainSyncAndWait(() -> {
activity.addView(newView, params);
});
return newView;
}
private List<Rect> getKeepClearRectsForActivity(Activity activity) {
return getKeepClearRectsForActivity(activity.getComponentName());
}
private List<Rect> getKeepClearRectsForActivity(ComponentName activityComponent) {
mWmState.computeState();
return mWmState.getWindowState(activityComponent).getKeepClearRects();
}
private List<Rect> getKeepClearRectsOnDefaultDisplay() {
mWmState.computeState();
return mWmState.getDisplay(DEFAULT_DISPLAY).getKeepClearRects();
}
private List<Rect> getUnrestrictedKeepClearRectsForActivity(Activity activity) {
mWmState.computeState();
return mWmState.getWindowState(activity.getComponentName()).getUnrestrictedKeepClearRects();
}
public static class TestActivity extends FocusableActivity {
private RelativeLayout mRootView;
public void addView(View v, LayoutParams params) {
mRootView.addView(v, params);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getIntent().getBooleanExtra(USE_KEEP_CLEAR_ATTR_LAYOUT, false)) {
setContentView(R.layout.keep_clear_attr_activity);
} else {
setContentView(R.layout.keep_clear_rects_activity);
}
mRootView = findViewById(R.id.root);
getWindow().setDecorFitsSystemWindows(false);
}
}
public static class TranslucentTestActivity extends TestActivity {}
private List<Rect> getRectsInScreenSpace(List<Rect> rects, ComponentName componentName) {
mWmState.computeState();
final WindowManagerState.WindowState windowState =
mWmState.getWindowState(componentName);
final List<Rect> result = new ArrayList<>();
for (Rect r : rects) {
Rect rectInScreenSpace = new Rect(r);
rectInScreenSpace.offset(windowState.getFrame().left, windowState.getFrame().top);
result.add(rectInScreenSpace);
}
return result;
}
private static <T> void assertSameElementsEventually(List<T> expected, Callable<List<T>> actual)
throws Exception {
PollingCheck.check("Lists do not have the same elements.",
SAME_ELEMENT_ASSERTION_TIMEOUT,
() -> hasSameElements(expected, actual.call()));
}
private static <T> boolean hasSameElements(List<T> fst, List<T> snd) {
if (fst.size() != snd.size()) return false;
for (T a : fst) {
if (!snd.contains(a)) {
return false;
}
}
return true;
}
}