mirror of
https://gitlab.com/android_translation_layer/android_translation_layer.git
synced 2025-04-28 20:27:58 +03:00
AssetManager: update to use v2 of libandroidfw C api
This commit is contained in:
parent
ca39c81224
commit
d97c3ee048
3 changed files with 179 additions and 143 deletions
|
@ -27,6 +27,9 @@ enum {
|
||||||
};
|
};
|
||||||
#undef JAVA_ENUM_CLASS
|
#undef JAVA_ENUM_CLASS
|
||||||
|
|
||||||
|
#define JAVA_COOKIE(cookie) (cookie != -1 ? (jint)(cookie + 1) : -1)
|
||||||
|
#define NATIVE_COOKIE(cookie) (cookie != -1 ? (ApkAssetsCookie)(cookie - 1) : -1)
|
||||||
|
|
||||||
#define ASSET_DIR "assets/"
|
#define ASSET_DIR "assets/"
|
||||||
char *get_app_data_dir();
|
char *get_app_data_dir();
|
||||||
|
|
||||||
|
@ -114,37 +117,48 @@ JNIEXPORT void JNICALL Java_android_content_res_AssetManager_init(JNIEnv *env, j
|
||||||
.density = /*ACONFIGURATION_DENSITY_MEDIUM*/ 160,
|
.density = /*ACONFIGURATION_DENSITY_MEDIUM*/ 160,
|
||||||
.sdkVersion = 24,
|
.sdkVersion = 24,
|
||||||
};
|
};
|
||||||
AssetManager_setConfiguration(asset_manager, &config, NULL);
|
AssetManager_setConfiguration(asset_manager, &config);
|
||||||
_SET_LONG_FIELD(this, "mObject", _INTPTR(asset_manager));
|
_SET_LONG_FIELD(this, "mObject", _INTPTR(asset_manager));
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jint JNICALL Java_android_content_res_AssetManager_addAssetPathNative(JNIEnv *env, jobject this, jstring path)
|
JNIEXPORT void JNICALL Java_android_content_res_AssetManager_native_1setApkAssets(JNIEnv *env, jobject this, jobjectArray paths, int num_assets)
|
||||||
{
|
{
|
||||||
int32_t cookie;
|
|
||||||
struct AssetManager *asset_manager = _PTR(_GET_LONG_FIELD(this, "mObject"));
|
struct AssetManager *asset_manager = _PTR(_GET_LONG_FIELD(this, "mObject"));
|
||||||
AssetManager_addAssetPath(asset_manager, _CSTRING(path), &cookie, false, false);
|
const struct ApkAssets* apk_assets[num_assets];
|
||||||
return cookie;
|
for (int i = 0; i < num_assets; i++) {
|
||||||
|
jstring path_jstr = (jstring)((*env)->GetObjectArrayElement(env, paths, i));
|
||||||
|
const char *path = (*env)->GetStringUTFChars(env, path_jstr, NULL);
|
||||||
|
if(path[strlen(path) - 1] == '/')
|
||||||
|
apk_assets[i] = ApkAssets_loadDir(strdup(path));
|
||||||
|
else
|
||||||
|
apk_assets[i] = ApkAssets_load(strdup(path), false);
|
||||||
|
(*env)->ReleaseStringUTFChars(env, path_jstr, path);
|
||||||
|
}
|
||||||
|
AssetManager_setApkAssets(asset_manager, apk_assets, num_assets, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jint JNICALL Java_android_content_res_AssetManager_loadResourceValue(JNIEnv *env, jobject this, jint ident, jshort density, jobject outValue, jboolean resolve)
|
JNIEXPORT jint JNICALL Java_android_content_res_AssetManager_loadResourceValue(JNIEnv *env, jobject this, jint ident, jshort density, jobject outValue, jboolean resolve)
|
||||||
{
|
{
|
||||||
struct AssetManager *asset_manager = _PTR(_GET_LONG_FIELD(this, "mObject"));
|
struct AssetManager *asset_manager = _PTR(_GET_LONG_FIELD(this, "mObject"));
|
||||||
const struct ResTable *res_table = AssetManager_getResources(asset_manager, true);
|
|
||||||
uint32_t resId = ident;
|
uint32_t resId = ident;
|
||||||
struct Res_value value;
|
struct Res_value value;
|
||||||
uint32_t outSpecFlags;
|
uint32_t outSpecFlags;
|
||||||
struct ResTable_config outConfig;
|
struct ResTable_config outConfig;
|
||||||
ssize_t block = ResTable_getResource(res_table, resId, &value, false, density, &outSpecFlags, &outConfig);
|
uint32_t ref;
|
||||||
|
ApkAssetsCookie cookie = AssetManager_getResource(asset_manager, resId, false, density,
|
||||||
|
&value, &outConfig, &outSpecFlags);
|
||||||
if (resolve) {
|
if (resolve) {
|
||||||
block = ResTable_resolveReference(res_table, &value, block, &resId, &outSpecFlags, &outConfig);
|
cookie = AssetManager_resolveReference(asset_manager, cookie,
|
||||||
|
&value, &outConfig,
|
||||||
|
&outSpecFlags, &ref);
|
||||||
}
|
}
|
||||||
if (block >= 0) {
|
if (cookie >= 0) {
|
||||||
_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);
|
_SET_INT_FIELD(outValue, "assetCookie", JAVA_COOKIE(cookie));
|
||||||
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 = AssetManager_getStringPoolForCookie(asset_manager, cookie);
|
||||||
size_t len;
|
size_t len;
|
||||||
const char16_t *string = ResStringPool_stringAt(string_pool, value.data, &len);
|
const char16_t *string = ResStringPool_stringAt(string_pool, value.data, &len);
|
||||||
_SET_OBJ_FIELD(outValue, "string", "Ljava/lang/CharSequence;", (*env)->NewString(env, string, len));
|
_SET_OBJ_FIELD(outValue, "string", "Ljava/lang/CharSequence;", (*env)->NewString(env, string, len));
|
||||||
|
@ -152,22 +166,25 @@ JNIEXPORT jint JNICALL Java_android_content_res_AssetManager_loadResourceValue(J
|
||||||
_SET_OBJ_FIELD(outValue, "string", "Ljava/lang/CharSequence;", NULL);
|
_SET_OBJ_FIELD(outValue, "string", "Ljava/lang/CharSequence;", NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return block;
|
return JAVA_COOKIE(cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jobjectArray JNICALL Java_android_content_res_AssetManager_getArrayStringResource(JNIEnv *env, jobject this, jint ident)
|
JNIEXPORT jobjectArray JNICALL Java_android_content_res_AssetManager_getArrayStringResource(JNIEnv *env, jobject this, jint ident)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
struct AssetManager *asset_manager = _PTR(_GET_LONG_FIELD(this, "mObject"));
|
struct AssetManager *asset_manager = _PTR(_GET_LONG_FIELD(this, "mObject"));
|
||||||
const struct ResTable *res_table = AssetManager_getResources(asset_manager, true);
|
const struct ResolvedBag* bag = AssetManager_getBag(asset_manager, ident);
|
||||||
const struct bag_entry *bag;
|
jobjectArray array = (*env)->NewObjectArray(env, bag->entry_count, (*env)->FindClass(env, "java/lang/String"), NULL);
|
||||||
int bag_count = ResTable_lockBag(res_table, ident, &bag);
|
for (int i = 0; i < bag->entry_count; i++) {
|
||||||
jobjectArray array = (*env)->NewObjectArray(env, bag_count, (*env)->FindClass(env, "java/lang/String"), NULL);
|
const struct ResolvedBag_Entry entry = bag->entries[i];
|
||||||
for (i = 0; i < bag_count; i++) {
|
struct Res_value value = entry.value;
|
||||||
struct Res_value value = bag[i].map.value;
|
struct ResTable_config outConfig;
|
||||||
ssize_t block = ResTable_resolveReference(res_table, &value, bag[i].stringBlock, NULL, NULL, NULL);
|
uint32_t outSpecFlags;
|
||||||
|
uint32_t ref;
|
||||||
|
ApkAssetsCookie cookie = AssetManager_resolveReference(asset_manager, entry.cookie,
|
||||||
|
&value, &outConfig,
|
||||||
|
&outSpecFlags, &ref);
|
||||||
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 = AssetManager_getStringPoolForCookie(asset_manager, cookie);
|
||||||
if (string_pool == NULL)
|
if (string_pool == NULL)
|
||||||
continue;
|
continue;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
@ -176,49 +193,38 @@ JNIEXPORT jobjectArray JNICALL Java_android_content_res_AssetManager_getArrayStr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ResTable_unlockBag(res_table, bag);
|
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jint JNICALL Java_android_content_res_AssetManager_getResourceIdentifier(JNIEnv *env, jobject this, jstring name, jstring defType, jstring defPackage)
|
JNIEXPORT jint JNICALL Java_android_content_res_AssetManager_getResourceIdentifier(JNIEnv *env, jobject this, jstring name_jstr, jstring type_jstr, jstring package_jstr)
|
||||||
{
|
{
|
||||||
const char16_t *name16 = NULL;
|
const char *name = "";
|
||||||
const char16_t *defType16 = NULL;
|
const char *type = "";
|
||||||
const char16_t *defPackage16 = NULL;
|
const char *package = "";
|
||||||
int name_len = 0;
|
uint32_t ret;
|
||||||
int defType_len = 0;
|
|
||||||
int defPackage_len = 0;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
struct AssetManager *asset_manager = _PTR(_GET_LONG_FIELD(this, "mObject"));
|
struct AssetManager *asset_manager = _PTR(_GET_LONG_FIELD(this, "mObject"));
|
||||||
const struct ResTable *res_table = AssetManager_getResources(asset_manager, true);
|
if (name_jstr)
|
||||||
if (name) {
|
name = (*env)->GetStringUTFChars(env, name_jstr, NULL);
|
||||||
name16 = (*env)->GetStringChars(env, name, NULL);
|
if (type_jstr)
|
||||||
name_len = (*env)->GetStringLength(env, name);
|
type = (*env)->GetStringUTFChars(env, type_jstr, NULL);
|
||||||
}
|
if (package_jstr)
|
||||||
if (defType) {
|
package = (*env)->GetStringUTFChars(env, package_jstr, NULL);
|
||||||
defType16 = (*env)->GetStringChars(env, defType, NULL);
|
|
||||||
defType_len = (*env)->GetStringLength(env, defType);
|
ret = AssetManager_getResourceId(asset_manager, name, type, package);
|
||||||
}
|
if (name_jstr)
|
||||||
if (defPackage) {
|
(*env)->ReleaseStringUTFChars(env, name_jstr, name);
|
||||||
defPackage16 = (*env)->GetStringChars(env, defPackage, NULL);
|
if (type_jstr)
|
||||||
defPackage_len = (*env)->GetStringLength(env, defPackage);
|
(*env)->ReleaseStringUTFChars(env, type_jstr, type);
|
||||||
}
|
if (package_jstr)
|
||||||
ret = ResTable_identifierForName(res_table, name16, name_len, defType16, defType_len, defPackage16, defPackage_len, NULL);
|
(*env)->ReleaseStringUTFChars(env, package_jstr, package);
|
||||||
if (name)
|
|
||||||
(*env)->ReleaseStringChars(env, name, name16);
|
|
||||||
if (defType)
|
|
||||||
(*env)->ReleaseStringChars(env, defType, defType16);
|
|
||||||
if (defPackage)
|
|
||||||
(*env)->ReleaseStringChars(env, defPackage, defPackage16);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jobject JNICALL Java_android_content_res_AssetManager_getPooledString(JNIEnv *env, jobject this, jint block, jint index)
|
JNIEXPORT jobject JNICALL Java_android_content_res_AssetManager_getPooledString(JNIEnv *env, jobject this, jint cookie, jint index)
|
||||||
{
|
{
|
||||||
struct AssetManager *asset_manager = _PTR(_GET_LONG_FIELD(this, "mObject"));
|
struct AssetManager *asset_manager = _PTR(_GET_LONG_FIELD(this, "mObject"));
|
||||||
const struct ResTable *res_table = AssetManager_getResources(asset_manager, true);
|
const struct ResStringPool *string_pool = AssetManager_getStringPoolForCookie(asset_manager, NATIVE_COOKIE(cookie));
|
||||||
const struct ResStringPool *string_pool = ResTable_getTableStringBlock(res_table, block);
|
|
||||||
size_t len;
|
size_t len;
|
||||||
const char16_t *string = ResStringPool_stringAt(string_pool, index, &len);
|
const char16_t *string = ResStringPool_stringAt(string_pool, index, &len);
|
||||||
return (*env)->NewString(env, string, len);
|
return (*env)->NewString(env, string, len);
|
||||||
|
@ -227,7 +233,7 @@ JNIEXPORT jobject JNICALL Java_android_content_res_AssetManager_getPooledString(
|
||||||
JNIEXPORT jlong JNICALL Java_android_content_res_AssetManager_newTheme(JNIEnv *env, jobject this)
|
JNIEXPORT jlong JNICALL Java_android_content_res_AssetManager_newTheme(JNIEnv *env, jobject this)
|
||||||
{
|
{
|
||||||
struct AssetManager *asset_manager = _PTR(_GET_LONG_FIELD(this, "mObject"));
|
struct AssetManager *asset_manager = _PTR(_GET_LONG_FIELD(this, "mObject"));
|
||||||
struct Theme *theme = Theme_new(AssetManager_getResources(asset_manager, true));
|
struct Theme *theme = AssetManager_newTheme(asset_manager);
|
||||||
return _INTPTR(theme);
|
return _INTPTR(theme);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,23 +250,24 @@ JNIEXPORT void JNICALL Java_android_content_res_AssetManager_applyThemeStyle(JNI
|
||||||
JNIEXPORT jint JNICALL Java_android_content_res_AssetManager_loadThemeAttributeValue(JNIEnv *env, jobject this, jlong theme_ptr, jint ident, jobject outValue, jboolean resolve)
|
JNIEXPORT jint JNICALL Java_android_content_res_AssetManager_loadThemeAttributeValue(JNIEnv *env, jobject this, jlong theme_ptr, jint ident, jobject outValue, jboolean resolve)
|
||||||
{
|
{
|
||||||
struct AssetManager *asset_manager = _PTR(_GET_LONG_FIELD(this, "mObject"));
|
struct AssetManager *asset_manager = _PTR(_GET_LONG_FIELD(this, "mObject"));
|
||||||
const struct ResTable *res_table = AssetManager_getResources(asset_manager, true);
|
|
||||||
struct Theme *theme = _PTR(theme_ptr);
|
struct Theme *theme = _PTR(theme_ptr);
|
||||||
uint32_t resId = 0;
|
|
||||||
struct Res_value value;
|
struct Res_value value;
|
||||||
uint32_t outSpecFlags;
|
uint32_t outSpecFlags;
|
||||||
struct ResTable_config outConfig;
|
struct ResTable_config outConfig;
|
||||||
int block = Theme_getAttribute(theme, ident, &value, &outSpecFlags);
|
uint32_t ref;
|
||||||
|
int cookie = Theme_getAttribute(theme, ident, &value, &outSpecFlags);
|
||||||
if (resolve) {
|
if (resolve) {
|
||||||
block = Theme_resolveAttributeReference(theme, &value, block, &resId, &outSpecFlags, &outConfig);
|
cookie = AssetManager_resolveReference(asset_manager, cookie,
|
||||||
|
&value, &outConfig,
|
||||||
|
&outSpecFlags, &ref);
|
||||||
}
|
}
|
||||||
if (block >= 0) {
|
if (cookie >= 0) {
|
||||||
_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", ref);
|
||||||
_SET_INT_FIELD(outValue, "assetCookie", block);
|
_SET_INT_FIELD(outValue, "assetCookie", JAVA_COOKIE(cookie));
|
||||||
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 = AssetManager_getStringPoolForCookie(asset_manager, cookie);
|
||||||
size_t len;
|
size_t len;
|
||||||
const char16_t *string = ResStringPool_stringAt(string_pool, value.data, &len);
|
const char16_t *string = ResStringPool_stringAt(string_pool, value.data, &len);
|
||||||
_SET_OBJ_FIELD(outValue, "string", "Ljava/lang/CharSequence;", (*env)->NewString(env, string, len));
|
_SET_OBJ_FIELD(outValue, "string", "Ljava/lang/CharSequence;", (*env)->NewString(env, string, len));
|
||||||
|
@ -268,7 +275,7 @@ JNIEXPORT jint JNICALL Java_android_content_res_AssetManager_loadThemeAttributeV
|
||||||
_SET_OBJ_FIELD(outValue, "string", "Ljava/lang/CharSequence;", NULL);
|
_SET_OBJ_FIELD(outValue, "string", "Ljava/lang/CharSequence;", NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return block;
|
return JAVA_COOKIE(cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* function ported from AOSP - Copyright 2006, The Android Open Source Project */
|
/* function ported from AOSP - Copyright 2006, The Android Open Source Project */
|
||||||
|
@ -345,86 +352,120 @@ JNIEXPORT jboolean JNICALL Java_android_content_res_AssetManager_resolveAttrs(JN
|
||||||
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"));
|
||||||
const struct ResTable *res_table = AssetManager_getResources(asset_manager, true);
|
const struct ResolvedBag* bag = AssetManager_getBag(asset_manager, ident);
|
||||||
const struct bag_entry *bag;
|
return bag->entry_count;
|
||||||
int bag_count = ResTable_lockBag(res_table, ident, &bag);
|
|
||||||
ResTable_unlockBag(res_table, bag);
|
|
||||||
return bag_count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jint JNICALL Java_android_content_res_AssetManager_retrieveArray(JNIEnv *env, jobject this, jint ident, jintArray outArray)
|
JNIEXPORT jint JNICALL Java_android_content_res_AssetManager_retrieveArray(JNIEnv *env, jobject this, jint ident, jintArray outArray)
|
||||||
{
|
{
|
||||||
struct AssetManager *asset_manager = _PTR(_GET_LONG_FIELD(this, "mObject"));
|
struct AssetManager *asset_manager = _PTR(_GET_LONG_FIELD(this, "mObject"));
|
||||||
const struct ResTable *res_table = AssetManager_getResources(asset_manager, true);
|
|
||||||
const struct bag_entry *bag;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
jint *array = (*env)->GetIntArrayElements(env, outArray, NULL);
|
jint *array = (*env)->GetIntArrayElements(env, outArray, NULL);
|
||||||
int bag_count = ResTable_lockBag(res_table, ident, &bag);
|
const struct ResolvedBag* bag = AssetManager_getBag(asset_manager, ident);
|
||||||
for (i = 0; i < bag_count; i++) {
|
for (int i = 0; i < bag->entry_count; i++) {
|
||||||
struct Res_value value = bag[i].map.value;
|
const struct ResolvedBag_Entry entry = bag->entries[i];
|
||||||
uint32_t resId = 0;
|
struct Res_value value = entry.value;
|
||||||
ssize_t block = ResTable_resolveReference(res_table, &value, bag[i].stringBlock, &resId, NULL, NULL);
|
struct ResTable_config outConfig;
|
||||||
|
uint32_t outSpecFlags;
|
||||||
|
uint32_t ref;
|
||||||
|
ApkAssetsCookie cookie = AssetManager_resolveReference(asset_manager, entry.cookie,
|
||||||
|
&value, &outConfig,
|
||||||
|
&outSpecFlags, &ref);
|
||||||
|
|
||||||
array[i*STYLE_NUM_ENTRIES + STYLE_TYPE] = value.dataType;
|
array[i*STYLE_NUM_ENTRIES + STYLE_TYPE] = value.dataType;
|
||||||
array[i*STYLE_NUM_ENTRIES + STYLE_DATA] = value.data;
|
array[i*STYLE_NUM_ENTRIES + STYLE_DATA] = value.data;
|
||||||
array[i*STYLE_NUM_ENTRIES + STYLE_ASSET_COOKIE] = block;
|
array[i*STYLE_NUM_ENTRIES + STYLE_ASSET_COOKIE] = JAVA_COOKIE(cookie);
|
||||||
array[i*STYLE_NUM_ENTRIES + STYLE_RESOURCE_ID] = resId;
|
array[i*STYLE_NUM_ENTRIES + STYLE_RESOURCE_ID] = ref;
|
||||||
|
|
||||||
}
|
}
|
||||||
ResTable_unlockBag(res_table, bag);
|
|
||||||
(*env)->ReleaseIntArrayElements(env, outArray, array, 0);
|
(*env)->ReleaseIntArrayElements(env, outArray, array, 0);
|
||||||
return bag_count;
|
return bag->entry_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jstring JNICALL Java_android_content_res_AssetManager_getResourceName(JNIEnv *env, jobject this, jint ident)
|
||||||
|
{
|
||||||
|
struct AssetManager *asset_manager = _PTR(_GET_LONG_FIELD(this, "mObject"));
|
||||||
|
struct resource_name res_name;
|
||||||
|
gchar *type8 = NULL;
|
||||||
|
gchar *entry8 = NULL;
|
||||||
|
bool ret = AssetManager_getResourceName(asset_manager, ident, &res_name);
|
||||||
|
if(!ret)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if(!res_name.type)
|
||||||
|
type8 = g_utf16_to_utf8(res_name.type16, res_name.type_len, NULL, NULL, NULL);
|
||||||
|
if(!res_name.entry)
|
||||||
|
entry8 = g_utf16_to_utf8(res_name.entry16, res_name.entry_len, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
gchar *result = g_strdup_printf("%.*s:%.*s/%.*s",
|
||||||
|
res_name.package ? (int)res_name.package_len : 0,
|
||||||
|
res_name.package ?: "",
|
||||||
|
(res_name.type || type8) ? (int)res_name.type_len : 0,
|
||||||
|
res_name.type ?: type8 ?: "",
|
||||||
|
(res_name.entry || entry8) ? (int)res_name.entry_len : 0,
|
||||||
|
res_name.entry ?: entry8 ?: "");
|
||||||
|
jstring result_jstr = _JSTRING(result);
|
||||||
|
free(result);
|
||||||
|
return result_jstr;
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jstring JNICALL Java_android_content_res_AssetManager_getResourcePackageName(JNIEnv *env, jobject this, jint ident)
|
JNIEXPORT jstring JNICALL Java_android_content_res_AssetManager_getResourcePackageName(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"));
|
||||||
const struct ResTable *res_table = AssetManager_getResources(asset_manager, true);
|
|
||||||
struct resource_name res_name;
|
struct resource_name res_name;
|
||||||
bool ret = ResTable_getResourceName(res_table, ident, false, &res_name);
|
bool ret = AssetManager_getResourceName(asset_manager, ident, &res_name);
|
||||||
return (ret && res_name.package) ? (*env)->NewString(env, res_name.package, res_name.packageLen) : NULL;
|
return (ret && res_name.package) ? (*env)->NewStringUTF(env, res_name.package) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jstring JNICALL Java_android_content_res_AssetManager_getResourceTypeName(JNIEnv *env, jobject this, jint ident)
|
JNIEXPORT jstring JNICALL Java_android_content_res_AssetManager_getResourceTypeName(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"));
|
||||||
const struct ResTable *res_table = AssetManager_getResources(asset_manager, true);
|
|
||||||
struct resource_name res_name;
|
struct resource_name res_name;
|
||||||
bool ret = ResTable_getResourceName(res_table, ident, false, &res_name);
|
bool ret = AssetManager_getResourceName(asset_manager, ident, &res_name);
|
||||||
return (ret && res_name.type) ? (*env)->NewString(env, res_name.type, res_name.typeLen) : NULL;
|
if(!ret)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return res_name.type ? (*env)->NewStringUTF(env, res_name.type) :
|
||||||
|
res_name.type16 ? (*env)->NewString(env, res_name.type16, res_name.type_len) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jstring JNICALL Java_android_content_res_AssetManager_getResourceEntryName(JNIEnv *env, jobject this, jint ident)
|
JNIEXPORT jstring JNICALL Java_android_content_res_AssetManager_getResourceEntryName(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"));
|
||||||
const struct ResTable *res_table = AssetManager_getResources(asset_manager, true);
|
|
||||||
struct resource_name res_name;
|
struct resource_name res_name;
|
||||||
bool ret = ResTable_getResourceName(res_table, ident, false, &res_name);
|
bool ret = AssetManager_getResourceName(asset_manager, ident, &res_name);
|
||||||
return (ret && res_name.name) ? (*env)->NewString(env, res_name.name, res_name.nameLen) : NULL;
|
if(!ret)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return res_name.entry ? (*env)->NewStringUTF(env, res_name.entry) :
|
||||||
|
res_name.entry16 ? (*env)->NewString(env, res_name.entry16, res_name.entry_len) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jint JNICALL Java_android_content_res_AssetManager_loadResourceBagValue(JNIEnv *env, jobject this, jint ident, jint bagEntryId, jobject outValue, jboolean resolve)
|
JNIEXPORT jint JNICALL Java_android_content_res_AssetManager_loadResourceBagValue(JNIEnv *env, jobject this, jint ident, jint bagEntryId, jobject outValue, jboolean resolve)
|
||||||
{
|
{
|
||||||
struct AssetManager *asset_manager = _PTR(_GET_LONG_FIELD(this, "mObject"));
|
struct AssetManager *asset_manager = _PTR(_GET_LONG_FIELD(this, "mObject"));
|
||||||
const struct ResTable *res_table = AssetManager_getResources(asset_manager, true);
|
ApkAssetsCookie cookie = -1;
|
||||||
const struct bag_entry *bag;
|
|
||||||
int i;
|
|
||||||
ssize_t block = -1;
|
|
||||||
|
|
||||||
int bag_count = ResTable_lockBag(res_table, ident, &bag);
|
const struct ResolvedBag* bag = AssetManager_getBag(asset_manager, ident);
|
||||||
for (i = 0; i < bag_count; i++) {
|
if(!bag)
|
||||||
if (bag[i].map.name.ident == bagEntryId) {
|
return -1;
|
||||||
struct Res_value value = bag[i].map.value;
|
for (int i = 0; i < bag->entry_count; i++) {
|
||||||
uint32_t resId = 0;
|
const struct ResolvedBag_Entry entry = bag->entries[i];
|
||||||
block = ResTable_resolveReference(res_table, &value, bag[i].stringBlock, &resId, NULL, NULL);
|
if (entry.key == bagEntryId) {
|
||||||
|
struct Res_value value = entry.value;
|
||||||
|
struct ResTable_config outConfig;
|
||||||
|
uint32_t outSpecFlags;
|
||||||
|
uint32_t ref;
|
||||||
|
cookie = AssetManager_resolveReference(asset_manager, entry.cookie,
|
||||||
|
&value, &outConfig,
|
||||||
|
&outSpecFlags, &ref);
|
||||||
|
|
||||||
_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", ref);
|
||||||
_SET_INT_FIELD(outValue, "assetCookie", block);
|
_SET_INT_FIELD(outValue, "assetCookie", JAVA_COOKIE(cookie));
|
||||||
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 = AssetManager_getStringPoolForCookie(asset_manager, cookie);
|
||||||
size_t len;
|
size_t len;
|
||||||
const char16_t *string = ResStringPool_stringAt(string_pool, value.data, &len);
|
const char16_t *string = ResStringPool_stringAt(string_pool, value.data, &len);
|
||||||
_SET_OBJ_FIELD(outValue, "string", "Ljava/lang/CharSequence;", (*env)->NewString(env, string, len));
|
_SET_OBJ_FIELD(outValue, "string", "Ljava/lang/CharSequence;", (*env)->NewString(env, string, len));
|
||||||
|
@ -435,8 +476,7 @@ JNIEXPORT jint JNICALL Java_android_content_res_AssetManager_loadResourceBagValu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ResTable_unlockBag(res_table, bag);
|
return JAVA_COOKIE(cookie);
|
||||||
return block;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_android_content_res_AssetManager_copyTheme(JNIEnv *env, jclass class, jlong dest, jlong src)
|
JNIEXPORT void JNICALL Java_android_content_res_AssetManager_copyTheme(JNIEnv *env, jclass class, jlong dest, jlong src)
|
||||||
|
@ -469,7 +509,7 @@ JNIEXPORT void JNICALL Java_android_content_res_AssetManager_setConfiguration(
|
||||||
.uiMode = uiMode,
|
.uiMode = uiMode,
|
||||||
.sdkVersion = majorVersion
|
.sdkVersion = majorVersion
|
||||||
};
|
};
|
||||||
AssetManager_setConfiguration(asset_manager, &config, NULL);
|
AssetManager_setConfiguration(asset_manager, &config);
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jobjectArray JNICALL Java_android_content_res_AssetManager_list(JNIEnv *env, jobject this, jstring _path)
|
JNIEXPORT jobjectArray JNICALL Java_android_content_res_AssetManager_list(JNIEnv *env, jobject this, jstring _path)
|
||||||
|
@ -528,7 +568,7 @@ JNIEXPORT jlong JNICALL Java_android_content_res_AssetManager_openXmlAssetNative
|
||||||
JNIEXPORT jobjectArray JNICALL Java_android_content_res_AssetManager_getLocales(JNIEnv *env, jobject this)
|
JNIEXPORT jobjectArray JNICALL Java_android_content_res_AssetManager_getLocales(JNIEnv *env, jobject this)
|
||||||
{
|
{
|
||||||
struct AssetManager *asset_manager = _PTR(_GET_LONG_FIELD(this, "mObject"));
|
struct AssetManager *asset_manager = _PTR(_GET_LONG_FIELD(this, "mObject"));
|
||||||
char **locales = AssetManager_getLocales(asset_manager, true);
|
char **locales = AssetManager_getLocales(asset_manager, false, true);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (locales[i] != NULL) i++;
|
while (locales[i] != NULL) i++;
|
||||||
jobjectArray array = (*env)->NewObjectArray(env, i, (*env)->FindClass(env, "java/lang/String"), NULL);
|
jobjectArray array = (*env)->NewObjectArray(env, i, (*env)->FindClass(env, "java/lang/String"), NULL);
|
||||||
|
|
|
@ -97,6 +97,14 @@ JNIEXPORT void JNICALL Java_android_content_res_AssetManager_setConfiguration
|
||||||
JNIEXPORT jint JNICALL Java_android_content_res_AssetManager_getResourceIdentifier
|
JNIEXPORT jint JNICALL Java_android_content_res_AssetManager_getResourceIdentifier
|
||||||
(JNIEnv *, jobject, jstring, jstring, jstring);
|
(JNIEnv *, jobject, jstring, jstring, jstring);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
@ -353,6 +361,14 @@ JNIEXPORT jintArray JNICALL Java_android_content_res_AssetManager_getArrayString
|
||||||
JNIEXPORT void JNICALL Java_android_content_res_AssetManager_init
|
JNIEXPORT void JNICALL Java_android_content_res_AssetManager_init
|
||||||
(JNIEnv *, jobject);
|
(JNIEnv *, jobject);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: android_content_res_AssetManager
|
||||||
|
* Method: native_setApkAssets
|
||||||
|
* Signature: ([Ljava/lang/Object;I)V
|
||||||
|
*/
|
||||||
|
JNIEXPORT void JNICALL Java_android_content_res_AssetManager_native_1setApkAssets
|
||||||
|
(JNIEnv *, jobject, jobjectArray, jint);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -21,6 +21,7 @@ import android.os.Environment;
|
||||||
import android.os.ParcelFileDescriptor;
|
import android.os.ParcelFileDescriptor;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.util.Slog;
|
||||||
import android.util.TypedValue;
|
import android.util.TypedValue;
|
||||||
|
|
||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
|
@ -91,6 +92,9 @@ public final class AssetManager {
|
||||||
private boolean mOpen = true;
|
private boolean mOpen = true;
|
||||||
private HashMap<Integer, RuntimeException> mRefStacks;
|
private HashMap<Integer, RuntimeException> mRefStacks;
|
||||||
|
|
||||||
|
private ArrayList<String> asset_paths = new ArrayList<String>();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new AssetManager containing only the basic system assets.
|
* Create a new AssetManager containing only the basic system assets.
|
||||||
* Applications will not generally use this method, instead retrieving the
|
* Applications will not generally use this method, instead retrieving the
|
||||||
|
@ -99,7 +103,6 @@ public final class AssetManager {
|
||||||
* {@hide}
|
* {@hide}
|
||||||
*/
|
*/
|
||||||
public AssetManager() {
|
public AssetManager() {
|
||||||
// FIXME: evaluate if this can be axed
|
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
if (DEBUG_REFS) {
|
if (DEBUG_REFS) {
|
||||||
mNumRefs = 0;
|
mNumRefs = 0;
|
||||||
|
@ -124,13 +127,15 @@ public final class AssetManager {
|
||||||
for (String path : paths) {
|
for (String path : paths) {
|
||||||
if (path != null) {
|
if (path != null) {
|
||||||
path = path.substring(path.indexOf("file:") + 5, path.indexOf("!/AndroidManifest.xml"));
|
path = path.substring(path.indexOf("file:") + 5, path.indexOf("!/AndroidManifest.xml"));
|
||||||
addAssetPath(path);
|
asset_paths.add(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Log.e(TAG, "failed to load resources.arsc" + e);
|
Log.e(TAG, "failed to load resources.arsc" + e);
|
||||||
}
|
}
|
||||||
addAssetPath(android.os.Environment.getExternalStorageDirectory().getAbsolutePath());
|
asset_paths.add(android.os.Environment.getExternalStorageDirectory().getAbsolutePath() + "/");
|
||||||
|
/*String*/Object[] asset_paths_arr = asset_paths.toArray();
|
||||||
|
native_setApkAssets(asset_paths_arr, asset_paths_arr.length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -598,33 +603,15 @@ public final class AssetManager {
|
||||||
* the cookie of the added asset, or 0 on failure.
|
* the cookie of the added asset, or 0 on failure.
|
||||||
* {@hide}
|
* {@hide}
|
||||||
*/
|
*/
|
||||||
public final int addAssetPath(String path) {
|
/* this is not particularly efficient, avoid if possible */
|
||||||
int res = addAssetPathNative(path);
|
public final void addAssetPath(String path) {
|
||||||
return res;
|
asset_paths.add(path);
|
||||||
|
/*String*/Object[] asset_paths_arr = asset_paths.toArray();
|
||||||
|
native_setApkAssets(asset_paths_arr, asset_paths_arr.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
private native final int addAssetPathNative(String path);
|
private native final int addAssetPathNative(String path);
|
||||||
|
|
||||||
/**
|
|
||||||
* Add multiple sets of assets to the asset manager at once. See
|
|
||||||
* {@link #addAssetPath(String)} for more information. Returns array of
|
|
||||||
* cookies for each added asset with 0 indicating failure, or null if
|
|
||||||
* the input array of paths is null.
|
|
||||||
* {@hide}
|
|
||||||
*/
|
|
||||||
public final int[] addAssetPaths(String[] paths) {
|
|
||||||
if (paths == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
int[] cookies = new int[paths.length];
|
|
||||||
for (int i = 0; i < paths.length; i++) {
|
|
||||||
cookies[i] = addAssetPath(paths[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return cookies;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void extractFromAPK(String path, String target) throws IOException {
|
public static void extractFromAPK(String path, String target) throws IOException {
|
||||||
if (path.endsWith("/")) { // directory
|
if (path.endsWith("/")) { // directory
|
||||||
try (JarFile apk = new JarFile(Context.this_application.getPackageCodePath())) {
|
try (JarFile apk = new JarFile(Context.this_application.getPackageCodePath())) {
|
||||||
|
@ -685,16 +672,7 @@ public final class AssetManager {
|
||||||
*/
|
*/
|
||||||
/*package*/ native final int getResourceIdentifier(String name, String type, String defPackage);
|
/*package*/ native final int getResourceIdentifier(String name, String type, String defPackage);
|
||||||
|
|
||||||
public /*native*/ final String getResourceName(int resid) {
|
public native final String getResourceName(int resid);
|
||||||
String name = getResourcePackageName(resid);
|
|
||||||
String type = getResourceTypeName(resid);
|
|
||||||
if (type != null)
|
|
||||||
name += ':' + type;
|
|
||||||
String entry = getResourceEntryName(resid);
|
|
||||||
if (entry != null)
|
|
||||||
name += '/' + entry;
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
/*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);
|
||||||
/*package*/ native final String getResourceEntryName(int resid);
|
/*package*/ native final String getResourceEntryName(int resid);
|
||||||
|
@ -872,7 +850,7 @@ public final class AssetManager {
|
||||||
|
|
||||||
private native final void init();
|
private native final void init();
|
||||||
private /*native*/ final void destroy() {
|
private /*native*/ final void destroy() {
|
||||||
System.out.println("AssetManager.destroy(): STUB");
|
Slog.w(TAG, "AssetManager.destroy(): STUB");
|
||||||
}
|
}
|
||||||
|
|
||||||
private final void incRefsLocked(int id) {
|
private final void incRefsLocked(int id) {
|
||||||
|
@ -898,4 +876,6 @@ public final class AssetManager {
|
||||||
destroy();
|
destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private native final void native_setApkAssets(/*String*/Object[] paths, int num_assets);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue