Home | History | Annotate | Download | only in robolectric
      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    */
     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    */
     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    */
     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    */
     79   public static void setMainThread(Thread newMainThread) {
     80     mainThread = newMainThread;
     81   }
     82 
     83   public static Object getActivityThread() {
     84     return activityThread;
     85   }
     86 
     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    */
     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    */
    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    */
    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 
    140   public static int getApiLevel() {
    141     return apiLevel;
    142   }
    143 
    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    */
    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    */
    175   public static void setMasterScheduler(Scheduler masterScheduler) {
    176     RuntimeEnvironment.masterScheduler = masterScheduler;
    177   }
    178 
    179   public static void setSystemResourceTable(ResourceTable systemResourceTable) {
    180     RuntimeEnvironment.systemResourceTable = systemResourceTable;
    181   }
    182 
    183   public static void setAppResourceTable(ResourceTable appResourceTable) {
    184     RuntimeEnvironment.appResourceTable = appResourceTable;
    185   }
    186 
    187   public static ResourceTable getSystemResourceTable() {
    188     return systemResourceTable;
    189   }
    190 
    191   public static ResourceTable getAppResourceTable() {
    192     return appResourceTable;
    193   }
    194 
    195   public static void setCompileTimeResourceTable(ResourceTable compileTimeResourceTable) {
    196     RuntimeEnvironment.compileTimeResourceTable = compileTimeResourceTable;
    197   }
    198 
    199   public static ResourceTable getCompileTimeResourceTable() {
    200     return compileTimeResourceTable;
    201   }
    202 
    203   public static void setTempDirectory(TempDirectory tempDirectory) {
    204     RuntimeEnvironment.tempDirectory = tempDirectory;
    205   }
    206 
    207   public static TempDirectory getTempDirectory() {
    208     return tempDirectory;
    209   }
    210 
    211   public static void setAndroidFrameworkJarPath(String localArtifactPath) {
    212     RuntimeEnvironment.androidFrameworkJar = localArtifactPath;
    213   }
    214 
    215   public static String getAndroidFrameworkJarPath() {
    216     return RuntimeEnvironment.androidFrameworkJar;
    217   }
    218 
    219   /**
    220    * Internal only.
    221    *
    222    * @deprecated Do not use.
    223    */
    224   @Deprecated
    225   public static boolean useLegacyResources() {
    226     return useLegacyResources;
    227   }
    228 
    229   /**
    230    * Internal only.
    231    *
    232    * @deprecated Do not use.
    233    */
    234   @Deprecated
    235   public static void setUseLegacyResources(boolean useLegacyResources) {
    236     RuntimeEnvironment.useLegacyResources = useLegacyResources;
    237   }
    238 }
    239