1 package com.android.settings.testutils.shadow; 2 3 import static org.robolectric.RuntimeEnvironment.application; 4 import static org.robolectric.shadow.api.Shadow.directlyOn; 5 6 import android.content.res.Resources; 7 import android.content.res.Resources.NotFoundException; 8 import android.util.SparseArray; 9 10 import androidx.annotation.ArrayRes; 11 12 import org.robolectric.annotation.Implementation; 13 import org.robolectric.annotation.Implements; 14 import org.robolectric.annotation.RealObject; 15 import org.robolectric.annotation.Resetter; 16 import org.robolectric.shadows.ShadowResources; 17 import org.robolectric.util.ReflectionHelpers.ClassParameter; 18 19 /** 20 * Shadow Resources and Theme classes to handle resource references that Robolectric shadows cannot 21 * handle because they are too new or private. 22 */ 23 @Implements(value = Resources.class) 24 public class SettingsShadowResources extends ShadowResources { 25 26 @RealObject 27 public Resources realResources; 28 29 private static SparseArray<Object> sResourceOverrides = new SparseArray<>(); 30 overrideResource(int id, Object value)31 public static void overrideResource(int id, Object value) { 32 sResourceOverrides.put(id, value); 33 } 34 overrideResource(String name, Object value)35 public static void overrideResource(String name, Object value) { 36 final Resources res = application.getResources(); 37 final int resId = res.getIdentifier(name, null, null); 38 if (resId == 0) { 39 throw new Resources.NotFoundException("Cannot override \"" + name + "\""); 40 } 41 overrideResource(resId, value); 42 } 43 44 @Resetter reset()45 public static void reset() { 46 sResourceOverrides.clear(); 47 } 48 49 @Implementation getIntArray(@rrayRes int id)50 protected int[] getIntArray(@ArrayRes int id) throws NotFoundException { 51 final Object override = sResourceOverrides.get(id); 52 if (override instanceof int[]) { 53 return (int[]) override; 54 } 55 return directlyOn(realResources, Resources.class).getIntArray(id); 56 } 57 58 @Implementation getString(int id)59 protected String getString(int id) { 60 final Object override = sResourceOverrides.get(id); 61 if (override instanceof String) { 62 return (String) override; 63 } 64 return directlyOn( 65 realResources, Resources.class, "getString", ClassParameter.from(int.class, id)); 66 } 67 68 @Implementation getInteger(int id)69 protected int getInteger(int id) { 70 final Object override = sResourceOverrides.get(id); 71 if (override instanceof Integer) { 72 return (Integer) override; 73 } 74 return directlyOn( 75 realResources, Resources.class, "getInteger", ClassParameter.from(int.class, id)); 76 } 77 78 @Implementation getBoolean(int id)79 protected boolean getBoolean(int id) { 80 final Object override = sResourceOverrides.get(id); 81 if (override instanceof Boolean) { 82 return (boolean) override; 83 } 84 return directlyOn(realResources, Resources.class, "getBoolean", 85 ClassParameter.from(int.class, id)); 86 } 87 } 88