Home | History | Annotate | Download | only in widget
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package androidx.wear.widget;
     18 
     19 import static android.support.test.espresso.Espresso.onView;
     20 import static android.support.test.espresso.matcher.ViewMatchers.withId;
     21 
     22 import static androidx.wear.widget.util.MoreViewAssertions.approximateBottom;
     23 import static androidx.wear.widget.util.MoreViewAssertions.approximateTop;
     24 import static androidx.wear.widget.util.MoreViewAssertions.bottom;
     25 import static androidx.wear.widget.util.MoreViewAssertions.left;
     26 import static androidx.wear.widget.util.MoreViewAssertions.right;
     27 import static androidx.wear.widget.util.MoreViewAssertions.screenBottom;
     28 import static androidx.wear.widget.util.MoreViewAssertions.screenLeft;
     29 import static androidx.wear.widget.util.MoreViewAssertions.screenRight;
     30 import static androidx.wear.widget.util.MoreViewAssertions.screenTop;
     31 import static androidx.wear.widget.util.MoreViewAssertions.top;
     32 
     33 import static org.hamcrest.Matchers.closeTo;
     34 import static org.hamcrest.Matchers.equalTo;
     35 import static org.hamcrest.Matchers.is;
     36 
     37 import android.content.Intent;
     38 import android.support.test.InstrumentationRegistry;
     39 import android.support.test.filters.MediumTest;
     40 import android.support.test.rule.ActivityTestRule;
     41 import android.support.test.runner.AndroidJUnit4;
     42 import android.util.DisplayMetrics;
     43 import android.view.View;
     44 
     45 import androidx.wear.test.R;
     46 import androidx.wear.widget.util.WakeLockRule;
     47 
     48 import org.junit.Rule;
     49 import org.junit.Test;
     50 import org.junit.runner.RunWith;
     51 
     52 import java.util.HashMap;
     53 import java.util.Map;
     54 
     55 @MediumTest
     56 @RunWith(AndroidJUnit4.class)
     57 public class BoxInsetLayoutTest {
     58     private static final float FACTOR = 0.146467f; //(1 - sqrt(2)/2)/2
     59 
     60     @Rule
     61     public final WakeLockRule mWakeLock = new WakeLockRule();
     62 
     63     @Rule
     64     public final ActivityTestRule<LayoutTestActivity> mActivityRule = new ActivityTestRule<>(
     65             LayoutTestActivity.class, true, false);
     66 
     67     @Test
     68     public void testCase1() throws Throwable {
     69         mActivityRule.launchActivity(new Intent().putExtra(LayoutTestActivity
     70                 .EXTRA_LAYOUT_RESOURCE_ID, R.layout.box_inset_layout_testcase_1));
     71         DisplayMetrics dm = InstrumentationRegistry.getTargetContext().getResources()
     72                 .getDisplayMetrics();
     73         int boxInset = (int) (FACTOR * Math.min(dm.widthPixels, dm.heightPixels));
     74 
     75         int desiredPadding = 0;
     76         if (mActivityRule.getActivity().getResources().getConfiguration().isScreenRound()) {
     77             desiredPadding = boxInset;
     78         }
     79 
     80         ViewFetchingRunnable customRunnable = new ViewFetchingRunnable(){
     81             @Override
     82             public void run() {
     83                 View box = mActivityRule.getActivity().findViewById(R.id.box);
     84                 mIdViewMap.put(R.id.box, box);
     85             }
     86         };
     87         mActivityRule.runOnUiThread(customRunnable);
     88 
     89         View box = customRunnable.mIdViewMap.get(R.id.box);
     90         // proxy for window location
     91         View boxParent = (View) box.getParent();
     92         int parentLeft = boxParent.getLeft();
     93         int parentTop = boxParent.getTop();
     94         int parentRight = boxParent.getLeft() + boxParent.getWidth();
     95         int parentBottom = boxParent.getTop() + boxParent.getHeight();
     96 
     97         // Child 1 is match_parent width and height
     98         // layout_box=right|bottom
     99         // Padding of boxInset should be added to the right and bottom sides only
    100         onView(withId(R.id.child1))
    101                 .check(screenLeft(equalTo(parentLeft)))
    102                 .check(screenTop(equalTo(parentTop)))
    103                 .check(screenRight(equalTo(parentRight - desiredPadding)))
    104                 .check(screenBottom(equalTo(parentBottom - desiredPadding)));
    105 
    106         // Content 1 is is width and height match_parent
    107         // The bottom and right sides should be inset by boxInset pixels due to padding
    108         // on the parent view
    109         onView(withId(R.id.content1))
    110                 .check(screenLeft(equalTo(parentLeft)))
    111                 .check(screenTop(equalTo(parentTop)))
    112                 .check(screenRight(equalTo(parentRight - desiredPadding)))
    113                 .check(screenBottom(equalTo(parentBottom - desiredPadding)));
    114     }
    115 
    116     @Test
    117     public void testCase2() throws Throwable {
    118         mActivityRule.launchActivity(
    119                 new Intent().putExtra(LayoutTestActivity.EXTRA_LAYOUT_RESOURCE_ID,
    120                         R.layout.box_inset_layout_testcase_2));
    121         DisplayMetrics dm =
    122                 InstrumentationRegistry.getTargetContext().getResources().getDisplayMetrics();
    123         int boxInset = (int) (FACTOR * Math.min(dm.widthPixels, dm.heightPixels));
    124 
    125         int desiredPadding = 0;
    126         if (mActivityRule.getActivity().getResources().getConfiguration().isScreenRound()) {
    127             desiredPadding = boxInset;
    128         }
    129 
    130         ViewFetchingRunnable customRunnable = new ViewFetchingRunnable(){
    131             @Override
    132             public void run() {
    133                 View box = mActivityRule.getActivity().findViewById(R.id.box);
    134                 View child1 = mActivityRule.getActivity().findViewById(R.id.child1);
    135                 View child2 = mActivityRule.getActivity().findViewById(R.id.child2);
    136                 View child3 = mActivityRule.getActivity().findViewById(R.id.child3);
    137                 View child4 = mActivityRule.getActivity().findViewById(R.id.child4);
    138                 mIdViewMap.put(R.id.box, box);
    139                 mIdViewMap.put(R.id.child1, child1);
    140                 mIdViewMap.put(R.id.child2, child2);
    141                 mIdViewMap.put(R.id.child3, child3);
    142                 mIdViewMap.put(R.id.child4, child4);
    143 
    144             }
    145         };
    146         mActivityRule.runOnUiThread(customRunnable);
    147 
    148         View box = customRunnable.mIdViewMap.get(R.id.box);
    149         View child1 = customRunnable.mIdViewMap.get(R.id.child1);
    150         View child2 = customRunnable.mIdViewMap.get(R.id.child2);
    151         View child3 = customRunnable.mIdViewMap.get(R.id.child3);
    152         View child4 = customRunnable.mIdViewMap.get(R.id.child4);
    153 
    154         // proxy for window location
    155         View boxParent = (View) box.getParent();
    156         int parentLeft = boxParent.getLeft();
    157         int parentTop = boxParent.getTop();
    158         int parentRight = boxParent.getLeft() + boxParent.getWidth();
    159         int parentBottom = boxParent.getTop() + boxParent.getHeight();
    160         int parentWidth = boxParent.getWidth();
    161         int parentHeight = boxParent.getHeight();
    162 
    163         // Child 1 is width match_parent, height=60dp, gravity top
    164         // layout_box=all means it should have padding added to left, top and right
    165         onView(withId(R.id.child1))
    166                 .check(screenLeft(is(equalTo(parentLeft + desiredPadding))))
    167                 .check(screenTop(is(equalTo(parentTop + desiredPadding))))
    168                 .check(screenRight(is(equalTo(parentRight - desiredPadding))))
    169                 .check(screenBottom(is(equalTo(parentTop + desiredPadding + child1.getHeight()))));
    170 
    171         // Content 1 is width and height match_parent
    172         // the left top and right edges should be inset by boxInset pixels, due to
    173         // padding in the parent
    174         onView(withId(R.id.content1))
    175                 .check(screenLeft(equalTo(parentLeft + desiredPadding)))
    176                 .check(screenTop(equalTo(parentTop + desiredPadding)))
    177                 .check(screenRight(equalTo(parentRight - desiredPadding)));
    178 
    179         // Child 2 is width match_parent, height=60dp, gravity bottom
    180         // layout_box=all means it should have padding added to left, bottom and right
    181         onView(withId(R.id.child2))
    182                 .check(screenLeft(is(equalTo(parentLeft + desiredPadding))))
    183                 .check(screenTop(is(equalTo(parentBottom - desiredPadding - child2.getHeight()))))
    184                 .check(screenRight(is(equalTo(parentRight - desiredPadding))))
    185                 .check(screenBottom(is(equalTo(parentBottom - desiredPadding))));
    186 
    187         // Content 2 is width and height match_parent
    188         // the left bottom and right edges should be inset by boxInset pixels, due to
    189         // padding in the parent
    190         onView(withId(R.id.content2))
    191                 .check(screenLeft(equalTo(parentLeft + desiredPadding)))
    192                 .check(screenRight(equalTo(parentRight - desiredPadding)))
    193                 .check(screenBottom(equalTo(parentBottom - desiredPadding)));
    194 
    195         // Child 3 is width wrap_content, height=20dp, gravity left|center_vertical.
    196         // layout_box=all means it should have padding added to left
    197         // marginLeft be ignored due to gravity and layout_box=all (screenLeft=0)
    198         onView(withId(R.id.child3))
    199                 .check(screenLeft(is(equalTo(parentLeft + desiredPadding))))
    200                 .check(approximateTop(is(closeTo((parentHeight / 2 - child3.getHeight() / 2), 1))))
    201                 .check(screenRight(is(equalTo(parentLeft + desiredPadding + child3.getWidth()))))
    202                 .check(approximateBottom(is(
    203                         closeTo((parentHeight / 2 + child3.getHeight() / 2), 1))));
    204 
    205         // Content 3 width and height match_parent
    206         // the left edge should be offset from the screen edge by boxInset pixels, due to left on
    207         // the parent
    208         onView(withId(R.id.content3)).check(screenLeft(equalTo(desiredPadding)));
    209 
    210         // Child 4 is width wrap_content, height=20dp, gravity right|center_vertical.
    211         // layout_box=all means it should have padding added to right
    212         // it should have marginRight ignored due to gravity and layout_box=all (screenRight=max)
    213         onView(withId(R.id.child4))
    214                 .check(screenLeft(is(parentWidth - desiredPadding - child4.getWidth())))
    215                 .check(approximateTop(is(closeTo((parentHeight / 2 - child3.getHeight() / 2), 1))))
    216                 .check(screenRight(is(equalTo(parentWidth - desiredPadding))))
    217                 .check(approximateBottom(is(
    218                         closeTo((parentHeight / 2 + child4.getHeight() / 2), 1))));
    219 
    220         // Content 4 width and height wrap_content
    221         // the right edge should be offset from the screen edge by boxInset pixels, due to
    222         // right on the parent
    223         onView(withId(R.id.content4)).check(screenRight(equalTo(parentWidth - desiredPadding)));
    224     }
    225 
    226     @Test
    227     public void testCase3() throws Throwable {
    228         mActivityRule.launchActivity(
    229                 new Intent().putExtra(LayoutTestActivity.EXTRA_LAYOUT_RESOURCE_ID,
    230                         R.layout.box_inset_layout_testcase_3));
    231         DisplayMetrics dm =
    232                 InstrumentationRegistry.getTargetContext().getResources().getDisplayMetrics();
    233         int boxInset = (int) (FACTOR * Math.min(dm.widthPixels, dm.heightPixels));
    234 
    235         int desiredPadding = 0;
    236         if (mActivityRule.getActivity().getResources().getConfiguration().isScreenRound()) {
    237             desiredPadding = boxInset;
    238         }
    239 
    240         ViewFetchingRunnable customRunnable = new ViewFetchingRunnable(){
    241             @Override
    242             public void run() {
    243                 View box = mActivityRule.getActivity().findViewById(R.id.box);
    244                 View child1 = mActivityRule.getActivity().findViewById(R.id.child1);
    245                 View child2 = mActivityRule.getActivity().findViewById(R.id.child2);
    246                 View child3 = mActivityRule.getActivity().findViewById(R.id.child3);
    247                 View child4 = mActivityRule.getActivity().findViewById(R.id.child4);
    248                 mIdViewMap.put(R.id.box, box);
    249                 mIdViewMap.put(R.id.child1, child1);
    250                 mIdViewMap.put(R.id.child2, child2);
    251                 mIdViewMap.put(R.id.child3, child3);
    252                 mIdViewMap.put(R.id.child4, child4);
    253             }
    254         };
    255         mActivityRule.runOnUiThread(customRunnable);
    256 
    257         View box = customRunnable.mIdViewMap.get(R.id.box);
    258         View child1 = customRunnable.mIdViewMap.get(R.id.child1);
    259         View child2 = customRunnable.mIdViewMap.get(R.id.child2);
    260         View child3 = customRunnable.mIdViewMap.get(R.id.child3);
    261         View child4 = customRunnable.mIdViewMap.get(R.id.child4);
    262         // proxy for window location
    263         View boxParent = (View) box.getParent();
    264         int parentLeft = boxParent.getLeft();
    265         int parentTop = boxParent.getTop();
    266         int parentBottom = boxParent.getTop() + boxParent.getHeight();
    267         int parentWidth = boxParent.getWidth();
    268 
    269         // Child 1 is width and height wrap_content
    270         // gravity is top|left, position should be 0,0 on screen
    271         onView(withId(R.id.child1))
    272                 .check(screenLeft(is(equalTo(parentLeft + desiredPadding))))
    273                 .check(screenTop(is(equalTo(parentTop + desiredPadding))))
    274                 .check(screenRight(is(equalTo(parentLeft + desiredPadding + child1.getWidth()))))
    275                 .check(screenBottom(is(equalTo(parentTop + desiredPadding + child1.getHeight()))));
    276 
    277         // Content 1 is width and height wrap_content
    278         // the left and top edges should be offset from the screen edges by boxInset pixels
    279         onView(withId(R.id.content1))
    280                 .check(screenLeft(equalTo(parentLeft + desiredPadding)))
    281                 .check(screenTop(equalTo(parentTop + desiredPadding)));
    282 
    283         // Child 2 is width and height wrap_content
    284         // gravity is top|right, position should be 0,max on screen
    285         onView(withId(R.id.child2))
    286                 .check(screenLeft(is(equalTo(parentWidth - desiredPadding - child2.getWidth()))))
    287                 .check(screenTop(is(equalTo(parentTop + desiredPadding))))
    288                 .check(screenRight(is(equalTo(parentWidth - desiredPadding))))
    289                 .check(screenBottom(is(equalTo(parentTop + desiredPadding + child2.getHeight()))));
    290 
    291         // Content 2 is width and height wrap_content
    292         // the top and right edges should be offset from the screen edges by boxInset pixels
    293         onView(withId(R.id.content2))
    294                 .check(screenTop(equalTo(parentTop + desiredPadding)))
    295                 .check(screenRight(equalTo(parentWidth - desiredPadding)));
    296 
    297         // Child 3 is width and height wrap_content
    298         // gravity is bottom|right, position should be max,max on screen
    299         onView(withId(R.id.child3))
    300                 .check(screenLeft(is(equalTo(parentWidth - desiredPadding - child3.getWidth()))))
    301                 .check(screenTop(is(
    302                         equalTo(parentBottom - desiredPadding - child3.getHeight()))))
    303                 .check(screenRight(is(equalTo(parentWidth - desiredPadding))))
    304                 .check(screenBottom(is(equalTo(parentBottom - desiredPadding))));
    305 
    306         // Content 3 is width and height wrap_content
    307         // the right and bottom edges should be offset from the screen edges by boxInset pixels
    308         onView(withId(R.id.content3))
    309                 .check(screenBottom(equalTo(parentBottom - desiredPadding)))
    310                 .check(screenRight(equalTo(parentWidth - desiredPadding)));
    311 
    312         // Child 4 is width and height wrap_content
    313         // gravity is bottom|left, position should be max,0 on screen
    314         onView(withId(R.id.child4))
    315                 .check(screenLeft(is(equalTo(parentLeft + desiredPadding))))
    316                 .check(screenTop(is(equalTo(parentBottom - desiredPadding - child4.getHeight()))))
    317                 .check(screenRight(is(equalTo(parentLeft + desiredPadding + child4.getWidth()))))
    318                 .check(screenBottom(is(equalTo(parentBottom - desiredPadding))));
    319 
    320         // Content 3 is width and height wrap_content
    321         // the bottom and left edges should be offset from the screen edges by boxInset pixels
    322         onView(withId(R.id.content4)).check(
    323                 screenBottom(equalTo(parentBottom - desiredPadding)))
    324                 .check(screenLeft(equalTo(parentLeft + desiredPadding)));
    325     }
    326 
    327     @Test
    328     public void testCase4() throws Throwable {
    329         mActivityRule.launchActivity(new Intent().putExtra(LayoutTestActivity
    330                 .EXTRA_LAYOUT_RESOURCE_ID, R.layout.box_inset_layout_testcase_4));
    331         DisplayMetrics dm = InstrumentationRegistry.getTargetContext().getResources()
    332                 .getDisplayMetrics();
    333         int boxInset = (int) (FACTOR * Math.min(dm.widthPixels, dm.heightPixels));
    334 
    335         int desiredPadding = 0;
    336         if (mActivityRule.getActivity().getResources().getConfiguration().isScreenRound()) {
    337             desiredPadding = boxInset;
    338         }
    339 
    340         ViewFetchingRunnable customRunnable = new ViewFetchingRunnable(){
    341             @Override
    342             public void run() {
    343                 View container = mActivityRule.getActivity().findViewById(R.id.container);
    344                 View child1 = mActivityRule.getActivity().findViewById(R.id.child1);
    345                 mIdViewMap.put(R.id.container, container);
    346                 mIdViewMap.put(R.id.child1, child1);
    347 
    348             }
    349         };
    350         mActivityRule.runOnUiThread(customRunnable);
    351 
    352         View container = customRunnable.mIdViewMap.get(R.id.container);
    353         View child1 = customRunnable.mIdViewMap.get(R.id.child1);
    354         // Child 1 is match_parent width and wrap_content height
    355         // layout_box=right|left
    356         // Padding of boxInset should be added to the right and bottom sides only
    357         onView(withId(R.id.child1)).check(left(equalTo(desiredPadding))).check(
    358                 top(equalTo(container.getTop()))).check(
    359                 right(equalTo(dm.widthPixels - desiredPadding))).check(
    360                 bottom(equalTo(container.getTop() + child1.getHeight())));
    361     }
    362 
    363     private abstract class ViewFetchingRunnable implements Runnable {
    364         Map<Integer, View> mIdViewMap = new HashMap<>();
    365     }
    366 }
    367