ViewRootImplTest.java revision 7419a17d9243ddb0629af24d0308797154e44925
1/*
2 * Copyright (C) 2018 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
17package android.view;
18
19import static org.hamcrest.Matchers.equalTo;
20import static org.junit.Assert.assertThat;
21
22import android.content.Context;
23import android.graphics.Rect;
24import android.platform.test.annotations.Presubmit;
25import android.support.test.InstrumentationRegistry;
26import android.support.test.filters.SmallTest;
27import android.support.test.runner.AndroidJUnit4;
28
29import org.junit.Before;
30import org.junit.Test;
31import org.junit.runner.RunWith;
32
33import java.lang.reflect.Field;
34import java.lang.reflect.Method;
35
36@Presubmit
37@SmallTest
38@RunWith(AndroidJUnit4.class)
39public class ViewRootImplTest {
40
41    private Context mContext;
42    private ViewRootImplAccessor mViewRootImpl;
43
44    @Before
45    public void setUp() throws Exception {
46        mContext = InstrumentationRegistry.getContext();
47
48        InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
49            mViewRootImpl = new ViewRootImplAccessor(
50                    new ViewRootImpl(mContext, mContext.getDisplay()));
51        });
52    }
53
54    @Test
55    public void negativeInsets_areSetToZero() throws Exception {
56        mViewRootImpl.getAttachInfo().getContentInsets().set(-10, -20, -30 , -40);
57        mViewRootImpl.getAttachInfo().getStableInsets().set(-10, -20, -30 , -40);
58        final WindowInsets insets = mViewRootImpl.getWindowInsets(true /* forceConstruct */);
59
60        assertThat(insets.getSystemWindowInsets(), equalTo(new Rect()));
61        assertThat(new Rect(insets.getStableInsetLeft(), insets.getStableInsetTop(),
62                insets.getStableInsetRight(), insets.getStableInsetBottom()), equalTo(new Rect()));
63    }
64
65    @Test
66    public void negativeInsets_areSetToZero_positiveAreLeftAsIs() throws Exception {
67        mViewRootImpl.getAttachInfo().getContentInsets().set(-10, 20, -30 , 40);
68        mViewRootImpl.getAttachInfo().getStableInsets().set(10, -20, 30 , -40);
69        final WindowInsets insets = mViewRootImpl.getWindowInsets(true /* forceConstruct */);
70
71        assertThat(insets.getSystemWindowInsets(), equalTo(new Rect(0, 20, 0, 40)));
72        assertThat(new Rect(insets.getStableInsetLeft(), insets.getStableInsetTop(),
73                insets.getStableInsetRight(), insets.getStableInsetBottom()),
74                equalTo(new Rect(10, 0, 30, 0)));
75    }
76
77    @Test
78    public void positiveInsets_areLeftAsIs() throws Exception {
79        mViewRootImpl.getAttachInfo().getContentInsets().set(10, 20, 30 , 40);
80        mViewRootImpl.getAttachInfo().getStableInsets().set(10, 20, 30 , 40);
81        final WindowInsets insets = mViewRootImpl.getWindowInsets(true /* forceConstruct */);
82
83        assertThat(insets.getSystemWindowInsets(), equalTo(new Rect(10, 20, 30, 40)));
84        assertThat(new Rect(insets.getStableInsetLeft(), insets.getStableInsetTop(),
85                insets.getStableInsetRight(), insets.getStableInsetBottom()),
86                equalTo(new Rect(10, 20, 30, 40)));
87    }
88
89    private static class ViewRootImplAccessor {
90
91        private final ViewRootImpl mViewRootImpl;
92
93        ViewRootImplAccessor(ViewRootImpl viewRootImpl) {
94            mViewRootImpl = viewRootImpl;
95        }
96
97        public ViewRootImpl get() {
98            return mViewRootImpl;
99        }
100
101        AttachInfoAccessor getAttachInfo() throws Exception {
102            return new AttachInfoAccessor(
103                    getField(mViewRootImpl, ViewRootImpl.class.getDeclaredField("mAttachInfo")));
104        }
105
106        WindowInsets getWindowInsets(boolean forceConstruct) throws Exception {
107            return (WindowInsets) invokeMethod(mViewRootImpl,
108                    ViewRootImpl.class.getDeclaredMethod("getWindowInsets", boolean.class),
109                    forceConstruct);
110        }
111
112        class AttachInfoAccessor {
113
114            private final Class<?> mClass;
115            private final Object mAttachInfo;
116
117            AttachInfoAccessor(Object attachInfo) throws Exception {
118                mAttachInfo = attachInfo;
119                mClass = ViewRootImpl.class.getClassLoader().loadClass(
120                        "android.view.View$AttachInfo");
121            }
122
123            Rect getContentInsets() throws Exception {
124                return (Rect) getField(mAttachInfo, mClass.getDeclaredField("mContentInsets"));
125            }
126
127            Rect getStableInsets() throws Exception {
128                return (Rect) getField(mAttachInfo, mClass.getDeclaredField("mStableInsets"));
129            }
130        }
131
132        private static Object getField(Object o, Field field) throws Exception {
133            field.setAccessible(true);
134            return field.get(o);
135        }
136
137        private static Object invokeMethod(Object o, Method method, Object... args)
138                throws Exception {
139            method.setAccessible(true);
140            return method.invoke(o, args);
141        }
142    }
143}
144