ShadowResources.java revision 9daa83d905eccca3b027ce27e4a77b3f57441a1e
133873d2b41a5cd2597b20a4e88eb8942944c0f23Tyler Schultzpackage com.xtremelabs.robolectric.shadows; 2b63effe7b28319e0430f0baa9b8d1b8ddd3ff307Christian Williams & Phil Goodwin 370a3ec81f0bda52d8388facf562a80e2d16ac96fGonçalo Silvaimport android.content.res.AssetManager; 46b77d40267d9b2d4d1b3e206f7d1bdd60a91d8c8Michael Portuesiimport android.content.res.Configuration; 5b63effe7b28319e0430f0baa9b8d1b8ddd3ff307Christian Williams & Phil Goodwinimport android.content.res.Resources; 6ec63d3ad017965dc341bd0ce15f07c65f35b4a90Christian Williamsimport android.content.res.TypedArray; 7b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williamsimport android.graphics.BitmapFactory; 8b63effe7b28319e0430f0baa9b8d1b8ddd3ff307Christian Williams & Phil Goodwinimport android.graphics.drawable.BitmapDrawable; 9b63effe7b28319e0430f0baa9b8d1b8ddd3ff307Christian Williams & Phil Goodwinimport android.graphics.drawable.Drawable; 10ec63d3ad017965dc341bd0ce15f07c65f35b4a90Christian Williamsimport android.util.AttributeSet; 11b63effe7b28319e0430f0baa9b8d1b8ddd3ff307Christian Williams & Phil Goodwinimport android.util.DisplayMetrics; 1270a3ec81f0bda52d8388facf562a80e2d16ac96fGonçalo Silvaimport com.xtremelabs.robolectric.Robolectric; 1322c22c9aa4ca68c2deac6164edc1d82bc9645310Christian Williams & Phil Goodwinimport com.xtremelabs.robolectric.internal.Implementation; 1422c22c9aa4ca68c2deac6164edc1d82bc9645310Christian Williams & Phil Goodwinimport com.xtremelabs.robolectric.internal.Implements; 15f64d95f87eb9715622e3f77eb0b369d60270054cChristian Williams & Phil Goodwinimport com.xtremelabs.robolectric.internal.RealObject; 16f320a2d3b8075716daf2a80f5a8f7890086fb609Mark Bakkerimport com.xtremelabs.robolectric.res.ResourceExtractor; 173f1d4fe696c2f3efe99b8ef39868c064928efb1aTyler Schultzimport com.xtremelabs.robolectric.res.ResourceLoader; 18b63effe7b28319e0430f0baa9b8d1b8ddd3ff307Christian Williams & Phil Goodwin 1924f155944b10583afd970905e5dbe0acdfc9e0efPhil Goodwin & Tyler Schultzimport java.io.InputStream; 2024f155944b10583afd970905e5dbe0acdfc9e0efPhil Goodwin & Tyler Schultzimport java.util.Locale; 2124f155944b10583afd970905e5dbe0acdfc9e0efPhil Goodwin & Tyler Schultz 22ec63d3ad017965dc341bd0ce15f07c65f35b4a90Christian Williamsimport static com.xtremelabs.robolectric.Robolectric.newInstanceOf; 2324f155944b10583afd970905e5dbe0acdfc9e0efPhil Goodwin & Tyler Schultzimport static com.xtremelabs.robolectric.Robolectric.shadowOf; 2424f155944b10583afd970905e5dbe0acdfc9e0efPhil Goodwin & Tyler Schultz 2559d9df0f147b94712b36ad44939ebd2afa4cf1b7Phil Goodwin/** 2659d9df0f147b94712b36ad44939ebd2afa4cf1b7Phil Goodwin * Shadow of {@code Resources} that simulates the loading of resources 2759d9df0f147b94712b36ad44939ebd2afa4cf1b7Phil Goodwin * 2859d9df0f147b94712b36ad44939ebd2afa4cf1b7Phil Goodwin * @see com.xtremelabs.robolectric.RobolectricTestRunner#RobolectricTestRunner(Class, String, String) 2959d9df0f147b94712b36ad44939ebd2afa4cf1b7Phil Goodwin */ 30b63effe7b28319e0430f0baa9b8d1b8ddd3ff307Christian Williams & Phil Goodwin@SuppressWarnings({"UnusedDeclaration"}) 31b63effe7b28319e0430f0baa9b8d1b8ddd3ff307Christian Williams & Phil Goodwin@Implements(Resources.class) 32afe0a89d904a7fe2f5980b9deb26cc3240192459Christian Williamspublic class ShadowResources { 33e02d2608f3fa739dd328c6b44a2122b9dfb73bedLowell Kirsh & Ryan Richard private float density = 1.0f; 34e02d2608f3fa739dd328c6b44a2122b9dfb73bedLowell Kirsh & Ryan Richard 3508d5f9aec95a889473eaff1f5d6afefbaa2bd489Christian Williams static Resources bind(Resources resources, ResourceLoader resourceLoader) { 36a8486da7c7a0b6a10e943c55992f34d9c256456dChristian Williams ShadowResources shadowResources = shadowOf(resources); 3703ce698c2bb5b203761ce51694d2fa104be4a40dTyler Schultz if (shadowResources.resourceLoader != null) throw new RuntimeException("ResourceLoader already set!"); 3803ce698c2bb5b203761ce51694d2fa104be4a40dTyler Schultz shadowResources.resourceLoader = resourceLoader; 3908d5f9aec95a889473eaff1f5d6afefbaa2bd489Christian Williams return resources; 4008d5f9aec95a889473eaff1f5d6afefbaa2bd489Christian Williams } 4108d5f9aec95a889473eaff1f5d6afefbaa2bd489Christian Williams 42b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams @RealObject Resources realResources; 4308d5f9aec95a889473eaff1f5d6afefbaa2bd489Christian Williams private ResourceLoader resourceLoader; 4408d5f9aec95a889473eaff1f5d6afefbaa2bd489Christian Williams 45de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams @Implementation 46f320a2d3b8075716daf2a80f5a8f7890086fb609Mark Bakker public int getIdentifier(String name, String defType, String defPackage) { 47f320a2d3b8075716daf2a80f5a8f7890086fb609Mark Bakker Integer index = 0; 48f320a2d3b8075716daf2a80f5a8f7890086fb609Mark Bakker 49f320a2d3b8075716daf2a80f5a8f7890086fb609Mark Bakker ResourceExtractor resourceExtractor = resourceLoader.getResourceExtractor(); 50f320a2d3b8075716daf2a80f5a8f7890086fb609Mark Bakker 51f320a2d3b8075716daf2a80f5a8f7890086fb609Mark Bakker index = resourceExtractor.getResourceId(defType + "/" + name); 52f320a2d3b8075716daf2a80f5a8f7890086fb609Mark Bakker if (index == null) { 53f320a2d3b8075716daf2a80f5a8f7890086fb609Mark Bakker return 0; 54f320a2d3b8075716daf2a80f5a8f7890086fb609Mark Bakker } 55f320a2d3b8075716daf2a80f5a8f7890086fb609Mark Bakker return index; 56f320a2d3b8075716daf2a80f5a8f7890086fb609Mark Bakker } 57f320a2d3b8075716daf2a80f5a8f7890086fb609Mark Bakker 58f320a2d3b8075716daf2a80f5a8f7890086fb609Mark Bakker @Implementation 59b63effe7b28319e0430f0baa9b8d1b8ddd3ff307Christian Williams & Phil Goodwin public int getColor(int id) throws Resources.NotFoundException { 6025cbf6f16c0fc8e6524935e6fa3d70ec2a92ed25Phil Goodwin & Tyler Schultz return resourceLoader.getColorValue(id); 61b63effe7b28319e0430f0baa9b8d1b8ddd3ff307Christian Williams & Phil Goodwin } 6240c6251719cccc0a84ae99c976d2836b14374ce6Christian Williams 636b77d40267d9b2d4d1b3e206f7d1bdd60a91d8c8Michael Portuesi @Implementation 646b77d40267d9b2d4d1b3e206f7d1bdd60a91d8c8Michael Portuesi public Configuration getConfiguration() { 6540c6251719cccc0a84ae99c976d2836b14374ce6Christian Williams Configuration configuration = new Configuration(); 6640c6251719cccc0a84ae99c976d2836b14374ce6Christian Williams configuration.setToDefaults(); 6759dd302ae512cbebc117b8687a634421fcff0993Gautier Hayoun if (configuration.locale == null) { 6859dd302ae512cbebc117b8687a634421fcff0993Gautier Hayoun configuration.locale = Locale.getDefault(); 6959dd302ae512cbebc117b8687a634421fcff0993Gautier Hayoun } 7040c6251719cccc0a84ae99c976d2836b14374ce6Christian Williams return configuration; 716b77d40267d9b2d4d1b3e206f7d1bdd60a91d8c8Michael Portuesi } 72b63effe7b28319e0430f0baa9b8d1b8ddd3ff307Christian Williams & Phil Goodwin 73de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams @Implementation 74b63effe7b28319e0430f0baa9b8d1b8ddd3ff307Christian Williams & Phil Goodwin public String getString(int id) throws Resources.NotFoundException { 7525cbf6f16c0fc8e6524935e6fa3d70ec2a92ed25Phil Goodwin & Tyler Schultz return resourceLoader.getStringValue(id); 76b63effe7b28319e0430f0baa9b8d1b8ddd3ff307Christian Williams & Phil Goodwin } 77b63effe7b28319e0430f0baa9b8d1b8ddd3ff307Christian Williams & Phil Goodwin 78de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams @Implementation 79b63effe7b28319e0430f0baa9b8d1b8ddd3ff307Christian Williams & Phil Goodwin public String getString(int id, Object... formatArgs) throws Resources.NotFoundException { 80b63effe7b28319e0430f0baa9b8d1b8ddd3ff307Christian Williams & Phil Goodwin String raw = getString(id); 81b63effe7b28319e0430f0baa9b8d1b8ddd3ff307Christian Williams & Phil Goodwin return String.format(Locale.ENGLISH, raw, formatArgs); 82b63effe7b28319e0430f0baa9b8d1b8ddd3ff307Christian Williams & Phil Goodwin } 83b63effe7b28319e0430f0baa9b8d1b8ddd3ff307Christian Williams & Phil Goodwin 84de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams @Implementation 859daa83d905eccca3b027ce27e4a77b3f57441a1eJan Berkel public String getQuantityString(int id, int quantity, Object... formatArgs) throws Resources.NotFoundException { 869daa83d905eccca3b027ce27e4a77b3f57441a1eJan Berkel String raw = getQuantityString(id, quantity); 879daa83d905eccca3b027ce27e4a77b3f57441a1eJan Berkel return String.format(Locale.ENGLISH, raw, formatArgs); 889daa83d905eccca3b027ce27e4a77b3f57441a1eJan Berkel } 899daa83d905eccca3b027ce27e4a77b3f57441a1eJan Berkel 909daa83d905eccca3b027ce27e4a77b3f57441a1eJan Berkel @Implementation 919daa83d905eccca3b027ce27e4a77b3f57441a1eJan Berkel public String getQuantityString(int id, int quantity) throws Resources.NotFoundException { 929daa83d905eccca3b027ce27e4a77b3f57441a1eJan Berkel return resourceLoader.getPluralStringValue(id, quantity); 939daa83d905eccca3b027ce27e4a77b3f57441a1eJan Berkel } 949daa83d905eccca3b027ce27e4a77b3f57441a1eJan Berkel 959daa83d905eccca3b027ce27e4a77b3f57441a1eJan Berkel @Implementation 96b63be1295e9d42211bd466585850db5897222aa1Macarse public InputStream openRawResource(int id) throws Resources.NotFoundException { 9740c6251719cccc0a84ae99c976d2836b14374ce6Christian Williams return resourceLoader.getRawValue(id); 98b63be1295e9d42211bd466585850db5897222aa1Macarse } 9940c6251719cccc0a84ae99c976d2836b14374ce6Christian Williams 100b63be1295e9d42211bd466585850db5897222aa1Macarse @Implementation 101b63effe7b28319e0430f0baa9b8d1b8ddd3ff307Christian Williams & Phil Goodwin public String[] getStringArray(int id) throws Resources.NotFoundException { 10225cbf6f16c0fc8e6524935e6fa3d70ec2a92ed25Phil Goodwin & Tyler Schultz String[] arrayValue = resourceLoader.getStringArrayValue(id); 103b63effe7b28319e0430f0baa9b8d1b8ddd3ff307Christian Williams & Phil Goodwin if (arrayValue == null) { 104b63effe7b28319e0430f0baa9b8d1b8ddd3ff307Christian Williams & Phil Goodwin throw new Resources.NotFoundException(); 105b63effe7b28319e0430f0baa9b8d1b8ddd3ff307Christian Williams & Phil Goodwin } 106b63effe7b28319e0430f0baa9b8d1b8ddd3ff307Christian Williams & Phil Goodwin return arrayValue; 107b63effe7b28319e0430f0baa9b8d1b8ddd3ff307Christian Williams & Phil Goodwin } 108b63effe7b28319e0430f0baa9b8d1b8ddd3ff307Christian Williams & Phil Goodwin 109de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams @Implementation 110bd9537bd36434865d4d25ef332bd388d39a51e34Christian Williams & Phil Goodwin public CharSequence[] getTextArray(int id) throws Resources.NotFoundException { 111bd9537bd36434865d4d25ef332bd388d39a51e34Christian Williams & Phil Goodwin return getStringArray(id); 112bd9537bd36434865d4d25ef332bd388d39a51e34Christian Williams & Phil Goodwin } 113bd9537bd36434865d4d25ef332bd388d39a51e34Christian Williams & Phil Goodwin 114bd9537bd36434865d4d25ef332bd388d39a51e34Christian Williams & Phil Goodwin @Implementation 115b63effe7b28319e0430f0baa9b8d1b8ddd3ff307Christian Williams & Phil Goodwin public CharSequence getText(int id) throws Resources.NotFoundException { 116b63effe7b28319e0430f0baa9b8d1b8ddd3ff307Christian Williams & Phil Goodwin return getString(id); 117b63effe7b28319e0430f0baa9b8d1b8ddd3ff307Christian Williams & Phil Goodwin } 118b63effe7b28319e0430f0baa9b8d1b8ddd3ff307Christian Williams & Phil Goodwin 119e02d2608f3fa739dd328c6b44a2122b9dfb73bedLowell Kirsh & Ryan Richard public void setDensity(float density) { 120e02d2608f3fa739dd328c6b44a2122b9dfb73bedLowell Kirsh & Ryan Richard this.density = density; 121e02d2608f3fa739dd328c6b44a2122b9dfb73bedLowell Kirsh & Ryan Richard } 122e02d2608f3fa739dd328c6b44a2122b9dfb73bedLowell Kirsh & Ryan Richard 123de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams @Implementation 124b63effe7b28319e0430f0baa9b8d1b8ddd3ff307Christian Williams & Phil Goodwin public DisplayMetrics getDisplayMetrics() { 125e02d2608f3fa739dd328c6b44a2122b9dfb73bedLowell Kirsh & Ryan Richard DisplayMetrics displayMetrics = new DisplayMetrics(); 126e02d2608f3fa739dd328c6b44a2122b9dfb73bedLowell Kirsh & Ryan Richard displayMetrics.density = this.density; 127e02d2608f3fa739dd328c6b44a2122b9dfb73bedLowell Kirsh & Ryan Richard return displayMetrics; 128b63effe7b28319e0430f0baa9b8d1b8ddd3ff307Christian Williams & Phil Goodwin } 129b63effe7b28319e0430f0baa9b8d1b8ddd3ff307Christian Williams & Phil Goodwin 130de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams @Implementation 131f1e19869f68b5b04688cc9701c3e2bf73cd35f76Ryan Richard public Drawable getDrawable(int drawableResourceId) throws Resources.NotFoundException { 132dc2eb2cd17a7fa2777e6e4f5a7566d90b2413cb4Josh Lauer & Christian Williams return new BitmapDrawable(BitmapFactory.decodeResource(realResources, drawableResourceId)); 133b63effe7b28319e0430f0baa9b8d1b8ddd3ff307Christian Williams & Phil Goodwin } 134b63effe7b28319e0430f0baa9b8d1b8ddd3ff307Christian Williams & Phil Goodwin 135de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams @Implementation 136fba19865a86f986189561f961a27f664eb23ce38Chee Wong & Phil Goodwin public float getDimension(int id) throws Resources.NotFoundException { 137fba19865a86f986189561f961a27f664eb23ce38Chee Wong & Phil Goodwin // todo: get this value from the xml resources and scale it by display metrics [xw 20101011] 13808d5f9aec95a889473eaff1f5d6afefbaa2bd489Christian Williams if (resourceLoader.dimensions.containsKey(id)) { 13908d5f9aec95a889473eaff1f5d6afefbaa2bd489Christian Williams return resourceLoader.dimensions.get(id); 140fba19865a86f986189561f961a27f664eb23ce38Chee Wong & Phil Goodwin } 141fba19865a86f986189561f961a27f664eb23ce38Chee Wong & Phil Goodwin return id - 0x7f000000; 142fba19865a86f986189561f961a27f664eb23ce38Chee Wong & Phil Goodwin } 143b63effe7b28319e0430f0baa9b8d1b8ddd3ff307Christian Williams & Phil Goodwin 144fba19865a86f986189561f961a27f664eb23ce38Chee Wong & Phil Goodwin @Implementation 145fba19865a86f986189561f961a27f664eb23ce38Chee Wong & Phil Goodwin public int getDimensionPixelSize(int id) throws Resources.NotFoundException { 146b63effe7b28319e0430f0baa9b8d1b8ddd3ff307Christian Williams & Phil Goodwin // The int value returned from here is probably going to be handed to TextView.setTextSize(), 147b63effe7b28319e0430f0baa9b8d1b8ddd3ff307Christian Williams & Phil Goodwin // which takes a float. Avoid int-to-float conversion errors by returning a value generated from this 148b63effe7b28319e0430f0baa9b8d1b8ddd3ff307Christian Williams & Phil Goodwin // resource ID but which isn't too big (resource values in R.java are all greater than 0x7f000000). 149b63effe7b28319e0430f0baa9b8d1b8ddd3ff307Christian Williams & Phil Goodwin 150fba19865a86f986189561f961a27f664eb23ce38Chee Wong & Phil Goodwin return (int) getDimension(id); 151fba19865a86f986189561f961a27f664eb23ce38Chee Wong & Phil Goodwin } 152fba19865a86f986189561f961a27f664eb23ce38Chee Wong & Phil Goodwin 153fba19865a86f986189561f961a27f664eb23ce38Chee Wong & Phil Goodwin @Implementation 154fba19865a86f986189561f961a27f664eb23ce38Chee Wong & Phil Goodwin public int getDimensionPixelOffset(int id) throws Resources.NotFoundException { 155fba19865a86f986189561f961a27f664eb23ce38Chee Wong & Phil Goodwin return (int) getDimension(id); 156fba19865a86f986189561f961a27f664eb23ce38Chee Wong & Phil Goodwin } 157fba19865a86f986189561f961a27f664eb23ce38Chee Wong & Phil Goodwin 158114296321cba71f8133713306049ce3b411e8563Gonçalo Silva @Implementation 15940c6251719cccc0a84ae99c976d2836b14374ce6Christian Williams public AssetManager getAssets() { 160a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin return ShadowAssetManager.bind(Robolectric.newInstanceOf(AssetManager.class), resourceLoader); 161114296321cba71f8133713306049ce3b411e8563Gonçalo Silva } 162fba19865a86f986189561f961a27f664eb23ce38Chee Wong & Phil Goodwin 163ec63d3ad017965dc341bd0ce15f07c65f35b4a90Christian Williams @Implementation 164ec63d3ad017965dc341bd0ce15f07c65f35b4a90Christian Williams public final android.content.res.Resources.Theme newTheme() { 165ec63d3ad017965dc341bd0ce15f07c65f35b4a90Christian Williams return newInstanceOf(Resources.Theme.class); 166ec63d3ad017965dc341bd0ce15f07c65f35b4a90Christian Williams } 167ec63d3ad017965dc341bd0ce15f07c65f35b4a90Christian Williams 16859d9df0f147b94712b36ad44939ebd2afa4cf1b7Phil Goodwin /** 16959d9df0f147b94712b36ad44939ebd2afa4cf1b7Phil Goodwin * Non-Android accessor that sets the value to be returned by {@link #getDimension(int)} 17059d9df0f147b94712b36ad44939ebd2afa4cf1b7Phil Goodwin * 17140c6251719cccc0a84ae99c976d2836b14374ce6Christian Williams * @param id ID to set the dimension for 17259d9df0f147b94712b36ad44939ebd2afa4cf1b7Phil Goodwin * @param value value to be returned 17359d9df0f147b94712b36ad44939ebd2afa4cf1b7Phil Goodwin */ 174fba19865a86f986189561f961a27f664eb23ce38Chee Wong & Phil Goodwin public void setDimension(int id, int value) { 17508d5f9aec95a889473eaff1f5d6afefbaa2bd489Christian Williams resourceLoader.dimensions.put(id, value); 176b63effe7b28319e0430f0baa9b8d1b8ddd3ff307Christian Williams & Phil Goodwin } 177ec63d3ad017965dc341bd0ce15f07c65f35b4a90Christian Williams 178ec63d3ad017965dc341bd0ce15f07c65f35b4a90Christian Williams @Implements(Resources.Theme.class) 179ec63d3ad017965dc341bd0ce15f07c65f35b4a90Christian Williams public static class ShadowTheme { 180ec63d3ad017965dc341bd0ce15f07c65f35b4a90Christian Williams @Implementation 181ec63d3ad017965dc341bd0ce15f07c65f35b4a90Christian Williams public TypedArray obtainStyledAttributes(int[] attrs) { 182ec63d3ad017965dc341bd0ce15f07c65f35b4a90Christian Williams return obtainStyledAttributes(0, attrs); 183ec63d3ad017965dc341bd0ce15f07c65f35b4a90Christian Williams } 184ec63d3ad017965dc341bd0ce15f07c65f35b4a90Christian Williams 185ec63d3ad017965dc341bd0ce15f07c65f35b4a90Christian Williams @Implementation 186ec63d3ad017965dc341bd0ce15f07c65f35b4a90Christian Williams public TypedArray obtainStyledAttributes(int resid, int[] attrs) throws android.content.res.Resources.NotFoundException { 187ec63d3ad017965dc341bd0ce15f07c65f35b4a90Christian Williams return obtainStyledAttributes(null, attrs, 0, 0); 188ec63d3ad017965dc341bd0ce15f07c65f35b4a90Christian Williams } 189ec63d3ad017965dc341bd0ce15f07c65f35b4a90Christian Williams 190ec63d3ad017965dc341bd0ce15f07c65f35b4a90Christian Williams @Implementation 191ec63d3ad017965dc341bd0ce15f07c65f35b4a90Christian Williams public TypedArray obtainStyledAttributes(AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes) { 192ec63d3ad017965dc341bd0ce15f07c65f35b4a90Christian Williams return newInstanceOf(TypedArray.class); 193ec63d3ad017965dc341bd0ce15f07c65f35b4a90Christian Williams } 194ec63d3ad017965dc341bd0ce15f07c65f35b4a90Christian Williams } 195b63effe7b28319e0430f0baa9b8d1b8ddd3ff307Christian Williams & Phil Goodwin} 196