implement obtainStyledAttributes() functions properly

This commit is contained in:
Julian Winkler
2023-08-17 10:00:50 +02:00
parent aa5d9b16df
commit c60e97f13f
5 changed files with 269 additions and 149 deletions

View File

@@ -33,6 +33,14 @@ extern "C" {
#define android_content_res_AssetManager_STYLE_CHANGING_CONFIGURATIONS 4L #define android_content_res_AssetManager_STYLE_CHANGING_CONFIGURATIONS 4L
#undef android_content_res_AssetManager_STYLE_DENSITY #undef android_content_res_AssetManager_STYLE_DENSITY
#define android_content_res_AssetManager_STYLE_DENSITY 5L #define android_content_res_AssetManager_STYLE_DENSITY 5L
/*
* Class: android_content_res_AssetManager
* Method: list
* Signature: (Ljava/lang/String;)[Ljava/lang/String;
*/
JNIEXPORT jobjectArray JNICALL Java_android_content_res_AssetManager_list
(JNIEnv *, jobject, jstring);
/* /*
* Class: android_content_res_AssetManager * Class: android_content_res_AssetManager
* Method: addAssetPathNative * Method: addAssetPathNative
@@ -65,22 +73,6 @@ JNIEXPORT void JNICALL Java_android_content_res_AssetManager_setLocale
JNIEXPORT jobjectArray JNICALL Java_android_content_res_AssetManager_getLocales JNIEXPORT jobjectArray JNICALL Java_android_content_res_AssetManager_getLocales
(JNIEnv *, jobject); (JNIEnv *, jobject);
/*
* Class: android_content_res_AssetManager
* Method: setConfiguration
* Signature: (IILjava/lang/String;IIIIIIIIIIIIII)V
*/
JNIEXPORT void JNICALL Java_android_content_res_AssetManager_setConfiguration
(JNIEnv *, jobject, jint, jint, jstring, jint, jint, jint, jint, jint, jint, jint, jint, jint, jint, jint, jint, jint, jint);
/*
* Class: android_content_res_AssetManager
* Method: getResourceName
* Signature: (I)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_android_content_res_AssetManager_getResourceName
(JNIEnv *, jobject, jint);
/* /*
* Class: android_content_res_AssetManager * Class: android_content_res_AssetManager
* Method: getResourcePackageName * Method: getResourcePackageName
@@ -89,14 +81,6 @@ JNIEXPORT jstring JNICALL Java_android_content_res_AssetManager_getResourceName
JNIEXPORT jstring JNICALL Java_android_content_res_AssetManager_getResourcePackageName JNIEXPORT jstring JNICALL Java_android_content_res_AssetManager_getResourcePackageName
(JNIEnv *, jobject, jint); (JNIEnv *, jobject, jint);
/*
* Class: android_content_res_AssetManager
* Method: getResourceTypeName
* Signature: (I)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_android_content_res_AssetManager_getResourceTypeName
(JNIEnv *, jobject, jint);
/* /*
* Class: android_content_res_AssetManager * Class: android_content_res_AssetManager
* Method: getResourceEntryName * Method: getResourceEntryName
@@ -193,14 +177,6 @@ JNIEXPORT jint JNICALL Java_android_content_res_AssetManager_loadResourceValue
JNIEXPORT jint JNICALL Java_android_content_res_AssetManager_loadResourceBagValue JNIEXPORT jint JNICALL Java_android_content_res_AssetManager_loadResourceBagValue
(JNIEnv *, jobject, jint, jint, jobject, jboolean); (JNIEnv *, jobject, jint, jint, jobject, jboolean);
/*
* Class: android_content_res_AssetManager
* Method: applyStyle
* Signature: (IIII[I[I[I)Z
*/
JNIEXPORT jboolean JNICALL Java_android_content_res_AssetManager_applyStyle
(JNIEnv *, jclass, jint, jint, jint, jint, jintArray, jintArray, jintArray);
/* /*
* Class: android_content_res_AssetManager * Class: android_content_res_AssetManager
* Method: retrieveAttributes * Method: retrieveAttributes
@@ -281,6 +257,14 @@ JNIEXPORT jint JNICALL Java_android_content_res_AssetManager_getGlobalAssetManag
JNIEXPORT jint JNICALL Java_android_content_res_AssetManager_newTheme JNIEXPORT jint JNICALL Java_android_content_res_AssetManager_newTheme
(JNIEnv *, jobject); (JNIEnv *, jobject);
/*
* Class: android_content_res_AssetManager
* Method: deleteTheme
* Signature: (I)V
*/
JNIEXPORT void JNICALL Java_android_content_res_AssetManager_deleteTheme
(JNIEnv *, jobject, jint);
/* /*
* Class: android_content_res_AssetManager * Class: android_content_res_AssetManager
* Method: applyThemeStyle * Method: applyThemeStyle
@@ -329,6 +313,14 @@ JNIEXPORT jobjectArray JNICALL Java_android_content_res_AssetManager_getArrayStr
JNIEXPORT jintArray JNICALL Java_android_content_res_AssetManager_getArrayStringInfo JNIEXPORT jintArray JNICALL Java_android_content_res_AssetManager_getArrayStringInfo
(JNIEnv *, jobject, jint); (JNIEnv *, jobject, jint);
/*
* Class: android_content_res_AssetManager
* Method: destroy
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_android_content_res_AssetManager_destroy
(JNIEnv *, jobject);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -57,6 +57,7 @@ public class Context extends Object {
static Configuration config; static Configuration config;
static Resources r; static Resources r;
static ApplicationInfo application_info; static ApplicationInfo application_info;
static Resources.Theme theme;
static String apk_path = "/tmp/APK_PATH_SHOULD_HAVE_BEEN_FILLED_IN_BY_CODE_IN_main.c/"; static String apk_path = "/tmp/APK_PATH_SHOULD_HAVE_BEEN_FILLED_IN_BY_CODE_IN_main.c/";
@@ -74,6 +75,7 @@ public class Context extends Object {
config = new Configuration(); config = new Configuration();
r = new Resources(assets, dm, config); r = new Resources(assets, dm, config);
this_application = new Application(); // TODO: the application context is presumably not identical to the Activity context, what is the difference for us though? this_application = new Application(); // TODO: the application context is presumably not identical to the Activity context, what is the difference for us though?
theme = r.newTheme();
application_info = new ApplicationInfo(); application_info = new ApplicationInfo();
InputStream inStream = ClassLoader.getSystemClassLoader().getResourceAsStream("AndroidManifest.xml"); InputStream inStream = ClassLoader.getSystemClassLoader().getResourceAsStream("AndroidManifest.xml");
@@ -93,7 +95,7 @@ public class Context extends Object {
} }
public Resources.Theme getTheme() { public Resources.Theme getTheme() {
return r.newTheme(); return theme;
} }
public ApplicationInfo getApplicationInfo() { public ApplicationInfo getApplicationInfo() {
@@ -313,9 +315,20 @@ public class Context extends Object {
System.out.println("------------------"); System.out.println("------------------");
} }
// these may not look like typical stubs, but they definitely are stubs public final TypedArray obtainStyledAttributes(AttributeSet set, int[] attrs) {
public final TypedArray obtainStyledAttributes(AttributeSet set, int[] attrs) { return new TypedArray(r, new int[1000], new int[1000], 0); } return getTheme().obtainStyledAttributes(set, attrs, 0, 0);
public final TypedArray obtainStyledAttributes(AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes) { return new TypedArray(r, new int[1000], new int[1000], 0); } }
public final TypedArray obtainStyledAttributes(int resid, int[] attrs) { return new TypedArray(r, new int[1000], new int[1000], 0); } public final TypedArray obtainStyledAttributes(AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes) {
public final TypedArray obtainStyledAttributes(int[] attrs) { return new TypedArray(r, new int[1000], new int[1000], 0); } return getTheme().obtainStyledAttributes(set, attrs, defStyleAttr, defStyleRes);
}
public final TypedArray obtainStyledAttributes(int resid, int[] attrs) {
return getTheme().obtainStyledAttributes(resid, attrs);
}
public final TypedArray obtainStyledAttributes(int[] attrs) {
return getTheme().obtainStyledAttributes(attrs);
}
public void setTheme(int resId) {
theme.applyStyle(resId, true);
}
} }

View File

@@ -19,16 +19,22 @@ 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.os.Trace;
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.PackageBlock;
import com.reandroid.arsc.chunk.TableBlock; 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.group.EntryGroup;
import com.reandroid.arsc.item.StringItem;
import com.reandroid.arsc.value.Entry;
import com.reandroid.arsc.value.EntryHeaderMap;
import com.reandroid.arsc.value.ResValue; import com.reandroid.arsc.value.ResValue;
import com.reandroid.arsc.value.ResValueMap; import com.reandroid.arsc.value.ResValueMap;
import com.reandroid.arsc.value.ValueItem;
import com.reandroid.arsc.value.ValueType; import com.reandroid.arsc.value.ValueType;
import java.io.FileDescriptor; import java.io.FileDescriptor;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
@@ -42,6 +48,7 @@ import java.nio.file.Paths;
import java.util.ArrayList; 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.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.XmlPullParser;
@@ -244,6 +251,7 @@ public final class AssetManager {
ResValue resValue = entryGroup.pickOne().getResValue(); ResValue resValue = entryGroup.pickOne().getResValue();
if (resValue == null) if (resValue == null)
return false; // not found return false; // not found
outValue.resourceId = ident;
outValue.type = resValue.getType(); outValue.type = resValue.getType();
outValue.data = resValue.getData(); outValue.data = resValue.getData();
if (outValue.type == TypedValue.TYPE_STRING) if (outValue.type == TypedValue.TYPE_STRING)
@@ -257,36 +265,63 @@ public final class AssetManager {
* @param id Resource id of the string array * @param id Resource id of the string array
*/ */
/*package*/ final CharSequence[] getResourceTextArray(final int id) { /*package*/ final CharSequence[] getResourceTextArray(final int id) {
int[] rawInfoArray = getArrayStringInfo(id); ResValueMap children[] = tableBlock.search(id).pickOne().getResValueMapArray().getChildes();
int rawInfoArrayLen = rawInfoArray.length; CharSequence values[] = new CharSequence[children.length];
final int infoArrayLen = rawInfoArrayLen / 2; for (int i = 0; i < children.length; i++) {
int block; StringItem stringItem = children[i].getDataAsPoolString();
int index; values[i] = (stringItem != null) ? stringItem.get() : "";
CharSequence[] retArray = new CharSequence[infoArrayLen];
for (int i = 0, j = 0; i < rawInfoArrayLen; i = i + 2, j++) {
block = rawInfoArray[i];
index = rawInfoArray[i + 1];
retArray[j] = index >= 0 ? mStringBlocks[block].get(index) : null;
} }
return retArray; return values;
}
public Map<Integer,ValueItem> loadStyle(int resId) {
Map<Integer,ValueItem> map = new HashMap<>();
EntryGroup entryGroup = tableBlock.search(resId);
while (entryGroup != null) {
Entry entry = entryGroup.pickOne();
ResValueMapArray array = entry.getResValueMapArray();
for (int i = 0; i < array.childesCount(); i++) {
map.putIfAbsent(array.get(i).getName(), array.get(i));
}
int parent_id = ((EntryHeaderMap)entry.getHeader()).getParentId();
entryGroup = tableBlock.search(parent_id);
}
return map;
} }
/*package*/ final boolean getThemeValue(int theme, int ident, /*package*/ final boolean getThemeValue(int theme, int ident,
TypedValue outValue, boolean resolveRefs) { TypedValue outValue, boolean resolveRefs) {
int block = loadThemeAttributeValue(theme, ident, outValue, resolveRefs); Map<Integer,ValueItem> style = loadStyle(theme);
if (block >= 0) { EntryGroup entryGroup = tableBlock.search(ident);
if (outValue.type != TypedValue.TYPE_STRING) { if (entryGroup == null)
return true; return false;
Entry entry = entryGroup.pickOne();
ValueItem valueItem = null;
while ("attr".equals(entry.getTypeName())) {
valueItem = null;
if (style.containsKey(ident))
valueItem = style.get(ident);
if (valueItem != null && valueItem.getValueType() == ValueType.ATTRIBUTE) {
ident = valueItem.getData();
entryGroup = tableBlock.search(ident);
if (entryGroup == null) {
break;
}
entry = entryGroup.pickOne();
} else {
break;
} }
StringBlock[] blocks = mStringBlocks;
if (blocks == null) {
ensureStringBlocks();
blocks = mStringBlocks;
}
outValue.string = blocks[block].get(outValue.data);
return true;
} }
return false; if (valueItem == null)
return false;
outValue.resourceId = 0;
outValue.type = valueItem.getType();
outValue.data = valueItem.getData();
outValue.assetCookie = -1;
if (outValue.type == TypedValue.TYPE_STRING) {
outValue.string = valueItem.getDataAsPoolString().get();
}
return true;
} }
/*package*/ final void ensureStringBlocks() { /*package*/ final void ensureStringBlocks() {
@@ -318,7 +353,7 @@ public final class AssetManager {
// System.out.println("Get pooled: block=" + block // System.out.println("Get pooled: block=" + block
// + ", id=#" + Integer.toHexString(id) // + ", id=#" + Integer.toHexString(id)
// + ", blocks=" + mStringBlocks); // + ", blocks=" + mStringBlocks);
return mStringBlocks[block - 1].get(id); return tableBlock.getStringPool().get(id).get();
} }
/** /**
@@ -584,7 +619,7 @@ public final class AssetManager {
/*package*/ final void releaseTheme(int theme) { /*package*/ final void releaseTheme(int theme) {
synchronized (this) { synchronized (this) {
deleteTheme(theme); // deleteTheme(theme);
decRefsLocked(theme); decRefsLocked(theme);
} }
} }
@@ -748,11 +783,11 @@ public final class AssetManager {
* applications. * applications.
* {@hide} * {@hide}
*/ */
public native final void setConfiguration(int mcc, int mnc, String locale, public /*native*/ final void setConfiguration(int mcc, int mnc, String locale,
int orientation, int touchscreen, int density, int keyboard, int orientation, int touchscreen, int density, int keyboard,
int keyboardHidden, int navigation, int screenWidth, int screenHeight, int keyboardHidden, int navigation, int screenWidth, int screenHeight,
int smallestScreenWidthDp, int screenWidthDp, int screenHeightDp, int smallestScreenWidthDp, int screenWidthDp, int screenHeightDp,
int screenLayout, int uiMode, int majorVersion); int screenLayout, int uiMode, int majorVersion) {}
/** /**
* Retrieve the resource identifier for the given resource name. * Retrieve the resource identifier for the given resource name.
@@ -769,9 +804,13 @@ public final class AssetManager {
return -1; return -1;
} }
/*package*/ native final String getResourceName(int resid); /*package*/ /*native*/ final String getResourceName(int resid) {
return tableBlock.search(resid).pickOne().getName();
}
/*package*/ native final String getResourcePackageName(int resid); /*package*/ native final String getResourcePackageName(int resid);
/*package*/ native final String getResourceTypeName(int resid); /*package*/ /*native*/ final String getResourceTypeName(int resid) {
return tableBlock.search(resid).pickOne().getTypeName();
}
/*package*/ native final String getResourceEntryName(int resid); /*package*/ native final String getResourceEntryName(int resid);
private native final int openAsset(String fileName, int accessMode); private native final int openAsset(String fileName, int accessMode);
@@ -808,9 +847,82 @@ public final class AssetManager {
/*package*/ static final int STYLE_RESOURCE_ID = 3; /*package*/ static final int STYLE_RESOURCE_ID = 3;
/*package*/ static final int STYLE_CHANGING_CONFIGURATIONS = 4; /*package*/ static final int STYLE_CHANGING_CONFIGURATIONS = 4;
/*package*/ static final int STYLE_DENSITY = 5; /*package*/ static final int STYLE_DENSITY = 5;
/*package*/ native static final boolean applyStyle(int theme, /*package*/ /*native*/ final boolean applyStyle(Map<Integer,ValueItem> theme,
int defStyleAttr, int defStyleRes, int xmlParser, int defStyleAttr, int defStyleRes, AttributeSet set,
int[] inAttrs, int[] outValues, int[] outIndices); int[] inAttrs, int[] outValues, int[] outIndices) {
if (defStyleRes == 0 && theme.containsKey(defStyleAttr))
defStyleRes = theme.get(defStyleAttr).getData();
Map<Integer,ValueItem> defStyle = loadStyle(defStyleRes);
ResXmlPullParser parser = (ResXmlPullParser)set;
for (int i = 0; i < inAttrs.length; i++) {
int d = i*AssetManager.STYLE_NUM_ENTRIES;
// 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] = 0;
int resId = inAttrs[i];
EntryGroup entryGroup = tableBlock.search(resId);
if (entryGroup == null)
continue;
Entry entry = entryGroup.pickOne();
ValueItem valueItem = null;
while ("attr".equals(entry.getTypeName())) {
valueItem = null;
if (set != null) {
for (int j=0; j<set.getAttributeCount(); j++) {
if (set.getAttributeNameResource(j) == resId) {
valueItem = parser.getResXmlAttributeAt(j);
break;
}
}
}
if (valueItem == null) {
valueItem = defStyle.get(resId);
if (valueItem != null && valueItem.getValueType() == ValueType.ATTRIBUTE && valueItem.getData() == resId)
valueItem = null;
}
if (valueItem == null)
valueItem = theme.get(resId);
if (valueItem != null && valueItem.getValueType() == ValueType.ATTRIBUTE) {
resId = valueItem.getData();
entryGroup = tableBlock.search(resId);
if (entryGroup == null) {
break;
}
entry = entryGroup.pickOne();
} else {
break;
}
}
if (valueItem == null)
continue;
if (valueItem.getValueType() == ValueType.REFERENCE) {
resId = valueItem.getData();
if (resId == 0)
continue;
entry = tableBlock.search(resId).pickOne();
outValues[d + AssetManager.STYLE_RESOURCE_ID] = resId;
ResValue resValue = entry.getResValue();
if (resValue != null) {
outValues[d + AssetManager.STYLE_TYPE] = entry.getResValue().getType();
outValues[d + AssetManager.STYLE_DATA] = entry.getResValue().getData();
} else {
outValues[d + AssetManager.STYLE_TYPE] = -1;
}
outValues[d + AssetManager.STYLE_ASSET_COOKIE] = -1;
} else {
outValues[d+AssetManager.STYLE_RESOURCE_ID] = 0;
outValues[d+AssetManager.STYLE_TYPE] = valueItem.getType();
outValues[d+AssetManager.STYLE_DATA] = valueItem.getData();
outValues[d+AssetManager.STYLE_ASSET_COOKIE] = -1;
}
}
return true;
}
/*package*/ native final boolean retrieveAttributes( /*package*/ native final boolean retrieveAttributes(
int xmlParser, int[] inAttrs, int[] outValues, int[] outIndices); int xmlParser, int[] inAttrs, int[] outValues, int[] outIndices);
/*package*/ native final int getArraySize(int resource); /*package*/ native final int getArraySize(int resource);

View File

@@ -33,11 +33,16 @@ import android.util.LongSparseArray;
import android.util.Slog; import android.util.Slog;
import android.util.TypedValue; import android.util.TypedValue;
import com.android.internal.util.XmlUtils; import com.android.internal.util.XmlUtils;
import com.reandroid.arsc.chunk.xml.ResXmlPullParser;
import com.reandroid.arsc.value.ValueItem;
// import android.view.DisplayAdjustments; // import android.view.DisplayAdjustments;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Locale; import java.util.Locale;
import java.util.Map;
import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserException;
@@ -1187,6 +1192,7 @@ public class Resources {
* retrieve XML attributes with style and theme information applied. * retrieve XML attributes with style and theme information applied.
*/ */
public final class Theme { public final class Theme {
private Map<Integer,ValueItem> themeMap = new HashMap<>();
/** /**
* Place new attribute values into the theme. The style resource * Place new attribute values into the theme. The style resource
* specified by <var>resid</var> will be retrieved from this Theme's * specified by <var>resid</var> will be retrieved from this Theme's
@@ -1205,7 +1211,7 @@ public class Resources {
* if not already defined in the theme. * if not already defined in the theme.
*/ */
public void applyStyle(int resid, boolean force) { public void applyStyle(int resid, boolean force) {
AssetManager.applyThemeStyle(mTheme, resid, force); themeMap = mAssets.loadStyle(resid);
} }
/** /**
@@ -1218,7 +1224,7 @@ public class Resources {
* @param other The existing Theme to copy from. * @param other The existing Theme to copy from.
*/ */
public void setTo(Theme other) { public void setTo(Theme other) {
AssetManager.copyTheme(mTheme, other.mTheme); themeMap = other.themeMap;
} }
/** /**
@@ -1244,8 +1250,7 @@ public class Resources {
int len = attrs.length; int len = attrs.length;
TypedArray array = getCachedStyledAttributes(len); TypedArray array = getCachedStyledAttributes(len);
array.mRsrcs = attrs; array.mRsrcs = attrs;
/* AssetManager.applyStyle(mTheme, 0, 0, 0, attrs, mAssets.applyStyle(themeMap, 0, 0, null, attrs, array.mData, array.mIndices);
array.mData, array.mIndices);*/
return array; return array;
} }
@@ -1274,35 +1279,34 @@ public class Resources {
int len = attrs.length; int len = attrs.length;
TypedArray array = getCachedStyledAttributes(len); TypedArray array = getCachedStyledAttributes(len);
array.mRsrcs = attrs; array.mRsrcs = attrs;
/* mAssets.applyStyle(themeMap, 0, resid, null, attrs,
AssetManager.applyStyle(mTheme, 0, resid, 0, attrs, array.mData, array.mIndices);
array.mData, array.mIndices); if (false) {
if (false) { int[] data = array.mData;
int[] data = array.mData;
System.out.println("**********************************************************"); System.out.println("**********************************************************");
System.out.println("**********************************************************"); System.out.println("**********************************************************");
System.out.println("**********************************************************"); System.out.println("**********************************************************");
System.out.println("Attributes:"); System.out.println("Attributes:");
String s = " Attrs:"; String s = " Attrs:";
int i; int i;
for (i=0; i<attrs.length; i++) { for (i=0; i<attrs.length; i++) {
s = s + " 0x" + Integer.toHexString(attrs[i]); s = s + " 0x" + Integer.toHexString(attrs[i]);
} }
System.out.println(s); System.out.println(s);
s = " Found:"; s = " Found:";
TypedValue value = new TypedValue(); TypedValue value = new TypedValue();
for (i=0; i<attrs.length; i++) { for (i=0; i<attrs.length; i++) {
int d = i*AssetManager.STYLE_NUM_ENTRIES; int d = i*AssetManager.STYLE_NUM_ENTRIES;
value.type = data[d+AssetManager.STYLE_TYPE]; value.type = data[d+AssetManager.STYLE_TYPE];
value.data = data[d+AssetManager.STYLE_DATA]; value.data = data[d+AssetManager.STYLE_DATA];
value.assetCookie = data[d+AssetManager.STYLE_ASSET_COOKIE]; value.assetCookie = data[d+AssetManager.STYLE_ASSET_COOKIE];
value.resourceId = data[d+AssetManager.STYLE_RESOURCE_ID]; value.resourceId = data[d+AssetManager.STYLE_RESOURCE_ID];
s = s + " 0x" + Integer.toHexString(attrs[i]) s = s + " 0x" + Integer.toHexString(attrs[i])
+ "=" + value; + "=" + value;
} }
System.out.println(s); System.out.println(s);
}*/ }
return array; return array;
} }
@@ -1358,49 +1362,44 @@ public class Resources {
int[] attrs, int defStyleAttr, int defStyleRes) { int[] attrs, int defStyleAttr, int defStyleRes) {
int len = attrs.length; int len = attrs.length;
TypedArray array = getCachedStyledAttributes(len); TypedArray array = getCachedStyledAttributes(len);
/*
// XXX note that for now we only work with compiled XML files.
// To support generic XML files we will need to manually parse
// out the attributes from the XML file (applying type information
// contained in the resources and such).
XmlBlock.Parser parser = (XmlBlock.Parser)set;
AssetManager.applyStyle(
mTheme, defStyleAttr, defStyleRes,
parser != null ? parser.mParseState : 0, attrs,
array.mData, array.mIndices);
array.mRsrcs = attrs; // XXX note that for now we only work with compiled XML files.
array.mXml = parser; // To support generic XML files we will need to manually parse
// out the attributes from the XML file (applying type information
if (false) { // contained in the resources and such).
int[] data = array.mData; ResXmlPullParser parser = (ResXmlPullParser)set;
mAssets.applyStyle(themeMap, defStyleAttr, defStyleRes,
System.out.println("Attributes:"); set, attrs, array.mData, array.mIndices);
String s = " Attrs:"; array.mRsrcs = attrs;
int i; array.mXml = parser;
for (i=0; i<set.getAttributeCount(); i++) { if (false) {
s = s + " " + set.getAttributeName(i); int[] data = array.mData;
int id = set.getAttributeNameResource(i);
if (id != 0) { System.out.println("Attributes:");
String s = " Attrs:";
int i;
for (i=0; i<set.getAttributeCount(); i++) {
s = s + " " + set.getAttributeName(i);
int id = set.getAttributeNameResource(i);
if (id != 0) {
s = s + "(0x" + Integer.toHexString(id) + ")"; s = s + "(0x" + Integer.toHexString(id) + ")";
}
s = s + "=" + set.getAttributeValue(i);
} }
System.out.println(s); s = s + "=" + set.getAttributeValue(i);
s = " Found:"; }
TypedValue value = new TypedValue(); System.out.println(s);
for (i=0; i<attrs.length; i++) { s = " Found:";
int d = i*AssetManager.STYLE_NUM_ENTRIES; TypedValue value = new TypedValue();
value.type = data[d+AssetManager.STYLE_TYPE]; for (i=0; i<attrs.length; i++) {
value.data = data[d+AssetManager.STYLE_DATA]; int d = i*AssetManager.STYLE_NUM_ENTRIES;
value.assetCookie = data[d+AssetManager.STYLE_ASSET_COOKIE]; value.type = data[d+AssetManager.STYLE_TYPE];
value.resourceId = data[d+AssetManager.STYLE_RESOURCE_ID]; value.data = data[d+AssetManager.STYLE_DATA];
s = s + " 0x" + Integer.toHexString(attrs[i]) value.assetCookie = data[d+AssetManager.STYLE_ASSET_COOKIE];
value.resourceId = data[d+AssetManager.STYLE_RESOURCE_ID];
s = s + " 0x" + Integer.toHexString(attrs[i])
+ "=" + value; + "=" + value;
} }
System.out.println(s); System.out.println(s);
} }
*/
return array; return array;
} }
@@ -1491,7 +1490,7 @@ public class Resources {
array.mData, array.mIndices); array.mData, array.mIndices);
array.mRsrcs = attrs; array.mRsrcs = attrs;
array.mXml = parser; // array.mXml = parser;
return array; return array;
} }

View File

@@ -23,6 +23,9 @@ import android.util.DisplayMetrics;
import android.util.Log; import android.util.Log;
import android.util.TypedValue; import android.util.TypedValue;
import com.android.internal.util.XmlUtils; import com.android.internal.util.XmlUtils;
import com.reandroid.arsc.chunk.xml.ResXmlPullParser;
import com.reandroid.arsc.item.ResXmlString;
import java.util.Arrays; import java.util.Arrays;
/** /**
@@ -36,7 +39,7 @@ import java.util.Arrays;
*/ */
public class TypedArray { public class TypedArray {
private final Resources mResources; private final Resources mResources;
/*package*/ XmlBlock.Parser mXml; /*package*/ ResXmlPullParser mXml;
/*package*/ int[] mRsrcs; /*package*/ int[] mRsrcs;
/*package*/ int[] mData; /*package*/ int[] mData;
/*package*/ int[] mIndices; /*package*/ int[] mIndices;
@@ -153,9 +156,7 @@ public class TypedArray {
if (type == TypedValue.TYPE_STRING) { if (type == TypedValue.TYPE_STRING) {
final int cookie = data[index + AssetManager.STYLE_ASSET_COOKIE]; final int cookie = data[index + AssetManager.STYLE_ASSET_COOKIE];
if (cookie < 0) { if (cookie < 0) {
return mXml.getPooledString( return mXml.getResXmlDocument().getStringPool().get(data[index + AssetManager.STYLE_DATA]).get();
data[index + AssetManager.STYLE_DATA])
.toString();
} }
} }
return null; return null;
@@ -689,10 +690,13 @@ public class TypedArray {
final int cookie = data[index + AssetManager.STYLE_ASSET_COOKIE]; final int cookie = data[index + AssetManager.STYLE_ASSET_COOKIE];
if (cookie < 0) { if (cookie < 0) {
if (mXml != null) { if (mXml != null) {
return mXml.getPooledString( ResXmlString xmlString = mXml.getResXmlDocument().getStringPool().get(data[index + AssetManager.STYLE_DATA]);
data[index + AssetManager.STYLE_DATA]); if (xmlString != null)
return xmlString.get();
}
if (data[index + AssetManager.STYLE_RESOURCE_ID] != 0) {
return mResources.mAssets.getResourceText(data[index + AssetManager.STYLE_RESOURCE_ID]);
} }
return null;
} }
// System.out.println("Getting pooled from: " + v); // System.out.println("Getting pooled from: " + v);
return mResources.mAssets.getPooledString( return mResources.mAssets.getPooledString(