1/*
2 * Copyright (C) 2012 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 com.android.internal.widget;
18
19import com.android.frameworks.coretests.R;
20
21import android.content.Context;
22import android.graphics.Color;
23import android.graphics.drawable.ColorDrawable;
24import android.test.AndroidTestCase;
25import android.test.suitebuilder.annotation.SmallTest;
26import android.view.LayoutInflater;
27import android.view.View;
28
29import com.android.internal.widget.SizeAdaptiveLayout;
30
31
32public class SizeAdaptiveLayoutTest extends AndroidTestCase {
33
34    private LayoutInflater mInflater;
35    private int mOneU;
36    private int mFourU;
37    private SizeAdaptiveLayout mSizeAdaptiveLayout;
38    private View mSmallView;
39    private View mMediumView;
40    private View mLargeView;
41
42    @Override
43    protected void setUp() throws Exception {
44        super.setUp();
45
46        // inflate the layout
47        final Context context = getContext();
48        mInflater = LayoutInflater.from(context);
49        mOneU = 64;
50        mFourU = 4 * mOneU;
51    }
52
53    private void inflate(int resource){
54        mSizeAdaptiveLayout = (SizeAdaptiveLayout) mInflater.inflate(resource, null);
55        mSizeAdaptiveLayout.onAttachedToWindow();
56
57        mSmallView = mSizeAdaptiveLayout.findViewById(R.id.one_u);
58        mMediumView = mSizeAdaptiveLayout.findViewById(R.id.two_u);
59        mLargeView = mSizeAdaptiveLayout.findViewById(R.id.four_u);
60    }
61
62    /**
63     * The name 'test preconditions' is a convention to signal that if this
64     * test doesn't pass, the test case was not set up properly and it might
65     * explain any and all failures in other tests.  This is not guaranteed
66     * to run before other tests, as junit uses reflection to find the tests.
67     */
68    @SmallTest
69    public void testPreconditions() {
70        assertNotNull(mInflater);
71
72        inflate(R.layout.size_adaptive);
73        assertNotNull(mSizeAdaptiveLayout);
74        assertNotNull(mSmallView);
75        assertNotNull(mLargeView);
76    }
77
78    @SmallTest
79    public void testOpenLarge() {
80        inflate(R.layout.size_adaptive);
81        SizeAdaptiveLayout.LayoutParams lp =
82          (SizeAdaptiveLayout.LayoutParams) mLargeView.getLayoutParams();
83        int height = (int) lp.minHeight + 10;
84
85        measureAndLayout(height);
86
87        assertEquals("4U should be visible",
88                View.VISIBLE,
89                mLargeView.getVisibility());
90        assertEquals("1U should be gone",
91                View.GONE,
92                mSmallView.getVisibility());
93    }
94
95    @SmallTest
96    public void testOpenSmall() {
97        inflate(R.layout.size_adaptive);
98        SizeAdaptiveLayout.LayoutParams lp =
99          (SizeAdaptiveLayout.LayoutParams) mSmallView.getLayoutParams();
100        int height = (int) lp.minHeight;
101
102        measureAndLayout(height);
103
104        assertEquals("1U should be visible",
105                View.VISIBLE,
106                mSmallView.getVisibility());
107        assertEquals("4U should be gone",
108                View.GONE,
109                mLargeView.getVisibility());
110    }
111
112    @SmallTest
113    public void testOpenTooSmall() {
114        inflate(R.layout.size_adaptive);
115        SizeAdaptiveLayout.LayoutParams lp =
116          (SizeAdaptiveLayout.LayoutParams) mSmallView.getLayoutParams();
117        int height = (int) lp.minHeight - 10;
118
119        measureAndLayout(height);
120
121        assertEquals("1U should be visible",
122                View.VISIBLE,
123                mSmallView.getVisibility());
124        assertEquals("4U should be gone",
125                View.GONE,
126                mLargeView.getVisibility());
127    }
128
129    @SmallTest
130    public void testOpenTooBig() {
131        inflate(R.layout.size_adaptive);
132        SizeAdaptiveLayout.LayoutParams lp =
133          (SizeAdaptiveLayout.LayoutParams) mLargeView.getLayoutParams();
134        lp.maxHeight = 500;
135        mLargeView.setLayoutParams(lp);
136        int height = (int) (lp.minHeight + 10);
137
138        measureAndLayout(height);
139
140        assertEquals("4U should be visible",
141                View.VISIBLE,
142                mLargeView.getVisibility());
143        assertEquals("1U should be gone",
144                View.GONE,
145                mSmallView.getVisibility());
146    }
147
148    @SmallTest
149    public void testOpenWrapContent() {
150        inflate(R.layout.size_adaptive_text);
151        SizeAdaptiveLayout.LayoutParams lp =
152          (SizeAdaptiveLayout.LayoutParams) mLargeView.getLayoutParams();
153        int height = (int) lp.minHeight + 10;
154
155        // manually measure it, and lay it out
156        int measureSpec = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.AT_MOST);
157        mSizeAdaptiveLayout.measure(500, measureSpec);
158        assertTrue("should not be forced to 4U",
159                mSizeAdaptiveLayout.getMeasuredHeight() < mFourU);
160    }
161
162    @SmallTest
163    public void testOpenOneUOnlySmall() {
164        inflate(R.layout.size_adaptive_singleton);
165        assertNull("largeView should be NULL in the singleton layout", mLargeView);
166
167        SizeAdaptiveLayout.LayoutParams lp =
168          (SizeAdaptiveLayout.LayoutParams) mSmallView.getLayoutParams();
169        int height = (int) lp.minHeight - 10;
170
171        measureAndLayout(height);
172
173        assertEquals("1U should be visible",
174                View.VISIBLE,
175                mSmallView.getVisibility());
176    }
177
178    @SmallTest
179    public void testOpenOneUOnlyLarge() {
180        inflate(R.layout.size_adaptive_singleton);
181        assertNull("largeView should be NULL in the singleton layout", mLargeView);
182
183        SizeAdaptiveLayout.LayoutParams lp =
184          (SizeAdaptiveLayout.LayoutParams) mSmallView.getLayoutParams();
185        int height = (int) lp.maxHeight + 10;
186
187        measureAndLayout(height);
188
189        assertEquals("1U should be visible",
190                View.VISIBLE,
191                mSmallView.getVisibility());
192    }
193
194    @SmallTest
195    public void testOpenOneUOnlyJustRight() {
196        inflate(R.layout.size_adaptive_singleton);
197        assertNull("largeView should be NULL in the singleton layout", mLargeView);
198
199        SizeAdaptiveLayout.LayoutParams lp =
200          (SizeAdaptiveLayout.LayoutParams) mSmallView.getLayoutParams();
201        int height = (int) lp.minHeight;
202
203        measureAndLayout(height);
204
205        assertEquals("1U should be visible",
206                View.VISIBLE,
207                mSmallView.getVisibility());
208    }
209
210    @SmallTest
211    public void testOpenFourUOnlySmall() {
212        inflate(R.layout.size_adaptive_large_only);
213        assertNull("smallView should be NULL in the singleton layout", mSmallView);
214
215        SizeAdaptiveLayout.LayoutParams lp =
216          (SizeAdaptiveLayout.LayoutParams) mLargeView.getLayoutParams();
217        int height = (int) lp.minHeight - 10;
218
219        measureAndLayout(height);
220
221        assertEquals("4U should be visible",
222                View.VISIBLE,
223                mLargeView.getVisibility());
224    }
225
226    @SmallTest
227    public void testOpenFourUOnlyLarge() {
228        inflate(R.layout.size_adaptive_large_only);
229        assertNull("smallView should be NULL in the singleton layout", mSmallView);
230
231        SizeAdaptiveLayout.LayoutParams lp =
232          (SizeAdaptiveLayout.LayoutParams) mLargeView.getLayoutParams();
233        int height = (int) lp.maxHeight + 10;
234
235        measureAndLayout(height);
236
237        assertEquals("4U should be visible",
238                View.VISIBLE,
239                mLargeView.getVisibility());
240    }
241
242    @SmallTest
243    public void testOpenFourUOnlyJustRight() {
244        inflate(R.layout.size_adaptive_large_only);
245        assertNull("smallView should be NULL in the singleton layout", mSmallView);
246
247        SizeAdaptiveLayout.LayoutParams lp =
248          (SizeAdaptiveLayout.LayoutParams) mLargeView.getLayoutParams();
249        int height = (int) lp.minHeight;
250
251        measureAndLayout(height);
252
253        assertEquals("4U should be visible",
254                View.VISIBLE,
255                mLargeView.getVisibility());
256    }
257
258    @SmallTest
259    public void testOpenIntoAGap() {
260        inflate(R.layout.size_adaptive_gappy);
261
262        SizeAdaptiveLayout.LayoutParams smallParams =
263          (SizeAdaptiveLayout.LayoutParams) mSmallView.getLayoutParams();
264        SizeAdaptiveLayout.LayoutParams largeParams =
265          (SizeAdaptiveLayout.LayoutParams) mLargeView.getLayoutParams();
266        assertTrue("gappy layout should have a gap",
267                smallParams.maxHeight + 10 < largeParams.minHeight);
268        int height = (int) smallParams.maxHeight + 10;
269
270        measureAndLayout(height);
271
272        assertTrue("one and only one view should be visible",
273                mLargeView.getVisibility() != mSmallView.getVisibility());
274        // behavior is undefined in this case.
275    }
276
277    @SmallTest
278    public void testOpenIntoAnOverlap() {
279        inflate(R.layout.size_adaptive_overlapping);
280
281        SizeAdaptiveLayout.LayoutParams smallParams =
282          (SizeAdaptiveLayout.LayoutParams) mSmallView.getLayoutParams();
283        SizeAdaptiveLayout.LayoutParams largeParams =
284          (SizeAdaptiveLayout.LayoutParams) mLargeView.getLayoutParams();
285        assertEquals("overlapping layout should overlap",
286                smallParams.minHeight,
287                largeParams.minHeight);
288        int height = (int) smallParams.maxHeight;
289
290        measureAndLayout(height);
291
292        assertTrue("one and only one view should be visible",
293                mLargeView.getVisibility() != mSmallView.getVisibility());
294        assertEquals("1U should get priority in an overlap because it is first",
295                View.VISIBLE,
296                mSmallView.getVisibility());
297    }
298
299    @SmallTest
300    public void testOpenThreeWayViewSmall() {
301        inflate(R.layout.size_adaptive_three_way);
302        assertNotNull("mMediumView should not be NULL in the three view layout", mMediumView);
303
304        SizeAdaptiveLayout.LayoutParams lp =
305          (SizeAdaptiveLayout.LayoutParams) mSmallView.getLayoutParams();
306        int height = (int) lp.minHeight;
307
308        measureAndLayout(height);
309
310        assertEquals("1U should be visible",
311                View.VISIBLE,
312                mSmallView.getVisibility());
313        assertEquals("2U should be gone",
314                View.GONE,
315                mMediumView.getVisibility());
316        assertEquals("4U should be gone",
317                View.GONE,
318                mLargeView.getVisibility());
319    }
320
321    @SmallTest
322    public void testOpenThreeWayViewMedium() {
323        inflate(R.layout.size_adaptive_three_way);
324        assertNotNull("mMediumView should not be NULL in the three view layout", mMediumView);
325
326        SizeAdaptiveLayout.LayoutParams lp =
327          (SizeAdaptiveLayout.LayoutParams) mMediumView.getLayoutParams();
328        int height = (int) lp.minHeight;
329
330        measureAndLayout(height);
331
332        assertEquals("1U should be gone",
333                View.GONE,
334                mSmallView.getVisibility());
335        assertEquals("2U should be visible",
336                View.VISIBLE,
337                mMediumView.getVisibility());
338        assertEquals("4U should be gone",
339                View.GONE,
340                mLargeView.getVisibility());
341    }
342
343    @SmallTest
344    public void testOpenThreeWayViewLarge() {
345        inflate(R.layout.size_adaptive_three_way);
346        assertNotNull("mMediumView should not be NULL in the three view layout", mMediumView);
347
348        SizeAdaptiveLayout.LayoutParams lp =
349          (SizeAdaptiveLayout.LayoutParams) mLargeView.getLayoutParams();
350        int height = (int) lp.minHeight;
351
352        measureAndLayout(height);
353
354        assertEquals("1U should be gone",
355                View.GONE,
356                mSmallView.getVisibility());
357        assertEquals("2U should be gone",
358                View.GONE,
359                mMediumView.getVisibility());
360        assertEquals("4U should be visible",
361                View.VISIBLE,
362                mLargeView.getVisibility());
363    }
364
365    @SmallTest
366    public void testResizeWithoutAnimation() {
367        inflate(R.layout.size_adaptive);
368
369        SizeAdaptiveLayout.LayoutParams largeParams =
370          (SizeAdaptiveLayout.LayoutParams) mLargeView.getLayoutParams();
371        int startHeight = (int) largeParams.minHeight + 10;
372        int endHeight = (int) largeParams.minHeight + 10;
373
374        measureAndLayout(startHeight);
375
376        assertEquals("4U should be visible",
377                View.VISIBLE,
378                mLargeView.getVisibility());
379        assertFalse("There should be no animation on initial rendering.",
380                    mSizeAdaptiveLayout.getTransitionAnimation().isRunning());
381
382        measureAndLayout(endHeight);
383
384        assertEquals("4U should still be visible",
385                View.VISIBLE,
386                mLargeView.getVisibility());
387        assertFalse("There should be no animation on scale within a view.",
388                    mSizeAdaptiveLayout.getTransitionAnimation().isRunning());
389    }
390
391    @SmallTest
392    public void testResizeWithAnimation() {
393        inflate(R.layout.size_adaptive);
394
395        SizeAdaptiveLayout.LayoutParams smallParams =
396          (SizeAdaptiveLayout.LayoutParams) mSmallView.getLayoutParams();
397        SizeAdaptiveLayout.LayoutParams largeParams =
398          (SizeAdaptiveLayout.LayoutParams) mLargeView.getLayoutParams();
399        int startHeight = (int) largeParams.minHeight + 10;
400        int endHeight = (int) smallParams.maxHeight;
401
402        measureAndLayout(startHeight);
403
404        assertEquals("4U should be visible",
405                View.VISIBLE,
406                mLargeView.getVisibility());
407        assertFalse("There should be no animation on initial rendering.",
408                    mSizeAdaptiveLayout.getTransitionAnimation().isRunning());
409
410        measureAndLayout(endHeight);
411
412        assertEquals("1U should now be visible",
413                View.VISIBLE,
414                mSmallView.getVisibility());
415        assertTrue("There should be an animation on scale between views.",
416                   mSizeAdaptiveLayout.getTransitionAnimation().isRunning());
417    }
418
419    @SmallTest
420    public void testModestyPanelChangesColorWhite() {
421        inflate(R.layout.size_adaptive_color);
422        View panel = mSizeAdaptiveLayout.getModestyPanel();
423        assertTrue("ModestyPanel should have a ColorDrawable background",
424                   panel.getBackground() instanceof ColorDrawable);
425        ColorDrawable panelColor = (ColorDrawable) panel.getBackground();
426        ColorDrawable salColor = (ColorDrawable) mSizeAdaptiveLayout.getBackground();
427        assertEquals("ModestyPanel color should match the SizeAdaptiveLayout",
428                     panelColor.getColor(), salColor.getColor());
429    }
430
431    @SmallTest
432    public void testModestyPanelTracksStateListColor() {
433        inflate(R.layout.size_adaptive_color_statelist);
434        View panel = mSizeAdaptiveLayout.getModestyPanel();
435        assertEquals("ModestyPanel should have a ColorDrawable background" ,
436                     panel.getBackground().getClass(), ColorDrawable.class);
437        ColorDrawable panelColor = (ColorDrawable) panel.getBackground();
438        assertEquals("ModestyPanel color should match the SizeAdaptiveLayout",
439                     panelColor.getColor(), Color.RED);
440    }
441
442    @SmallTest
443    public void testModestyPanelHasDefault() {
444        inflate(R.layout.size_adaptive);
445        View panel = mSizeAdaptiveLayout.getModestyPanel();
446        assertNull("SizeAdaptiveLayout should have no background for this test",
447                     mSizeAdaptiveLayout.getBackground());
448        assertTrue("ModestyPanel should have a ColorDrawable background",
449                   panel.getBackground() instanceof ColorDrawable);
450    }
451
452    @SmallTest
453    public void testOpenSmallEvenWhenLargeIsActuallySmall() {
454        inflate(R.layout.size_adaptive_lies);
455        SizeAdaptiveLayout.LayoutParams lp =
456          (SizeAdaptiveLayout.LayoutParams) mSmallView.getLayoutParams();
457        int height = (int) lp.minHeight;
458
459        measureAndLayout(height);
460
461        assertEquals("1U should be visible",
462                View.VISIBLE,
463                mSmallView.getVisibility());
464        assertTrue("1U should also have been measured",
465                   mSmallView.getMeasuredHeight() > 0);
466    }
467
468    @SmallTest
469    public void testOpenLargeEvenWhenLargeIsActuallySmall() {
470        inflate(R.layout.size_adaptive_lies);
471        SizeAdaptiveLayout.LayoutParams lp =
472          (SizeAdaptiveLayout.LayoutParams) mLargeView.getLayoutParams();
473        int height = (int) lp.minHeight;
474
475        measureAndLayout(height);
476
477        assertEquals("4U should be visible",
478                View.VISIBLE,
479                mLargeView.getVisibility());
480        assertTrue("4U should also have been measured",
481                   mLargeView.getMeasuredHeight() > 0);
482    }
483
484    private void measureAndLayout(int height) {
485        // manually measure it, and lay it out
486        int measureSpec = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.AT_MOST);
487        mSizeAdaptiveLayout.measure(500, measureSpec);
488        mSizeAdaptiveLayout.layout(0, 0, 500, mSizeAdaptiveLayout.getMeasuredHeight());
489    }
490}
491