1a2043a8fff01f3e2d9a5e30dd1cf5fb6a5342f4dTyler Schultzpackage com.xtremelabs.robolectric.res; 247bd528af49de6d8459c8aeda60b88cc7a3c961fChristian Williams 3bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogenimport static com.xtremelabs.robolectric.Robolectric.shadowOf; 4bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogen 5bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogenimport com.xtremelabs.robolectric.Robolectric; 6bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogenimport com.xtremelabs.robolectric.shadows.ShadowContextWrapper; 7bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogenimport com.xtremelabs.robolectric.util.I18nException; 8bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogenimport com.xtremelabs.robolectric.util.PropertiesHelper; 9bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogen 10828b5524de2393f92fdd52204c16a75e608db62fPhil Goodwinimport android.R; 115ec776796c773be831b2fd1cfd940da663f6c4c3Phil Goodwin & Tyler Schultzimport android.content.Context; 12fac8bbf7dfc7904540716be8649b2f5a5c9f6d15adriancowhamimport android.graphics.drawable.AnimationDrawable; 13fac8bbf7dfc7904540716be8649b2f5a5c9f6d15adriancowhamimport android.graphics.drawable.ColorDrawable; 14fac8bbf7dfc7904540716be8649b2f5a5c9f6d15adriancowhamimport android.graphics.drawable.Drawable; 155ec242e7f4ba642abb5cc3dceee0dc49ce2f1a3fRich Humphreyimport android.preference.PreferenceScreen; 16dd40f718cf785a56e63c0685feeb73d266c13e3fWenhui Yaoimport android.text.TextUtils; 17b539366073ccb47433de7191dbbf519ed4ab2d8fPhil Goodwinimport android.view.Menu; 1825cbf6f16c0fc8e6524935e6fa3d70ec2a92ed25Phil Goodwin & Tyler Schultzimport android.view.View; 1925cbf6f16c0fc8e6524935e6fa3d70ec2a92ed25Phil Goodwin & Tyler Schultzimport android.view.ViewGroup; 2070650f03fb9161ce77255654517d34b67232588eChristian Williams & Phil Goodwin 21bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogenimport java.io.BufferedReader; 22bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogenimport java.io.File; 23bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogenimport java.io.FileFilter; 24bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogenimport java.io.FileInputStream; 25bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogenimport java.io.IOException; 26bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogenimport java.io.InputStream; 27bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogenimport java.io.InputStreamReader; 288900025d7fa03579c0ae4d19255d3a8650cbf12aPhil Goodwin & Ryan Richardimport java.lang.reflect.Field; 29bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogenimport java.util.HashSet; 30bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogenimport java.util.Properties; 31bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogenimport java.util.Set; 328900025d7fa03579c0ae4d19255d3a8650cbf12aPhil Goodwin & Ryan Richard 3347bd528af49de6d8459c8aeda60b88cc7a3c961fChristian Williamspublic class ResourceLoader { 3448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private static final FileFilter MENU_DIR_FILE_FILTER = new FileFilter() { 3548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao @Override 3648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao public boolean accept( File file ) { 3748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao return isMenuDirectory( file.getPath() ); 3848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 3948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao }; 4048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private static final FileFilter LAYOUT_DIR_FILE_FILTER = new FileFilter() { 4148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao @Override 4248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao public boolean accept( File file ) { 4348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao return isLayoutDirectory( file.getPath() ); 4448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 4548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao }; 4648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private static final FileFilter DRAWABLE_DIR_FILE_FILTER = new FileFilter() { 4748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao @Override 4848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao public boolean accept( File file ) { 4948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao return isDrawableDirectory( file.getPath() ); 5048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 5148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao }; 5248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 5348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private File resourceDir; 5448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private File assetsDir; 5548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private int sdkVersion; 5648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private Class rClass; 5748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 5848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private final ResourceExtractor resourceExtractor; 5948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private ViewLoader viewLoader; 6048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private MenuLoader menuLoader; 6148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private PreferenceLoader preferenceLoader; 6248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private final StringResourceLoader stringResourceLoader; 6348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private final PluralResourceLoader pluralResourceLoader; 6448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private final StringArrayResourceLoader stringArrayResourceLoader; 6548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private final AttrResourceLoader attrResourceLoader; 6648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private final ColorResourceLoader colorResourceLoader; 6748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private final DrawableResourceLoader drawableResourceLoader; 6848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private final RawResourceLoader rawResourceLoader; 6948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private final DimenResourceLoader dimenResourceLoader; 7048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private final IntegerResourceLoader integerResourceLoader; 7148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private boolean isInitialized = false; 7248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private boolean strictI18n = false; 73dd40f718cf785a56e63c0685feeb73d266c13e3fWenhui Yao private String locale=""; 747fb9367f21d1d50fa798098f24e0c3e9f7497324Jon Boekenoogen 75ea277a780371ce94fb402f7853daefc3a8580f0cMichael Portuesi private final Set<Integer> ninePatchDrawableIds = new HashSet<Integer>(); 7648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 77dd40f718cf785a56e63c0685feeb73d266c13e3fWenhui Yao public ResourceLoader( int sdkVersion, Class rClass, File resourceDir, File assetsDir ) throws Exception { 78dd40f718cf785a56e63c0685feeb73d266c13e3fWenhui Yao this( sdkVersion, rClass, resourceDir, assetsDir, ""); 79dd40f718cf785a56e63c0685feeb73d266c13e3fWenhui Yao } 807fb9367f21d1d50fa798098f24e0c3e9f7497324Jon Boekenoogen 81dd40f718cf785a56e63c0685feeb73d266c13e3fWenhui Yao public ResourceLoader( int sdkVersion, Class rClass, File resourceDir, File assetsDir, String locale ) throws Exception { 8248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao this.sdkVersion = sdkVersion; 8348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao this.assetsDir = assetsDir; 8448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao this.rClass = rClass; 85dd40f718cf785a56e63c0685feeb73d266c13e3fWenhui Yao this.locale = locale; 867fb9367f21d1d50fa798098f24e0c3e9f7497324Jon Boekenoogen 8748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao resourceExtractor = new ResourceExtractor(); 88df5951775e9c13526de56166ccdb841aa910a674Jon Boekenoogen if ( rClass != null ) { 89df5951775e9c13526de56166ccdb841aa910a674Jon Boekenoogen resourceExtractor.addLocalRClass( rClass ); 90df5951775e9c13526de56166ccdb841aa910a674Jon Boekenoogen } 9148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao resourceExtractor.addSystemRClass( R.class ); 9248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 9348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao stringResourceLoader = new StringResourceLoader( resourceExtractor ); 9448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao pluralResourceLoader = new PluralResourceLoader( resourceExtractor, stringResourceLoader ); 9548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao stringArrayResourceLoader = new StringArrayResourceLoader( resourceExtractor, stringResourceLoader ); 9648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao colorResourceLoader = new ColorResourceLoader( resourceExtractor ); 9748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao attrResourceLoader = new AttrResourceLoader( resourceExtractor ); 9848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao drawableResourceLoader = new DrawableResourceLoader( resourceExtractor, resourceDir ); 9948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao rawResourceLoader = new RawResourceLoader( resourceExtractor, resourceDir ); 10048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao dimenResourceLoader = new DimenResourceLoader( resourceExtractor ); 10148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao integerResourceLoader = new IntegerResourceLoader( resourceExtractor ); 10248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 10348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao this.resourceDir = resourceDir; 10448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 10548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 10648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao public void setStrictI18n( boolean strict ) { 10748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao this.strictI18n = strict; 10848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao if ( viewLoader != null ) { 10948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao viewLoader.setStrictI18n( strict ); 11048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 11148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao if ( menuLoader != null ) { 11248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao menuLoader.setStrictI18n( strict ); 11348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 11448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao if ( preferenceLoader != null ) { 11548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao preferenceLoader.setStrictI18n( strict ); 11648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 11748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 11848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 11948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao public boolean getStrictI18n() { 12048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao return strictI18n; 12148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 12248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 12348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private void init() { 12448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao if ( isInitialized ) { 12548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao return; 12648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 1277fb9367f21d1d50fa798098f24e0c3e9f7497324Jon Boekenoogen 12848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao try { 12948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao if ( resourceDir != null ) { 13048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao viewLoader = new ViewLoader( resourceExtractor, attrResourceLoader ); 13148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao menuLoader = new MenuLoader( resourceExtractor, attrResourceLoader ); 13248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao preferenceLoader = new PreferenceLoader( resourceExtractor ); 13348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 13448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao viewLoader.setStrictI18n( strictI18n ); 13548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao menuLoader.setStrictI18n( strictI18n ); 13648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao preferenceLoader.setStrictI18n( strictI18n ); 13748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 13848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao File systemResourceDir = getSystemResourceDir( getPathToAndroidResources() ); 13948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao File localValueResourceDir = getValueResourceDir( resourceDir ); 14048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao File systemValueResourceDir = getValueResourceDir( systemResourceDir ); 14148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao File preferenceDir = getPreferenceResourceDir( resourceDir ); 14248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 14348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao loadStringResources( localValueResourceDir, systemValueResourceDir ); 14448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao loadPluralsResources( localValueResourceDir, systemValueResourceDir ); 14548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao loadValueResources( localValueResourceDir, systemValueResourceDir ); 14648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao loadDimenResources( localValueResourceDir, systemValueResourceDir ); 14734bf42d4b3689b33c474e2f6e2f6294c429ce1a6Maja Bratseth loadIntegerResource( localValueResourceDir, systemValueResourceDir ); 14848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao loadViewResources( systemResourceDir, resourceDir ); 14948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao loadMenuResources( resourceDir ); 15048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao loadDrawableResources( resourceDir ); 15148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao loadPreferenceResources( preferenceDir ); 1527fb9367f21d1d50fa798098f24e0c3e9f7497324Jon Boekenoogen 153ea277a780371ce94fb402f7853daefc3a8580f0cMichael Portuesi listNinePatchResources(ninePatchDrawableIds, resourceDir); 15448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } else { 15548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao viewLoader = null; 15648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao menuLoader = null; 15748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao preferenceLoader = null; 15848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 15948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } catch ( I18nException e ) { 16048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao throw e; 16148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } catch ( Exception e ) { 16248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao throw new RuntimeException( e ); 16348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 16448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao isInitialized = true; 16548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 16648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 16748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private File getSystemResourceDir( String pathToAndroidResources ) { 16848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao return pathToAndroidResources != null ? new File( pathToAndroidResources ) : null; 16948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 17048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 17148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private void loadStringResources( File localResourceDir, File systemValueResourceDir ) throws Exception { 17248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao DocumentLoader stringResourceDocumentLoader = new DocumentLoader( this.stringResourceLoader ); 17348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao loadValueResourcesFromDirs( stringResourceDocumentLoader, localResourceDir, systemValueResourceDir ); 17448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 17548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 17648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private void loadPluralsResources( File localResourceDir, File systemValueResourceDir ) throws Exception { 17748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao DocumentLoader stringResourceDocumentLoader = new DocumentLoader( this.pluralResourceLoader ); 17848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao loadValueResourcesFromDirs( stringResourceDocumentLoader, localResourceDir, systemValueResourceDir ); 17948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 18048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 18148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private void loadValueResources( File localResourceDir, File systemValueResourceDir ) throws Exception { 18248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao DocumentLoader valueResourceLoader = new DocumentLoader( stringArrayResourceLoader, colorResourceLoader, 18348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao attrResourceLoader ); 18448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao loadValueResourcesFromDirs( valueResourceLoader, localResourceDir, systemValueResourceDir ); 18548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 18648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 18748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private void loadDimenResources( File localResourceDir, File systemValueResourceDir ) throws Exception { 18848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao DocumentLoader dimenResourceDocumentLoader = new DocumentLoader( this.dimenResourceLoader ); 18948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao loadValueResourcesFromDirs( dimenResourceDocumentLoader, localResourceDir, systemValueResourceDir ); 19048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 19148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 19248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private void loadIntegerResource( File localResourceDir, File systemValueResourceDir ) throws Exception { 19348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao DocumentLoader integerResourceDocumentLoader = new DocumentLoader( this.integerResourceLoader ); 19448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao loadValueResourcesFromDirs( integerResourceDocumentLoader, localResourceDir, systemValueResourceDir ); 19548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 19648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 19748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private void loadViewResources( File systemResourceDir, File xmlResourceDir ) throws Exception { 19848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao DocumentLoader viewDocumentLoader = new DocumentLoader( viewLoader ); 19948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao loadLayoutResourceXmlSubDirs( viewDocumentLoader, xmlResourceDir, false ); 20048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao loadLayoutResourceXmlSubDirs( viewDocumentLoader, systemResourceDir, true ); 20148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 20248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 20348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private void loadMenuResources( File xmlResourceDir ) throws Exception { 20448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao DocumentLoader menuDocumentLoader = new DocumentLoader( menuLoader ); 20548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao loadMenuResourceXmlDirs( menuDocumentLoader, xmlResourceDir ); 20648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 20748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 20848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private void loadDrawableResources( File xmlResourceDir ) throws Exception { 20948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao DocumentLoader drawableDocumentLoader = new DocumentLoader( drawableResourceLoader ); 21048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao loadDrawableResourceXmlDirs( drawableDocumentLoader, xmlResourceDir ); 21148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 21248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 21348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private void loadPreferenceResources( File xmlResourceDir ) throws Exception { 21448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao if ( xmlResourceDir.exists() ) { 21548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao DocumentLoader preferenceDocumentLoader = new DocumentLoader( preferenceLoader ); 21648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao preferenceDocumentLoader.loadResourceXmlDir( xmlResourceDir ); 21748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 21848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 21948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 22048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private void loadLayoutResourceXmlSubDirs( DocumentLoader layoutDocumentLoader, File xmlResourceDir, boolean isSystem ) 22148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao throws Exception { 22248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao if ( xmlResourceDir != null ) { 22348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao layoutDocumentLoader.loadResourceXmlDirs( isSystem, xmlResourceDir.listFiles( LAYOUT_DIR_FILE_FILTER ) ); 22448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 22548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 22648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 22748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private void loadMenuResourceXmlDirs( DocumentLoader menuDocumentLoader, File xmlResourceDir ) throws Exception { 22848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao if ( xmlResourceDir != null ) { 22948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao menuDocumentLoader.loadResourceXmlDirs( xmlResourceDir.listFiles( MENU_DIR_FILE_FILTER ) ); 23048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 23148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 23248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 23348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private void loadDrawableResourceXmlDirs( DocumentLoader drawableResourceLoader, File xmlResourceDir ) throws Exception { 23448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao if ( xmlResourceDir != null ) { 23548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao drawableResourceLoader.loadResourceXmlDirs( xmlResourceDir.listFiles( DRAWABLE_DIR_FILE_FILTER ) ); 23648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 23748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 23848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 23948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private void loadValueResourcesFromDirs( DocumentLoader documentLoader, File localValueResourceDir, 24048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao File systemValueResourceDir ) throws Exception { 24148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao loadValueResourcesFromDir( documentLoader, localValueResourceDir ); 24248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao loadSystemResourceXmlDir( documentLoader, systemValueResourceDir ); 24348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 24448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 24548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private void loadValueResourcesFromDir( DocumentLoader documentloader, File xmlResourceDir ) throws Exception { 24648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao if ( xmlResourceDir != null ) { 24748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao documentloader.loadResourceXmlDir( xmlResourceDir ); 24848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 24948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 25048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 25148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private void loadSystemResourceXmlDir( DocumentLoader documentLoader, File stringResourceDir ) throws Exception { 25248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao if ( stringResourceDir != null ) { 25348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao documentLoader.loadSystemResourceXmlDir( stringResourceDir ); 25448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 25548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 25648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 25748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private File getValueResourceDir( File xmlResourceDir ) { 258dd40f718cf785a56e63c0685feeb73d266c13e3fWenhui Yao String valuesDir = "values"; 259dd40f718cf785a56e63c0685feeb73d266c13e3fWenhui Yao if( !TextUtils.isEmpty( locale ) ){ 260dd40f718cf785a56e63c0685feeb73d266c13e3fWenhui Yao valuesDir += "-"+ locale; 261dd40f718cf785a56e63c0685feeb73d266c13e3fWenhui Yao } 262dd40f718cf785a56e63c0685feeb73d266c13e3fWenhui Yao File result = ( xmlResourceDir != null ) ? new File( xmlResourceDir, valuesDir ) : null; 2637fb9367f21d1d50fa798098f24e0c3e9f7497324Jon Boekenoogen if( result != null && !result.exists() ){ 264dd40f718cf785a56e63c0685feeb73d266c13e3fWenhui Yao throw new RuntimeException("Couldn't find value resource directory: " + result.getAbsolutePath() ); 265dd40f718cf785a56e63c0685feeb73d266c13e3fWenhui Yao } 266dd40f718cf785a56e63c0685feeb73d266c13e3fWenhui Yao return result; 26748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 26848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 26948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private File getPreferenceResourceDir( File xmlResourceDir ) { 27048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao return xmlResourceDir != null ? new File( xmlResourceDir, "xml" ) : null; 27148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 27248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 27348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private String getPathToAndroidResources() { 274bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogen String resFolder = getAndroidResourcePathFromLocalProperties(); 275bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogen if (resFolder == null) { 276bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogen resFolder = getAndroidResourcePathFromSystemEnvironment(); 277bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogen if (resFolder == null) { 278bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogen resFolder = getAndroidResourcePathFromSystemProperty(); 279bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogen if (resFolder == null) { 280bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogen resFolder = getAndroidResourcePathByExecingWhichAndroid(); 281bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogen } 282bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogen } 283bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogen } 284bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogen 285bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogen // Go through last 5 sdk versions looking for resource folders. 286bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogen if (resFolder != null) { 287bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogen for (int i = sdkVersion; i >= sdkVersion - 5 && i >= 4; i--) { 288bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogen File resourcePath = new File(resFolder, getAndroidResourceSubPath(i)); 289bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogen if (resourcePath.exists()) { 290bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogen return resourcePath.getAbsolutePath(); 291bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogen } else { 292bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogen System.out.println("WARNING: Unable to find Android resources at: " + 293bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogen resourcePath.toString() + " continuing."); 294bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogen } 295bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogen } 296bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogen } else { 297bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogen System.out.println("WARNING: Unable to find path to Android SDK"); 29848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 29948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 30048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao return null; 30148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 30248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 30348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private String getAndroidResourcePathFromLocalProperties() { 30448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao // Hand tested 30548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao // This is the path most often taken by IntelliJ 30648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao File rootDir = resourceDir.getParentFile(); 30748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao String localPropertiesFileName = "local.properties"; 30848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao File localPropertiesFile = new File( rootDir, localPropertiesFileName ); 30948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao if ( !localPropertiesFile.exists() ) { 31048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao localPropertiesFile = new File( localPropertiesFileName ); 31148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 31248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao if ( localPropertiesFile.exists() ) { 31348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao Properties localProperties = new Properties(); 31448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao try { 31548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao localProperties.load( new FileInputStream( localPropertiesFile ) ); 31648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao PropertiesHelper.doSubstitutions( localProperties ); 317bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogen return localProperties.getProperty( "sdk.dir" ); 31848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } catch ( IOException e ) { 31948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao // fine, we'll try something else 32048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 32148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 32248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao return null; 32348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 32448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 32548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private String getAndroidResourcePathFromSystemEnvironment() { 32648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao // Hand tested 327bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogen return System.getenv().get( "ANDROID_HOME" ); 32848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 32948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 33048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private String getAndroidResourcePathFromSystemProperty() { 33148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao // this is used by the android-maven-plugin 332bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogen return System.getProperty( "android.sdk.path" ); 33348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 33448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 33548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao private String getAndroidResourcePathByExecingWhichAndroid() { 33648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao // Hand tested 33748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao // Should always work from the command line. Often fails in IDEs because 33848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao // they don't pass the full PATH in the environment 33948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao try { 34048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao Process process = Runtime.getRuntime().exec( new String[] { "which", "android" } ); 34148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao String sdkPath = new BufferedReader( new InputStreamReader( process.getInputStream() ) ).readLine(); 34248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao if ( sdkPath != null && sdkPath.endsWith( "tools/android" ) ) { 343bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogen return sdkPath.substring(0, sdkPath.indexOf( "tools/android")); 34448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 34548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } catch ( IOException e ) { 34648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao // fine we'll try something else 34748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 34848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao return null; 34948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 35048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 351bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogen private static String getAndroidResourceSubPath(int version) { 352bd20b3c07ba0d63c0e62744eef3c90b69cd6b126Jon Boekenoogen return "platforms/android-" + version + "/data/res"; 35348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 35448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 35548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao static boolean isLayoutDirectory( String path ) { 35648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao return path.contains( File.separator + "layout" ); 35748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 35848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 35948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao static boolean isDrawableDirectory( String path ) { 36048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao return path.contains( File.separator + "drawable" ); 36148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 36248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 36348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao static boolean isMenuDirectory( String path ) { 36448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao return path.contains( File.separator + "menu" ); 36548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 36648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 36748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao /* 36848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao * For tests only... 36948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao */ 37048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao protected ResourceLoader( StringResourceLoader stringResourceLoader ) { 37148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao resourceExtractor = new ResourceExtractor(); 37248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao this.stringResourceLoader = stringResourceLoader; 37348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao pluralResourceLoader = null; 37448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao viewLoader = null; 37548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao stringArrayResourceLoader = null; 37648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao attrResourceLoader = null; 37748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao colorResourceLoader = null; 37848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao drawableResourceLoader = null; 37948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao rawResourceLoader = null; 38048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao dimenResourceLoader = null; 38148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao integerResourceLoader = null; 38248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 38348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 38448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao public static ResourceLoader getFrom( Context context ) { 38548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao ResourceLoader resourceLoader = shadowOf( context.getApplicationContext() ).getResourceLoader(); 38648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao resourceLoader.init(); 38748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao return resourceLoader; 38848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 38948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 39048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao public String getNameForId( int viewId ) { 39148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao init(); 39248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao return resourceExtractor.getResourceName( viewId ); 39348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 39448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 39548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao public View inflateView( Context context, int resource, ViewGroup viewGroup ) { 39648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao init(); 39748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao return viewLoader.inflateView( context, resource, viewGroup ); 39848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 39948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 40048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao public int getColorValue( int id ) { 40148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao init(); 40248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao return colorResourceLoader.getValue( id ); 40348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 40448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 40548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao public String getStringValue( int id ) { 40648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao init(); 40748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao return stringResourceLoader.getValue( id ); 40848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 40948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 41048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao public String getPluralStringValue( int id, int quantity ) { 41148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao init(); 41248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao return pluralResourceLoader.getValue( id, quantity ); 41348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 41448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 41548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao public float getDimenValue( int id ) { 41648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao init(); 41748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao return dimenResourceLoader.getValue( id ); 41848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 41948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 42048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao public int getIntegerValue( int id ) { 42148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao init(); 42248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao return integerResourceLoader.getValue( id ); 42348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 42448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 42548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao public boolean isDrawableXml( int resourceId ) { 42648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao init(); 42748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao return drawableResourceLoader.isXml( resourceId ); 42848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 42948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 430aec1d0888fe04efd0cde7514e155870b18c41286Rick Kawala & Wei Wu public boolean isAnimatableXml( int resourceId ) { 431aec1d0888fe04efd0cde7514e155870b18c41286Rick Kawala & Wei Wu init(); 432aec1d0888fe04efd0cde7514e155870b18c41286Rick Kawala & Wei Wu return drawableResourceLoader.isAnimationDrawable( resourceId ); 433aec1d0888fe04efd0cde7514e155870b18c41286Rick Kawala & Wei Wu } 434aec1d0888fe04efd0cde7514e155870b18c41286Rick Kawala & Wei Wu 43548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao public int[] getDrawableIds( int resourceId ) { 43648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao init(); 43748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao return drawableResourceLoader.getDrawableIds( resourceId ); 43848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 43948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 44048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao public Drawable getXmlDrawable( int resourceId ) { 44148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao return drawableResourceLoader.getXmlDrawable( resourceId ); 44248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 44348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 44448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao public Drawable getAnimDrawable( int resourceId ) { 44548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao return getInnerRClassDrawable( resourceId, "$anim", AnimationDrawable.class ); 44648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 44748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 44848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao public Drawable getColorDrawable( int resourceId ) { 44948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao return getInnerRClassDrawable( resourceId, "$color", ColorDrawable.class ); 45048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 45148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 45248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao @SuppressWarnings("rawtypes") 453fac8bbf7dfc7904540716be8649b2f5a5c9f6d15adriancowham private Drawable getInnerRClassDrawable( int drawableResourceId, String suffix, Class returnClass ) { 45448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao ShadowContextWrapper shadowApp = Robolectric.shadowOf( Robolectric.application ); 45548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao Class rClass = shadowApp.getResourceLoader().getLocalRClass(); 45648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 45748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao // Check to make sure there is actually an R Class, if not 45848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao // return just a BitmapDrawable 45948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao if ( rClass == null ) { 46048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao return null; 46148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 46248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 46348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao // Load the Inner Class for interrogation 46448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao Class animClass = null; 46548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao try { 46648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao animClass = Class.forName( rClass.getCanonicalName() + suffix ); 46748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } catch ( ClassNotFoundException e ) { 468fac8bbf7dfc7904540716be8649b2f5a5c9f6d15adriancowham return null; 469fac8bbf7dfc7904540716be8649b2f5a5c9f6d15adriancowham } 47048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 471fac8bbf7dfc7904540716be8649b2f5a5c9f6d15adriancowham // Try to find the passed in resource ID 472fac8bbf7dfc7904540716be8649b2f5a5c9f6d15adriancowham try { 47348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao for ( Field field : animClass.getDeclaredFields() ) { 47448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao if ( field.getInt( animClass ) == drawableResourceId ) { 47548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao return ( Drawable ) returnClass.newInstance(); 47648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 47748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 47848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } catch ( Exception e ) { 47948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 48048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 481fac8bbf7dfc7904540716be8649b2f5a5c9f6d15adriancowham return null; 48248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 4837fb9367f21d1d50fa798098f24e0c3e9f7497324Jon Boekenoogen 484ea277a780371ce94fb402f7853daefc3a8580f0cMichael Portuesi public boolean isNinePatchDrawable(int drawableResourceId) { 485ea277a780371ce94fb402f7853daefc3a8580f0cMichael Portuesi return ninePatchDrawableIds.contains(drawableResourceId); 486ea277a780371ce94fb402f7853daefc3a8580f0cMichael Portuesi } 4877fb9367f21d1d50fa798098f24e0c3e9f7497324Jon Boekenoogen 488ea277a780371ce94fb402f7853daefc3a8580f0cMichael Portuesi /** 489ea277a780371ce94fb402f7853daefc3a8580f0cMichael Portuesi * Returns a collection of resource IDs for all nine-patch drawables 490ea277a780371ce94fb402f7853daefc3a8580f0cMichael Portuesi * in the project. 4917fb9367f21d1d50fa798098f24e0c3e9f7497324Jon Boekenoogen * 492ea277a780371ce94fb402f7853daefc3a8580f0cMichael Portuesi * @param resourceIds 493ea277a780371ce94fb402f7853daefc3a8580f0cMichael Portuesi * @param dir 494ea277a780371ce94fb402f7853daefc3a8580f0cMichael Portuesi */ 495ea277a780371ce94fb402f7853daefc3a8580f0cMichael Portuesi private void listNinePatchResources(Set<Integer> resourceIds, File dir) { 496ea277a780371ce94fb402f7853daefc3a8580f0cMichael Portuesi File[] files = dir.listFiles(); 497ea277a780371ce94fb402f7853daefc3a8580f0cMichael Portuesi if (files != null) { 498ea277a780371ce94fb402f7853daefc3a8580f0cMichael Portuesi for (File f : files) { 499ea277a780371ce94fb402f7853daefc3a8580f0cMichael Portuesi if (f.isDirectory() && isDrawableDirectory(f.getPath())) { 500ea277a780371ce94fb402f7853daefc3a8580f0cMichael Portuesi listNinePatchResources(resourceIds, f); 501ea277a780371ce94fb402f7853daefc3a8580f0cMichael Portuesi } else { 502ea277a780371ce94fb402f7853daefc3a8580f0cMichael Portuesi String name = f.getName(); 503ea277a780371ce94fb402f7853daefc3a8580f0cMichael Portuesi if (name.endsWith(".9.png")) { 504ea277a780371ce94fb402f7853daefc3a8580f0cMichael Portuesi String[] tokens = name.split("\\.9\\.png$"); 505ea277a780371ce94fb402f7853daefc3a8580f0cMichael Portuesi resourceIds.add(resourceExtractor.getResourceId("@drawable/" + tokens[0])); 506ea277a780371ce94fb402f7853daefc3a8580f0cMichael Portuesi } 507ea277a780371ce94fb402f7853daefc3a8580f0cMichael Portuesi } 508ea277a780371ce94fb402f7853daefc3a8580f0cMichael Portuesi } 509ea277a780371ce94fb402f7853daefc3a8580f0cMichael Portuesi } 510ea277a780371ce94fb402f7853daefc3a8580f0cMichael Portuesi } 51148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 51248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao public InputStream getRawValue( int id ) { 51348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao init(); 51448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao return rawResourceLoader.getValue( id ); 51548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 51648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 51748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao public String[] getStringArrayValue( int id ) { 51848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao init(); 51948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao return stringArrayResourceLoader.getArrayValue( id ); 52048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 52148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 52248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao public void inflateMenu( Context context, int resource, Menu root ) { 52348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao init(); 52448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao menuLoader.inflateMenu( context, resource, root ); 52548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 52648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 52748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao public PreferenceScreen inflatePreferences( Context context, int resourceId ) { 52848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao init(); 52948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao return preferenceLoader.inflatePreferences( context, resourceId ); 53048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 53148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 53248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao public File getAssetsBase() { 53348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao return assetsDir; 53448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 53548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 53648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao @SuppressWarnings("rawtypes") 53748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao public Class getLocalRClass() { 53848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao return rClass; 53948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 54048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 54148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao public void setLocalRClass( Class clazz ) { 54248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao rClass = clazz; 54348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 54448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 54548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao public ResourceExtractor getResourceExtractor() { 54648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao return resourceExtractor; 54748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 54848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 54948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao public ViewLoader.ViewNode getLayoutViewNode( String layoutName ) { 55048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao return viewLoader.viewNodesByLayoutName.get( layoutName ); 55148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 55248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao 55348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao public void setLayoutQualifierSearchPath( String... locations ) { 55448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao init(); 55548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao viewLoader.setLayoutQualifierSearchPath( locations ); 55648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao } 55747bd528af49de6d8459c8aeda60b88cc7a3c961fChristian Williams} 558