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.view.LayoutInflater;
     27 import android.view.View.MeasureSpec;
     28 
     29 import com.android.frameworks.coretests.R;
     30 import com.google.common.base.Function;
     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((i) -> 3);
     56 
     57         mView.setNumIndentLines(2);
     58         mView.addView(child);
     59 
     60         mView.measure(WIDTH_SPEC, HEIGHT_SPEC);
     61         mView.layout(0, 0, mView.getMeasuredWidth(), mView.getMeasuredHeight());
     62 
     63         assertEquals(3, child.getNumIndentLines());
     64         assertFalse(child.isHidden());
     65         assertEquals(150, mView.getMeasuredHeight());
     66     }
     67 
     68     @Test
     69     public void testLargeSmall() {
     70         FakeImageFloatingTextView child1 = fakeChild((i) -> 3);
     71         FakeImageFloatingTextView child2 = fakeChild((i) -> 1);
     72 
     73         mView.setNumIndentLines(2);
     74         mView.addView(child1);
     75         mView.addView(child2);
     76 
     77         mView.measure(WIDTH_SPEC, HEIGHT_SPEC);
     78         mView.layout(0, 0, mView.getMeasuredWidth(), mView.getMeasuredHeight());
     79 
     80         assertEquals(3, child1.getNumIndentLines());
     81         assertEquals(0, child2.getNumIndentLines());
     82         assertFalse("child1 should not be hidden", child1.isHidden());
     83         assertFalse("child2 should not be hidden", child2.isHidden());
     84         assertEquals(205, mView.getMeasuredHeight());
     85     }
     86 
     87     @Test
     88     public void testSmallSmall() {
     89         FakeImageFloatingTextView child1 = fakeChild((i) -> 1);
     90         FakeImageFloatingTextView child2 = fakeChild((i) -> 1);
     91 
     92         mView.setNumIndentLines(2);
     93         mView.addView(child1);
     94         mView.addView(child2);
     95 
     96         mView.measure(WIDTH_SPEC, HEIGHT_SPEC);
     97         mView.layout(0, 0, mView.getMeasuredWidth(), mView.getMeasuredHeight());
     98 
     99         assertEquals(2, child1.getNumIndentLines());
    100         assertEquals(1, child2.getNumIndentLines());
    101         assertFalse("child1 should not be hidden", child1.isHidden());
    102         assertFalse("child2 should not be hidden", child2.isHidden());
    103         assertEquals(105, mView.getMeasuredHeight());
    104     }
    105 
    106     @Test
    107     public void testLargeLarge() {
    108         FakeImageFloatingTextView child1 = fakeChild((i) -> 7);
    109         FakeImageFloatingTextView child2 = fakeChild((i) -> 7);
    110 
    111         mView.setNumIndentLines(2);
    112         mView.addView(child1);
    113         mView.addView(child2);
    114 
    115         mView.measure(WIDTH_SPEC, HEIGHT_SPEC);
    116         mView.layout(0, 0, mView.getMeasuredWidth(), mView.getMeasuredHeight());
    117 
    118         assertEquals(3, child2.getNumIndentLines());
    119         assertTrue("child1 should be hidden", child1.isHidden());
    120         assertFalse("child2 should not be hidden", child2.isHidden());
    121         assertEquals(350, mView.getMeasuredHeight());
    122     }
    123 
    124     @Test
    125     public void testLargeSmall_largeWrapsWith3indentbutNotFullHeight_andHitsMax() {
    126         FakeImageFloatingTextView child1 = fakeChild((i) -> i > 2 ? 7 : 6);
    127         FakeImageFloatingTextView child2 = fakeChild((i) -> 1);
    128 
    129         mView.setNumIndentLines(2);
    130         mView.addView(child1);
    131         mView.addView(child2);
    132 
    133         mView.measure(WIDTH_SPEC, HEIGHT_SPEC);
    134         mView.layout(0, 0, mView.getMeasuredWidth(), mView.getMeasuredHeight());
    135 
    136         assertFalse("child1 should not be hidden", child1.isHidden());
    137         assertFalse("child2 should not be hidden", child2.isHidden());
    138         assertEquals(355, mView.getMeasuredHeight());
    139         assertEquals(3, child1.getNumIndentLines());
    140         assertEquals(0, child2.getNumIndentLines());
    141     }
    142 
    143     @Test
    144     public void testLargeSmall_largeWrapsWith3indentbutnot3() {
    145         FakeImageFloatingTextView child1 = fakeChild((i) -> i > 2 ? 4 : 3);
    146         FakeImageFloatingTextView child2 = fakeChild((i) -> 1);
    147 
    148         mView.setNumIndentLines(2);
    149         mView.addView(child1);
    150         mView.addView(child2);
    151 
    152         mView.measure(WIDTH_SPEC, HEIGHT_SPEC);
    153         mView.layout(0, 0, mView.getMeasuredWidth(), mView.getMeasuredHeight());
    154 
    155         assertFalse("child1 should not be hidden", child1.isHidden());
    156         assertFalse("child2 should not be hidden", child2.isHidden());
    157         assertEquals(255, mView.getMeasuredHeight());
    158         assertEquals(3, child1.getNumIndentLines());
    159         assertEquals(0, child2.getNumIndentLines());
    160     }
    161 
    162     private class FakeImageFloatingTextView extends ImageFloatingTextView {
    163 
    164         public static final int LINE_HEIGHT = 50;
    165         private final Function<Integer, Integer> mLinesForIndent;
    166         private int mNumIndentLines;
    167 
    168         public FakeImageFloatingTextView(Context context,
    169                 Function<Integer, Integer> linesForIndent) {
    170             super(context, null, 0, 0);
    171             mLinesForIndent = linesForIndent;
    172         }
    173 
    174         @Override
    175         public boolean setNumIndentLines(int lines) {
    176             boolean changed = (mNumIndentLines != lines);
    177             mNumIndentLines = lines;
    178             return changed;
    179         }
    180 
    181         public int getNumIndentLines() {
    182             return mNumIndentLines;
    183         }
    184 
    185         @Override
    186         public int getLayoutHeight() {
    187             return Math.max(LINE_HEIGHT, getMeasuredHeight());
    188         }
    189 
    190         @Override
    191         protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    192             setMeasuredDimension(
    193                     getDefaultSize(500, widthMeasureSpec),
    194                     clampToMultiplesOfLineHeight(resolveSize(getDesiredHeight(),
    195                             heightMeasureSpec)));
    196         }
    197 
    198         private int clampToMultiplesOfLineHeight(int size) {
    199             if (size <= LINE_HEIGHT) {
    200                 return size;
    201             }
    202             return (size / LINE_HEIGHT) * LINE_HEIGHT;
    203         }
    204 
    205         @Override
    206         public int getLineCount() {
    207             return mLinesForIndent.apply(mNumIndentLines);
    208         }
    209 
    210         public int getDesiredHeight() {
    211             return LINE_HEIGHT * getLineCount();
    212         }
    213 
    214         @Override
    215         protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    216             // swallow
    217         }
    218 
    219         public boolean isHidden() {
    220             MessagingLinearLayout.LayoutParams lp =
    221                     (MessagingLinearLayout.LayoutParams) getLayoutParams();
    222             try {
    223                 Field hide = MessagingLinearLayout.LayoutParams.class.getDeclaredField("hide");
    224                 hide.setAccessible(true);
    225                 return hide.getBoolean(lp);
    226             } catch (ReflectiveOperationException e) {
    227                 throw new RuntimeException(e);
    228             }
    229         }
    230     }
    231 
    232     private FakeImageFloatingTextView fakeChild(Function<Integer,Integer> linesForIndent) {
    233         return new FakeImageFloatingTextView(mContext, linesForIndent);
    234     }
    235 }
    236