AssetManager: implement resolveAttrs

This commit is contained in:
Mis012
2025-01-02 22:18:45 +01:00
parent b56f42ec3d
commit 7d59407138
5 changed files with 116 additions and 10 deletions

View File

@@ -15,6 +15,18 @@
#include <glib.h> #include <glib.h>
#include <dirent.h> #include <dirent.h>
#define JAVA_ENUM_CLASS android_content_res_AssetManager
enum {
JAVA_ENUM(STYLE_TYPE),
JAVA_ENUM(STYLE_DATA),
JAVA_ENUM(STYLE_ASSET_COOKIE),
JAVA_ENUM(STYLE_RESOURCE_ID),
JAVA_ENUM(STYLE_CHANGING_CONFIGURATIONS),
JAVA_ENUM(STYLE_DENSITY),
JAVA_ENUM(STYLE_NUM_ENTRIES),
};
#undef JAVA_ENUM_CLASS
#define ASSET_DIR "assets/" #define ASSET_DIR "assets/"
char *get_app_data_dir(); char *get_app_data_dir();
@@ -259,6 +271,77 @@ JNIEXPORT jint JNICALL Java_android_content_res_AssetManager_loadThemeAttributeV
return block; return block;
} }
/* function ported from AOSP - Copyright 2006, The Android Open Source Project */
JNIEXPORT jboolean JNICALL Java_android_content_res_AssetManager_resolveAttrs(JNIEnv *env, jclass this,
jlong theme_ptr, jint def_style_attr,
jint def_style_res, jintArray java_values,
jintArray java_attrs, jintArray out_java_values,
jintArray out_java_indices)
{
struct Theme *theme = _PTR(theme_ptr);
const jsize attrs_len = (*env)->GetArrayLength(env, java_attrs);
const jsize out_values_len = (*env)->GetArrayLength(env, out_java_values);
if (out_values_len < (attrs_len * STYLE_NUM_ENTRIES)) {
(*env)->ThrowNew(env, (*env)->FindClass(env, "java/lang/IndexOutOfBoundsException"), "outValues too small");
return false;
}
jint *attrs = (jint *)(*env)->GetPrimitiveArrayCritical(env, java_attrs, NULL);
if (attrs == NULL) {
return true;
}
jint *values = NULL;
jsize values_len = 0;
if (java_values != NULL) {
values_len = (*env)->GetArrayLength(env, java_values);
values = (jint *)(*env)->GetPrimitiveArrayCritical(env, java_values, NULL);
if (values == NULL) {
(*env)->ReleasePrimitiveArrayCritical(env, java_attrs, attrs, JNI_ABORT);
return false;
}
}
jint *out_values = (jint *)(*env)->GetPrimitiveArrayCritical(env, out_java_values, NULL);
if (!out_values) {
(*env)->ReleasePrimitiveArrayCritical(env, java_attrs, attrs, JNI_ABORT);
if (values) {
(*env)->ReleasePrimitiveArrayCritical(env, java_values, values, JNI_ABORT);
}
return false;
}
jint *out_indices = NULL;
if (out_java_indices) {
jsize out_indices_len = (*env)->GetArrayLength(env, out_java_indices);
if (out_indices_len > attrs_len) {
out_indices = (jint *)(*env)->GetPrimitiveArrayCritical(env, out_java_indices, NULL);
if (!out_indices) {
(*env)->ReleasePrimitiveArrayCritical(env, java_attrs, attrs, JNI_ABORT);
if (values)
(*env)->ReleasePrimitiveArrayCritical(env, java_values, values, JNI_ABORT);
(*env)->ReleasePrimitiveArrayCritical(env, out_java_values, out_values, JNI_ABORT);
return false;
}
}
}
bool ret = ResolveAttrs(theme, def_style_attr, def_style_res,
(uint32_t *)values, values_len,
(uint32_t *)attrs, attrs_len,
(uint32_t *)out_values, (uint32_t *)out_indices);
if (out_indices)
(*env)->ReleasePrimitiveArrayCritical(env, out_java_indices, out_indices, 0);
(*env)->ReleasePrimitiveArrayCritical(env, out_java_values, out_values, 0);
if (values)
(*env)->ReleasePrimitiveArrayCritical(env, java_values, values, JNI_ABORT);
(*env)->ReleasePrimitiveArrayCritical(env, java_attrs, attrs, JNI_ABORT);
return ret;
}
JNIEXPORT jint JNICALL Java_android_content_res_AssetManager_getArraySize(JNIEnv *env, jobject this, jint ident) JNIEXPORT jint JNICALL Java_android_content_res_AssetManager_getArraySize(JNIEnv *env, jobject this, jint ident)
{ {
struct AssetManager *asset_manager = _PTR(_GET_LONG_FIELD(this, "mObject")); struct AssetManager *asset_manager = _PTR(_GET_LONG_FIELD(this, "mObject"));
@@ -283,10 +366,10 @@ JNIEXPORT jint JNICALL Java_android_content_res_AssetManager_retrieveArray(JNIEn
uint32_t resId = 0; uint32_t resId = 0;
ssize_t block = ResTable_resolveReference(res_table, &value, bag[i].stringBlock, &resId, NULL, NULL); ssize_t block = ResTable_resolveReference(res_table, &value, bag[i].stringBlock, &resId, NULL, NULL);
array[i*android_content_res_AssetManager_STYLE_NUM_ENTRIES + android_content_res_AssetManager_STYLE_TYPE] = value.dataType; array[i*STYLE_NUM_ENTRIES + STYLE_TYPE] = value.dataType;
array[i*android_content_res_AssetManager_STYLE_NUM_ENTRIES + android_content_res_AssetManager_STYLE_DATA] = value.data; array[i*STYLE_NUM_ENTRIES + STYLE_DATA] = value.data;
array[i*android_content_res_AssetManager_STYLE_NUM_ENTRIES + android_content_res_AssetManager_STYLE_ASSET_COOKIE] = block; array[i*STYLE_NUM_ENTRIES + STYLE_ASSET_COOKIE] = block;
array[i*android_content_res_AssetManager_STYLE_NUM_ENTRIES + android_content_res_AssetManager_STYLE_RESOURCE_ID] = resId; array[i*STYLE_NUM_ENTRIES + STYLE_RESOURCE_ID] = resId;
} }
ResTable_unlockBag(res_table, bag); ResTable_unlockBag(res_table, bag);

View File

@@ -40,6 +40,17 @@
#define _GET_BYTE_ARRAY_ELEMENTS(b_array) ((*env)->GetByteArrayElements(env, b_array, NULL)) #define _GET_BYTE_ARRAY_ELEMENTS(b_array) ((*env)->GetByteArrayElements(env, b_array, NULL))
#define _RELEASE_BYTE_ARRAY_ELEMENTS(b_array, buffer_ptr) ((*env)->ReleaseByteArrayElements(env, b_array, buffer_ptr, 0)) #define _RELEASE_BYTE_ARRAY_ELEMENTS(b_array, buffer_ptr) ((*env)->ReleaseByteArrayElements(env, b_array, buffer_ptr, 0))
// token pasting with macro expansion
#define __JOIN(x, y) x ## y
#define JOIN(x, y) __JOIN(x, y)
#define JOIN3(x, y, z) JOIN(JOIN(x, y), z)
// define enum member value to a value from autogenerated header
#define JAVA_ENUM(name) \
name = JOIN3(JAVA_ENUM_CLASS, _, name)
// this really doesn't belong here, should probably put this in Java and deal with ugly name convention of autogenerated headers // this really doesn't belong here, should probably put this in Java and deal with ugly name convention of autogenerated headers
#define MOTION_EVENT_ACTION_DOWN 0 #define MOTION_EVENT_ACTION_DOWN 0

View File

@@ -201,6 +201,14 @@ 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: resolveAttrs
* Signature: (JII[I[I[I[I)Z
*/
JNIEXPORT jboolean JNICALL Java_android_content_res_AssetManager_resolveAttrs
(JNIEnv *, jclass, jlong, jint, jint, jintArray, jintArray, jintArray, jintArray);
/* /*
* Class: android_content_res_AssetManager * Class: android_content_res_AssetManager
* Method: retrieveAttributes * Method: retrieveAttributes

View File

@@ -47,6 +47,7 @@ public class ActivityManager {
} }
public int getMemoryClass() {return 20;} // suggested heap size in MB public int getMemoryClass() {return 20;} // suggested heap size in MB
public int getLargeMemoryClass() {return 60;} // value chosen arbitrarily
public static void getMyMemoryState(RunningAppProcessInfo outInfo) {} public static void getMyMemoryState(RunningAppProcessInfo outInfo) {}
@@ -56,7 +57,7 @@ public class ActivityManager {
public List<ActivityManager.AppTask> getAppTasks() { public List<ActivityManager.AppTask> getAppTasks() {
return new ArrayList<>(); return new ArrayList<>();
} }
public static class RunningServiceInfo implements Parcelable { public static class RunningServiceInfo implements Parcelable {
public RunningServiceInfo() { public RunningServiceInfo() {
} }
@@ -72,7 +73,7 @@ public class ActivityManager {
public void readFromParcel(Parcel source) { public void readFromParcel(Parcel source) {
return; return;
} }
} }
public List<RunningServiceInfo> getRunningServices(int maxNum) public List<RunningServiceInfo> getRunningServices(int maxNum)
@@ -80,8 +81,6 @@ public class ActivityManager {
return new ArrayList<>(); return new ArrayList<>();
} }
public int getLargeMemoryClass() {return getMemoryClass();}
public List<ApplicationExitInfo> getHistoricalProcessExitReasons(String pkgname, int pid, int maxNum) { public List<ApplicationExitInfo> getHistoricalProcessExitReasons(String pkgname, int pid, int maxNum) {
return Collections.emptyList(); return Collections.emptyList();
} }

View File

@@ -812,8 +812,13 @@ public final class AssetManager {
} }
return true; return true;
} }
/*package*/ native final boolean retrieveAttributes(
int xmlParser, int[] inAttrs, int[] outValues, int[] outIndices); /*package*/ native static final boolean resolveAttrs(long theme, int defStyleAttr,
int defStyleRes, int[] inValues,
int[] inAttrs, int[] outValues,
int[] outIndices);
/*package*/ native final boolean retrieveAttributes(int xmlParser, int[] inAttrs,
int[] outValues, int[] outIndices);
/*package*/ native final int getArraySize(int resource); /*package*/ native final int getArraySize(int resource);
/*package*/ native final int retrieveArray(int resource, int[] outValues); /*package*/ native final int retrieveArray(int resource, int[] outValues);
private native final int getStringBlockCount(); private native final int getStringBlockCount();