Home | History | Annotate | Download | only in android
      1 package org.robolectric.android;
      2 
      3 import static android.content.res.Configuration.KEYBOARDHIDDEN_SOFT;
      4 import static android.content.res.Configuration.KEYBOARDHIDDEN_YES;
      5 import static android.content.res.Configuration.KEYBOARD_12KEY;
      6 import static android.content.res.Configuration.KEYBOARD_NOKEYS;
      7 import static android.content.res.Configuration.NAVIGATIONHIDDEN_YES;
      8 import static android.content.res.Configuration.NAVIGATION_DPAD;
      9 import static android.content.res.Configuration.NAVIGATION_NONAV;
     10 import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
     11 import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
     12 import static android.content.res.Configuration.SCREENLAYOUT_LAYOUTDIR_LTR;
     13 import static android.content.res.Configuration.SCREENLAYOUT_LAYOUTDIR_MASK;
     14 import static android.content.res.Configuration.SCREENLAYOUT_LAYOUTDIR_RTL;
     15 import static android.content.res.Configuration.SCREENLAYOUT_LONG_MASK;
     16 import static android.content.res.Configuration.SCREENLAYOUT_LONG_NO;
     17 import static android.content.res.Configuration.SCREENLAYOUT_LONG_YES;
     18 import static android.content.res.Configuration.SCREENLAYOUT_ROUND_MASK;
     19 import static android.content.res.Configuration.SCREENLAYOUT_ROUND_NO;
     20 import static android.content.res.Configuration.SCREENLAYOUT_ROUND_YES;
     21 import static android.content.res.Configuration.SCREENLAYOUT_SIZE_MASK;
     22 import static android.content.res.Configuration.SCREENLAYOUT_SIZE_NORMAL;
     23 import static android.content.res.Configuration.SCREENLAYOUT_SIZE_XLARGE;
     24 import static android.content.res.Configuration.TOUCHSCREEN_FINGER;
     25 import static android.content.res.Configuration.TOUCHSCREEN_NOTOUCH;
     26 import static android.content.res.Configuration.UI_MODE_NIGHT_MASK;
     27 import static android.content.res.Configuration.UI_MODE_NIGHT_NO;
     28 import static android.content.res.Configuration.UI_MODE_NIGHT_YES;
     29 import static android.content.res.Configuration.UI_MODE_TYPE_APPLIANCE;
     30 import static android.content.res.Configuration.UI_MODE_TYPE_MASK;
     31 import static android.content.res.Configuration.UI_MODE_TYPE_UNDEFINED;
     32 import static android.os.Build.VERSION_CODES.JELLY_BEAN;
     33 import static android.view.Surface.ROTATION_0;
     34 import static android.view.Surface.ROTATION_90;
     35 import static org.assertj.core.api.Assertions.assertThat;
     36 import static org.junit.Assert.fail;
     37 
     38 import android.content.Context;
     39 import android.content.res.Configuration;
     40 import android.hardware.display.DisplayManager;
     41 import android.os.Build;
     42 import android.util.DisplayMetrics;
     43 import android.view.Display;
     44 import android.view.DisplayInfo;
     45 import java.util.Locale;
     46 import org.junit.Before;
     47 import org.junit.Test;
     48 import org.junit.runner.RunWith;
     49 import org.robolectric.RobolectricTestRunner;
     50 import org.robolectric.RuntimeEnvironment;
     51 import org.robolectric.annotation.Config;
     52 
     53 @RunWith(RobolectricTestRunner.class)
     54 public class BootstrapTest {
     55 
     56   private Configuration configuration;
     57   private DisplayMetrics displayMetrics;
     58 
     59   @Before
     60   public void setUp() throws Exception {
     61     configuration = new Configuration();
     62     displayMetrics = new DisplayMetrics();
     63   }
     64 
     65   @Test
     66   @Config(qualifiers = "w480dp-h640dp")
     67   public void shouldSetUpRealisticDisplay() throws Exception {
     68     if (Build.VERSION.SDK_INT > JELLY_BEAN) {
     69       DisplayManager displayManager = (DisplayManager) RuntimeEnvironment.application
     70           .getSystemService(Context.DISPLAY_SERVICE);
     71       DisplayInfo displayInfo = new DisplayInfo();
     72       Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
     73       display.getDisplayInfo(displayInfo);
     74 
     75       assertThat(displayInfo.name).isEqualTo("Built-in screen");
     76       assertThat(displayInfo.appWidth).isEqualTo(480);
     77       assertThat(displayInfo.appHeight).isEqualTo(640);
     78       assertThat(displayInfo.smallestNominalAppWidth).isEqualTo(480);
     79       assertThat(displayInfo.smallestNominalAppHeight).isEqualTo(480);
     80       assertThat(displayInfo.largestNominalAppWidth).isEqualTo(640);
     81       assertThat(displayInfo.largestNominalAppHeight).isEqualTo(640);
     82       assertThat(displayInfo.logicalWidth).isEqualTo(480);
     83       assertThat(displayInfo.logicalHeight).isEqualTo(640);
     84       assertThat(displayInfo.rotation).isEqualTo(ROTATION_0);
     85       assertThat(displayInfo.logicalDensityDpi).isEqualTo(160);
     86       assertThat(displayInfo.physicalXDpi).isEqualTo(160f);
     87       assertThat(displayInfo.physicalYDpi).isEqualTo(160f);
     88       if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {
     89         assertThat(displayInfo.state).isEqualTo(Display.STATE_ON);
     90       }
     91     }
     92 
     93     DisplayMetrics displayMetrics = RuntimeEnvironment.application.getResources()
     94         .getDisplayMetrics();
     95     assertThat(displayMetrics.widthPixels).isEqualTo(480);
     96     assertThat(displayMetrics.heightPixels).isEqualTo(640);
     97   }
     98 
     99   @Test
    100   @Config(qualifiers = "w480dp-h640dp-land-hdpi")
    101   public void shouldSetUpRealisticDisplay_landscapeHighDensity() throws Exception {
    102     if (Build.VERSION.SDK_INT > JELLY_BEAN) {
    103       DisplayManager displayManager = (DisplayManager) RuntimeEnvironment.application
    104           .getSystemService(Context.DISPLAY_SERVICE);
    105       DisplayInfo displayInfo = new DisplayInfo();
    106       Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
    107       display.getDisplayInfo(displayInfo);
    108 
    109       assertThat(displayInfo.name).isEqualTo("Built-in screen");
    110       assertThat(displayInfo.appWidth).isEqualTo(960);
    111       assertThat(displayInfo.appHeight).isEqualTo(720);
    112       assertThat(displayInfo.smallestNominalAppWidth).isEqualTo(720);
    113       assertThat(displayInfo.smallestNominalAppHeight).isEqualTo(720);
    114       assertThat(displayInfo.largestNominalAppWidth).isEqualTo(960);
    115       assertThat(displayInfo.largestNominalAppHeight).isEqualTo(960);
    116       assertThat(displayInfo.logicalWidth).isEqualTo(960);
    117       assertThat(displayInfo.logicalHeight).isEqualTo(720);
    118       assertThat(displayInfo.rotation).isEqualTo(ROTATION_90);
    119       assertThat(displayInfo.logicalDensityDpi).isEqualTo(240);
    120       assertThat(displayInfo.physicalXDpi).isEqualTo(240f);
    121       assertThat(displayInfo.physicalYDpi).isEqualTo(240f);
    122       if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {
    123         assertThat(displayInfo.state).isEqualTo(Display.STATE_ON);
    124       }
    125     }
    126 
    127     DisplayMetrics displayMetrics = RuntimeEnvironment.application.getResources()
    128         .getDisplayMetrics();
    129     assertThat(displayMetrics.widthPixels).isEqualTo(960);
    130     assertThat(displayMetrics.heightPixels).isEqualTo(720);
    131   }
    132 
    133   @Test
    134   public void applyQualifiers_shouldAddDefaults() {
    135     Bootstrap.applyQualifiers("", Build.VERSION.RESOURCES_SDK_INT, configuration, displayMetrics);
    136     String outQualifiers = ConfigurationV25.resourceQualifierString(configuration, displayMetrics);
    137 
    138     assertThat(outQualifiers)
    139         .isEqualTo("en-rUS-ldltr-sw320dp-w320dp-h470dp-normal-notlong-notround-port-notnight-mdpi" +
    140             "-finger-keyssoft-nokeys-navhidden-nonav-v" + Build.VERSION.RESOURCES_SDK_INT);
    141 
    142     assertThat(configuration.mcc).isEqualTo(0);
    143     assertThat(configuration.mnc).isEqualTo(0);
    144     assertThat(configuration.locale).isEqualTo(new Locale("en", "US"));
    145     assertThat(configuration.screenLayout & SCREENLAYOUT_LAYOUTDIR_MASK).isEqualTo(SCREENLAYOUT_LAYOUTDIR_LTR);
    146     assertThat(configuration.smallestScreenWidthDp).isEqualTo(320);
    147     assertThat(configuration.screenWidthDp).isEqualTo(320);
    148     assertThat(configuration.screenHeightDp).isEqualTo(470);
    149     assertThat(configuration.screenLayout & SCREENLAYOUT_SIZE_MASK).isEqualTo(SCREENLAYOUT_SIZE_NORMAL);
    150     assertThat(configuration.screenLayout & SCREENLAYOUT_LONG_MASK).isEqualTo(SCREENLAYOUT_LONG_NO);
    151     assertThat(configuration.screenLayout & SCREENLAYOUT_ROUND_MASK).isEqualTo(SCREENLAYOUT_ROUND_NO);
    152     assertThat(configuration.orientation).isEqualTo(ORIENTATION_PORTRAIT);
    153     assertThat(configuration.uiMode & UI_MODE_TYPE_MASK).isEqualTo(UI_MODE_TYPE_UNDEFINED);
    154     assertThat(configuration.uiMode & UI_MODE_NIGHT_MASK).isEqualTo(UI_MODE_NIGHT_NO);
    155 
    156     if (RuntimeEnvironment.getApiLevel() > JELLY_BEAN) {
    157       assertThat(configuration.densityDpi).isEqualTo(DisplayMetrics.DENSITY_DEFAULT);
    158     } else {
    159       assertThat(displayMetrics.densityDpi).isEqualTo(DisplayMetrics.DENSITY_DEFAULT);
    160       assertThat(displayMetrics.density).isEqualTo(1.0f);
    161     }
    162 
    163     assertThat(configuration.touchscreen).isEqualTo(TOUCHSCREEN_FINGER);
    164     assertThat(configuration.keyboardHidden).isEqualTo(KEYBOARDHIDDEN_SOFT);
    165     assertThat(configuration.keyboard).isEqualTo(KEYBOARD_NOKEYS);
    166     assertThat(configuration.navigationHidden).isEqualTo(NAVIGATIONHIDDEN_YES);
    167     assertThat(configuration.navigation).isEqualTo(NAVIGATION_NONAV);
    168   }
    169 
    170   @Test
    171   public void applyQualifiers_shouldHonorSpecifiedQualifiers() {
    172     Bootstrap.applyQualifiers(
    173         "mcc310-mnc004-fr-rFR-ldrtl-sw400dp-w480dp-h456dp-xlarge-long-round-land-"
    174             + "appliance-night-hdpi-notouch-keyshidden-12key-navhidden-dpad",
    175         Build.VERSION.RESOURCES_SDK_INT,
    176         configuration,
    177         displayMetrics);
    178     String outQualifiers = ConfigurationV25.resourceQualifierString(configuration, displayMetrics);
    179 
    180     if (RuntimeEnvironment.getApiLevel() > JELLY_BEAN) {
    181       assertThat(outQualifiers).isEqualTo("mcc310-mnc4-fr-rFR-ldltr-sw400dp-w480dp-h456dp-xlarge"
    182           + "-long-round-land-appliance-night-hdpi-notouch-keyshidden-12key-navhidden-dpad-v"
    183           + Build.VERSION.RESOURCES_SDK_INT);
    184     } else {
    185       assertThat(outQualifiers).isEqualTo("mcc310-mnc4-fr-rFR-ldrtl-sw400dp-w480dp-h456dp-xlarge"
    186           + "-long-round-land-appliance-night-hdpi-notouch-keyshidden-12key-navhidden-dpad-v"
    187           + Build.VERSION.RESOURCES_SDK_INT);
    188     }
    189 
    190     assertThat(configuration.mcc).isEqualTo(310);
    191     assertThat(configuration.mnc).isEqualTo(4);
    192     assertThat(configuration.locale).isEqualTo(new Locale("fr", "FR"));
    193     if (RuntimeEnvironment.getApiLevel() > JELLY_BEAN) {
    194       // note that locale overrides ltr/rtl
    195       assertThat(configuration.screenLayout & SCREENLAYOUT_LAYOUTDIR_MASK)
    196           .isEqualTo(SCREENLAYOUT_LAYOUTDIR_LTR);
    197     } else {
    198       // but not on Jelly Bean...
    199       assertThat(configuration.screenLayout & SCREENLAYOUT_LAYOUTDIR_MASK)
    200           .isEqualTo(SCREENLAYOUT_LAYOUTDIR_RTL);
    201     }
    202     assertThat(configuration.smallestScreenWidthDp).isEqualTo(400);
    203     assertThat(configuration.screenWidthDp).isEqualTo(480);
    204     assertThat(configuration.screenHeightDp).isEqualTo(456);
    205     assertThat(configuration.screenLayout & SCREENLAYOUT_SIZE_MASK).isEqualTo(SCREENLAYOUT_SIZE_XLARGE);
    206     assertThat(configuration.screenLayout & SCREENLAYOUT_LONG_MASK).isEqualTo(SCREENLAYOUT_LONG_YES);
    207     assertThat(configuration.screenLayout & SCREENLAYOUT_ROUND_MASK).isEqualTo(SCREENLAYOUT_ROUND_YES);
    208     assertThat(configuration.orientation).isEqualTo(ORIENTATION_LANDSCAPE);
    209     assertThat(configuration.uiMode & UI_MODE_TYPE_MASK).isEqualTo(UI_MODE_TYPE_APPLIANCE);
    210     assertThat(configuration.uiMode & UI_MODE_NIGHT_MASK).isEqualTo(UI_MODE_NIGHT_YES);
    211     if (RuntimeEnvironment.getApiLevel() > JELLY_BEAN) {
    212       assertThat(configuration.densityDpi).isEqualTo(DisplayMetrics.DENSITY_HIGH);
    213     } else {
    214       assertThat(displayMetrics.densityDpi).isEqualTo(DisplayMetrics.DENSITY_HIGH);
    215       assertThat(displayMetrics.density).isEqualTo(1.5f);
    216     }
    217     assertThat(configuration.touchscreen).isEqualTo(TOUCHSCREEN_NOTOUCH);
    218     assertThat(configuration.keyboardHidden).isEqualTo(KEYBOARDHIDDEN_YES);
    219     assertThat(configuration.keyboard).isEqualTo(KEYBOARD_12KEY);
    220     assertThat(configuration.navigationHidden).isEqualTo(NAVIGATIONHIDDEN_YES);
    221     assertThat(configuration.navigation).isEqualTo(NAVIGATION_DPAD);
    222   }
    223 
    224   @Test
    225   public void applyQualifiers_longShouldMakeScreenTaller() throws Exception {
    226     Bootstrap.applyQualifiers("long",
    227         RuntimeEnvironment.getApiLevel(), configuration, displayMetrics);
    228     assertThat(configuration.smallestScreenWidthDp).isEqualTo(320);
    229     assertThat(configuration.screenWidthDp).isEqualTo(320);
    230     assertThat(configuration.screenHeightDp).isEqualTo(587);
    231     assertThat(configuration.screenLayout & Configuration.SCREENLAYOUT_LONG_MASK)
    232         .isEqualTo(Configuration.SCREENLAYOUT_LONG_YES);
    233   }
    234 
    235   @Test
    236   public void whenScreenRationGreatherThan175Percent_applyQualifiers_ShouldSetLong() throws Exception {
    237     Bootstrap.applyQualifiers("w400dp-h200dp",
    238         RuntimeEnvironment.getApiLevel(), configuration, displayMetrics);
    239     assertThat(configuration.screenWidthDp).isEqualTo(400);
    240     assertThat(configuration.screenHeightDp).isEqualTo(200);
    241     assertThat(configuration.screenLayout & Configuration.SCREENLAYOUT_LONG_MASK)
    242         .isEqualTo(Configuration.SCREENLAYOUT_LONG_YES);
    243   }
    244 
    245   @Test
    246   public void applyQualifiers_shouldRejectUnknownQualifiers() {
    247     try {
    248       Bootstrap.applyQualifiers("notareal-qualifier-sw400dp-w480dp-more-wrong-stuff",
    249           RuntimeEnvironment.getApiLevel(), configuration, displayMetrics);
    250       fail("should have thrown");
    251     } catch (IllegalArgumentException e) {
    252       // expected
    253       assertThat(e.getMessage()).contains("notareal");
    254     }
    255   }
    256 
    257   @Test
    258   public void applyQualifiers_shouldRejectSdkVersion() {
    259     try {
    260       Bootstrap.applyQualifiers("sw400dp-w480dp-v7",
    261           RuntimeEnvironment.getApiLevel(), configuration, displayMetrics);
    262       fail("should have thrown");
    263     } catch (IllegalArgumentException e) {
    264       // expected
    265       assertThat(e.getMessage()).contains("Cannot specify conflicting platform version");
    266     }
    267   }
    268 
    269   @Test
    270   public void applyQualifiers_shouldRejectAnydpi() {
    271     try {
    272       Bootstrap.applyQualifiers("anydpi",
    273           RuntimeEnvironment.getApiLevel(), configuration, displayMetrics);
    274       fail("should have thrown");
    275     } catch (IllegalArgumentException e) {
    276       // expected
    277       assertThat(e.getMessage()).contains("'anydpi' isn't actually a dpi");
    278     }
    279   }
    280 
    281   @Test
    282   public void applyQualifiers_shouldRejectNodpi() {
    283     try {
    284       Bootstrap.applyQualifiers("nodpi",
    285           RuntimeEnvironment.getApiLevel(), configuration, displayMetrics);
    286       fail("should have thrown");
    287     } catch (IllegalArgumentException e) {
    288       // expected
    289       assertThat(e.getMessage()).contains("'nodpi' isn't actually a dpi");
    290     }
    291   }
    292 
    293   @Test
    294   @Config(sdk = JELLY_BEAN)
    295   public void applyQualifiers_densityOnJellyBean() {
    296     Bootstrap.applyQualifiers("hdpi", RuntimeEnvironment.getApiLevel(), configuration,
    297         displayMetrics);
    298     assertThat(displayMetrics.density).isEqualTo(1.5f);
    299     assertThat(displayMetrics.densityDpi).isEqualTo(240);
    300   }
    301 
    302   @Test
    303   public void applyQualifiers_shouldSetLocaleScript() throws Exception {
    304     Bootstrap.applyQualifiers("b+sr+Latn", RuntimeEnvironment.getApiLevel(),
    305         configuration, displayMetrics);
    306     String outQualifiers = ConfigurationV25.resourceQualifierString(configuration, displayMetrics);
    307 
    308     assertThat(configuration.locale.getScript()).isEqualTo("Latn");
    309     assertThat(outQualifiers).contains("b+sr+Latn");
    310   }
    311 
    312   @Test
    313   public void spaceSeparated_applyQualifiers_shouldReplaceQualifiers() throws Exception {
    314     Bootstrap.applyQualifiers("ru-rRU-h123dp-large fr-w321dp", RuntimeEnvironment.getApiLevel(),
    315         configuration, displayMetrics);
    316     String outQualifiers = ConfigurationV25.resourceQualifierString(configuration, displayMetrics);
    317 
    318     assertThat(outQualifiers).startsWith("fr-ldltr-sw321dp-w321dp-h470dp-normal");
    319   }
    320 
    321   @Test
    322   public void whenPrefixedWithPlus_applyQualifiers_shouldOverlayQualifiers() throws Exception {
    323     Bootstrap.applyQualifiers("+en ru-rRU-h123dp-large +fr-w321dp-small", RuntimeEnvironment.getApiLevel(),
    324         configuration, displayMetrics);
    325     String outQualifiers = ConfigurationV25.resourceQualifierString(configuration, displayMetrics);
    326 
    327     assertThat(outQualifiers).startsWith("fr-ldltr-sw321dp-w321dp-h426dp-small");
    328   }
    329 
    330   @Test
    331   public void whenAllPrefixedWithPlus_applyQualifiers_shouldOverlayQualifiers() throws Exception {
    332     Bootstrap.applyQualifiers("+xxhdpi +ru-rRU-h123dp-large +fr-w321dp-small", RuntimeEnvironment.getApiLevel(),
    333         configuration, displayMetrics);
    334     String outQualifiers = ConfigurationV25.resourceQualifierString(configuration, displayMetrics);
    335 
    336     assertThat(outQualifiers).startsWith("fr-ldltr-sw321dp-w321dp-h426dp-small")
    337         .contains("-xxhdpi-");
    338   }
    339 }
    340