Loading core/java/android/content/res/AssetManager.java +5 −4 Original line number Diff line number Diff line Loading @@ -149,7 +149,7 @@ public final class AssetManager { /*package*/ final CharSequence getResourceText(int ident) { synchronized (this) { TypedValue tmpValue = mValue; int block = loadResourceValue(ident, tmpValue, true); int block = loadResourceValue(ident, (short) 0, tmpValue, true); if (block >= 0) { if (tmpValue.type == TypedValue.TYPE_STRING) { return mStringBlocks[block].get(tmpValue.data); Loading Loading @@ -190,10 +190,11 @@ public final class AssetManager { /*package*/ final boolean getResourceValue(int ident, int density, TypedValue outValue, boolean resolveRefs) { int block = loadResourceValue(ident, outValue, resolveRefs); int block = loadResourceValue(ident, (short) density, outValue, resolveRefs); if (block >= 0) { if (outValue.type != TypedValue.TYPE_STRING) { return true; Loading Loading @@ -681,7 +682,7 @@ public final class AssetManager { /** Returns true if the resource was found, filling in mRetStringBlock and * mRetData. */ private native final int loadResourceValue(int ident, TypedValue outValue, private native final int loadResourceValue(int ident, short density, TypedValue outValue, boolean resolve); /** Returns true if the resource was found, filling in mRetStringBlock and * mRetData. */ Loading core/java/android/content/res/Resources.java +68 −1 Original line number Diff line number Diff line Loading @@ -627,6 +627,50 @@ public class Resources { } } /** * Return a drawable object associated with a particular resource ID for the * given screen density in DPI. This will set the drawable's density to be * the device's density multiplied by the ratio of actual drawable density * to requested density. This allows the drawable to be scaled up to the * correct size if needed. Various types of objects will be returned * depending on the underlying resource -- for example, a solid color, PNG * image, scalable image, etc. The Drawable API hides these implementation * details. * * @param id The desired resource identifier, as generated by the aapt tool. * This integer encodes the package, type, and resource entry. * The value 0 is an invalid identifier. * @param density the desired screen density indicated by the resource as * found in {@link DisplayMetrics}. * @throws NotFoundException Throws NotFoundException if the given ID does * not exist. * @return Drawable An object that can be used to draw this resource. * @hide */ public Drawable getDrawableForDensity(int id, int density) throws NotFoundException { synchronized (mTmpValue) { TypedValue value = mTmpValue; getValueForDensity(id, density, value, true); /* * Pretend the requested density is actually the display density. If * the drawable returned is not the requested density, then force it * to be scaled later by dividing its density by the ratio of * requested density to actual device density. Drawables that have * undefined density or no density don't need to be handled here. */ if (value.density > 0 && value.density != TypedValue.DENSITY_NONE) { if (value.density == density) { value.density = DisplayMetrics.DENSITY_DEVICE; } else { value.density = (value.density * DisplayMetrics.DENSITY_DEVICE) / density; } } return loadDrawable(value, id); } } /** * Return a movie object associated with the particular resource ID. * @param id The desired resource identifier, as generated by the aapt Loading Loading @@ -930,7 +974,7 @@ public class Resources { */ public void getValue(int id, TypedValue outValue, boolean resolveRefs) throws NotFoundException { boolean found = mAssets.getResourceValue(id, outValue, resolveRefs); boolean found = mAssets.getResourceValue(id, 0, outValue, resolveRefs); if (found) { return; } Loading @@ -938,6 +982,29 @@ public class Resources { + Integer.toHexString(id)); } /** * Get the raw value associated with a resource with associated density. * * @param id resource identifier * @param density density in DPI * @param resolveRefs If true, a resource that is a reference to another * resource will be followed so that you receive the actual final * resource data. If false, the TypedValue will be filled in with * the reference itself. * @throws NotFoundException Throws NotFoundException if the given ID does * not exist. * @see #getValue(String, TypedValue, boolean) * @hide */ public void getValueForDensity(int id, int density, TypedValue outValue, boolean resolveRefs) throws NotFoundException { boolean found = mAssets.getResourceValue(id, density, outValue, resolveRefs); if (found) { return; } throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)); } /** * Return the raw data associated with a particular resource ID. * See getIdentifier() for information on how names are mapped to resource Loading core/jni/android_util_AssetManager.cpp +3 −2 Original line number Diff line number Diff line Loading @@ -701,6 +701,7 @@ static jstring android_content_AssetManager_getResourceEntryName(JNIEnv* env, jo static jint android_content_AssetManager_loadResourceValue(JNIEnv* env, jobject clazz, jint ident, jshort density, jobject outValue, jboolean resolve) { Loading @@ -713,7 +714,7 @@ static jint android_content_AssetManager_loadResourceValue(JNIEnv* env, jobject Res_value value; ResTable_config config; uint32_t typeSpecFlags; ssize_t block = res.getResource(ident, &value, false, &typeSpecFlags, &config); ssize_t block = res.getResource(ident, &value, false, density, &typeSpecFlags, &config); #if THROW_ON_BAD_ID if (block == BAD_INDEX) { jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!"); Loading Loading @@ -1703,7 +1704,7 @@ static JNINativeMethod gAssetManagerMethods[] = { (void*) android_content_AssetManager_getResourceTypeName }, { "getResourceEntryName","(I)Ljava/lang/String;", (void*) android_content_AssetManager_getResourceEntryName }, { "loadResourceValue","(ILandroid/util/TypedValue;Z)I", { "loadResourceValue","(ISLandroid/util/TypedValue;Z)I", (void*) android_content_AssetManager_loadResourceValue }, { "loadResourceBagValue","(IILandroid/util/TypedValue;Z)I", (void*) android_content_AssetManager_loadResourceBagValue }, Loading include/utils/ResourceTypes.h +5 −3 Original line number Diff line number Diff line Loading @@ -1772,11 +1772,13 @@ public: * @return ssize_t Either a >= 0 table index or a negative error code. */ ssize_t getResource(uint32_t resID, Res_value* outValue, bool mayBeBag = false, uint32_t* outSpecFlags=NULL, ResTable_config* outConfig=NULL) const; uint16_t density = 0, uint32_t* outSpecFlags = NULL, ResTable_config* outConfig = NULL) const; inline ssize_t getResource(const ResTable_ref& res, Res_value* outValue, uint32_t* outSpecFlags=NULL) const { return getResource(res.ident, outValue, false, outSpecFlags, NULL); return getResource(res.ident, outValue, false, 0, outSpecFlags, NULL); } ssize_t resolveReference(Res_value* inOutValue, Loading libs/utils/ResourceTypes.cpp +34 −10 Original line number Diff line number Diff line Loading @@ -1896,7 +1896,7 @@ bool ResTable::getResourceName(uint32_t resID, resource_name* outName) const return false; } ssize_t ResTable::getResource(uint32_t resID, Res_value* outValue, bool mayBeBag, ssize_t ResTable::getResource(uint32_t resID, Res_value* outValue, bool mayBeBag, uint16_t density, uint32_t* outSpecFlags, ResTable_config* outConfig) const { if (mError != NO_ERROR) { Loading Loading @@ -1934,6 +1934,22 @@ ssize_t ResTable::getResource(uint32_t resID, Res_value* outValue, bool mayBeBag LOGW("Bad identifier when getting value for resource number 0x%08x", resID); return BAD_INDEX; } // Allow overriding density const ResTable_config* desiredConfig = &mParams; ResTable_config* overrideConfig = NULL; if (density > 0) { overrideConfig = (ResTable_config*) malloc(sizeof(ResTable_config)); if (overrideConfig == NULL) { LOGE("Couldn't malloc ResTable_config for overrides: %s", strerror(errno)); return BAD_INDEX; } memcpy(overrideConfig, &mParams, sizeof(ResTable_config)); overrideConfig->density = density; desiredConfig = overrideConfig; } ssize_t rc = BAD_INDEX; size_t ip = grp->packages.size(); while (ip > 0) { ip--; Loading @@ -1943,12 +1959,13 @@ ssize_t ResTable::getResource(uint32_t resID, Res_value* outValue, bool mayBeBag const ResTable_type* type; const ResTable_entry* entry; const Type* typeClass; ssize_t offset = getEntry(package, t, e, &mParams, &type, &entry, &typeClass); ssize_t offset = getEntry(package, t, e, desiredConfig, &type, &entry, &typeClass); if (offset <= 0) { if (offset < 0) { LOGW("Failure getting entry for 0x%08x (t=%d e=%d) in package %zd (error %d)\n", resID, t, e, ip, (int)offset); return offset; rc = offset; goto out; } continue; } Loading @@ -1967,7 +1984,8 @@ ssize_t ResTable::getResource(uint32_t resID, Res_value* outValue, bool mayBeBag if ((size_t)offset > (dtohl(type->header.size)-sizeof(Res_value))) { LOGW("ResTable_item at %d is beyond type chunk data %d", (int)offset, dtohl(type->header.size)); return BAD_TYPE; rc = BAD_TYPE; goto out; } const Res_value* item = Loading Loading @@ -2011,10 +2029,16 @@ ssize_t ResTable::getResource(uint32_t resID, Res_value* outValue, bool mayBeBag outValue->data, &len)).string() : "", outValue->data)); return bestPackage->header->index; rc = bestPackage->header->index; goto out; } out: if (overrideConfig != NULL) { free(overrideConfig); } return BAD_VALUE; return rc; } ssize_t ResTable::resolveReference(Res_value* value, ssize_t blockIndex, Loading @@ -2027,7 +2051,7 @@ ssize_t ResTable::resolveReference(Res_value* value, ssize_t blockIndex, if (outLastRef) *outLastRef = value->data; uint32_t lastRef = value->data; uint32_t newFlags = 0; const ssize_t newIndex = getResource(value->data, value, true, &newFlags, const ssize_t newIndex = getResource(value->data, value, true, 0, &newFlags, outConfig); if (newIndex == BAD_INDEX) { return BAD_INDEX; Loading Loading
core/java/android/content/res/AssetManager.java +5 −4 Original line number Diff line number Diff line Loading @@ -149,7 +149,7 @@ public final class AssetManager { /*package*/ final CharSequence getResourceText(int ident) { synchronized (this) { TypedValue tmpValue = mValue; int block = loadResourceValue(ident, tmpValue, true); int block = loadResourceValue(ident, (short) 0, tmpValue, true); if (block >= 0) { if (tmpValue.type == TypedValue.TYPE_STRING) { return mStringBlocks[block].get(tmpValue.data); Loading Loading @@ -190,10 +190,11 @@ public final class AssetManager { /*package*/ final boolean getResourceValue(int ident, int density, TypedValue outValue, boolean resolveRefs) { int block = loadResourceValue(ident, outValue, resolveRefs); int block = loadResourceValue(ident, (short) density, outValue, resolveRefs); if (block >= 0) { if (outValue.type != TypedValue.TYPE_STRING) { return true; Loading Loading @@ -681,7 +682,7 @@ public final class AssetManager { /** Returns true if the resource was found, filling in mRetStringBlock and * mRetData. */ private native final int loadResourceValue(int ident, TypedValue outValue, private native final int loadResourceValue(int ident, short density, TypedValue outValue, boolean resolve); /** Returns true if the resource was found, filling in mRetStringBlock and * mRetData. */ Loading
core/java/android/content/res/Resources.java +68 −1 Original line number Diff line number Diff line Loading @@ -627,6 +627,50 @@ public class Resources { } } /** * Return a drawable object associated with a particular resource ID for the * given screen density in DPI. This will set the drawable's density to be * the device's density multiplied by the ratio of actual drawable density * to requested density. This allows the drawable to be scaled up to the * correct size if needed. Various types of objects will be returned * depending on the underlying resource -- for example, a solid color, PNG * image, scalable image, etc. The Drawable API hides these implementation * details. * * @param id The desired resource identifier, as generated by the aapt tool. * This integer encodes the package, type, and resource entry. * The value 0 is an invalid identifier. * @param density the desired screen density indicated by the resource as * found in {@link DisplayMetrics}. * @throws NotFoundException Throws NotFoundException if the given ID does * not exist. * @return Drawable An object that can be used to draw this resource. * @hide */ public Drawable getDrawableForDensity(int id, int density) throws NotFoundException { synchronized (mTmpValue) { TypedValue value = mTmpValue; getValueForDensity(id, density, value, true); /* * Pretend the requested density is actually the display density. If * the drawable returned is not the requested density, then force it * to be scaled later by dividing its density by the ratio of * requested density to actual device density. Drawables that have * undefined density or no density don't need to be handled here. */ if (value.density > 0 && value.density != TypedValue.DENSITY_NONE) { if (value.density == density) { value.density = DisplayMetrics.DENSITY_DEVICE; } else { value.density = (value.density * DisplayMetrics.DENSITY_DEVICE) / density; } } return loadDrawable(value, id); } } /** * Return a movie object associated with the particular resource ID. * @param id The desired resource identifier, as generated by the aapt Loading Loading @@ -930,7 +974,7 @@ public class Resources { */ public void getValue(int id, TypedValue outValue, boolean resolveRefs) throws NotFoundException { boolean found = mAssets.getResourceValue(id, outValue, resolveRefs); boolean found = mAssets.getResourceValue(id, 0, outValue, resolveRefs); if (found) { return; } Loading @@ -938,6 +982,29 @@ public class Resources { + Integer.toHexString(id)); } /** * Get the raw value associated with a resource with associated density. * * @param id resource identifier * @param density density in DPI * @param resolveRefs If true, a resource that is a reference to another * resource will be followed so that you receive the actual final * resource data. If false, the TypedValue will be filled in with * the reference itself. * @throws NotFoundException Throws NotFoundException if the given ID does * not exist. * @see #getValue(String, TypedValue, boolean) * @hide */ public void getValueForDensity(int id, int density, TypedValue outValue, boolean resolveRefs) throws NotFoundException { boolean found = mAssets.getResourceValue(id, density, outValue, resolveRefs); if (found) { return; } throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)); } /** * Return the raw data associated with a particular resource ID. * See getIdentifier() for information on how names are mapped to resource Loading
core/jni/android_util_AssetManager.cpp +3 −2 Original line number Diff line number Diff line Loading @@ -701,6 +701,7 @@ static jstring android_content_AssetManager_getResourceEntryName(JNIEnv* env, jo static jint android_content_AssetManager_loadResourceValue(JNIEnv* env, jobject clazz, jint ident, jshort density, jobject outValue, jboolean resolve) { Loading @@ -713,7 +714,7 @@ static jint android_content_AssetManager_loadResourceValue(JNIEnv* env, jobject Res_value value; ResTable_config config; uint32_t typeSpecFlags; ssize_t block = res.getResource(ident, &value, false, &typeSpecFlags, &config); ssize_t block = res.getResource(ident, &value, false, density, &typeSpecFlags, &config); #if THROW_ON_BAD_ID if (block == BAD_INDEX) { jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!"); Loading Loading @@ -1703,7 +1704,7 @@ static JNINativeMethod gAssetManagerMethods[] = { (void*) android_content_AssetManager_getResourceTypeName }, { "getResourceEntryName","(I)Ljava/lang/String;", (void*) android_content_AssetManager_getResourceEntryName }, { "loadResourceValue","(ILandroid/util/TypedValue;Z)I", { "loadResourceValue","(ISLandroid/util/TypedValue;Z)I", (void*) android_content_AssetManager_loadResourceValue }, { "loadResourceBagValue","(IILandroid/util/TypedValue;Z)I", (void*) android_content_AssetManager_loadResourceBagValue }, Loading
include/utils/ResourceTypes.h +5 −3 Original line number Diff line number Diff line Loading @@ -1772,11 +1772,13 @@ public: * @return ssize_t Either a >= 0 table index or a negative error code. */ ssize_t getResource(uint32_t resID, Res_value* outValue, bool mayBeBag = false, uint32_t* outSpecFlags=NULL, ResTable_config* outConfig=NULL) const; uint16_t density = 0, uint32_t* outSpecFlags = NULL, ResTable_config* outConfig = NULL) const; inline ssize_t getResource(const ResTable_ref& res, Res_value* outValue, uint32_t* outSpecFlags=NULL) const { return getResource(res.ident, outValue, false, outSpecFlags, NULL); return getResource(res.ident, outValue, false, 0, outSpecFlags, NULL); } ssize_t resolveReference(Res_value* inOutValue, Loading
libs/utils/ResourceTypes.cpp +34 −10 Original line number Diff line number Diff line Loading @@ -1896,7 +1896,7 @@ bool ResTable::getResourceName(uint32_t resID, resource_name* outName) const return false; } ssize_t ResTable::getResource(uint32_t resID, Res_value* outValue, bool mayBeBag, ssize_t ResTable::getResource(uint32_t resID, Res_value* outValue, bool mayBeBag, uint16_t density, uint32_t* outSpecFlags, ResTable_config* outConfig) const { if (mError != NO_ERROR) { Loading Loading @@ -1934,6 +1934,22 @@ ssize_t ResTable::getResource(uint32_t resID, Res_value* outValue, bool mayBeBag LOGW("Bad identifier when getting value for resource number 0x%08x", resID); return BAD_INDEX; } // Allow overriding density const ResTable_config* desiredConfig = &mParams; ResTable_config* overrideConfig = NULL; if (density > 0) { overrideConfig = (ResTable_config*) malloc(sizeof(ResTable_config)); if (overrideConfig == NULL) { LOGE("Couldn't malloc ResTable_config for overrides: %s", strerror(errno)); return BAD_INDEX; } memcpy(overrideConfig, &mParams, sizeof(ResTable_config)); overrideConfig->density = density; desiredConfig = overrideConfig; } ssize_t rc = BAD_INDEX; size_t ip = grp->packages.size(); while (ip > 0) { ip--; Loading @@ -1943,12 +1959,13 @@ ssize_t ResTable::getResource(uint32_t resID, Res_value* outValue, bool mayBeBag const ResTable_type* type; const ResTable_entry* entry; const Type* typeClass; ssize_t offset = getEntry(package, t, e, &mParams, &type, &entry, &typeClass); ssize_t offset = getEntry(package, t, e, desiredConfig, &type, &entry, &typeClass); if (offset <= 0) { if (offset < 0) { LOGW("Failure getting entry for 0x%08x (t=%d e=%d) in package %zd (error %d)\n", resID, t, e, ip, (int)offset); return offset; rc = offset; goto out; } continue; } Loading @@ -1967,7 +1984,8 @@ ssize_t ResTable::getResource(uint32_t resID, Res_value* outValue, bool mayBeBag if ((size_t)offset > (dtohl(type->header.size)-sizeof(Res_value))) { LOGW("ResTable_item at %d is beyond type chunk data %d", (int)offset, dtohl(type->header.size)); return BAD_TYPE; rc = BAD_TYPE; goto out; } const Res_value* item = Loading Loading @@ -2011,10 +2029,16 @@ ssize_t ResTable::getResource(uint32_t resID, Res_value* outValue, bool mayBeBag outValue->data, &len)).string() : "", outValue->data)); return bestPackage->header->index; rc = bestPackage->header->index; goto out; } out: if (overrideConfig != NULL) { free(overrideConfig); } return BAD_VALUE; return rc; } ssize_t ResTable::resolveReference(Res_value* value, ssize_t blockIndex, Loading @@ -2027,7 +2051,7 @@ ssize_t ResTable::resolveReference(Res_value* value, ssize_t blockIndex, if (outLastRef) *outLastRef = value->data; uint32_t lastRef = value->data; uint32_t newFlags = 0; const ssize_t newIndex = getResource(value->data, value, true, &newFlags, const ssize_t newIndex = getResource(value->data, value, true, 0, &newFlags, outConfig); if (newIndex == BAD_INDEX) { return BAD_INDEX; Loading