1 package org.robolectric; 2 3 import static android.os.Build.VERSION_CODES.LOLLIPOP; 4 5 import android.app.Application; 6 import android.content.Context; 7 import android.content.res.Configuration; 8 import android.content.res.Resources; 9 import android.util.DisplayMetrics; 10 import org.robolectric.android.Bootstrap; 11 import org.robolectric.android.ConfigurationV25; 12 import org.robolectric.res.FsFile; 13 import org.robolectric.res.ResourceTable; 14 import org.robolectric.util.Scheduler; 15 import org.robolectric.util.TempDirectory; 16 17 public class RuntimeEnvironment { 18 public static Context systemContext; 19 20 /** 21 * @deprecated Please migrate to {@link 22 * androidx.test.core.app.ApplicationProvider#getApplicationContext} 23 */ 24 @Deprecated public static Application application; 25 26 private volatile static Thread mainThread = Thread.currentThread(); 27 private static Object activityThread; 28 private static int apiLevel; 29 private static Scheduler masterScheduler; 30 private static ResourceTable systemResourceTable; 31 private static ResourceTable appResourceTable; 32 private static ResourceTable compileTimeResourceTable; 33 private static TempDirectory tempDirectory = new TempDirectory("no-test-yet"); 34 private static String androidFrameworkJar; 35 public static FsFile compileTimeSystemResourcesFile; 36 37 private static boolean useLegacyResources; 38 39 /** 40 * Tests if the given thread is currently set as the main thread. 41 * 42 * @param thread the thread to test. 43 * @return <tt>true</tt> if the specified thread is the main thread, <tt>false</tt> otherwise. 44 * @see #isMainThread() 45 */ isMainThread(Thread thread)46 public static boolean isMainThread(Thread thread) { 47 return thread == mainThread; 48 } 49 50 /** 51 * Tests if the current thread is currently set as the main thread. 52 * 53 * @return <tt>true</tt> if the current thread is the main thread, <tt>false</tt> otherwise. 54 */ isMainThread()55 public static boolean isMainThread() { 56 return isMainThread(Thread.currentThread()); 57 } 58 59 /** 60 * Retrieves the main thread. The main thread is the thread to which the main looper is attached. 61 * Defaults to the thread that initialises the <tt>RuntimeEnvironment</tt> class. 62 * 63 * @return The main thread. 64 * @see #setMainThread(Thread) 65 * @see #isMainThread() 66 */ getMainThread()67 public static Thread getMainThread() { 68 return mainThread; 69 } 70 71 /** 72 * Sets the main thread. The main thread is the thread to which the main looper is attached. 73 * Defaults to the thread that initialises the <tt>RuntimeEnvironment</tt> class. 74 * 75 * @param newMainThread the new main thread. 76 * @see #setMainThread(Thread) 77 * @see #isMainThread() 78 */ setMainThread(Thread newMainThread)79 public static void setMainThread(Thread newMainThread) { 80 mainThread = newMainThread; 81 } 82 getActivityThread()83 public static Object getActivityThread() { 84 return activityThread; 85 } 86 setActivityThread(Object newActivityThread)87 public static void setActivityThread(Object newActivityThread) { 88 activityThread = newActivityThread; 89 } 90 91 /** 92 * Returns a qualifier string describing the current {@link Configuration} of the system resources. 93 * 94 * @return a qualifier string as described (https://developer.android.com/guide/topics/resources/providing-resources.html#QualifierRules)[here]. 95 */ getQualifiers()96 public static String getQualifiers() { 97 Resources systemResources = Resources.getSystem(); 98 return getQualifiers(systemResources.getConfiguration(), systemResources.getDisplayMetrics()); 99 } 100 101 /** 102 * Returns a qualifier string describing the given configuration and display metrics. 103 * 104 * @param configuration the configuration. 105 * @param displayMetrics the display metrics. 106 * @return a qualifier string as described (https://developer.android.com/guide/topics/resources/providing-resources.html#QualifierRules)[here]. 107 */ getQualifiers(Configuration configuration, DisplayMetrics displayMetrics)108 public static String getQualifiers(Configuration configuration, DisplayMetrics displayMetrics) { 109 return ConfigurationV25.resourceQualifierString(configuration, displayMetrics); 110 } 111 112 /** 113 * Overrides the current device configuration. 114 * 115 * If `newQualifiers` starts with a plus (`+`), the prior configuration is used as the base 116 * configuration, with the given changes applied additively. Otherwise, default values are used 117 * for unspecified properties, as described [here](http://robolectric.org/device-configuration/). 118 * 119 * @param newQualifiers the qualifiers to apply 120 */ setQualifiers(String newQualifiers)121 public static void setQualifiers(String newQualifiers) { 122 Configuration configuration; 123 DisplayMetrics displayMetrics = new DisplayMetrics(); 124 if (newQualifiers.startsWith("+")) { 125 configuration = new Configuration(Resources.getSystem().getConfiguration()); 126 displayMetrics.setTo(Resources.getSystem().getDisplayMetrics()); 127 } else { 128 configuration = new Configuration(); 129 } 130 Bootstrap.applyQualifiers(newQualifiers, getApiLevel(), configuration, displayMetrics); 131 132 Resources systemResources = Resources.getSystem(); 133 systemResources.updateConfiguration(configuration, displayMetrics); 134 135 if (application != null) { 136 application.getResources().updateConfiguration(configuration, displayMetrics); 137 } 138 } 139 getApiLevel()140 public static int getApiLevel() { 141 return apiLevel; 142 } 143 castNativePtr(long ptr)144 public static Number castNativePtr(long ptr) { 145 // Weird, using a ternary here doesn't work, there's some auto promotion of boxed types happening. 146 if (getApiLevel() >= LOLLIPOP) { 147 return ptr; 148 } else { 149 return (int) ptr; 150 } 151 } 152 153 /** 154 * Retrieves the current master scheduler. This scheduler is always used by the main 155 * {@link android.os.Looper Looper}, and if the global scheduler option is set it is also used for 156 * the background scheduler and for all other {@link android.os.Looper Looper}s 157 * @return The current master scheduler. 158 * @see #setMasterScheduler(Scheduler) 159 * see org.robolectric.Robolectric#getForegroundThreadScheduler() 160 * see org.robolectric.Robolectric#getBackgroundThreadScheduler() 161 */ getMasterScheduler()162 public static Scheduler getMasterScheduler() { 163 return masterScheduler; 164 } 165 166 /** 167 * Sets the current master scheduler. See {@link #getMasterScheduler()} for details. 168 * Note that this method is primarily intended to be called by the Robolectric core setup code. 169 * Changing the master scheduler during a test will have unpredictable results. 170 * @param masterScheduler the new master scheduler. 171 * @see #getMasterScheduler() 172 * see org.robolectric.Robolectric#getForegroundThreadScheduler() 173 * see org.robolectric.Robolectric#getBackgroundThreadScheduler() 174 */ setMasterScheduler(Scheduler masterScheduler)175 public static void setMasterScheduler(Scheduler masterScheduler) { 176 RuntimeEnvironment.masterScheduler = masterScheduler; 177 } 178 setSystemResourceTable(ResourceTable systemResourceTable)179 public static void setSystemResourceTable(ResourceTable systemResourceTable) { 180 RuntimeEnvironment.systemResourceTable = systemResourceTable; 181 } 182 setAppResourceTable(ResourceTable appResourceTable)183 public static void setAppResourceTable(ResourceTable appResourceTable) { 184 RuntimeEnvironment.appResourceTable = appResourceTable; 185 } 186 getSystemResourceTable()187 public static ResourceTable getSystemResourceTable() { 188 return systemResourceTable; 189 } 190 getAppResourceTable()191 public static ResourceTable getAppResourceTable() { 192 return appResourceTable; 193 } 194 setCompileTimeResourceTable(ResourceTable compileTimeResourceTable)195 public static void setCompileTimeResourceTable(ResourceTable compileTimeResourceTable) { 196 RuntimeEnvironment.compileTimeResourceTable = compileTimeResourceTable; 197 } 198 getCompileTimeResourceTable()199 public static ResourceTable getCompileTimeResourceTable() { 200 return compileTimeResourceTable; 201 } 202 setTempDirectory(TempDirectory tempDirectory)203 public static void setTempDirectory(TempDirectory tempDirectory) { 204 RuntimeEnvironment.tempDirectory = tempDirectory; 205 } 206 getTempDirectory()207 public static TempDirectory getTempDirectory() { 208 return tempDirectory; 209 } 210 setAndroidFrameworkJarPath(String localArtifactPath)211 public static void setAndroidFrameworkJarPath(String localArtifactPath) { 212 RuntimeEnvironment.androidFrameworkJar = localArtifactPath; 213 } 214 getAndroidFrameworkJarPath()215 public static String getAndroidFrameworkJarPath() { 216 return RuntimeEnvironment.androidFrameworkJar; 217 } 218 219 /** 220 * Internal only. 221 * 222 * @deprecated Do not use. 223 */ 224 @Deprecated useLegacyResources()225 public static boolean useLegacyResources() { 226 return useLegacyResources; 227 } 228 229 /** 230 * Internal only. 231 * 232 * @deprecated Do not use. 233 */ 234 @Deprecated setUseLegacyResources(boolean useLegacyResources)235 public static void setUseLegacyResources(boolean useLegacyResources) { 236 RuntimeEnvironment.useLegacyResources = useLegacyResources; 237 } 238 } 239