1 package org.robolectric.internal; 2 3 import javax.annotation.Nonnull; 4 import org.robolectric.internal.bytecode.Sandbox; 5 import org.robolectric.internal.dependency.DependencyJar; 6 import org.robolectric.internal.dependency.DependencyResolver; 7 import org.robolectric.res.Fs; 8 import org.robolectric.res.FsFile; 9 import org.robolectric.res.PackageResourceTable; 10 import org.robolectric.res.ResourcePath; 11 import org.robolectric.res.ResourceTableFactory; 12 13 public class SdkEnvironment extends Sandbox { 14 private final SdkConfig sdkConfig; 15 private FsFile compileTimeSystemResourcesFile; 16 private PackageResourceTable systemResourceTable; 17 SdkEnvironment(SdkConfig sdkConfig, ClassLoader robolectricClassLoader)18 public SdkEnvironment(SdkConfig sdkConfig, ClassLoader robolectricClassLoader) { 19 super(robolectricClassLoader); 20 this.sdkConfig = sdkConfig; 21 } 22 getCompileTimeSystemResourcesFile(DependencyResolver dependencyResolver)23 public synchronized FsFile getCompileTimeSystemResourcesFile(DependencyResolver dependencyResolver) { 24 if (compileTimeSystemResourcesFile == null) { 25 DependencyJar compileTimeJar = new SdkConfig(27).getAndroidSdkDependency(); 26 compileTimeSystemResourcesFile = 27 Fs.newFile(dependencyResolver.getLocalArtifactUrl(compileTimeJar).getFile()); 28 } 29 return compileTimeSystemResourcesFile; 30 } 31 getSystemResourceTable(DependencyResolver dependencyResolver)32 public synchronized PackageResourceTable getSystemResourceTable(DependencyResolver dependencyResolver) { 33 if (systemResourceTable == null) { 34 ResourcePath resourcePath = createRuntimeSdkResourcePath(dependencyResolver); 35 systemResourceTable = new ResourceTableFactory().newFrameworkResourceTable(resourcePath); 36 } 37 return systemResourceTable; 38 } 39 40 @Nonnull createRuntimeSdkResourcePath(DependencyResolver dependencyResolver)41 private ResourcePath createRuntimeSdkResourcePath(DependencyResolver dependencyResolver) { 42 try { 43 Fs systemResFs = Fs.fromJar(dependencyResolver.getLocalArtifactUrl(sdkConfig.getAndroidSdkDependency())); 44 Class<?> androidRClass = getRobolectricClassLoader().loadClass("android.R"); 45 Class<?> androidInternalRClass = getRobolectricClassLoader().loadClass("com.android.internal.R"); 46 // TODO: verify these can be loaded via raw-res path 47 return new ResourcePath(androidRClass, 48 systemResFs.join("raw-res/res"), 49 systemResFs.join("raw-res/assets"), 50 androidInternalRClass); 51 } catch (ClassNotFoundException e) { 52 throw new RuntimeException(e); 53 } 54 } 55 getSdkConfig()56 public SdkConfig getSdkConfig() { 57 return sdkConfig; 58 } 59 } 60