make AssetManager feature complete with pre androidfw version

This commit is contained in:
Julian Winkler
2024-02-03 23:00:14 +01:00
parent c1d8956309
commit 7c59ed33bd
2 changed files with 57 additions and 65 deletions

View File

@@ -146,6 +146,7 @@ JNIEXPORT jint JNICALL Java_android_content_res_AssetManager_loadResourceValue(J
_SET_INT_FIELD(outValue, "type", value.dataType); _SET_INT_FIELD(outValue, "type", value.dataType);
_SET_INT_FIELD(outValue, "data", value.data); _SET_INT_FIELD(outValue, "data", value.data);
_SET_INT_FIELD(outValue, "resourceId", resId); _SET_INT_FIELD(outValue, "resourceId", resId);
_SET_INT_FIELD(outValue, "assetCookie", block);
if (value.dataType == TYPE_STRING) { if (value.dataType == TYPE_STRING) {
const struct ResStringPool *string_pool = ResTable_getTableStringBlock(res_table, block); const struct ResStringPool *string_pool = ResTable_getTableStringBlock(res_table, block);
size_t len; size_t len;
@@ -261,6 +262,7 @@ JNIEXPORT jint JNICALL Java_android_content_res_AssetManager_loadThemeAttributeV
_SET_INT_FIELD(outValue, "type", value.dataType); _SET_INT_FIELD(outValue, "type", value.dataType);
_SET_INT_FIELD(outValue, "data", value.data); _SET_INT_FIELD(outValue, "data", value.data);
_SET_INT_FIELD(outValue, "resourceId", resId); _SET_INT_FIELD(outValue, "resourceId", resId);
_SET_INT_FIELD(outValue, "assetCookie", block);
if (value.dataType == TYPE_STRING) { if (value.dataType == TYPE_STRING) {
const struct ResStringPool *string_pool = ResTable_getTableStringBlock(res_table, block); const struct ResStringPool *string_pool = ResTable_getTableStringBlock(res_table, block);
size_t len; size_t len;
@@ -353,6 +355,7 @@ JNIEXPORT jint JNICALL Java_android_content_res_AssetManager_loadResourceBagValu
_SET_INT_FIELD(outValue, "type", value.dataType); _SET_INT_FIELD(outValue, "type", value.dataType);
_SET_INT_FIELD(outValue, "data", value.data); _SET_INT_FIELD(outValue, "data", value.data);
_SET_INT_FIELD(outValue, "resourceId", resId); _SET_INT_FIELD(outValue, "resourceId", resId);
_SET_INT_FIELD(outValue, "assetCookie", block);
if (value.dataType == TYPE_STRING) { if (value.dataType == TYPE_STRING) {
const struct ResStringPool *string_pool = ResTable_getTableStringBlock(res_table, block); const struct ResStringPool *string_pool = ResTable_getTableStringBlock(res_table, block);
size_t len; size_t len;

View File

@@ -18,46 +18,27 @@ package android.content.res;
import android.content.Context; import android.content.Context;
import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor;
import android.os.Trace;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.Log; import android.util.Log;
import android.util.TypedValue; import android.util.TypedValue;
import com.reandroid.arsc.array.ResValueMapArray;
import com.reandroid.arsc.chunk.PackageBlock;
import com.reandroid.arsc.chunk.TableBlock;
import com.reandroid.arsc.chunk.xml.ResXmlDocument; import com.reandroid.arsc.chunk.xml.ResXmlDocument;
import com.reandroid.arsc.chunk.xml.ResXmlPullParser; import com.reandroid.arsc.chunk.xml.ResXmlPullParser;
import com.reandroid.arsc.group.EntryGroup;
import com.reandroid.arsc.item.StringItem;
import com.reandroid.arsc.value.Entry;
import com.reandroid.arsc.value.EntryHeaderMap;
import com.reandroid.arsc.item.TableString;
import com.reandroid.arsc.value.ResValue;
import com.reandroid.arsc.value.ResValueMap;
import com.reandroid.arsc.value.ValueItem; import com.reandroid.arsc.value.ValueItem;
import com.reandroid.arsc.value.ValueType;
import com.reandroid.arsc.value.plurals.PluralsBag;
import com.reandroid.arsc.value.plurals.PluralsQuantity;
import java.io.FileDescriptor; import java.io.FileDescriptor;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.URL; import java.net.URL;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.List;
import java.util.jar.JarEntry; import java.util.jar.JarEntry;
import java.util.jar.JarFile; import java.util.jar.JarFile;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;
/** /**
* Provides access to an application's raw asset files; see {@link Resources} * Provides access to an application's raw asset files; see {@link Resources}
@@ -783,6 +764,17 @@ public final class AssetManager {
/*package*/ /*native*/ final boolean applyStyle(long theme, /*package*/ /*native*/ final boolean applyStyle(long theme,
int defStyleAttr, int defStyleRes, AttributeSet set, int defStyleAttr, int defStyleRes, AttributeSet set,
int[] inAttrs, int[] outValues, int[] outIndices) { int[] inAttrs, int[] outValues, int[] outIndices) {
TypedValue value = new TypedValue();
if (defStyleRes == 0 && theme != 0 && loadThemeAttributeValue(theme, defStyleAttr, value, true) >= 0)
defStyleRes = value.data;
if (defStyleRes == 0 && set != null)
defStyleRes = set.getAttributeResourceValue(null, "style", 0);
long defStyle = 0;
if (defStyleRes != 0) {
defStyle = newTheme();
applyThemeStyle(defStyle, defStyleRes, true);
}
ResXmlPullParser parser = (ResXmlPullParser)set; ResXmlPullParser parser = (ResXmlPullParser)set;
outIndices[0] = 0; outIndices[0] = 0;
@@ -795,64 +787,61 @@ public final class AssetManager {
for (int i = 0; i < inAttrs.length; i++) { for (int i = 0; i < inAttrs.length; i++) {
int d = i*AssetManager.STYLE_NUM_ENTRIES; int d = i*AssetManager.STYLE_NUM_ENTRIES;
// reset values in case of cached array // reset values in case of cached array
outValues[d+AssetManager.STYLE_RESOURCE_ID] = 0;
outValues[d+AssetManager.STYLE_TYPE] = 0;
outValues[d+AssetManager.STYLE_DATA] = 0;
outValues[d+AssetManager.STYLE_ASSET_COOKIE] = -1;
int resId = inAttrs[i]; int resId = inAttrs[i];
ValueItem valueItem = null; boolean found = false;
if (xmlCache.containsKey(resId)) { value.resourceId = 0;
valueItem = parser.getResXmlAttributeAt(xmlCache.get(resId)); value.type = -1;
} value.data = 0;
if (valueItem == null) { value.assetCookie = -1;
if (theme != 0) { while (true) {
TypedValue value = new TypedValue(); if (resId == 0) {
int block = loadThemeAttributeValue(theme, resId, value, true); value.type = 0;
value.data = 0;
value.resourceId = 0;
value.assetCookie = -1;
found = true;
} else if (xmlCache.containsKey(resId)) {
ValueItem valueItem = parser.getResXmlAttributeAt(xmlCache.get(resId));
value.type = valueItem.getType();
value.data = valueItem.getData();
value.resourceId = resId;
value.assetCookie = -1;
if (value.type != TypedValue.TYPE_ATTRIBUTE)
found = true;
} else {
int block = -1;
if (theme != 0 && (value.type == TypedValue.TYPE_ATTRIBUTE || value.type == -1))
block = loadThemeAttributeValue(theme, resId, value, true);
if (block < 0 && defStyle != 0 && (value.type == TypedValue.TYPE_ATTRIBUTE || value.type == -1))
block = loadThemeAttributeValue(defStyle, resId, value, true);
if (block < 0 && value.type == TypedValue.TYPE_REFERENCE)
block = loadResourceValue(resId, (short)0, value, true);
if (block >= 0) { if (block >= 0) {
outValues[d + AssetManager.STYLE_RESOURCE_ID] = value.resourceId; found = true;
outValues[d + AssetManager.STYLE_TYPE] = value.type;
outValues[d + AssetManager.STYLE_DATA] = value.data;
outValues[d + AssetManager.STYLE_ASSET_COOKIE] = block;
outIndices[++outIndices[0]] = i;
} }
} }
continue; if ((value.type == TypedValue.TYPE_REFERENCE || value.type == TypedValue.TYPE_ATTRIBUTE) && value.data != resId) {
resId = value.data;
} else {
break;
}
} }
if (valueItem.getValueType() == ValueType.REFERENCE || valueItem.getValueType() == ValueType.ATTRIBUTE) { if (found) {
int prev_resId = resId;
resId = valueItem.getData();
TypedValue value = new TypedValue();
int block = -1;
if (theme != 0)
block = loadThemeAttributeValue(theme, resId, value, true);
if (block < 0)
block = loadResourceValue(resId, (short)0, value, true);
if (block < 0) {
block = -1;
if (resId == 0) {
value.resourceId = 0;
value.type = 0;
value.data = 0;
} else {
value.resourceId = prev_resId;
value.type = valueItem.getType();
value.data = valueItem.getData();
}
}
outValues[d + AssetManager.STYLE_RESOURCE_ID] = value.resourceId; outValues[d + AssetManager.STYLE_RESOURCE_ID] = value.resourceId;
outValues[d + AssetManager.STYLE_TYPE] = value.type; outValues[d + AssetManager.STYLE_TYPE] = value.type;
outValues[d + AssetManager.STYLE_DATA] = value.data; outValues[d + AssetManager.STYLE_DATA] = value.data;
outValues[d + AssetManager.STYLE_ASSET_COOKIE] = block; outValues[d + AssetManager.STYLE_ASSET_COOKIE] = value.assetCookie;
outIndices[++outIndices[0]] = i; outIndices[++outIndices[0]] = i;
continue;
} else { } else {
outValues[d + AssetManager.STYLE_RESOURCE_ID] = 0; outValues[d+AssetManager.STYLE_RESOURCE_ID] = 0;
outValues[d + AssetManager.STYLE_TYPE] = valueItem.getType(); outValues[d+AssetManager.STYLE_TYPE] = 0;
outValues[d + AssetManager.STYLE_DATA] = valueItem.getData(); outValues[d+AssetManager.STYLE_DATA] = 0;
outValues[d + AssetManager.STYLE_ASSET_COOKIE] = -1; outValues[d+AssetManager.STYLE_ASSET_COOKIE] = -1;
outIndices[++outIndices[0]] = i;
} }
} }
if (defStyle != 0) {
deleteTheme(defStyle);
}
return true; return true;
} }
/*package*/ native final boolean retrieveAttributes( /*package*/ native final boolean retrieveAttributes(