Home | History | Annotate | Download | only in internal
      1 package org.robolectric.internal;
      2 
      3 import java.net.URL;
      4 import java.util.LinkedHashMap;
      5 import java.util.Map;
      6 import javax.annotation.Nonnull;
      7 import org.robolectric.internal.bytecode.InstrumentationConfiguration;
      8 import org.robolectric.internal.bytecode.SandboxClassLoader;
      9 import org.robolectric.internal.dependency.DependencyResolver;
     10 import org.robolectric.util.Pair;
     11 
     12 public class SandboxFactory {
     13   public static final SandboxFactory INSTANCE = new SandboxFactory();
     14 
     15   /** The factor for cache size. See {@link #CACHE_SIZE} for details. */
     16   private static final int CACHE_SIZE_FACTOR = 3;
     17 
     18   /** We need to set the cache size of class loaders more than the number of supported APIs as different tests may have different configurations. */
     19   private static final int CACHE_SIZE = SdkConfig.getSupportedApis().size() * CACHE_SIZE_FACTOR;
     20 
     21   // Simple LRU Cache. SdkEnvironments are unique across InstrumentationConfiguration and SdkConfig
     22   private final LinkedHashMap<Pair<InstrumentationConfiguration, SdkConfig>, SdkEnvironment> sdkToEnvironment = new LinkedHashMap<Pair<InstrumentationConfiguration, SdkConfig>, SdkEnvironment>() {
     23     @Override
     24     protected boolean removeEldestEntry(Map.Entry<Pair<InstrumentationConfiguration, SdkConfig>, SdkEnvironment> eldest) {
     25       return size() > CACHE_SIZE;
     26     }
     27   };
     28 
     29   public synchronized SdkEnvironment getSdkEnvironment(InstrumentationConfiguration instrumentationConfig, DependencyResolver dependencyResolver, SdkConfig sdkConfig) {
     30     Pair<InstrumentationConfiguration, SdkConfig> key = Pair.create(instrumentationConfig, sdkConfig);
     31 
     32     SdkEnvironment sdkEnvironment = sdkToEnvironment.get(key);
     33     if (sdkEnvironment == null) {
     34       URL url = dependencyResolver.getLocalArtifactUrl(sdkConfig.getAndroidSdkDependency());
     35 
     36       ClassLoader robolectricClassLoader = createClassLoader(instrumentationConfig, url);
     37       sdkEnvironment = new SdkEnvironment(sdkConfig, robolectricClassLoader);
     38 
     39       sdkToEnvironment.put(key, sdkEnvironment);
     40     }
     41     return sdkEnvironment;
     42   }
     43 
     44   @Nonnull
     45   public ClassLoader createClassLoader(InstrumentationConfiguration instrumentationConfig, URL... urls) {
     46     return new SandboxClassLoader(ClassLoader.getSystemClassLoader(), instrumentationConfig, urls);
     47   }
     48 
     49 }
     50