private ResName getResName(int id) { ResName resName = resourceLoader.getResourceIndex().getResName(id); if (resName == null) { throw new Resources.NotFoundException("couldn't find a name for resource id " + id); } return resName; }
@Implementation public float getDimension(int id) throws Resources.NotFoundException { String dimenValue = resourceLoader.getDimenValue(getResName(id), getQualifiers()); if (dimenValue == null) throw new Resources.NotFoundException(notFound(id)); // DimensionConverter.stringToDimension(dimenValue, displayMetrics); return temporaryDimenConverter(dimenValue); }
@Implementation public boolean getBoolean(int id) throws Resources.NotFoundException { try { return resourceLoader.getBooleanValue(getResName(id), getQualifiers()); } catch (NullPointerException e) { throw new Resources.NotFoundException(notFound(id)); } }
@Implementation public String[] getStringArray(int id) throws Resources.NotFoundException { String[] arrayValue = resourceLoader.getStringArrayValue(getResName(id), getQualifiers()); if (arrayValue == null) { throw new Resources.NotFoundException(); } return arrayValue; }
@Implementation public Drawable getDrawable(int drawableResourceId) throws Resources.NotFoundException { ResName resName = getResName(drawableResourceId); String qualifiers = getQualifiers(); DrawableNode drawableNode = resourceLoader.getDrawableNode(resName, qualifiers); final DrawableBuilder drawableBuilder = new DrawableBuilder(getResourceLoader().getResourceIndex()); return drawableBuilder.getDrawable(resName, realResources, drawableNode); }
@Implementation public XmlResourceParser getXml(int id) throws Resources.NotFoundException { Document document = resourceLoader.getXml(getResName(id), getQualifiers()); if (document == null) { throw new Resources.NotFoundException(); } XmlFileBuilder xmlFileBuilder = new XmlFileBuilder(); XmlResourceParser parser = xmlFileBuilder.getXml(document); return parser; }
@Implementation public int getIdentifier(String name, String defType, String defPackage) { ResourceIndex resourceIndex = resourceLoader.getResourceIndex(); // Probably ResName should be refactored to accept partial names. // ResName should act as a qualifiedName parser in this case. if (!name.contains("/") && defType != null) { name = defType + "/" + name; } Integer index = ResName.getResourceId(resourceIndex, name, defPackage); if (index == null) { return 0; } return index; }
public static void convertAndFill( Attribute attribute, TypedValue outValue, ResourceLoader resourceLoader, String qualifiers, boolean resolveRefs) { if (attribute == null || attribute.isNull() || attribute.isEmpty()) { outValue.type = TypedValue.TYPE_NULL; if (attribute != null && attribute.isEmpty()) { outValue.data = TypedValue.DATA_NULL_EMPTY; } else { outValue.data = TypedValue.DATA_NULL_UNDEFINED; } return; } TypedResource attrTypeData = resourceLoader.getValue(attribute.resName, qualifiers); if (attrTypeData == null) { return; } AttrData attrData = (AttrData) attrTypeData.getData(); convertAndFill(attribute, outValue, resourceLoader, qualifiers, attrData, resolveRefs); }
public static void convertAndFill( Attribute attribute, TypedValue outValue, ResourceLoader resourceLoader, String qualifiers, AttrData attrData, boolean resolveRefs) { // short-circuit Android caching of loaded resources cuz our string positions don't remain // stable... outValue.assetCookie = getNextStringCookie(); // TODO: Handle resource and style references if (attribute.isStyleReference()) { return; } ResourceIndex resourceIndex = resourceLoader.getResourceIndex(); while (attribute.isResourceReference()) { ResName resName = attribute.getResourceReference(); Integer resourceId = resourceIndex.getResourceId(resName); if (resourceId == null) { throw new Resources.NotFoundException("unknown resource " + resName); } outValue.type = TypedValue.TYPE_REFERENCE; outValue.resourceId = resourceId; TypedResource dereferencedRef = resourceLoader.getValue(resName, qualifiers); if (dereferencedRef == null) { if (resName.type.equals("id")) { return; } else if (resName.type.equals("layout")) { return; // resourceId is good enough, right? } else if (resName.type.equals("dimen")) { return; } else if (resName.type.equals("transition")) { return; } else if (resName.type.equals("interpolator")) { return; } else if (resName.type.equals("menu")) { return; } else if (resName.type.equals("raw")) { return; } else if (DrawableResourceLoader.isStillHandledHere(resName)) { // wtf. color and drawable references reference are all kinds of stupid. DrawableNode drawableNode = resourceLoader.getDrawableNode(resName, qualifiers); if (drawableNode == null) { throw new Resources.NotFoundException("can't find file for " + resName); } else { outValue.type = TypedValue.TYPE_STRING; outValue.data = 0; outValue.assetCookie = getNextStringCookie(); outValue.string = drawableNode.getFsFile().getPath(); return; } } else { throw new RuntimeException("huh? " + resName); } } else { if (dereferencedRef.isFile()) { outValue.type = TypedValue.TYPE_STRING; outValue.data = 0; outValue.assetCookie = getNextStringCookie(); outValue.string = dereferencedRef.asString(); return; } else if (dereferencedRef.getData() instanceof String) { attribute = new Attribute(attribute.resName, dereferencedRef.asString(), resName.packageName); if (attribute.isResourceReference()) { continue; } if (resolveRefs) { getConverter(dereferencedRef.getResType()).fillTypedValue(attribute.value, outValue); return; } } } break; } if (attribute.isNull()) { outValue.type = TypedValue.TYPE_NULL; return; } String format = attrData.getFormat(); String[] types = format.split("\\|"); for (String type : types) { if ("reference".equals(type)) continue; // already handled above Converter converter = getConverterFor(attrData, type); if (converter != null) { if (converter.fillTypedValue(attribute.value, outValue)) { return; } } } }
@Implementation public int[] getIntArray(int id) throws Resources.NotFoundException { int[] arrayValue = resourceLoader.getIntegerArrayValue(getResName(id), getQualifiers()); if (arrayValue == null) throw new Resources.NotFoundException(notFound(id)); return arrayValue; }
@Implementation public int getInteger(int id) throws Resources.NotFoundException { return resourceLoader.getIntegerValue(getResName(id), getQualifiers()); }
@Implementation public InputStream openRawResource(int id) throws Resources.NotFoundException { return resourceLoader.getRawValue(getResName(id)); }
@Implementation public String getQuantityString(int id, int quantity) throws Resources.NotFoundException { return resourceLoader.getPluralStringValue(getResName(id), quantity, getQualifiers()); }
@Implementation public String getString(int id) throws Resources.NotFoundException { return resourceLoader.getStringValue(getResName(id), getQualifiers()); }
@Implementation public int getColor(int id) throws Resources.NotFoundException { String colorValue = resourceLoader.getColorValue(getResName(id), getQualifiers()); if (isEmpty(colorValue)) throw new Resources.NotFoundException(notFound(id)); return Color.parseColor(colorValue); }
@Override public void addManifest(AndroidManifest androidManifest, ResourceLoader loader) { androidManifests.put(androidManifest.getPackageName(), androidManifest); ResourceIndex resourceIndex = loader.getResourceIndex(); // first opportunity to access a resource index for this manifest, use it to init the references androidManifest.initMetaData(loader); PackageInfo packageInfo = new PackageInfo(); packageInfo.packageName = androidManifest.getPackageName(); packageInfo.versionName = androidManifest.getVersionName(); packageInfo.versionCode = androidManifest.getVersionCode(); ContentProviderData[] cpdata = androidManifest.getContentProviders().toArray(new ContentProviderData[] {}); if (cpdata.length == 0) { packageInfo.providers = null; } else { packageInfo.providers = new ProviderInfo[cpdata.length]; for (int i = 0; i < cpdata.length; i++) { ProviderInfo info = new ProviderInfo(); info.authority = cpdata[i].getAuthority(); info.name = cpdata[i].getClassName(); info.packageName = androidManifest.getPackageName(); packageInfo.providers[i] = info; } } // Populate information related to BroadcastReceivers. Broadcast receivers can be queried in two // possible ways, // 1. PackageManager#getPackageInfo(...), // 2. PackageManager#queryBroadcastReceivers(...) // The following piece of code will let you enable querying receivers through both the methods. List<ActivityInfo> receiverActivityInfos = new ArrayList<ActivityInfo>(); for (int i = 0; i < androidManifest.getBroadcastReceivers().size(); ++i) { ActivityInfo activityInfo = new ActivityInfo(); activityInfo.name = androidManifest.getBroadcastReceivers().get(i).getClassName(); activityInfo.permission = androidManifest.getBroadcastReceivers().get(i).getPermission(); receiverActivityInfos.add(activityInfo); ResolveInfo resolveInfo = new ResolveInfo(); resolveInfo.activityInfo = activityInfo; IntentFilter filter = new IntentFilter(); for (String action : androidManifest.getBroadcastReceivers().get(i).getActions()) { filter.addAction(action); } resolveInfo.filter = filter; for (String action : androidManifest.getBroadcastReceivers().get(i).getActions()) { Intent intent = new Intent(action); intent.setPackage(androidManifest.getPackageName()); addResolveInfoForIntent(intent, resolveInfo); } } packageInfo.receivers = receiverActivityInfos.toArray(new ActivityInfo[0]); String[] usedPermissions = androidManifest.getUsedPermissions().toArray(new String[] {}); if (usedPermissions.length == 0) { packageInfo.requestedPermissions = null; } else { packageInfo.requestedPermissions = usedPermissions; } ApplicationInfo applicationInfo = new ApplicationInfo(); applicationInfo.flags = androidManifest.getApplicationFlags(); applicationInfo.targetSdkVersion = androidManifest.getTargetSdkVersion(); applicationInfo.packageName = androidManifest.getPackageName(); applicationInfo.processName = androidManifest.getProcessName(); applicationInfo.name = androidManifest.getApplicationName(); applicationInfo.metaData = metaDataToBundle(androidManifest.getApplicationMetaData()); applicationInfo.sourceDir = new File(".").getAbsolutePath(); applicationInfo.dataDir = createTempDir("android-tmp").getAbsolutePath(); if (androidManifest.getLabelRef() != null && resourceIndex != null) { Integer id = ResName.getResourceId( resourceIndex, androidManifest.getLabelRef(), androidManifest.getPackageName()); applicationInfo.labelRes = id != null ? id : 0; } packageInfo.applicationInfo = applicationInfo; addPackage(packageInfo); }