blob: 979a839d2ffea6de92b2e04ea368ebfbd085e8e7 [file] [log] [blame]
/*
* Copyright (C) 2019 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.view;
import static androidx.test.InstrumentationRegistry.getContext;
import static org.junit.Assert.assertEquals;
import android.content.Context;
import android.graphics.Region;
import android.platform.test.annotations.Presubmit;
import androidx.test.filters.SmallTest;
import org.junit.Test;
/**
* Test basic functions of ViewGroup.
*
* Build/Install/Run:
* atest FrameworksCoreTests:ViewGroupTest
*/
@Presubmit
@SmallTest
public class ViewGroupTest {
/**
* Test if {@link ViewGroup#subtractObscuredTouchableRegion} works as expected.
*
* The view hierarchy:
* A---B---C
* \ \
* \ --D
* \
* E---F
*
* The layer and bounds of each view:
* F -- (invisible)
* E --
* D ----
* C ----------
* B ------
* A --------
*/
@Test
public void testSubtractObscuredTouchableRegion() {
final Context context = getContext();
final TestView viewA = new TestView(context, 8 /* right */);
final TestView viewB = new TestView(context, 6 /* right */);
final TestView viewC = new TestView(context, 10 /* right */);
final TestView viewD = new TestView(context, 4 /* right */);
final TestView viewE = new TestView(context, 2 /* right */);
final TestView viewF = new TestView(context, 2 /* right */);
viewA.addView(viewB);
viewA.addView(viewE);
viewB.addView(viewC);
viewB.addView(viewD);
viewE.addView(viewF);
viewF.setVisibility(View.INVISIBLE);
final Region r = new Region();
getUnobscuredTouchableRegion(r, viewA);
assertRegionContainPoint(1 /* x */, r, true /* contain */);
assertRegionContainPoint(3 /* x */, r, true /* contain */);
assertRegionContainPoint(5 /* x */, r, true /* contain */);
assertRegionContainPoint(7 /* x */, r, true /* contain */);
assertRegionContainPoint(9 /* x */, r, false /* contain */); // Outside of bounds
getUnobscuredTouchableRegion(r, viewB);
assertRegionContainPoint(1 /* x */, r, false /* contain */); // Obscured by E
assertRegionContainPoint(3 /* x */, r, true /* contain */);
assertRegionContainPoint(5 /* x */, r, true /* contain */);
assertRegionContainPoint(7 /* x */, r, false /* contain */); // Outside of bounds
getUnobscuredTouchableRegion(r, viewC);
assertRegionContainPoint(1 /* x */, r, false /* contain */); // Obscured by D and E
assertRegionContainPoint(3 /* x */, r, false /* contain */); // Obscured by D
assertRegionContainPoint(5 /* x */, r, true /* contain */);
assertRegionContainPoint(7 /* x */, r, false /* contain */); // Outside of parent bounds
getUnobscuredTouchableRegion(r, viewD);
assertRegionContainPoint(1 /* x */, r, false /* contain */); // Obscured by E
assertRegionContainPoint(3 /* x */, r, true /* contain */);
assertRegionContainPoint(5 /* x */, r, false /* contain */); // Outside of bounds
getUnobscuredTouchableRegion(r, viewE);
assertRegionContainPoint(1 /* x */, r, true /* contain */);
assertRegionContainPoint(3 /* x */, r, false /* contain */); // Outside of bounds
}
private static void getUnobscuredTouchableRegion(Region outRegion, View view) {
outRegion.set(view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
final ViewParent parent = view.getParent();
if (parent != null) {
parent.subtractObscuredTouchableRegion(outRegion, view);
}
}
private static void assertRegionContainPoint(int x, Region region, boolean contain) {
assertEquals(String.format("Touchable region must%s contain (%s, 0).",
(contain ? "" : " not"), x), contain, region.contains(x, 0 /* y */));
}
private static class TestView extends ViewGroup {
TestView(Context context, int right) {
super(context);
setFrame(0 /* left */, 0 /* top */, right, 1 /* bottom */);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// We don't layout this view.
}
}
}