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 com.android.internal.widget;
     18 
     19 import static org.junit.Assert.assertEquals;
     20 import static org.junit.Assert.assertFalse;
     21 import static org.junit.Assert.assertTrue;
     22 
     23 import android.content.Context;
     24 import android.support.test.InstrumentationRegistry;
     25 import android.support.test.filters.SmallTest;
     26 import android.text.Layout;
     27 import android.view.LayoutInflater;
     28 import android.view.View.MeasureSpec;
     29 
     30 import com.android.frameworks.coretests.R;
     31 
     32 import org.junit.Before;
     33 import org.junit.Test;
     34 
     35 import java.lang.reflect.Field;
     36 
     37 @SmallTest
     38 public class MessagingLinearLayoutTest {
     39 
     40     public static final int WIDTH_SPEC = MeasureSpec.makeMeasureSpec(500, MeasureSpec.EXACTLY);
     41     public static final int HEIGHT_SPEC = MeasureSpec.makeMeasureSpec(400, MeasureSpec.AT_MOST);
     42     private Context mContext;
     43     private MessagingLinearLayout mView;
     44 
     45     @Before
     46     public void setup() {
     47         mContext = InstrumentationRegistry.getTargetContext();
     48         // spacing: 5px
     49         mView = (MessagingLinearLayout) LayoutInflater.from(mContext).inflate(
     50                 R.layout.messaging_linear_layout_test, null);
     51     }
     52 
     53     @Test
     54     public void testSingleChild() {
     55         FakeImageFloatingTextView child = fakeChild(3);
     56 
     57         mView.addView(child);
     58 
     59         mView.measure(WIDTH_SPEC, HEIGHT_SPEC);
     60         mView.layout(0, 0, mView.getMeasuredWidth(), mView.getMeasuredHeight());
     61 
     62         assertFalse(child.isHidden());
     63         assertEquals(150, mView.getMeasuredHeight());
     64     }
     65 
     66     @Test
     67     public void testLargeSmall() {
     68         FakeImageFloatingTextView child1 = fakeChild(3);
     69         FakeImageFloatingTextView child2 = fakeChild(1);
     70 
     71         mView.addView(child1);
     72         mView.addView(child2);
     73 
     74         mView.measure(WIDTH_SPEC, HEIGHT_SPEC);
     75         mView.layout(0, 0, mView.getMeasuredWidth(), mView.getMeasuredHeight());
     76 
     77         assertFalse("child1 should not be hidden", child1.isHidden());
     78         assertFalse("child2 should not be hidden", child2.isHidden());
     79         assertEquals(205, mView.getMeasuredHeight());
     80     }
     81 
     82     @Test
     83     public void testSmallSmall() {
     84         FakeImageFloatingTextView child1 = fakeChild(1);
     85         FakeImageFloatingTextView child2 = fakeChild(1);
     86 
     87         mView.addView(child1);
     88         mView.addView(child2);
     89 
     90         mView.measure(WIDTH_SPEC, HEIGHT_SPEC);
     91         mView.layout(0, 0, mView.getMeasuredWidth(), mView.getMeasuredHeight());
     92 
     93         assertFalse("child1 should not be hidden", child1.isHidden());
     94         assertFalse("child2 should not be hidden", child2.isHidden());
     95         assertEquals(105, mView.getMeasuredHeight());
     96     }
     97 
     98     @Test
     99     public void testLargeLarge() {
    100         FakeImageFloatingTextView child1 = fakeChild(7);
    101         FakeImageFloatingTextView child2 = fakeChild(7);
    102 
    103         mView.addView(child1);
    104         mView.addView(child2);
    105 
    106         mView.measure(WIDTH_SPEC, HEIGHT_SPEC);
    107         mView.layout(0, 0, mView.getMeasuredWidth(), mView.getMeasuredHeight());
    108 
    109         assertTrue("child1 should be hidden", child1.isHidden());
    110         assertFalse("child2 should not be hidden", child2.isHidden());
    111         assertEquals(350, mView.getMeasuredHeight());
    112     }
    113 
    114     @Test
    115     public void testLargeSmall_largeWrapsWith3indentbutNotFullHeight_andHitsMax() {
    116         FakeImageFloatingTextView child1 = fakeChild(7);
    117         FakeImageFloatingTextView child2 = fakeChild(1);
    118 
    119         mView.addView(child1);
    120         mView.addView(child2);
    121 
    122         mView.measure(WIDTH_SPEC, HEIGHT_SPEC);
    123         mView.layout(0, 0, mView.getMeasuredWidth(), mView.getMeasuredHeight());
    124 
    125         assertFalse("child1 should not be hidden", child1.isHidden());
    126         assertFalse("child2 should not be hidden", child2.isHidden());
    127         assertEquals(355, mView.getMeasuredHeight());;
    128     }
    129 
    130     private class FakeImageFloatingTextView extends MessagingTextMessage {
    131 
    132         public static final int LINE_HEIGHT = 50;
    133         private final int mNumLines;
    134 
    135         public FakeImageFloatingTextView(Context context,
    136                 int linesForIndent) {
    137             super(context, null, 0, 0);
    138             mNumLines = linesForIndent;
    139         }
    140 
    141         @Override
    142         public int getLayoutHeight() {
    143             return Math.max(LINE_HEIGHT, getMeasuredHeight());
    144         }
    145 
    146         @Override
    147         protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    148             setMeasuredDimension(
    149                     getDefaultSize(500, widthMeasureSpec),
    150                     clampToMultiplesOfLineHeight(resolveSize(getDesiredHeight(),
    151                             heightMeasureSpec)));
    152         }
    153 
    154         public int getMeasuredType() {
    155             boolean measuredTooSmall = getMeasuredHeight()
    156                     < getLayoutHeight() + getPaddingTop() + getPaddingBottom();
    157             if (measuredTooSmall) {
    158                 return MEASURED_TOO_SMALL;
    159             } else {
    160                 if (getMeasuredHeight() == getDesiredHeight()) {
    161                     return MEASURED_NORMAL;
    162                 } else {
    163                     return MEASURED_SHORTENED;
    164                 }
    165             }
    166         }
    167 
    168         private int clampToMultiplesOfLineHeight(int size) {
    169             if (size <= LINE_HEIGHT) {
    170                 return size;
    171             }
    172             return (size / LINE_HEIGHT) * LINE_HEIGHT;
    173         }
    174 
    175         @Override
    176         public int getLineCount() {
    177             return mNumLines;
    178         }
    179 
    180         public int getDesiredHeight() {
    181             return LINE_HEIGHT * getLineCount();
    182         }
    183 
    184         @Override
    185         protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    186             // swallow
    187         }
    188 
    189         public boolean isHidden() {
    190             MessagingLinearLayout.LayoutParams lp =
    191                     (MessagingLinearLayout.LayoutParams) getLayoutParams();
    192             try {
    193                 Field hide = MessagingLinearLayout.LayoutParams.class.getDeclaredField("hide");
    194                 hide.setAccessible(true);
    195                 return hide.getBoolean(lp);
    196             } catch (ReflectiveOperationException e) {
    197                 throw new RuntimeException(e);
    198             }
    199         }
    200     }
    201 
    202     private FakeImageFloatingTextView fakeChild(int numLines) {
    203         return new FakeImageFloatingTextView(mContext, numLines);
    204     }
    205 }
    206