1 /* 2 * Copyright 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 * https://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 android.content.res.cts; 18 19 import android.content.Context; 20 import android.content.cts.R; 21 import android.content.cts.util.XmlUtils; 22 import android.content.pm.ActivityInfo; 23 import android.content.res.AssetManager; 24 import android.content.res.ColorStateList; 25 import android.content.res.Configuration; 26 import android.content.res.Resources; 27 import android.content.res.Resources.NotFoundException; 28 import android.content.res.TypedArray; 29 import android.content.res.XmlResourceParser; 30 import android.graphics.Paint; 31 import android.graphics.Typeface; 32 import android.graphics.drawable.AdaptiveIconDrawable; 33 import android.graphics.drawable.ColorDrawable; 34 import android.graphics.drawable.ColorStateListDrawable; 35 import android.graphics.drawable.Drawable; 36 import android.os.Bundle; 37 import android.os.LocaleList; 38 import android.platform.test.annotations.AppModeFull; 39 import android.test.AndroidTestCase; 40 import android.util.AttributeSet; 41 import android.util.DisplayMetrics; 42 import android.util.TypedValue; 43 import android.util.Xml; 44 import android.view.Display; 45 import android.view.LayoutInflater; 46 import android.view.View; 47 import android.view.WindowManager; 48 49 import androidx.test.InstrumentationRegistry; 50 51 import org.xmlpull.v1.XmlPullParser; 52 import org.xmlpull.v1.XmlPullParserException; 53 54 import java.io.IOException; 55 import java.io.InputStream; 56 import java.util.Locale; 57 58 public class ResourcesTest extends AndroidTestCase { 59 private static final String CONFIG_VARYING = "configVarying"; 60 private static final String SIMPLE = "simple"; 61 private static final String CONFIG_VARYING_SIMPLE = "configVarying/simple"; 62 private static final String PACKAGE_NAME = "android.content.cts"; 63 private static final String COM_ANDROID_CTS_STUB_IDENTIFIER = 64 "android.content.cts:configVarying/simple"; 65 private Resources mResources; 66 67 @Override setUp()68 protected void setUp() throws Exception { 69 super.setUp(); 70 71 mResources = getContext().getResources(); 72 } 73 testIdNull()74 public void testIdNull() { 75 assertEquals(0, Resources.ID_NULL); 76 } 77 testResources()78 public void testResources() { 79 final AssetManager am = new AssetManager(); 80 final Configuration cfg = new Configuration(); 81 cfg.keyboard = Configuration.KEYBOARDHIDDEN_YES; 82 final DisplayMetrics dm = new DisplayMetrics(); 83 dm.setToDefaults(); 84 85 final Resources r = new Resources(am, dm, cfg); 86 final Configuration c = r.getConfiguration(); 87 assertEquals(Configuration.KEYBOARDHIDDEN_YES, c.keyboard); 88 } 89 testGetString()90 public void testGetString() { 91 try { 92 mResources.getString(-1, "%s"); 93 fail("Failed at testGetString2"); 94 } catch (NotFoundException e) { 95 //expected 96 } 97 98 final String strGo = mResources.getString(R.string.go, "%1$s%%", 12); 99 assertEquals("Go", strGo); 100 } 101 testObtainAttributes()102 public void testObtainAttributes() throws XmlPullParserException, IOException { 103 final XmlPullParser parser = mResources.getXml(R.xml.test_color); 104 XmlUtils.beginDocument(parser, "resources"); 105 final AttributeSet set = Xml.asAttributeSet(parser); 106 final TypedArray testTypedArray = mResources.obtainAttributes(set, R.styleable.Style1); 107 assertNotNull(testTypedArray); 108 assertEquals(2, testTypedArray.length()); 109 assertEquals(0, testTypedArray.getColor(0, 0)); 110 assertEquals(128, testTypedArray.getColor(1, 128)); 111 assertEquals(mResources, testTypedArray.getResources()); 112 testTypedArray.recycle(); 113 } 114 testObtainTypedArray()115 public void testObtainTypedArray() { 116 try { 117 mResources.obtainTypedArray(-1); 118 fail("Failed at testObtainTypedArray"); 119 } catch (NotFoundException e) { 120 //expected 121 } 122 123 final TypedArray ta = mResources.obtainTypedArray(R.array.string); 124 assertEquals(3, ta.length()); 125 assertEquals("Test String 1", ta.getString(0)); 126 assertEquals("Test String 2", ta.getString(1)); 127 assertEquals("Test String 3", ta.getString(2)); 128 assertEquals(mResources, ta.getResources()); 129 } 130 getResources(final Configuration config, final int mcc, final int mnc, final int touchscreen, final int keyboard, final int keysHidden, final int navigation, final int width, final int height)131 private Resources getResources(final Configuration config, final int mcc, final int mnc, 132 final int touchscreen, final int keyboard, final int keysHidden, final int navigation, 133 final int width, final int height) { 134 final AssetManager assmgr = new AssetManager(); 135 assmgr.addAssetPath(mContext.getPackageResourcePath()); 136 final DisplayMetrics metrics = new DisplayMetrics(); 137 final WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); 138 final Display d = wm.getDefaultDisplay(); 139 d.getMetrics(metrics); 140 config.mcc = mcc; 141 config.mnc = mnc; 142 config.touchscreen = touchscreen; 143 config.keyboard = keyboard; 144 config.keyboardHidden = keysHidden; 145 config.navigation = navigation; 146 metrics.widthPixels = width; 147 metrics.heightPixels = height; 148 return new Resources(assmgr, metrics, config); 149 } 150 checkGetText1(final Resources res, final int resId, final String expectedValue)151 private static void checkGetText1(final Resources res, final int resId, 152 final String expectedValue) { 153 final String actual = res.getText(resId).toString(); 154 assertNotNull("Returned wrong configuration-based simple value: expected <nothing>, " 155 + "got '" + actual + "' from resource 0x" + Integer.toHexString(resId), 156 expectedValue); 157 assertEquals("Returned wrong configuration-based simple value: expected " + expectedValue 158 + ", got '" + actual + "' from resource 0x" + Integer.toHexString(resId), 159 expectedValue, actual); 160 } 161 checkGetText2(final Resources res, final int resId, final String expectedValue)162 private static void checkGetText2(final Resources res, final int resId, 163 final String expectedValue) { 164 final String actual = res.getText(resId, null).toString(); 165 assertNotNull("Returned wrong configuration-based simple value: expected <nothing>, " 166 + "got '" + actual + "' from resource 0x" + Integer.toHexString(resId), 167 expectedValue); 168 assertEquals("Returned wrong configuration-based simple value: expected " + expectedValue 169 + ", got '" + actual + "' from resource 0x" + Integer.toHexString(resId), 170 expectedValue, actual); 171 } 172 testGetMovie()173 public void testGetMovie() { 174 try { 175 mResources.getMovie(-1); 176 fail("Failed at testGetMovie"); 177 } catch (NotFoundException e) { 178 //expected 179 } 180 } 181 testGetDimension()182 public void testGetDimension() { 183 try { 184 mResources.getDimension(-1); 185 fail("Failed at testGetDimension"); 186 } catch (NotFoundException e) { 187 //expected 188 } 189 190 // app_icon_size is 48px, as defined in cts/tests/res/values/resources_test.xml 191 final float dim = mResources.getDimension(R.dimen.app_icon_size); 192 assertEquals(48.0f, dim); 193 } 194 testGetDimensionPixelOffset()195 public void testGetDimensionPixelOffset() { 196 try { 197 mResources.getDimensionPixelOffset(-1); 198 fail("Failed at testGetDimensionPixelOffset"); 199 } catch (NotFoundException e) { 200 //expected 201 } 202 203 // app_icon_size is 48px, as defined in cts/tests/res/values/resources_test.xml 204 final int dim = mResources.getDimensionPixelOffset(R.dimen.app_icon_size); 205 assertEquals(48, dim); 206 } 207 testGetColorStateList()208 public void testGetColorStateList() { 209 try { 210 mResources.getColorStateList(-1); 211 fail("Failed at testGetColorStateList"); 212 } catch (NotFoundException e) { 213 //expected 214 } 215 216 final ColorStateList colorStateList = mResources.getColorStateList(R.color.color1); 217 final int[] focusedState = {android.R.attr.state_focused}; 218 final int focusColor = colorStateList.getColorForState(focusedState, R.color.failColor); 219 assertEquals(mResources.getColor(R.color.testcolor1), focusColor); 220 } 221 testGetColorStateListThrows()222 public void testGetColorStateListThrows() { 223 try { 224 // XML that's not a selector or gradient throws 225 mResources.getColorStateList(R.drawable.density_test); 226 fail("Failed at testGetColorStateList"); 227 } catch (NotFoundException expected) { 228 // expected 229 } 230 } 231 testGetColor()232 public void testGetColor() { 233 try { 234 mResources.getColor(-1); 235 fail("Failed at testGetColor"); 236 } catch (NotFoundException e) { 237 //expected 238 } 239 240 final int color = mResources.getColor(R.color.testcolor1); 241 assertEquals(0xff00ff00, color); 242 } 243 createNewResources()244 public Resources createNewResources() { 245 final DisplayMetrics dm = new DisplayMetrics(); 246 dm.setToDefaults(); 247 final Configuration cfg = new Configuration(); 248 cfg.setToDefaults(); 249 return new Resources(new AssetManager(), dm, cfg); 250 } 251 testUpdateConfiguration()252 public void testUpdateConfiguration() { 253 Resources res = createNewResources(); 254 final Configuration cfg = new Configuration(res.getConfiguration()); 255 assertTrue(cfg.fontScale != 5); 256 257 cfg.fontScale = 5; 258 res.updateConfiguration(cfg, null); 259 assertEquals(5.0f, res.getConfiguration().fontScale, 0.001f); 260 } 261 testUpdateConfiguration_emptyLocaleIsOverridden()262 public void testUpdateConfiguration_emptyLocaleIsOverridden() { 263 Resources res = createNewResources(); 264 res.getConfiguration().setLocales(null); 265 assertTrue(res.getConfiguration().getLocales().isEmpty()); 266 267 final Configuration cfg = new Configuration(); 268 cfg.setToDefaults(); 269 assertTrue(cfg.getLocales().isEmpty()); 270 271 res.updateConfiguration(cfg, null); 272 assertEquals(LocaleList.getDefault(), res.getConfiguration().getLocales()); 273 } 274 testUpdateConfiguration_copyLocales()275 public void testUpdateConfiguration_copyLocales() { 276 Resources res = createNewResources(); 277 final Configuration cfg = new Configuration(res.getConfiguration()); 278 279 cfg.setLocales(LocaleList.forLanguageTags("az-Arab,ru")); 280 281 res.updateConfiguration(cfg, null); 282 283 // Depending on the locales available in the framework resources, the LocaleList may be 284 // re-arranged. Check that any valid permutation is present. 285 final LocaleList locales = res.getConfiguration().getLocales(); 286 assertTrue(LocaleList.forLanguageTags("az-Arab,ru").equals(locales) || 287 LocaleList.forLanguageTags("ru,az-Arab").equals(locales)); 288 } 289 testUpdateConfiguration_emptyAfterUpdate()290 public void testUpdateConfiguration_emptyAfterUpdate() { 291 Resources res = createNewResources(); 292 final Configuration cfg = new Configuration(res.getConfiguration()); 293 cfg.setLocales(LocaleList.forLanguageTags("az-Arab")); 294 295 res.updateConfiguration(cfg, null); 296 assertEquals(LocaleList.forLanguageTags("az-Arab"), res.getConfiguration().getLocales()); 297 298 res.getConfiguration().setLocales(null); 299 cfg.setLocales(null); 300 res.updateConfiguration(cfg, null); 301 assertEquals(LocaleList.getDefault(), res.getConfiguration().getLocales()); 302 } 303 testGetDimensionPixelSize()304 public void testGetDimensionPixelSize() { 305 try { 306 mResources.getDimensionPixelSize(-1); 307 fail("Failed at testGetDimensionPixelSize"); 308 } catch (NotFoundException e) { 309 //expected 310 } 311 312 // app_icon_size is 48px, as defined in cts/tests/res/values/resources_test.xml 313 final int size = mResources.getDimensionPixelSize(R.dimen.app_icon_size); 314 assertEquals(48, size); 315 assertEquals(1, mResources.getDimensionPixelSize(R.dimen.pos_dimen_149)); 316 assertEquals(2, mResources.getDimensionPixelSize(R.dimen.pos_dimen_151)); 317 assertEquals(-1, mResources.getDimensionPixelSize(R.dimen.neg_dimen_149)); 318 assertEquals(-2, mResources.getDimensionPixelSize(R.dimen.neg_dimen_151)); 319 } 320 testGetDrawable()321 public void testGetDrawable() { 322 try { 323 mResources.getDrawable(-1); 324 fail("Failed at testGetDrawable"); 325 } catch (NotFoundException e) { 326 //expected 327 } 328 329 // testimage is defined in cts/tests/res/drawable/testimage.jpg and measures 212px x 142px 330 final Drawable draw = mResources.getDrawable(R.drawable.testimage); 331 int targetDensity = mResources.getDisplayMetrics().densityDpi; 332 int defaultDensity = DisplayMetrics.DENSITY_DEFAULT; 333 assertNotNull(draw); 334 assertEquals(212 * targetDensity / defaultDensity, draw.getIntrinsicWidth(), 1); 335 assertEquals(142 * targetDensity / defaultDensity, draw.getIntrinsicHeight(), 1); 336 337 // Some apps rely on the fact that this will return null (rather than throwing). 338 assertNull(mResources.getDrawable(R.drawable.fake_image_will_not_decode)); 339 } 340 testGetDrawable_StackOverflowErrorDrawable()341 public void testGetDrawable_StackOverflowErrorDrawable() { 342 try { 343 mResources.getDrawable(R.drawable.drawable_recursive); 344 fail("Failed at testGetDrawable_StackOverflowErrorDrawable"); 345 } catch (NotFoundException e) { 346 //expected 347 } 348 } 349 testGetDrawable_StackOverflowErrorDrawable_mipmap()350 public void testGetDrawable_StackOverflowErrorDrawable_mipmap() { 351 try { 352 mResources.getDrawable(R.mipmap.icon_recursive); 353 fail("Failed at testGetDrawable_StackOverflowErrorDrawable_mipmap"); 354 } catch (NotFoundException e) { 355 //expected 356 } 357 } 358 testGetDrawableForDensity()359 public void testGetDrawableForDensity() { 360 final Drawable ldpi = mResources.getDrawableForDensity( 361 R.drawable.density_test, DisplayMetrics.DENSITY_LOW); 362 assertEquals(300, ldpi.getIntrinsicWidth()); 363 364 final Drawable mdpi = mResources.getDrawableForDensity( 365 R.drawable.density_test, DisplayMetrics.DENSITY_MEDIUM); 366 assertEquals(200, mdpi.getIntrinsicWidth()); 367 368 final Drawable hdpi = mResources.getDrawableForDensity( 369 R.drawable.density_test, DisplayMetrics.DENSITY_HIGH); 370 assertEquals(100, hdpi.getIntrinsicWidth()); 371 } 372 testGetDrawableForDensityWithZeroDensityIsSameAsGetDrawable()373 public void testGetDrawableForDensityWithZeroDensityIsSameAsGetDrawable() { 374 final Drawable defaultDrawable = mResources.getDrawable(R.drawable.density_test, null); 375 assertNotNull(defaultDrawable); 376 377 final Drawable densityDrawable = mResources.getDrawableForDensity(R.drawable.density_test, 378 0 /*density*/, null); 379 assertNotNull(densityDrawable); 380 381 assertEquals(defaultDrawable.getIntrinsicWidth(), densityDrawable.getIntrinsicWidth()); 382 } 383 extractForegroundFromAdaptiveIconDrawable(int id, int density)384 private Drawable extractForegroundFromAdaptiveIconDrawable(int id, int density) { 385 final Drawable drawable = mResources.getDrawableForDensity(id, density, null); 386 assertTrue(drawable instanceof AdaptiveIconDrawable); 387 return ((AdaptiveIconDrawable) drawable).getForeground(); 388 } 389 testGetDrawableForDensityWithAdaptiveIconDrawable()390 public void testGetDrawableForDensityWithAdaptiveIconDrawable() { 391 final Drawable ldpi = extractForegroundFromAdaptiveIconDrawable(R.drawable.adaptive_icon, 392 DisplayMetrics.DENSITY_LOW); 393 assertNotNull(ldpi); 394 assertEquals(300, ldpi.getIntrinsicWidth()); 395 396 final Drawable mdpi = extractForegroundFromAdaptiveIconDrawable(R.drawable.adaptive_icon, 397 DisplayMetrics.DENSITY_MEDIUM); 398 assertNotNull(mdpi); 399 assertEquals(200, mdpi.getIntrinsicWidth()); 400 401 final Drawable hdpi = extractForegroundFromAdaptiveIconDrawable(R.drawable.adaptive_icon, 402 DisplayMetrics.DENSITY_HIGH); 403 assertNotNull(hdpi); 404 assertEquals(100, hdpi.getIntrinsicWidth()); 405 } 406 testGetAnimation()407 public void testGetAnimation() throws Exception { 408 try { 409 mResources.getAnimation(-1); 410 fail("Failed at testGetAnimation"); 411 } catch (NotFoundException e) { 412 //expected 413 } 414 415 final XmlResourceParser ani = mResources.getAnimation(R.anim.anim_rotate); 416 assertNotNull(ani); 417 XmlUtils.beginDocument(ani, "rotate"); 418 assertEquals(7, ani.getAttributeCount()); 419 assertEquals("Binary XML file line #18", ani.getPositionDescription()); 420 assertEquals("interpolator", ani.getAttributeName(0)); 421 assertEquals("@17432582", ani.getAttributeValue(0)); 422 } 423 testGetQuantityString1()424 public void testGetQuantityString1() { 425 try { 426 mResources.getQuantityString(-1, 1, ""); 427 fail("Failed at testGetQuantityString1"); 428 } catch (NotFoundException e) { 429 //expected 430 } 431 432 final String strGo = mResources.getQuantityString(R.plurals.plurals_test, 1, ""); 433 assertEquals("A dog", strGo); 434 } 435 testGetQuantityString2()436 public void testGetQuantityString2() { 437 try { 438 mResources.getQuantityString(-1, 1); 439 fail("Failed at testGetQuantityString2"); 440 } catch (NotFoundException e) { 441 //expected 442 } 443 444 final String strGo = mResources.getQuantityString(R.plurals.plurals_test, 1); 445 assertEquals("A dog", strGo); 446 } 447 testGetInteger()448 public void testGetInteger() { 449 try { 450 mResources.getInteger(-1); 451 fail("Failed at testGetInteger"); 452 } catch (NotFoundException e) { 453 //expected 454 } 455 456 final int i = mResources.getInteger(R.integer.resource_test_int); 457 assertEquals(10, i); 458 } 459 testGetValue()460 public void testGetValue() { 461 final TypedValue tv = new TypedValue(); 462 463 try { 464 mResources.getValue("null", tv, false); 465 fail("Failed at testGetValue"); 466 } catch (NotFoundException e) { 467 //expected 468 } 469 470 mResources.getValue("android.content.cts:raw/text", tv, false); 471 assertNotNull(tv); 472 assertEquals("res/raw/text.txt", tv.coerceToString()); 473 } 474 testGetValueForDensity()475 public void testGetValueForDensity() { 476 final TypedValue tv = new TypedValue(); 477 478 mResources.getValueForDensity(R.string.density_string, 479 DisplayMetrics.DENSITY_LOW, tv, false); 480 assertEquals("ldpi", tv.coerceToString()); 481 482 mResources.getValueForDensity(R.string.density_string, 483 DisplayMetrics.DENSITY_MEDIUM, tv, false); 484 assertEquals("mdpi", tv.coerceToString()); 485 486 mResources.getValueForDensity(R.string.density_string, 487 DisplayMetrics.DENSITY_HIGH, tv, false); 488 assertEquals("hdpi", tv.coerceToString()); 489 } 490 testGetValueForDensityWithZeroDensityIsSameAsGetValue()491 public void testGetValueForDensityWithZeroDensityIsSameAsGetValue() { 492 final TypedValue defaultTv = new TypedValue(); 493 mResources.getValue(R.string.density_string, defaultTv, false); 494 495 final TypedValue densityTv = new TypedValue(); 496 mResources.getValueForDensity(R.string.density_string, 0 /*density*/, densityTv, false); 497 498 assertEquals(defaultTv.assetCookie, densityTv.assetCookie); 499 assertEquals(defaultTv.data, densityTv.data); 500 assertEquals(defaultTv.type, densityTv.type); 501 assertEquals(defaultTv.string, densityTv.string); 502 } 503 testGetAssets()504 public void testGetAssets() { 505 final AssetManager aM = mResources.getAssets(); 506 assertNotNull(aM); 507 assertTrue(aM.isUpToDate()); 508 } 509 testGetSystem()510 public void testGetSystem() { 511 assertNotNull(Resources.getSystem()); 512 } 513 testGetLayout()514 public void testGetLayout() throws Exception { 515 try { 516 mResources.getLayout(-1); 517 fail("Failed at testGetLayout"); 518 } catch (NotFoundException e) { 519 //expected 520 } 521 522 final XmlResourceParser layout = mResources.getLayout(R.layout.abslistview_layout); 523 assertNotNull(layout); 524 XmlUtils.beginDocument(layout, "ViewGroup_Layout"); 525 assertEquals(3, layout.getAttributeCount()); 526 assertEquals("id", layout.getAttributeName(0)); 527 assertEquals("@" + R.id.abslistview_root, layout.getAttributeValue(0)); 528 } 529 testGetBoolean()530 public void testGetBoolean() { 531 try { 532 mResources.getBoolean(-1); 533 fail("Failed at testGetBoolean"); 534 } catch (NotFoundException e) { 535 //expected 536 } 537 538 final boolean b = mResources.getBoolean(R.integer.resource_test_int); 539 assertTrue(b); 540 } 541 testgetFraction()542 public void testgetFraction() { 543 assertEquals(1, (int)mResources.getFraction(R.dimen.frac100perc, 1, 1)); 544 assertEquals(100, (int)mResources.getFraction(R.dimen.frac100perc, 100, 1)); 545 } 546 testParseBundleExtras()547 public void testParseBundleExtras() throws XmlPullParserException, IOException { 548 final Bundle b = new Bundle(); 549 XmlResourceParser parser = mResources.getXml(R.xml.extra); 550 XmlUtils.beginDocument(parser, "tag"); 551 552 assertEquals(0, b.size()); 553 mResources.parseBundleExtras(parser, b); 554 assertEquals(1, b.size()); 555 assertEquals("android", b.getString("google")); 556 } 557 testParseBundleExtra()558 public void testParseBundleExtra() throws XmlPullParserException, IOException { 559 final Bundle b = new Bundle(); 560 XmlResourceParser parser = mResources.getXml(R.xml.extra); 561 562 XmlUtils.beginDocument(parser, "tag"); 563 assertEquals(0, b.size()); 564 mResources.parseBundleExtra("test", parser, b); 565 assertEquals(1, b.size()); 566 assertEquals("Lee", b.getString("Bruce")); 567 } 568 testGetIdentifier()569 public void testGetIdentifier() { 570 571 int resid = mResources.getIdentifier(COM_ANDROID_CTS_STUB_IDENTIFIER, null, null); 572 assertEquals(R.configVarying.simple, resid); 573 574 resid = mResources.getIdentifier(CONFIG_VARYING_SIMPLE, null, PACKAGE_NAME); 575 assertEquals(R.configVarying.simple, resid); 576 577 resid = mResources.getIdentifier(SIMPLE, CONFIG_VARYING, PACKAGE_NAME); 578 assertEquals(R.configVarying.simple, resid); 579 } 580 testGetIntArray()581 public void testGetIntArray() { 582 final int NO_EXIST_ID = -1; 583 try { 584 mResources.getIntArray(NO_EXIST_ID); 585 fail("should throw out NotFoundException"); 586 } catch (NotFoundException e) { 587 // expected 588 } 589 // expected value is defined in res/value/arrays.xml 590 final int[] expectedArray1 = new int[] { 591 0, 0, 0 592 }; 593 final int[] expectedArray2 = new int[] { 594 0, 1, 101 595 }; 596 int[]array1 = mResources.getIntArray(R.array.strings); 597 int[]array2 = mResources.getIntArray(R.array.integers); 598 599 checkArrayEqual(expectedArray1, array1); 600 checkArrayEqual(expectedArray2, array2); 601 602 } 603 checkArrayEqual(int[] array1, int[] array2)604 private void checkArrayEqual(int[] array1, int[] array2) { 605 assertNotNull(array2); 606 assertEquals(array1.length, array2.length); 607 for (int i = 0; i < array1.length; i++) { 608 assertEquals(array1[i], array2[i]); 609 } 610 } 611 testGetQuantityText()612 public void testGetQuantityText() { 613 CharSequence cs; 614 final Resources res = resourcesForLanguage("cs"); 615 616 cs = res.getQuantityText(R.plurals.plurals_test, 0); 617 assertEquals("Some Czech dogs", cs.toString()); 618 619 cs = res.getQuantityText(R.plurals.plurals_test, 1); 620 assertEquals("A Czech dog", cs.toString()); 621 622 cs = res.getQuantityText(R.plurals.plurals_test, 2); 623 assertEquals("Few Czech dogs", cs.toString()); 624 625 cs = res.getQuantityText(R.plurals.plurals_test, 5); 626 assertEquals("Some Czech dogs", cs.toString()); 627 628 cs = res.getQuantityText(R.plurals.plurals_test, 500); 629 assertEquals("Some Czech dogs", cs.toString()); 630 631 } 632 testChangingConfiguration()633 public void testChangingConfiguration() { 634 ColorDrawable dr1 = (ColorDrawable) mResources.getDrawable(R.color.varies_uimode); 635 assertEquals(ActivityInfo.CONFIG_UI_MODE, dr1.getChangingConfigurations()); 636 637 // Test again with a drawable obtained from the cache. 638 ColorDrawable dr2 = (ColorDrawable) mResources.getDrawable(R.color.varies_uimode); 639 assertEquals(ActivityInfo.CONFIG_UI_MODE, dr2.getChangingConfigurations()); 640 } 641 resourcesForLanguage(final String lang)642 private Resources resourcesForLanguage(final String lang) { 643 final Configuration config = new Configuration(); 644 config.updateFrom(mResources.getConfiguration()); 645 config.setLocale(new Locale(lang)); 646 return new Resources(mResources.getAssets(), mResources.getDisplayMetrics(), config); 647 } 648 testGetResourceEntryName()649 public void testGetResourceEntryName() { 650 assertEquals(SIMPLE, mResources.getResourceEntryName(R.configVarying.simple)); 651 } 652 testGetResourceName()653 public void testGetResourceName() { 654 final String fullName = mResources.getResourceName(R.configVarying.simple); 655 assertEquals(COM_ANDROID_CTS_STUB_IDENTIFIER, fullName); 656 657 final String packageName = mResources.getResourcePackageName(R.configVarying.simple); 658 assertEquals(PACKAGE_NAME, packageName); 659 660 final String typeName = mResources.getResourceTypeName(R.configVarying.simple); 661 assertEquals(CONFIG_VARYING, typeName); 662 } 663 testGetStringWithIntParam()664 public void testGetStringWithIntParam() { 665 checkString(R.string.formattedStringNone, 666 mResources.getString(R.string.formattedStringNone), 667 "Format[]"); 668 checkString(R.string.formattedStringOne, 669 mResources.getString(R.string.formattedStringOne), 670 "Format[%d]"); 671 checkString(R.string.formattedStringTwo, mResources.getString(R.string.formattedStringTwo), 672 "Format[%3$d,%2$s]"); 673 // Make sure the formatted one works 674 checkString(R.string.formattedStringNone, 675 mResources.getString(R.string.formattedStringNone), 676 "Format[]"); 677 checkString(R.string.formattedStringOne, 678 mResources.getString(R.string.formattedStringOne, 42), 679 "Format[42]"); 680 checkString(R.string.formattedStringTwo, 681 mResources.getString(R.string.formattedStringTwo, "unused", "hi", 43), 682 "Format[43,hi]"); 683 } 684 checkString(final int resid, final String actual, final String expected)685 private static void checkString(final int resid, final String actual, final String expected) { 686 assertEquals("Expecting string value \"" + expected + "\" got \"" 687 + actual + "\" in resources 0x" + Integer.toHexString(resid), 688 expected, actual); 689 } 690 testGetStringArray()691 public void testGetStringArray() { 692 checkStringArray(R.array.strings, new String[] { 693 "zero", "1", "here" 694 }); 695 checkTextArray(R.array.strings, new String[] { 696 "zero", "1", "here" 697 }); 698 checkStringArray(R.array.integers, new String[] { 699 null, null, null 700 }); 701 checkTextArray(R.array.integers, new String[] { 702 null, null, null 703 }); 704 } 705 checkStringArray(final int resid, final String[] expected)706 private void checkStringArray(final int resid, final String[] expected) { 707 final String[] res = mResources.getStringArray(resid); 708 assertEquals(res.length, expected.length); 709 for (int i = 0; i < expected.length; i++) { 710 checkEntry(resid, i, res[i], expected[i]); 711 } 712 } 713 checkEntry(final int resid, final int index, final Object res, final Object expected)714 private void checkEntry(final int resid, final int index, final Object res, 715 final Object expected) { 716 assertEquals("in resource 0x" + Integer.toHexString(resid) 717 + " at index " + index, expected, res); 718 } 719 checkTextArray(final int resid, final String[] expected)720 private void checkTextArray(final int resid, final String[] expected) { 721 final CharSequence[] res = mResources.getTextArray(resid); 722 assertEquals(res.length, expected.length); 723 for (int i = 0; i < expected.length; i++) { 724 checkEntry(resid, i, res[i], expected[i]); 725 } 726 } 727 testGetValueWithID()728 public void testGetValueWithID() { 729 tryBoolean(R.bool.trueRes, true); 730 tryBoolean(R.bool.falseRes, false); 731 732 tryString(R.string.coerceIntegerToString, "100"); 733 tryString(R.string.coerceBooleanToString, "true"); 734 tryString(R.string.coerceColorToString, "#fff"); 735 tryString(R.string.coerceFloatToString, "100.0"); 736 tryString(R.string.coerceDimensionToString, "100px"); 737 tryString(R.string.coerceFractionToString, "100%"); 738 } 739 tryBoolean(final int resid, final boolean expected)740 private void tryBoolean(final int resid, final boolean expected) { 741 final TypedValue v = new TypedValue(); 742 mContext.getResources().getValue(resid, v, true); 743 assertEquals(TypedValue.TYPE_INT_BOOLEAN, v.type); 744 assertEquals("Expecting boolean value " + expected + " got " + v 745 + " from TypedValue: in resource 0x" + Integer.toHexString(resid), 746 expected, v.data != 0); 747 assertEquals("Expecting boolean value " + expected + " got " + v 748 + " from getBoolean(): in resource 0x" + Integer.toHexString(resid), 749 expected, mContext.getResources().getBoolean(resid)); 750 } 751 tryString(final int resid, final String expected)752 private void tryString(final int resid, final String expected) { 753 final TypedValue v = new TypedValue(); 754 mContext.getResources().getValue(resid, v, true); 755 assertEquals(TypedValue.TYPE_STRING, v.type); 756 assertEquals("Expecting string value " + expected + " got " + v 757 + ": in resource 0x" + Integer.toHexString(resid), 758 expected, v.string); 759 } 760 testRawResource()761 public void testRawResource() throws Exception { 762 assertNotNull(mResources.newTheme()); 763 764 InputStream is = mResources.openRawResource(R.raw.text); 765 verifyTextAsset(is); 766 767 is = mResources.openRawResource(R.raw.text, new TypedValue()); 768 verifyTextAsset(is); 769 770 assertNotNull(mResources.openRawResourceFd(R.raw.text)); 771 } 772 verifyTextAsset(final InputStream is)773 static void verifyTextAsset(final InputStream is) throws IOException { 774 final String expectedString = "OneTwoThreeFourFiveSixSevenEightNineTen"; 775 final byte[] buffer = new byte[10]; 776 777 int readCount; 778 int curIndex = 0; 779 while ((readCount = is.read(buffer, 0, buffer.length)) > 0) { 780 for (int i = 0; i < readCount; i++) { 781 assertEquals("At index " + curIndex 782 + " expected " + expectedString.charAt(curIndex) 783 + " but found " + ((char) buffer[i]), 784 buffer[i], expectedString.charAt(curIndex)); 785 curIndex++; 786 } 787 } 788 789 readCount = is.read(buffer, 0, buffer.length); 790 assertEquals("Reading end of buffer: expected readCount=-1 but got " + readCount, 791 -1, readCount); 792 793 readCount = is.read(buffer, buffer.length, 0); 794 assertEquals("Reading end of buffer length 0: expected readCount=0 but got " + readCount, 795 0, readCount); 796 797 is.close(); 798 } 799 testGetFont_invalidResourceId()800 public void testGetFont_invalidResourceId() { 801 try { 802 mResources.getFont(-1); 803 fail("Font resource -1 should not be found."); 804 } catch (NotFoundException e) { 805 //expected 806 } 807 } 808 testGetFont_fontFile()809 public void testGetFont_fontFile() { 810 Typeface font = mResources.getFont(R.font.sample_regular_font); 811 812 assertNotNull(font); 813 assertNotSame(Typeface.DEFAULT, font); 814 } 815 testGetFont_xmlFile()816 public void testGetFont_xmlFile() { 817 Typeface font = mResources.getFont(R.font.samplexmlfont); 818 819 assertNotNull(font); 820 assertNotSame(Typeface.DEFAULT, font); 821 } 822 getLargerTypeface(String text, Typeface typeface1, Typeface typeface2)823 private Typeface getLargerTypeface(String text, Typeface typeface1, Typeface typeface2) { 824 Paint p1 = new Paint(); 825 p1.setTypeface(typeface1); 826 float width1 = p1.measureText(text); 827 Paint p2 = new Paint(); 828 p2.setTypeface(typeface2); 829 float width2 = p2.measureText(text); 830 831 if (width1 > width2) { 832 return typeface1; 833 } else if (width1 < width2) { 834 return typeface2; 835 } else { 836 fail("The widths of the text should not be the same"); 837 return null; 838 } 839 } 840 testGetFont_xmlFileWithTtc()841 public void testGetFont_xmlFileWithTtc() { 842 // Here we test that building typefaces by indexing in font collections works correctly. 843 // We want to ensure that the built typefaces correspond to the fonts with the right index. 844 // sample_font_collection.ttc contains two fonts (with indices 0 and 1). The first one has 845 // glyph "a" of 3em width, and all the other glyphs 1em. The second one has glyph "b" of 846 // 3em width, and all the other glyphs 1em. Hence, we can compare the width of these 847 // glyphs to assert that ttc indexing works. 848 Typeface normalFont = mResources.getFont(R.font.sample_ttc_family); 849 assertNotNull(normalFont); 850 Typeface italicFont = Typeface.create(normalFont, Typeface.ITALIC); 851 assertNotNull(italicFont); 852 853 assertEquals(getLargerTypeface("a", normalFont, italicFont), normalFont); 854 assertEquals(getLargerTypeface("b", normalFont, italicFont), italicFont); 855 } 856 testGetFont_xmlFileWithVariationSettings()857 public void testGetFont_xmlFileWithVariationSettings() { 858 // Here we test that specifying variation settings for fonts in XMLs works. 859 // We build typefaces from two families containing one font each, using the same font 860 // resource, but having different values for the 'wdth' tag. Then we measure the painted 861 // text to ensure that the tag affects the text width. The font resource used supports 862 // the 'wdth' axis for the dash (-) character. 863 Typeface typeface1 = mResources.getFont(R.font.sample_variation_settings_family1); 864 assertNotNull(typeface1); 865 Typeface typeface2 = mResources.getFont(R.font.sample_variation_settings_family2); 866 assertNotNull(typeface2); 867 868 assertNotSame(typeface1, typeface2); 869 assertEquals(getLargerTypeface("-", typeface1, typeface2), typeface2); 870 } 871 testGetFont_invalidXmlFile()872 public void testGetFont_invalidXmlFile() { 873 try { 874 assertNull(mResources.getFont(R.font.invalid_xmlfamily)); 875 } catch (NotFoundException e) { 876 // pass 877 } 878 879 try { 880 assertNull(mResources.getFont(R.font.invalid_xmlempty)); 881 } catch (NotFoundException e) { 882 // pass 883 } 884 } 885 testGetFont_invalidFontFiles()886 public void testGetFont_invalidFontFiles() { 887 try { 888 mResources.getFont(R.font.invalid_xmlfont); 889 fail(); 890 } catch (RuntimeException e) { 891 // pass 892 } 893 894 try { 895 mResources.getFont(R.font.invalid_font); 896 fail(); 897 } catch (RuntimeException e) { 898 // pass 899 } 900 901 try { 902 mResources.getFont(R.font.invalid_xmlfont_contains_invalid_font_file); 903 fail(); 904 } catch (RuntimeException e) { 905 // pass 906 } 907 908 try { 909 mResources.getFont(R.font.invalid_xmlfont_nosource); 910 fail(); 911 } catch (RuntimeException e) { 912 // pass 913 } 914 915 } 916 testGetFont_brokenFontFiles()917 public void testGetFont_brokenFontFiles() { 918 try { 919 mResources.getFont(R.font.brokenfont); 920 fail(); 921 } catch (RuntimeException e) { 922 // pass 923 } 924 925 try { 926 mResources.getFont(R.font.broken_xmlfont); 927 fail(); 928 } catch (RuntimeException e) { 929 // pass 930 } 931 } 932 testGetFont_fontFileIsCached()933 public void testGetFont_fontFileIsCached() { 934 Typeface font = mResources.getFont(R.font.sample_regular_font); 935 Typeface font2 = mResources.getFont(R.font.sample_regular_font); 936 937 assertEquals(font, font2); 938 } 939 testGetFont_xmlFileIsCached()940 public void testGetFont_xmlFileIsCached() { 941 Typeface font = mResources.getFont(R.font.samplexmlfont); 942 Typeface font2 = mResources.getFont(R.font.samplexmlfont); 943 944 assertEquals(font, font2); 945 } 946 testGetFont_resolveByFontTable()947 public void testGetFont_resolveByFontTable() { 948 assertEquals(Typeface.NORMAL, mResources.getFont(R.font.sample_regular_font).getStyle()); 949 assertEquals(Typeface.BOLD, mResources.getFont(R.font.sample_bold_font).getStyle()); 950 assertEquals(Typeface.ITALIC, mResources.getFont(R.font.sample_italic_font).getStyle()); 951 assertEquals(Typeface.BOLD_ITALIC, 952 mResources.getFont(R.font.sample_bolditalic_font).getStyle()); 953 954 assertEquals(Typeface.NORMAL, mResources.getFont(R.font.sample_regular_family).getStyle()); 955 assertEquals(Typeface.BOLD, mResources.getFont(R.font.sample_bold_family).getStyle()); 956 assertEquals(Typeface.ITALIC, mResources.getFont(R.font.sample_italic_family).getStyle()); 957 assertEquals(Typeface.BOLD_ITALIC, 958 mResources.getFont(R.font.sample_bolditalic_family).getStyle()); 959 } 960 961 // TODO Figure out why it fails in the instant mode. 962 @AppModeFull testComplextColorDrawableAttrInflation()963 public void testComplextColorDrawableAttrInflation() { 964 Context context = InstrumentationRegistry.getTargetContext(); 965 LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService( 966 Context.LAYOUT_INFLATER_SERVICE); 967 968 View view = layoutInflater.inflate(R.layout.complex_color_drawable_attr_layout, null); 969 assertTrue(view.getBackground() instanceof ColorStateListDrawable); 970 } 971 testGetAttributeSetSourceResId()972 public void testGetAttributeSetSourceResId() { 973 assertEquals(Resources.ID_NULL, Resources.getAttributeSetSourceResId(null)); 974 975 XmlPullParser test_color_parser = mResources.getXml(R.xml.test_color); 976 AttributeSet test_color_set = Xml.asAttributeSet(test_color_parser); 977 assertEquals(R.xml.test_color, Resources.getAttributeSetSourceResId(test_color_set)); 978 979 XmlPullParser colors_parser = mResources.getXml(R.xml.colors); 980 AttributeSet colors_set = Xml.asAttributeSet(colors_parser); 981 assertEquals(R.xml.colors, Resources.getAttributeSetSourceResId(colors_set)); 982 983 XmlPullParser content_layout_parser = mResources.getLayout(R.layout.context_layout); 984 AttributeSet content_layout_set = Xml.asAttributeSet(content_layout_parser); 985 assertEquals(R.layout.context_layout, 986 Resources.getAttributeSetSourceResId(content_layout_set)); 987 988 XmlPullParser anim_rotate_parser = mResources.getAnimation(R.anim.anim_rotate); 989 AttributeSet anim_rotate_set = Xml.asAttributeSet(anim_rotate_parser); 990 assertEquals(R.anim.anim_rotate, Resources.getAttributeSetSourceResId(anim_rotate_set)); 991 } 992 } 993