All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.robolectric.RuntimeEnvironment Maven / Gradle / Ivy

The newest version!
package org.robolectric;

import static org.robolectric.annotation.LooperMode.Mode.LEGACY;
import static org.robolectric.shadows.ShadowLooper.assertLooperMode;

import android.app.Application;
import android.app.ResourcesManager;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.util.DisplayMetrics;
import android.view.Display;
import com.google.common.base.Supplier;
import java.nio.file.Path;
import org.robolectric.android.Bootstrap;
import org.robolectric.android.ConfigurationV25;
import org.robolectric.shadows.ShadowDisplayManager;
import org.robolectric.shadows.ShadowInstrumentation;
import org.robolectric.shadows.ShadowView;
import org.robolectric.util.Scheduler;
import org.robolectric.util.TempDirectory;

public class RuntimeEnvironment {
  /**
   * @deprecated Use {@link #getApplication} instead. Note that unlike the alternative, this field
   *     is inherently incompatible with {@link
   *     org.robolectric.annotation.experimental.LazyApplication}. This field may be removed in a
   *     later release
   */
  @Deprecated public static Context systemContext;

  /**
   * @deprecated Please use {#getApplication} instead. Accessing this field directly is inherently
   *     incompatible with {@link org.robolectric.annotation.experimental.LazyApplication} and
   *     Robolectric makes no guarantees if a test *modifies* this field during execution.
   */
  @Deprecated public static volatile Application application;

  private static volatile Thread mainThread;
  private static volatile Object activityThread;
  private static int apiLevel;
  private static Scheduler masterScheduler;
  private static TempDirectory tempDirectory = new TempDirectory("no-test-yet");
  private static Path androidFrameworkJar;
  public static Path compileTimeSystemResourcesFile;

  private static Supplier applicationSupplier;
  private static final Object supplierLock = new Object();

  /**
   * Get a reference to the {@link Application} under test.
   *
   * 

The Application may be created a test setup time or created lazily at call time, based on * the test's {@link org.robolectric.annotation.experimental.LazyApplication} setting. If lazy * loading is enabled, this method must be called on the main/test thread. * *

An alternate API outside of Robolectric is {@link * androidx.test.core.app.ApplicationProvider#getApplicationContext()}, which is preferable if you * desire cross platform tests that work on the JVM and real Android devices. */ public static Application getApplication() { // IMPORTANT NOTE: Given the order in which these are nulled out when cleaning up in // AndroidTestEnvironment, the application null check must happen before the supplier null // check. Otherwise the get() call can try to load an application that has already been // loaded and cleaned up (as well as race with other threads trying to load the "correct" // application) if (application == null) { synchronized (supplierLock) { if (applicationSupplier != null) { ShadowInstrumentation.runOnMainSyncNoIdle(() -> application = applicationSupplier.get()); } } } return application; } /** internal use only */ public static void setApplicationSupplier(Supplier applicationSupplier) { synchronized (supplierLock) { RuntimeEnvironment.applicationSupplier = applicationSupplier; } } private static Class applicationClass; public static Class getConfiguredApplicationClass() { return applicationClass; } public static void setConfiguredApplicationClass(Class clazz) { applicationClass = clazz; } /** * Tests if the given thread is currently set as the main thread. * * @param thread the thread to test. * @return true if the specified thread is the main thread, false otherwise. * @see #isMainThread() */ public static boolean isMainThread(Thread thread) { assertLooperMode(LEGACY); return thread == mainThread; } /** * Tests if the current thread is currently set as the main thread. * *

Not supported in realistic looper mode. * * @return true if the current thread is the main thread, false otherwise. */ public static boolean isMainThread() { assertLooperMode(LEGACY); return isMainThread(Thread.currentThread()); } /** * Retrieves the main thread. The main thread is the thread to which the main looper is attached. * Defaults to the thread that initialises the {@link RuntimeEnvironment} class. * *

Not supported in realistic looper mode. * * @return The main thread. * @see #setMainThread(Thread) * @see #isMainThread() */ public static Thread getMainThread() { assertLooperMode(LEGACY); return mainThread; } /** * Sets the main thread. The main thread is the thread to which the main looper is attached. * Defaults to the thread that initialises the {@link RuntimeEnvironment} class. * *

Not supported in realistic looper mode. * * @param newMainThread the new main thread. * @see #setMainThread(Thread) * @see #isMainThread() */ public static void setMainThread(Thread newMainThread) { assertLooperMode(LEGACY); mainThread = newMainThread; } public static Object getActivityThread() { return activityThread; } public static void setActivityThread(Object newActivityThread) { activityThread = newActivityThread; } /** * Returns a qualifier string describing the current {@link Configuration} of the system * resources. * * @return a qualifier string as described * (https://developer.android.com/guide/topics/resources/providing-resources.html#QualifierRules)[here]. */ public static String getQualifiers() { Resources systemResources = Resources.getSystem(); return getQualifiers(systemResources.getConfiguration(), systemResources.getDisplayMetrics()); } /** * Returns a qualifier string describing the given configuration and display metrics. * * @param configuration the configuration. * @param displayMetrics the display metrics. * @return a qualifier string as described * (https://developer.android.com/guide/topics/resources/providing-resources.html#QualifierRules)[here]. */ public static String getQualifiers(Configuration configuration, DisplayMetrics displayMetrics) { return ConfigurationV25.resourceQualifierString(configuration, displayMetrics); } /** * Overrides the current device configuration. * *

If {@param newQualifiers} starts with a plus ('+'), the prior configuration is used as the * base configuration, with the given changes applied additively. Otherwise, default values are * used for unspecified properties, as described here. * * @param newQualifiers the qualifiers to apply */ public static void setQualifiers(String newQualifiers) { ShadowDisplayManager.changeDisplay(Display.DEFAULT_DISPLAY, newQualifiers); Configuration configuration; DisplayMetrics displayMetrics = new DisplayMetrics(); if (newQualifiers.startsWith("+")) { configuration = new Configuration(Resources.getSystem().getConfiguration()); displayMetrics.setTo(Resources.getSystem().getDisplayMetrics()); } else { configuration = new Configuration(); } Bootstrap.applyQualifiers(newQualifiers, getApiLevel(), configuration, displayMetrics); if (ShadowView.useRealGraphics()) { Bitmap.setDefaultDensity(displayMetrics.densityDpi); } updateConfiguration(configuration, displayMetrics); } public static void setFontScale(float fontScale) { Resources systemResources = getApplication().getResources(); DisplayMetrics displayMetrics = systemResources.getDisplayMetrics(); Configuration configuration = systemResources.getConfiguration(); displayMetrics.scaledDensity = displayMetrics.density * fontScale; configuration.fontScale = fontScale; updateConfiguration(configuration, displayMetrics); } public static float getFontScale() { Resources systemResources = getApplication().getResources(); return systemResources.getConfiguration().fontScale; } private static void updateConfiguration( Configuration configuration, DisplayMetrics displayMetrics) { // Update the resources last so that listeners will have a consistent environment. // TODO(paulsowden): Can we call ResourcesManager.getInstance().applyConfigurationToResources()? if (ResourcesManager.getInstance().getConfiguration() != null) { ResourcesManager.getInstance().getConfiguration().updateFrom(configuration); } Resources.getSystem().updateConfiguration(configuration, displayMetrics); if (RuntimeEnvironment.application != null) { getApplication().getResources().updateConfiguration(configuration, displayMetrics); } else { // if application is not yet loaded, update the configuration in Bootstrap so that the // changes will be propagated once the application is finally loaded Bootstrap.updateDisplayResources(configuration, displayMetrics); } } public static int getApiLevel() { return apiLevel; } /** * Retrieves the current master scheduler. This scheduler is always used by the main {@link * android.os.Looper Looper}, and if the global scheduler option is set it is also used for the * background scheduler and for all other {@link android.os.Looper Looper}s * * @return The current master scheduler. * @see #setMasterScheduler(Scheduler) see * org.robolectric.Robolectric#getForegroundThreadScheduler() see * org.robolectric.Robolectric#getBackgroundThreadScheduler() */ public static Scheduler getMasterScheduler() { return masterScheduler; } /** * Sets the current master scheduler. See {@link #getMasterScheduler()} for details. Note that * this method is primarily intended to be called by the Robolectric core setup code. Changing the * master scheduler during a test will have unpredictable results. * * @param masterScheduler the new master scheduler. * @see #getMasterScheduler() see org.robolectric.Robolectric#getForegroundThreadScheduler() see * org.robolectric.Robolectric#getBackgroundThreadScheduler() */ public static void setMasterScheduler(Scheduler masterScheduler) { RuntimeEnvironment.masterScheduler = masterScheduler; } public static void setTempDirectory(TempDirectory tempDirectory) { RuntimeEnvironment.tempDirectory = tempDirectory; } public static TempDirectory getTempDirectory() { return tempDirectory; } public static void setAndroidFrameworkJarPath(Path localArtifactPath) { RuntimeEnvironment.androidFrameworkJar = localArtifactPath; } public static Path getAndroidFrameworkJarPath() { return RuntimeEnvironment.androidFrameworkJar; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy