blob: c2800e78698da5172fca4128faf4b3bc917ce586 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/* //device/libs/android_runtime/android_util_AssetManager.cpp
2**
3** Copyright 2006, The Android Open Source Project
4**
Elliott Hughes69a017b2011-04-08 14:10:28 -07005** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008**
Elliott Hughes69a017b2011-04-08 14:10:28 -07009** http://www.apache.org/licenses/LICENSE-2.0
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010**
Elliott Hughes69a017b2011-04-08 14:10:28 -070011** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015** limitations under the License.
16*/
17
18#define LOG_TAG "asset"
19
20#include <android_runtime/android_util_AssetManager.h>
21
Dan Albert46d84442014-11-18 16:07:51 -080022#include <inttypes.h>
23#include <linux/capability.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024#include <stdio.h>
Mårten Kongstad48d22322014-01-31 14:43:27 +010025#include <sys/types.h>
26#include <sys/wait.h>
Mårten Kongstad83ab0d72015-03-20 12:57:36 +010027#include <sys/stat.h>
Jakub Adamek1c15c632016-09-23 09:07:11 +010028#include <sys/system_properties.h>
Mårten Kongstad48d22322014-01-31 14:43:27 +010029
Dan Albert46d84442014-11-18 16:07:51 -080030#include <private/android_filesystem_config.h> // for AID_SYSTEM
31
Dan Albert3a091b72014-11-20 15:41:25 -080032#include "androidfw/Asset.h"
33#include "androidfw/AssetManager.h"
Adam Lesinski4452e132016-10-12 07:47:28 -070034#include "androidfw/AttributeResolution.h"
Dan Albert3a091b72014-11-20 15:41:25 -080035#include "androidfw/ResourceTypes.h"
36#include "android_runtime/AndroidRuntime.h"
37#include "android_util_Binder.h"
38#include "core_jni_helpers.h"
39#include "jni.h"
Dan Albert46d84442014-11-18 16:07:51 -080040#include "JNIHelp.h"
41#include "ScopedStringChars.h"
42#include "ScopedUtfChars.h"
Dan Albert46d84442014-11-18 16:07:51 -080043#include "utils/Log.h"
44#include "utils/misc.h"
Jakub Adamek1c15c632016-09-23 09:07:11 +010045#include "utils/String8.h"
Dan Albert46d84442014-11-18 16:07:51 -080046
Mårten Kongstad48d22322014-01-31 14:43:27 +010047extern "C" int capget(cap_user_header_t hdrp, cap_user_data_t datap);
48extern "C" int capset(cap_user_header_t hdrp, const cap_user_data_t datap);
49
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050
51namespace android {
52
Andreas Gampe0f0b4912014-11-12 08:03:48 -080053static const bool kThrowOnBadId = false;
Andreas Gampe0f0b4912014-11-12 08:03:48 -080054
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080055// ----------------------------------------------------------------------------
56
57static struct typedvalue_offsets_t
58{
59 jfieldID mType;
60 jfieldID mData;
61 jfieldID mString;
62 jfieldID mAssetCookie;
63 jfieldID mResourceId;
64 jfieldID mChangingConfigurations;
65 jfieldID mDensity;
66} gTypedValueOffsets;
67
68static struct assetfiledescriptor_offsets_t
69{
70 jfieldID mFd;
71 jfieldID mStartOffset;
72 jfieldID mLength;
73} gAssetFileDescriptorOffsets;
74
75static struct assetmanager_offsets_t
76{
77 jfieldID mObject;
78} gAssetManagerOffsets;
79
Adam Lesinskide898ff2014-01-29 18:20:45 -080080static struct sparsearray_offsets_t
81{
82 jclass classObject;
83 jmethodID constructor;
84 jmethodID put;
85} gSparseArrayOffsets;
86
Filip Gruszczynski23493322015-07-29 17:02:59 -070087static struct configuration_offsets_t
88{
89 jclass classObject;
90 jmethodID constructor;
91 jfieldID mSmallestScreenWidthDpOffset;
92 jfieldID mScreenWidthDpOffset;
93 jfieldID mScreenHeightDpOffset;
94} gConfigurationOffsets;
95
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080096jclass g_stringClass = NULL;
97
98// ----------------------------------------------------------------------------
99
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100static jint copyValue(JNIEnv* env, jobject outValue, const ResTable* table,
101 const Res_value& value, uint32_t ref, ssize_t block,
102 uint32_t typeSpecFlags, ResTable_config* config = NULL);
103
104jint copyValue(JNIEnv* env, jobject outValue, const ResTable* table,
105 const Res_value& value, uint32_t ref, ssize_t block,
106 uint32_t typeSpecFlags, ResTable_config* config)
107{
108 env->SetIntField(outValue, gTypedValueOffsets.mType, value.dataType);
109 env->SetIntField(outValue, gTypedValueOffsets.mAssetCookie,
Ashok Bhat896043d2014-01-17 16:02:38 +0000110 static_cast<jint>(table->getTableCookie(block)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800111 env->SetIntField(outValue, gTypedValueOffsets.mData, value.data);
112 env->SetObjectField(outValue, gTypedValueOffsets.mString, NULL);
113 env->SetIntField(outValue, gTypedValueOffsets.mResourceId, ref);
114 env->SetIntField(outValue, gTypedValueOffsets.mChangingConfigurations,
115 typeSpecFlags);
116 if (config != NULL) {
117 env->SetIntField(outValue, gTypedValueOffsets.mDensity, config->density);
118 }
119 return block;
120}
121
122// ----------------------------------------------------------------------------
123
124// this guy is exported to other jni routines
125AssetManager* assetManagerForJavaObject(JNIEnv* env, jobject obj)
126{
Ashok Bhat896043d2014-01-17 16:02:38 +0000127 jlong amHandle = env->GetLongField(obj, gAssetManagerOffsets.mObject);
128 AssetManager* am = reinterpret_cast<AssetManager*>(amHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800129 if (am != NULL) {
130 return am;
131 }
132 jniThrowException(env, "java/lang/IllegalStateException", "AssetManager has been finalized!");
133 return NULL;
134}
135
Ashok Bhat896043d2014-01-17 16:02:38 +0000136static jlong android_content_AssetManager_openAsset(JNIEnv* env, jobject clazz,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800137 jstring fileName, jint mode)
138{
139 AssetManager* am = assetManagerForJavaObject(env, clazz);
140 if (am == NULL) {
141 return 0;
142 }
143
Steve Block71f2cf12011-10-20 11:56:00 +0100144 ALOGV("openAsset in %p (Java object %p)\n", am, clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800145
Elliott Hughes69a017b2011-04-08 14:10:28 -0700146 ScopedUtfChars fileName8(env, fileName);
147 if (fileName8.c_str() == NULL) {
Ashok Bhat896043d2014-01-17 16:02:38 +0000148 jniThrowException(env, "java/lang/IllegalArgumentException", "Empty file name");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800149 return -1;
150 }
151
152 if (mode != Asset::ACCESS_UNKNOWN && mode != Asset::ACCESS_RANDOM
153 && mode != Asset::ACCESS_STREAMING && mode != Asset::ACCESS_BUFFER) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -0700154 jniThrowException(env, "java/lang/IllegalArgumentException", "Bad access mode");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800155 return -1;
156 }
157
Elliott Hughes69a017b2011-04-08 14:10:28 -0700158 Asset* a = am->open(fileName8.c_str(), (Asset::AccessMode)mode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800159
160 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700161 jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800162 return -1;
163 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800164
165 //printf("Created Asset Stream: %p\n", a);
166
Ashok Bhat896043d2014-01-17 16:02:38 +0000167 return reinterpret_cast<jlong>(a);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800168}
169
170static jobject returnParcelFileDescriptor(JNIEnv* env, Asset* a, jlongArray outOffsets)
171{
Kenny Rootddb76c42010-11-24 12:56:06 -0800172 off64_t startOffset, length;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800173 int fd = a->openFileDescriptor(&startOffset, &length);
174 delete a;
Elliott Hughes69a017b2011-04-08 14:10:28 -0700175
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800176 if (fd < 0) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -0700177 jniThrowException(env, "java/io/FileNotFoundException",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800178 "This file can not be opened as a file descriptor; it is probably compressed");
179 return NULL;
180 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700181
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800182 jlong* offsets = (jlong*)env->GetPrimitiveArrayCritical(outOffsets, 0);
183 if (offsets == NULL) {
184 close(fd);
185 return NULL;
186 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700187
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800188 offsets[0] = startOffset;
189 offsets[1] = length;
Elliott Hughes69a017b2011-04-08 14:10:28 -0700190
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800191 env->ReleasePrimitiveArrayCritical(outOffsets, offsets, 0);
Elliott Hughes69a017b2011-04-08 14:10:28 -0700192
Elliott Hughesa3804cf2011-04-11 16:50:19 -0700193 jobject fileDesc = jniCreateFileDescriptor(env, fd);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800194 if (fileDesc == NULL) {
195 close(fd);
196 return NULL;
197 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700198
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800199 return newParcelFileDescriptor(env, fileDesc);
200}
201
202static jobject android_content_AssetManager_openAssetFd(JNIEnv* env, jobject clazz,
203 jstring fileName, jlongArray outOffsets)
204{
205 AssetManager* am = assetManagerForJavaObject(env, clazz);
206 if (am == NULL) {
207 return NULL;
208 }
209
Steve Block71f2cf12011-10-20 11:56:00 +0100210 ALOGV("openAssetFd in %p (Java object %p)\n", am, clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800211
Elliott Hughes69a017b2011-04-08 14:10:28 -0700212 ScopedUtfChars fileName8(env, fileName);
213 if (fileName8.c_str() == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800214 return NULL;
215 }
216
Elliott Hughes69a017b2011-04-08 14:10:28 -0700217 Asset* a = am->open(fileName8.c_str(), Asset::ACCESS_RANDOM);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800218
219 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700220 jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800221 return NULL;
222 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800223
224 //printf("Created Asset Stream: %p\n", a);
225
226 return returnParcelFileDescriptor(env, a, outOffsets);
227}
228
Ashok Bhat896043d2014-01-17 16:02:38 +0000229static jlong android_content_AssetManager_openNonAssetNative(JNIEnv* env, jobject clazz,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800230 jint cookie,
231 jstring fileName,
232 jint mode)
233{
234 AssetManager* am = assetManagerForJavaObject(env, clazz);
235 if (am == NULL) {
236 return 0;
237 }
238
Steve Block71f2cf12011-10-20 11:56:00 +0100239 ALOGV("openNonAssetNative in %p (Java object %p)\n", am, clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800240
Elliott Hughes69a017b2011-04-08 14:10:28 -0700241 ScopedUtfChars fileName8(env, fileName);
242 if (fileName8.c_str() == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800243 return -1;
244 }
245
246 if (mode != Asset::ACCESS_UNKNOWN && mode != Asset::ACCESS_RANDOM
247 && mode != Asset::ACCESS_STREAMING && mode != Asset::ACCESS_BUFFER) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -0700248 jniThrowException(env, "java/lang/IllegalArgumentException", "Bad access mode");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800249 return -1;
250 }
251
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800252 Asset* a = cookie
Narayan Kamath745d4ef2014-01-27 11:17:22 +0000253 ? am->openNonAsset(static_cast<int32_t>(cookie), fileName8.c_str(),
254 (Asset::AccessMode)mode)
Elliott Hughes69a017b2011-04-08 14:10:28 -0700255 : am->openNonAsset(fileName8.c_str(), (Asset::AccessMode)mode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800256
257 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700258 jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800259 return -1;
260 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800261
262 //printf("Created Asset Stream: %p\n", a);
263
Ashok Bhat896043d2014-01-17 16:02:38 +0000264 return reinterpret_cast<jlong>(a);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800265}
266
267static jobject android_content_AssetManager_openNonAssetFdNative(JNIEnv* env, jobject clazz,
268 jint cookie,
269 jstring fileName,
270 jlongArray outOffsets)
271{
272 AssetManager* am = assetManagerForJavaObject(env, clazz);
273 if (am == NULL) {
274 return NULL;
275 }
276
Steve Block71f2cf12011-10-20 11:56:00 +0100277 ALOGV("openNonAssetFd in %p (Java object %p)\n", am, clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800278
Elliott Hughes69a017b2011-04-08 14:10:28 -0700279 ScopedUtfChars fileName8(env, fileName);
280 if (fileName8.c_str() == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800281 return NULL;
282 }
283
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800284 Asset* a = cookie
Narayan Kamath745d4ef2014-01-27 11:17:22 +0000285 ? am->openNonAsset(static_cast<int32_t>(cookie), fileName8.c_str(), Asset::ACCESS_RANDOM)
Elliott Hughes69a017b2011-04-08 14:10:28 -0700286 : am->openNonAsset(fileName8.c_str(), Asset::ACCESS_RANDOM);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800287
288 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700289 jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800290 return NULL;
291 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800292
293 //printf("Created Asset Stream: %p\n", a);
294
295 return returnParcelFileDescriptor(env, a, outOffsets);
296}
297
298static jobjectArray android_content_AssetManager_list(JNIEnv* env, jobject clazz,
299 jstring fileName)
300{
301 AssetManager* am = assetManagerForJavaObject(env, clazz);
302 if (am == NULL) {
303 return NULL;
304 }
305
Elliott Hughes69a017b2011-04-08 14:10:28 -0700306 ScopedUtfChars fileName8(env, fileName);
307 if (fileName8.c_str() == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800308 return NULL;
309 }
310
Elliott Hughes69a017b2011-04-08 14:10:28 -0700311 AssetDir* dir = am->openDir(fileName8.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800312
313 if (dir == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700314 jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800315 return NULL;
316 }
317
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800318 size_t N = dir->getFileCount();
319
320 jobjectArray array = env->NewObjectArray(dir->getFileCount(),
Vladimir Markoaa5fe3d2013-06-17 12:46:22 +0100321 g_stringClass, NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800322 if (array == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800323 delete dir;
324 return NULL;
325 }
326
327 for (size_t i=0; i<N; i++) {
328 const String8& name = dir->getFileName(i);
329 jstring str = env->NewStringUTF(name.string());
330 if (str == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800331 delete dir;
332 return NULL;
333 }
334 env->SetObjectArrayElement(array, i, str);
Gilles Debunne4d4040b2010-08-26 15:59:54 -0700335 env->DeleteLocalRef(str);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800336 }
337
338 delete dir;
339
340 return array;
341}
342
343static void android_content_AssetManager_destroyAsset(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +0000344 jlong assetHandle)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800345{
Ashok Bhat896043d2014-01-17 16:02:38 +0000346 Asset* a = reinterpret_cast<Asset*>(assetHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800347
348 //printf("Destroying Asset Stream: %p\n", a);
349
350 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700351 jniThrowNullPointerException(env, "asset");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800352 return;
353 }
354
355 delete a;
356}
357
358static jint android_content_AssetManager_readAssetChar(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +0000359 jlong assetHandle)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800360{
Ashok Bhat896043d2014-01-17 16:02:38 +0000361 Asset* a = reinterpret_cast<Asset*>(assetHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800362
363 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700364 jniThrowNullPointerException(env, "asset");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800365 return -1;
366 }
367
368 uint8_t b;
369 ssize_t res = a->read(&b, 1);
370 return res == 1 ? b : -1;
371}
372
373static jint android_content_AssetManager_readAsset(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +0000374 jlong assetHandle, jbyteArray bArray,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800375 jint off, jint len)
376{
Ashok Bhat896043d2014-01-17 16:02:38 +0000377 Asset* a = reinterpret_cast<Asset*>(assetHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800378
379 if (a == NULL || bArray == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700380 jniThrowNullPointerException(env, "asset");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800381 return -1;
382 }
383
384 if (len == 0) {
385 return 0;
386 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700387
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800388 jsize bLen = env->GetArrayLength(bArray);
389 if (off < 0 || off >= bLen || len < 0 || len > bLen || (off+len) > bLen) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -0700390 jniThrowException(env, "java/lang/IndexOutOfBoundsException", "");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800391 return -1;
392 }
393
394 jbyte* b = env->GetByteArrayElements(bArray, NULL);
395 ssize_t res = a->read(b+off, len);
396 env->ReleaseByteArrayElements(bArray, b, 0);
397
Ashok Bhat896043d2014-01-17 16:02:38 +0000398 if (res > 0) return static_cast<jint>(res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800399
400 if (res < 0) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -0700401 jniThrowException(env, "java/io/IOException", "");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800402 }
403 return -1;
404}
405
406static jlong android_content_AssetManager_seekAsset(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +0000407 jlong assetHandle,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800408 jlong offset, jint whence)
409{
Ashok Bhat896043d2014-01-17 16:02:38 +0000410 Asset* a = reinterpret_cast<Asset*>(assetHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800411
412 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700413 jniThrowNullPointerException(env, "asset");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800414 return -1;
415 }
416
417 return a->seek(
418 offset, (whence > 0) ? SEEK_END : (whence < 0 ? SEEK_SET : SEEK_CUR));
419}
420
421static jlong android_content_AssetManager_getAssetLength(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +0000422 jlong assetHandle)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800423{
Ashok Bhat896043d2014-01-17 16:02:38 +0000424 Asset* a = reinterpret_cast<Asset*>(assetHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800425
426 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700427 jniThrowNullPointerException(env, "asset");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800428 return -1;
429 }
430
431 return a->getLength();
432}
433
434static jlong android_content_AssetManager_getAssetRemainingLength(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +0000435 jlong assetHandle)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800436{
Ashok Bhat896043d2014-01-17 16:02:38 +0000437 Asset* a = reinterpret_cast<Asset*>(assetHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800438
439 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700440 jniThrowNullPointerException(env, "asset");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800441 return -1;
442 }
443
444 return a->getRemainingLength();
445}
446
447static jint android_content_AssetManager_addAssetPath(JNIEnv* env, jobject clazz,
Tao Baia6d7e3f2015-09-01 18:49:54 -0700448 jstring path, jboolean appAsLib)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800449{
Elliott Hughes69a017b2011-04-08 14:10:28 -0700450 ScopedUtfChars path8(env, path);
451 if (path8.c_str() == NULL) {
Glenn Kasten129e19c2012-01-10 17:57:36 -0800452 return 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800453 }
454
455 AssetManager* am = assetManagerForJavaObject(env, clazz);
456 if (am == NULL) {
Glenn Kasten129e19c2012-01-10 17:57:36 -0800457 return 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800458 }
459
Narayan Kamath745d4ef2014-01-27 11:17:22 +0000460 int32_t cookie;
Tao Baia6d7e3f2015-09-01 18:49:54 -0700461 bool res = am->addAssetPath(String8(path8.c_str()), &cookie, appAsLib);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800462
Narayan Kamath745d4ef2014-01-27 11:17:22 +0000463 return (res) ? static_cast<jint>(cookie) : 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800464}
465
Mårten Kongstad48d22322014-01-31 14:43:27 +0100466static jint android_content_AssetManager_addOverlayPath(JNIEnv* env, jobject clazz,
467 jstring idmapPath)
468{
469 ScopedUtfChars idmapPath8(env, idmapPath);
470 if (idmapPath8.c_str() == NULL) {
471 return 0;
472 }
473
474 AssetManager* am = assetManagerForJavaObject(env, clazz);
475 if (am == NULL) {
476 return 0;
477 }
478
479 int32_t cookie;
480 bool res = am->addOverlayPath(String8(idmapPath8.c_str()), &cookie);
481
482 return (res) ? (jint)cookie : 0;
483}
484
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800485static jboolean android_content_AssetManager_isUpToDate(JNIEnv* env, jobject clazz)
486{
487 AssetManager* am = assetManagerForJavaObject(env, clazz);
488 if (am == NULL) {
489 return JNI_TRUE;
490 }
491 return am->isUpToDate() ? JNI_TRUE : JNI_FALSE;
492}
493
Roozbeh Pournader1c686f22015-12-18 14:22:14 -0800494static jobjectArray getLocales(JNIEnv* env, jobject clazz, bool includeSystemLocales)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800495{
496 Vector<String8> locales;
497
498 AssetManager* am = assetManagerForJavaObject(env, clazz);
499 if (am == NULL) {
500 return NULL;
501 }
502
Roozbeh Pournader1c686f22015-12-18 14:22:14 -0800503 am->getLocales(&locales, includeSystemLocales);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800504
505 const int N = locales.size();
506
507 jobjectArray result = env->NewObjectArray(N, g_stringClass, NULL);
508 if (result == NULL) {
509 return NULL;
510 }
511
512 for (int i=0; i<N; i++) {
Gilles Debunne0db187a2010-08-27 11:51:34 -0700513 jstring str = env->NewStringUTF(locales[i].string());
Gilles Debunne4d4040b2010-08-26 15:59:54 -0700514 if (str == NULL) {
515 return NULL;
516 }
517 env->SetObjectArrayElement(result, i, str);
518 env->DeleteLocalRef(str);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800519 }
520
521 return result;
522}
523
Roozbeh Pournader1c686f22015-12-18 14:22:14 -0800524static jobjectArray android_content_AssetManager_getLocales(JNIEnv* env, jobject clazz)
525{
526 return getLocales(env, clazz, true /* include system locales */);
527}
528
529static jobjectArray android_content_AssetManager_getNonSystemLocales(JNIEnv* env, jobject clazz)
530{
531 return getLocales(env, clazz, false /* don't include system locales */);
532}
533
Filip Gruszczynski23493322015-07-29 17:02:59 -0700534static jobject constructConfigurationObject(JNIEnv* env, const ResTable_config& config) {
535 jobject result = env->NewObject(gConfigurationOffsets.classObject,
536 gConfigurationOffsets.constructor);
537 if (result == NULL) {
538 return NULL;
539 }
540
541 env->SetIntField(result, gConfigurationOffsets.mSmallestScreenWidthDpOffset,
542 config.smallestScreenWidthDp);
543 env->SetIntField(result, gConfigurationOffsets.mScreenWidthDpOffset, config.screenWidthDp);
544 env->SetIntField(result, gConfigurationOffsets.mScreenHeightDpOffset, config.screenHeightDp);
545
546 return result;
547}
548
549static jobjectArray getSizeConfigurationsInternal(JNIEnv* env,
550 const Vector<ResTable_config>& configs) {
551 const int N = configs.size();
552 jobjectArray result = env->NewObjectArray(N, gConfigurationOffsets.classObject, NULL);
553 if (result == NULL) {
554 return NULL;
555 }
556
557 for (int i=0; i<N; i++) {
558 jobject config = constructConfigurationObject(env, configs[i]);
559 if (config == NULL) {
560 env->DeleteLocalRef(result);
561 return NULL;
562 }
563
564 env->SetObjectArrayElement(result, i, config);
565 env->DeleteLocalRef(config);
566 }
567
568 return result;
569}
570
571static jobjectArray android_content_AssetManager_getSizeConfigurations(JNIEnv* env, jobject clazz) {
572 AssetManager* am = assetManagerForJavaObject(env, clazz);
573 if (am == NULL) {
574 return NULL;
575 }
576
577 const ResTable& res(am->getResources());
578 Vector<ResTable_config> configs;
579 res.getConfigurations(&configs, false /* ignoreMipmap */, true /* ignoreAndroidPackage */);
580
581 return getSizeConfigurationsInternal(env, configs);
582}
583
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800584static void android_content_AssetManager_setConfiguration(JNIEnv* env, jobject clazz,
585 jint mcc, jint mnc,
586 jstring locale, jint orientation,
587 jint touchscreen, jint density,
588 jint keyboard, jint keyboardHidden,
589 jint navigation,
590 jint screenWidth, jint screenHeight,
Dianne Hackborn69cb8752011-05-19 18:13:32 -0700591 jint smallestScreenWidthDp,
Dianne Hackborn3fc982f2011-03-30 16:20:26 -0700592 jint screenWidthDp, jint screenHeightDp,
Tobias Haamel27b28b32010-02-09 23:09:17 +0100593 jint screenLayout, jint uiMode,
Romain Guy408afbf2017-01-25 10:23:03 -0800594 jint colorMode, jint sdkVersion)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800595{
596 AssetManager* am = assetManagerForJavaObject(env, clazz);
597 if (am == NULL) {
598 return;
599 }
600
601 ResTable_config config;
602 memset(&config, 0, sizeof(config));
Elliott Hughes69a017b2011-04-08 14:10:28 -0700603
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800604 const char* locale8 = locale != NULL ? env->GetStringUTFChars(locale, NULL) : NULL;
Elliott Hughes69a017b2011-04-08 14:10:28 -0700605
Adam Lesinski2738c962015-05-14 14:25:36 -0700606 // Constants duplicated from Java class android.content.res.Configuration.
607 static const jint kScreenLayoutRoundMask = 0x300;
608 static const jint kScreenLayoutRoundShift = 8;
609
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800610 config.mcc = (uint16_t)mcc;
611 config.mnc = (uint16_t)mnc;
612 config.orientation = (uint8_t)orientation;
613 config.touchscreen = (uint8_t)touchscreen;
614 config.density = (uint16_t)density;
615 config.keyboard = (uint8_t)keyboard;
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700616 config.inputFlags = (uint8_t)keyboardHidden;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800617 config.navigation = (uint8_t)navigation;
618 config.screenWidth = (uint16_t)screenWidth;
619 config.screenHeight = (uint16_t)screenHeight;
Dianne Hackborn69cb8752011-05-19 18:13:32 -0700620 config.smallestScreenWidthDp = (uint16_t)smallestScreenWidthDp;
Dianne Hackborn3fc982f2011-03-30 16:20:26 -0700621 config.screenWidthDp = (uint16_t)screenWidthDp;
622 config.screenHeightDp = (uint16_t)screenHeightDp;
Dianne Hackborn723738c2009-06-25 19:48:04 -0700623 config.screenLayout = (uint8_t)screenLayout;
Tobias Haamel27b28b32010-02-09 23:09:17 +0100624 config.uiMode = (uint8_t)uiMode;
Romain Guy408afbf2017-01-25 10:23:03 -0800625 config.colorMode = (uint8_t)colorMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800626 config.sdkVersion = (uint16_t)sdkVersion;
627 config.minorVersion = 0;
Adam Lesinski2738c962015-05-14 14:25:36 -0700628
629 // In Java, we use a 32bit integer for screenLayout, while we only use an 8bit integer
630 // in C++. We must extract the round qualifier out of the Java screenLayout and put it
631 // into screenLayout2.
632 config.screenLayout2 =
633 (uint8_t)((screenLayout & kScreenLayoutRoundMask) >> kScreenLayoutRoundShift);
634
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800635 am->setConfiguration(config, locale8);
Elliott Hughes69a017b2011-04-08 14:10:28 -0700636
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800637 if (locale != NULL) env->ReleaseStringUTFChars(locale, locale8);
638}
639
640static jint android_content_AssetManager_getResourceIdentifier(JNIEnv* env, jobject clazz,
641 jstring name,
642 jstring defType,
643 jstring defPackage)
644{
Elliott Hughes69a017b2011-04-08 14:10:28 -0700645 ScopedStringChars name16(env, name);
646 if (name16.get() == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800647 return 0;
648 }
649
650 AssetManager* am = assetManagerForJavaObject(env, clazz);
651 if (am == NULL) {
652 return 0;
653 }
654
Dan Albert66987492014-11-20 11:41:21 -0800655 const char16_t* defType16 = reinterpret_cast<const char16_t*>(defType)
656 ? reinterpret_cast<const char16_t*>(env->GetStringChars(defType, NULL))
657 : NULL;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800658 jsize defTypeLen = defType
659 ? env->GetStringLength(defType) : 0;
Dan Albert66987492014-11-20 11:41:21 -0800660 const char16_t* defPackage16 = reinterpret_cast<const char16_t*>(defPackage)
661 ? reinterpret_cast<const char16_t*>(env->GetStringChars(defPackage,
662 NULL))
663 : NULL;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800664 jsize defPackageLen = defPackage
665 ? env->GetStringLength(defPackage) : 0;
666
667 jint ident = am->getResources().identifierForName(
Dan Albert66987492014-11-20 11:41:21 -0800668 reinterpret_cast<const char16_t*>(name16.get()), name16.size(),
669 defType16, defTypeLen, defPackage16, defPackageLen);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800670
671 if (defPackage16) {
Dan Albert66987492014-11-20 11:41:21 -0800672 env->ReleaseStringChars(defPackage,
673 reinterpret_cast<const jchar*>(defPackage16));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800674 }
675 if (defType16) {
Dan Albert66987492014-11-20 11:41:21 -0800676 env->ReleaseStringChars(defType,
677 reinterpret_cast<const jchar*>(defType16));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800678 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800679
680 return ident;
681}
682
683static jstring android_content_AssetManager_getResourceName(JNIEnv* env, jobject clazz,
684 jint resid)
685{
686 AssetManager* am = assetManagerForJavaObject(env, clazz);
687 if (am == NULL) {
688 return NULL;
689 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700690
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800691 ResTable::resource_name name;
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700692 if (!am->getResources().getResourceName(resid, true, &name)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800693 return NULL;
694 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700695
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800696 String16 str;
697 if (name.package != NULL) {
698 str.setTo(name.package, name.packageLen);
699 }
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700700 if (name.type8 != NULL || name.type != NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800701 if (str.size() > 0) {
702 char16_t div = ':';
703 str.append(&div, 1);
704 }
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700705 if (name.type8 != NULL) {
706 str.append(String16(name.type8, name.typeLen));
707 } else {
708 str.append(name.type, name.typeLen);
709 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800710 }
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700711 if (name.name8 != NULL || name.name != NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800712 if (str.size() > 0) {
713 char16_t div = '/';
714 str.append(&div, 1);
715 }
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700716 if (name.name8 != NULL) {
717 str.append(String16(name.name8, name.nameLen));
718 } else {
719 str.append(name.name, name.nameLen);
720 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800721 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700722
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800723 return env->NewString((const jchar*)str.string(), str.size());
724}
725
726static jstring android_content_AssetManager_getResourcePackageName(JNIEnv* env, jobject clazz,
727 jint resid)
728{
729 AssetManager* am = assetManagerForJavaObject(env, clazz);
730 if (am == NULL) {
731 return NULL;
732 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700733
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800734 ResTable::resource_name name;
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700735 if (!am->getResources().getResourceName(resid, true, &name)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800736 return NULL;
737 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700738
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800739 if (name.package != NULL) {
740 return env->NewString((const jchar*)name.package, name.packageLen);
741 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700742
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800743 return NULL;
744}
745
746static jstring android_content_AssetManager_getResourceTypeName(JNIEnv* env, jobject clazz,
747 jint resid)
748{
749 AssetManager* am = assetManagerForJavaObject(env, clazz);
750 if (am == NULL) {
751 return NULL;
752 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700753
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800754 ResTable::resource_name name;
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700755 if (!am->getResources().getResourceName(resid, true, &name)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800756 return NULL;
757 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700758
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700759 if (name.type8 != NULL) {
760 return env->NewStringUTF(name.type8);
761 }
762
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800763 if (name.type != NULL) {
764 return env->NewString((const jchar*)name.type, name.typeLen);
765 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700766
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800767 return NULL;
768}
769
770static jstring android_content_AssetManager_getResourceEntryName(JNIEnv* env, jobject clazz,
771 jint resid)
772{
773 AssetManager* am = assetManagerForJavaObject(env, clazz);
774 if (am == NULL) {
775 return NULL;
776 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700777
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800778 ResTable::resource_name name;
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700779 if (!am->getResources().getResourceName(resid, true, &name)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800780 return NULL;
781 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700782
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700783 if (name.name8 != NULL) {
784 return env->NewStringUTF(name.name8);
785 }
786
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800787 if (name.name != NULL) {
788 return env->NewString((const jchar*)name.name, name.nameLen);
789 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700790
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800791 return NULL;
792}
793
794static jint android_content_AssetManager_loadResourceValue(JNIEnv* env, jobject clazz,
795 jint ident,
Kenny Root55fc8502010-10-28 14:47:01 -0700796 jshort density,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800797 jobject outValue,
798 jboolean resolve)
799{
Dianne Hackborn1f7d3072013-02-11 17:03:32 -0800800 if (outValue == NULL) {
Dianne Hackborne5b50a62013-02-11 16:18:42 -0800801 jniThrowNullPointerException(env, "outValue");
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700802 return 0;
Dianne Hackborne5b50a62013-02-11 16:18:42 -0800803 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800804 AssetManager* am = assetManagerForJavaObject(env, clazz);
805 if (am == NULL) {
806 return 0;
807 }
808 const ResTable& res(am->getResources());
809
810 Res_value value;
811 ResTable_config config;
812 uint32_t typeSpecFlags;
Kenny Root55fc8502010-10-28 14:47:01 -0700813 ssize_t block = res.getResource(ident, &value, false, density, &typeSpecFlags, &config);
Andreas Gampe0f0b4912014-11-12 08:03:48 -0800814 if (kThrowOnBadId) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -0800815 if (block == BAD_INDEX) {
816 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
817 return 0;
818 }
Andreas Gampe0f0b4912014-11-12 08:03:48 -0800819 }
820 uint32_t ref = ident;
821 if (resolve) {
822 block = res.resolveReference(&value, block, &ref, &typeSpecFlags, &config);
823 if (kThrowOnBadId) {
824 if (block == BAD_INDEX) {
825 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
826 return 0;
827 }
828 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800829 }
Ashok Bhat896043d2014-01-17 16:02:38 +0000830 if (block >= 0) {
831 return copyValue(env, outValue, &res, value, ref, block, typeSpecFlags, &config);
832 }
833
834 return static_cast<jint>(block);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800835}
836
837static jint android_content_AssetManager_loadResourceBagValue(JNIEnv* env, jobject clazz,
838 jint ident, jint bagEntryId,
839 jobject outValue, jboolean resolve)
840{
841 AssetManager* am = assetManagerForJavaObject(env, clazz);
842 if (am == NULL) {
843 return 0;
844 }
845 const ResTable& res(am->getResources());
Elliott Hughes69a017b2011-04-08 14:10:28 -0700846
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800847 // Now lock down the resource object and start pulling stuff from it.
848 res.lock();
Elliott Hughes69a017b2011-04-08 14:10:28 -0700849
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800850 ssize_t block = -1;
851 Res_value value;
852
853 const ResTable::bag_entry* entry = NULL;
854 uint32_t typeSpecFlags;
855 ssize_t entryCount = res.getBagLocked(ident, &entry, &typeSpecFlags);
856
857 for (ssize_t i=0; i<entryCount; i++) {
858 if (((uint32_t)bagEntryId) == entry->map.name.ident) {
859 block = entry->stringBlock;
860 value = entry->map.value;
861 }
862 entry++;
863 }
864
865 res.unlock();
866
867 if (block < 0) {
Ashok Bhat896043d2014-01-17 16:02:38 +0000868 return static_cast<jint>(block);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800869 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700870
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800871 uint32_t ref = ident;
872 if (resolve) {
873 block = res.resolveReference(&value, block, &ref, &typeSpecFlags);
Andreas Gampe0f0b4912014-11-12 08:03:48 -0800874 if (kThrowOnBadId) {
875 if (block == BAD_INDEX) {
876 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
877 return 0;
878 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -0800879 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800880 }
Ashok Bhat896043d2014-01-17 16:02:38 +0000881 if (block >= 0) {
882 return copyValue(env, outValue, &res, value, ref, block, typeSpecFlags);
883 }
884
885 return static_cast<jint>(block);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800886}
887
888static jint android_content_AssetManager_getStringBlockCount(JNIEnv* env, jobject clazz)
889{
890 AssetManager* am = assetManagerForJavaObject(env, clazz);
891 if (am == NULL) {
892 return 0;
893 }
894 return am->getResources().getTableCount();
895}
896
Ashok Bhat896043d2014-01-17 16:02:38 +0000897static jlong android_content_AssetManager_getNativeStringBlock(JNIEnv* env, jobject clazz,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800898 jint block)
899{
900 AssetManager* am = assetManagerForJavaObject(env, clazz);
901 if (am == NULL) {
902 return 0;
903 }
Ashok Bhat896043d2014-01-17 16:02:38 +0000904 return reinterpret_cast<jlong>(am->getResources().getTableStringBlock(block));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800905}
906
907static jstring android_content_AssetManager_getCookieName(JNIEnv* env, jobject clazz,
908 jint cookie)
909{
910 AssetManager* am = assetManagerForJavaObject(env, clazz);
911 if (am == NULL) {
912 return NULL;
913 }
Narayan Kamath745d4ef2014-01-27 11:17:22 +0000914 String8 name(am->getAssetPath(static_cast<int32_t>(cookie)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800915 if (name.length() == 0) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -0700916 jniThrowException(env, "java/lang/IndexOutOfBoundsException", "Empty cookie name");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800917 return NULL;
918 }
919 jstring str = env->NewStringUTF(name.string());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800920 return str;
921}
922
Adam Lesinskide898ff2014-01-29 18:20:45 -0800923static jobject android_content_AssetManager_getAssignedPackageIdentifiers(JNIEnv* env, jobject clazz)
924{
925 AssetManager* am = assetManagerForJavaObject(env, clazz);
926 if (am == NULL) {
927 return 0;
928 }
929
930 const ResTable& res = am->getResources();
931
932 jobject sparseArray = env->NewObject(gSparseArrayOffsets.classObject,
933 gSparseArrayOffsets.constructor);
934 const size_t N = res.getBasePackageCount();
935 for (size_t i = 0; i < N; i++) {
936 const String16 name = res.getBasePackageName(i);
Dan Albert66987492014-11-20 11:41:21 -0800937 env->CallVoidMethod(
938 sparseArray, gSparseArrayOffsets.put,
939 static_cast<jint>(res.getBasePackageId(i)),
940 env->NewString(reinterpret_cast<const jchar*>(name.string()),
941 name.size()));
Adam Lesinskide898ff2014-01-29 18:20:45 -0800942 }
943 return sparseArray;
944}
945
Ashok Bhat896043d2014-01-17 16:02:38 +0000946static jlong android_content_AssetManager_newTheme(JNIEnv* env, jobject clazz)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800947{
948 AssetManager* am = assetManagerForJavaObject(env, clazz);
949 if (am == NULL) {
950 return 0;
951 }
Ashok Bhat896043d2014-01-17 16:02:38 +0000952 return reinterpret_cast<jlong>(new ResTable::Theme(am->getResources()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800953}
954
955static void android_content_AssetManager_deleteTheme(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +0000956 jlong themeHandle)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800957{
Ashok Bhat896043d2014-01-17 16:02:38 +0000958 ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800959 delete theme;
960}
961
962static void android_content_AssetManager_applyThemeStyle(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +0000963 jlong themeHandle,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800964 jint styleRes,
965 jboolean force)
966{
Ashok Bhat896043d2014-01-17 16:02:38 +0000967 ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800968 theme->applyStyle(styleRes, force ? true : false);
969}
970
971static void android_content_AssetManager_copyTheme(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +0000972 jlong destHandle, jlong srcHandle)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800973{
Ashok Bhat896043d2014-01-17 16:02:38 +0000974 ResTable::Theme* dest = reinterpret_cast<ResTable::Theme*>(destHandle);
975 ResTable::Theme* src = reinterpret_cast<ResTable::Theme*>(srcHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800976 dest->setTo(*src);
977}
978
Alan Viverettee54d2452015-05-06 10:41:43 -0700979static void android_content_AssetManager_clearTheme(JNIEnv* env, jobject clazz, jlong themeHandle)
980{
981 ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeHandle);
982 theme->clear();
983}
984
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800985static jint android_content_AssetManager_loadThemeAttributeValue(
Ashok Bhat896043d2014-01-17 16:02:38 +0000986 JNIEnv* env, jobject clazz, jlong themeHandle, jint ident, jobject outValue, jboolean resolve)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800987{
Ashok Bhat896043d2014-01-17 16:02:38 +0000988 ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800989 const ResTable& res(theme->getResTable());
990
991 Res_value value;
992 // XXX value could be different in different configs!
993 uint32_t typeSpecFlags = 0;
994 ssize_t block = theme->getAttribute(ident, &value, &typeSpecFlags);
995 uint32_t ref = 0;
996 if (resolve) {
997 block = res.resolveReference(&value, block, &ref, &typeSpecFlags);
Andreas Gampe0f0b4912014-11-12 08:03:48 -0800998 if (kThrowOnBadId) {
999 if (block == BAD_INDEX) {
1000 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
1001 return 0;
1002 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001003 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001004 }
1005 return block >= 0 ? copyValue(env, outValue, &res, value, ref, block, typeSpecFlags) : block;
1006}
1007
Alan Viverettec1d52792015-05-05 09:49:03 -07001008static jint android_content_AssetManager_getThemeChangingConfigurations(JNIEnv* env, jobject clazz,
1009 jlong themeHandle)
1010{
1011 ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeHandle);
1012 return theme->getChangingConfigurations();
1013}
1014
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001015static void android_content_AssetManager_dumpTheme(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +00001016 jlong themeHandle, jint pri,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001017 jstring tag, jstring prefix)
1018{
Ashok Bhat896043d2014-01-17 16:02:38 +00001019 ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001020 const ResTable& res(theme->getResTable());
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001021 (void)res;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001022
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001023 // XXX Need to use params.
1024 theme->dumpToLog();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001025}
1026
Alan Viverette52b999f2014-03-24 18:00:26 -07001027static jboolean android_content_AssetManager_resolveAttrs(JNIEnv* env, jobject clazz,
1028 jlong themeToken,
1029 jint defStyleAttr,
1030 jint defStyleRes,
1031 jintArray inValues,
1032 jintArray attrs,
1033 jintArray outValues,
1034 jintArray outIndices)
1035{
1036 if (themeToken == 0) {
1037 jniThrowNullPointerException(env, "theme token");
1038 return JNI_FALSE;
1039 }
1040 if (attrs == NULL) {
1041 jniThrowNullPointerException(env, "attrs");
1042 return JNI_FALSE;
1043 }
1044 if (outValues == NULL) {
1045 jniThrowNullPointerException(env, "out values");
1046 return JNI_FALSE;
1047 }
1048
Alan Viverette52b999f2014-03-24 18:00:26 -07001049 const jsize NI = env->GetArrayLength(attrs);
1050 const jsize NV = env->GetArrayLength(outValues);
1051 if (NV < (NI*STYLE_NUM_ENTRIES)) {
1052 jniThrowException(env, "java/lang/IndexOutOfBoundsException", "out values too small");
1053 return JNI_FALSE;
1054 }
1055
1056 jint* src = (jint*)env->GetPrimitiveArrayCritical(attrs, 0);
1057 if (src == NULL) {
1058 return JNI_FALSE;
1059 }
1060
1061 jint* srcValues = (jint*)env->GetPrimitiveArrayCritical(inValues, 0);
1062 const jsize NSV = srcValues == NULL ? 0 : env->GetArrayLength(inValues);
1063
1064 jint* baseDest = (jint*)env->GetPrimitiveArrayCritical(outValues, 0);
Adam Lesinski4452e132016-10-12 07:47:28 -07001065 if (baseDest == NULL) {
Alan Viverette52b999f2014-03-24 18:00:26 -07001066 env->ReleasePrimitiveArrayCritical(attrs, src, 0);
1067 return JNI_FALSE;
1068 }
1069
1070 jint* indices = NULL;
Alan Viverette52b999f2014-03-24 18:00:26 -07001071 if (outIndices != NULL) {
1072 if (env->GetArrayLength(outIndices) > NI) {
1073 indices = (jint*)env->GetPrimitiveArrayCritical(outIndices, 0);
1074 }
1075 }
1076
Adam Lesinski4452e132016-10-12 07:47:28 -07001077 ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeToken);
Adam Lesinski7a37b742016-10-12 14:05:55 -07001078 bool result = ResolveAttrs(theme, defStyleAttr, defStyleRes,
Adam Lesinski4452e132016-10-12 07:47:28 -07001079 (uint32_t*) srcValues, NSV,
1080 (uint32_t*) src, NI,
1081 (uint32_t*) baseDest,
1082 (uint32_t*) indices);
Alan Viverette52b999f2014-03-24 18:00:26 -07001083
1084 if (indices != NULL) {
Alan Viverette52b999f2014-03-24 18:00:26 -07001085 env->ReleasePrimitiveArrayCritical(outIndices, indices, 0);
1086 }
1087 env->ReleasePrimitiveArrayCritical(outValues, baseDest, 0);
1088 env->ReleasePrimitiveArrayCritical(inValues, srcValues, 0);
1089 env->ReleasePrimitiveArrayCritical(attrs, src, 0);
Adam Lesinski4452e132016-10-12 07:47:28 -07001090 return result ? JNI_TRUE : JNI_FALSE;
Alan Viverette52b999f2014-03-24 18:00:26 -07001091}
1092
John Reckf32adf42016-11-23 10:39:40 -08001093static void android_content_AssetManager_applyStyle(JNIEnv* env, jobject, jlong themeToken,
1094 jint defStyleAttr, jint defStyleRes, jlong xmlParserToken, jintArray attrsObj, jint length,
1095 jlong outValuesAddress, jlong outIndicesAddress) {
1096 jint* attrs = env->GetIntArrayElements(attrsObj, 0);
Adam Lesinski4452e132016-10-12 07:47:28 -07001097 ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeToken);
1098 ResXMLParser* xmlParser = reinterpret_cast<ResXMLParser*>(xmlParserToken);
John Reckf32adf42016-11-23 10:39:40 -08001099 uint32_t* outValues = reinterpret_cast<uint32_t*>(static_cast<uintptr_t>(outValuesAddress));
1100 uint32_t* outIndices = reinterpret_cast<uint32_t*>(static_cast<uintptr_t>(outIndicesAddress));
1101 ApplyStyle(theme, xmlParser, defStyleAttr, defStyleRes,
1102 reinterpret_cast<const uint32_t*>(attrs), length, outValues, outIndices);
1103 env->ReleaseIntArrayElements(attrsObj, attrs, JNI_ABORT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001104}
1105
1106static jboolean android_content_AssetManager_retrieveAttributes(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +00001107 jlong xmlParserToken,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001108 jintArray attrs,
1109 jintArray outValues,
1110 jintArray outIndices)
1111{
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001112 if (xmlParserToken == 0) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001113 jniThrowNullPointerException(env, "xmlParserToken");
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001114 return JNI_FALSE;
1115 }
1116 if (attrs == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001117 jniThrowNullPointerException(env, "attrs");
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001118 return JNI_FALSE;
1119 }
1120 if (outValues == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001121 jniThrowNullPointerException(env, "out values");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001122 return JNI_FALSE;
1123 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001124
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001125 AssetManager* am = assetManagerForJavaObject(env, clazz);
1126 if (am == NULL) {
1127 return JNI_FALSE;
1128 }
1129 const ResTable& res(am->getResources());
1130 ResXMLParser* xmlParser = (ResXMLParser*)xmlParserToken;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001131
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001132 const jsize NI = env->GetArrayLength(attrs);
1133 const jsize NV = env->GetArrayLength(outValues);
1134 if (NV < (NI*STYLE_NUM_ENTRIES)) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001135 jniThrowException(env, "java/lang/IndexOutOfBoundsException", "out values too small");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001136 return JNI_FALSE;
1137 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001138
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001139 jint* src = (jint*)env->GetPrimitiveArrayCritical(attrs, 0);
1140 if (src == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001141 return JNI_FALSE;
1142 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001143
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001144 jint* baseDest = (jint*)env->GetPrimitiveArrayCritical(outValues, 0);
Adam Lesinski4452e132016-10-12 07:47:28 -07001145 if (baseDest == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001146 env->ReleasePrimitiveArrayCritical(attrs, src, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001147 return JNI_FALSE;
1148 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001149
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001150 jint* indices = NULL;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001151 if (outIndices != NULL) {
1152 if (env->GetArrayLength(outIndices) > NI) {
1153 indices = (jint*)env->GetPrimitiveArrayCritical(outIndices, 0);
1154 }
1155 }
1156
Adam Lesinski7a37b742016-10-12 14:05:55 -07001157 bool result = RetrieveAttributes(&res, xmlParser,
Adam Lesinski4452e132016-10-12 07:47:28 -07001158 (uint32_t*) src, NI,
1159 (uint32_t*) baseDest,
1160 (uint32_t*) indices);
Elliott Hughes69a017b2011-04-08 14:10:28 -07001161
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001162 if (indices != NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001163 env->ReleasePrimitiveArrayCritical(outIndices, indices, 0);
1164 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001165 env->ReleasePrimitiveArrayCritical(outValues, baseDest, 0);
1166 env->ReleasePrimitiveArrayCritical(attrs, src, 0);
Adam Lesinski4452e132016-10-12 07:47:28 -07001167 return result ? JNI_TRUE : JNI_FALSE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001168}
1169
1170static jint android_content_AssetManager_getArraySize(JNIEnv* env, jobject clazz,
1171 jint id)
1172{
1173 AssetManager* am = assetManagerForJavaObject(env, clazz);
1174 if (am == NULL) {
Olivier Baillyd7c86722010-11-18 14:43:36 -08001175 return 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001176 }
1177 const ResTable& res(am->getResources());
Elliott Hughes69a017b2011-04-08 14:10:28 -07001178
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001179 res.lock();
1180 const ResTable::bag_entry* defStyleEnt = NULL;
1181 ssize_t bagOff = res.getBagLocked(id, &defStyleEnt);
1182 res.unlock();
Elliott Hughes69a017b2011-04-08 14:10:28 -07001183
Ashok Bhat896043d2014-01-17 16:02:38 +00001184 return static_cast<jint>(bagOff);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001185}
1186
1187static jint android_content_AssetManager_retrieveArray(JNIEnv* env, jobject clazz,
1188 jint id,
1189 jintArray outValues)
1190{
1191 if (outValues == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001192 jniThrowNullPointerException(env, "out values");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001193 return JNI_FALSE;
1194 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001195
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001196 AssetManager* am = assetManagerForJavaObject(env, clazz);
1197 if (am == NULL) {
1198 return JNI_FALSE;
1199 }
1200 const ResTable& res(am->getResources());
Dianne Hackborn0d221012009-07-29 15:41:19 -07001201 ResTable_config config;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001202 Res_value value;
1203 ssize_t block;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001204
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001205 const jsize NV = env->GetArrayLength(outValues);
Elliott Hughes69a017b2011-04-08 14:10:28 -07001206
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001207 jint* baseDest = (jint*)env->GetPrimitiveArrayCritical(outValues, 0);
1208 jint* dest = baseDest;
1209 if (dest == NULL) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001210 jniThrowException(env, "java/lang/OutOfMemoryError", "");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001211 return JNI_FALSE;
1212 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001213
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001214 // Now lock down the resource object and start pulling stuff from it.
1215 res.lock();
Elliott Hughes69a017b2011-04-08 14:10:28 -07001216
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001217 const ResTable::bag_entry* arrayEnt = NULL;
1218 uint32_t arrayTypeSetFlags = 0;
1219 ssize_t bagOff = res.getBagLocked(id, &arrayEnt, &arrayTypeSetFlags);
1220 const ResTable::bag_entry* endArrayEnt = arrayEnt +
1221 (bagOff >= 0 ? bagOff : 0);
Elliott Hughes69a017b2011-04-08 14:10:28 -07001222
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001223 int i = 0;
1224 uint32_t typeSetFlags;
1225 while (i < NV && arrayEnt < endArrayEnt) {
1226 block = arrayEnt->stringBlock;
1227 typeSetFlags = arrayTypeSetFlags;
Dianne Hackborn0d221012009-07-29 15:41:19 -07001228 config.density = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001229 value = arrayEnt->map.value;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001230
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001231 uint32_t resid = 0;
1232 if (value.dataType != Res_value::TYPE_NULL) {
1233 // Take care of resolving the found resource to its final value.
1234 //printf("Resolving attribute reference\n");
Dianne Hackborn0d221012009-07-29 15:41:19 -07001235 ssize_t newBlock = res.resolveReference(&value, block, &resid,
1236 &typeSetFlags, &config);
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001237 if (kThrowOnBadId) {
1238 if (newBlock == BAD_INDEX) {
1239 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
1240 return JNI_FALSE;
1241 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001242 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001243 if (newBlock >= 0) block = newBlock;
1244 }
1245
1246 // Deal with the special @null value -- it turns back to TYPE_NULL.
1247 if (value.dataType == Res_value::TYPE_REFERENCE && value.data == 0) {
1248 value.dataType = Res_value::TYPE_NULL;
Alan Viverettef2969402014-10-29 17:09:36 -07001249 value.data = Res_value::DATA_NULL_UNDEFINED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001250 }
1251
1252 //printf("Attribute 0x%08x: final type=0x%x, data=0x%08x\n", curIdent, value.dataType, value.data);
1253
1254 // Write the final value back to Java.
1255 dest[STYLE_TYPE] = value.dataType;
1256 dest[STYLE_DATA] = value.data;
Ashok Bhat896043d2014-01-17 16:02:38 +00001257 dest[STYLE_ASSET_COOKIE] = reinterpret_cast<jint>(res.getTableCookie(block));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001258 dest[STYLE_RESOURCE_ID] = resid;
1259 dest[STYLE_CHANGING_CONFIGURATIONS] = typeSetFlags;
Dianne Hackborn0d221012009-07-29 15:41:19 -07001260 dest[STYLE_DENSITY] = config.density;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001261 dest += STYLE_NUM_ENTRIES;
1262 i+= STYLE_NUM_ENTRIES;
1263 arrayEnt++;
1264 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001265
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001266 i /= STYLE_NUM_ENTRIES;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001267
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001268 res.unlock();
Elliott Hughes69a017b2011-04-08 14:10:28 -07001269
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001270 env->ReleasePrimitiveArrayCritical(outValues, baseDest, 0);
Elliott Hughes69a017b2011-04-08 14:10:28 -07001271
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001272 return i;
1273}
1274
Ashok Bhat896043d2014-01-17 16:02:38 +00001275static jlong android_content_AssetManager_openXmlAssetNative(JNIEnv* env, jobject clazz,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001276 jint cookie,
1277 jstring fileName)
1278{
1279 AssetManager* am = assetManagerForJavaObject(env, clazz);
1280 if (am == NULL) {
1281 return 0;
1282 }
1283
Steve Block71f2cf12011-10-20 11:56:00 +01001284 ALOGV("openXmlAsset in %p (Java object %p)\n", am, clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001285
Elliott Hughes69a017b2011-04-08 14:10:28 -07001286 ScopedUtfChars fileName8(env, fileName);
1287 if (fileName8.c_str() == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001288 return 0;
1289 }
1290
Adam Lesinskide898ff2014-01-29 18:20:45 -08001291 int32_t assetCookie = static_cast<int32_t>(cookie);
1292 Asset* a = assetCookie
1293 ? am->openNonAsset(assetCookie, fileName8.c_str(), Asset::ACCESS_BUFFER)
1294 : am->openNonAsset(fileName8.c_str(), Asset::ACCESS_BUFFER, &assetCookie);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001295
1296 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001297 jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001298 return 0;
1299 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001300
Adam Lesinskide898ff2014-01-29 18:20:45 -08001301 const DynamicRefTable* dynamicRefTable =
1302 am->getResources().getDynamicRefTableForCookie(assetCookie);
1303 ResXMLTree* block = new ResXMLTree(dynamicRefTable);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001304 status_t err = block->setTo(a->getBuffer(true), a->getLength(), true);
1305 a->close();
1306 delete a;
1307
1308 if (err != NO_ERROR) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001309 jniThrowException(env, "java/io/FileNotFoundException", "Corrupt XML binary file");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001310 return 0;
1311 }
1312
Ashok Bhat896043d2014-01-17 16:02:38 +00001313 return reinterpret_cast<jlong>(block);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001314}
1315
1316static jintArray android_content_AssetManager_getArrayStringInfo(JNIEnv* env, jobject clazz,
1317 jint arrayResId)
1318{
1319 AssetManager* am = assetManagerForJavaObject(env, clazz);
1320 if (am == NULL) {
1321 return NULL;
1322 }
1323 const ResTable& res(am->getResources());
1324
1325 const ResTable::bag_entry* startOfBag;
1326 const ssize_t N = res.lockBag(arrayResId, &startOfBag);
1327 if (N < 0) {
1328 return NULL;
1329 }
1330
1331 jintArray array = env->NewIntArray(N * 2);
1332 if (array == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001333 res.unlockBag(startOfBag);
1334 return NULL;
1335 }
1336
1337 Res_value value;
1338 const ResTable::bag_entry* bag = startOfBag;
1339 for (size_t i = 0, j = 0; ((ssize_t)i)<N; i++, bag++) {
1340 jint stringIndex = -1;
1341 jint stringBlock = 0;
1342 value = bag->map.value;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001343
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001344 // Take care of resolving the found resource to its final value.
1345 stringBlock = res.resolveReference(&value, bag->stringBlock, NULL);
1346 if (value.dataType == Res_value::TYPE_STRING) {
1347 stringIndex = value.data;
1348 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001349
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001350 if (kThrowOnBadId) {
1351 if (stringBlock == BAD_INDEX) {
1352 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
1353 return array;
1354 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001355 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001356
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001357 //todo: It might be faster to allocate a C array to contain
1358 // the blocknums and indices, put them in there and then
1359 // do just one SetIntArrayRegion()
1360 env->SetIntArrayRegion(array, j, 1, &stringBlock);
1361 env->SetIntArrayRegion(array, j + 1, 1, &stringIndex);
1362 j = j + 2;
1363 }
1364 res.unlockBag(startOfBag);
1365 return array;
1366}
1367
1368static jobjectArray android_content_AssetManager_getArrayStringResource(JNIEnv* env, jobject clazz,
1369 jint arrayResId)
1370{
1371 AssetManager* am = assetManagerForJavaObject(env, clazz);
1372 if (am == NULL) {
1373 return NULL;
1374 }
1375 const ResTable& res(am->getResources());
1376
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001377 const ResTable::bag_entry* startOfBag;
1378 const ssize_t N = res.lockBag(arrayResId, &startOfBag);
1379 if (N < 0) {
1380 return NULL;
1381 }
1382
Vladimir Markoaa5fe3d2013-06-17 12:46:22 +01001383 jobjectArray array = env->NewObjectArray(N, g_stringClass, NULL);
Kenny Root485dd212010-05-06 16:06:48 -07001384 if (env->ExceptionCheck()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001385 res.unlockBag(startOfBag);
1386 return NULL;
1387 }
1388
1389 Res_value value;
1390 const ResTable::bag_entry* bag = startOfBag;
1391 size_t strLen = 0;
1392 for (size_t i=0; ((ssize_t)i)<N; i++, bag++) {
1393 value = bag->map.value;
1394 jstring str = NULL;
Kenny Root780d2a12010-02-22 22:36:26 -08001395
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001396 // Take care of resolving the found resource to its final value.
1397 ssize_t block = res.resolveReference(&value, bag->stringBlock, NULL);
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001398 if (kThrowOnBadId) {
1399 if (block == BAD_INDEX) {
1400 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
1401 return array;
1402 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001403 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001404 if (value.dataType == Res_value::TYPE_STRING) {
Kenny Root780d2a12010-02-22 22:36:26 -08001405 const ResStringPool* pool = res.getTableStringBlock(block);
1406 const char* str8 = pool->string8At(value.data, &strLen);
1407 if (str8 != NULL) {
1408 str = env->NewStringUTF(str8);
1409 } else {
1410 const char16_t* str16 = pool->stringAt(value.data, &strLen);
Dan Albert66987492014-11-20 11:41:21 -08001411 str = env->NewString(reinterpret_cast<const jchar*>(str16),
1412 strLen);
Kenny Root485dd212010-05-06 16:06:48 -07001413 }
1414
1415 // If one of our NewString{UTF} calls failed due to memory, an
1416 // exception will be pending.
1417 if (env->ExceptionCheck()) {
1418 res.unlockBag(startOfBag);
1419 return NULL;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001420 }
Kenny Root780d2a12010-02-22 22:36:26 -08001421
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001422 env->SetObjectArrayElement(array, i, str);
Kenny Root485dd212010-05-06 16:06:48 -07001423
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001424 // str is not NULL at that point, otherwise ExceptionCheck would have been true.
1425 // If we have a large amount of strings in our array, we might
1426 // overflow the local reference table of the VM.
Kenny Root485dd212010-05-06 16:06:48 -07001427 env->DeleteLocalRef(str);
1428 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001429 }
1430 res.unlockBag(startOfBag);
1431 return array;
1432}
1433
1434static jintArray android_content_AssetManager_getArrayIntResource(JNIEnv* env, jobject clazz,
1435 jint arrayResId)
1436{
1437 AssetManager* am = assetManagerForJavaObject(env, clazz);
1438 if (am == NULL) {
1439 return NULL;
1440 }
1441 const ResTable& res(am->getResources());
1442
1443 const ResTable::bag_entry* startOfBag;
1444 const ssize_t N = res.lockBag(arrayResId, &startOfBag);
1445 if (N < 0) {
1446 return NULL;
1447 }
1448
1449 jintArray array = env->NewIntArray(N);
1450 if (array == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001451 res.unlockBag(startOfBag);
1452 return NULL;
1453 }
1454
1455 Res_value value;
1456 const ResTable::bag_entry* bag = startOfBag;
1457 for (size_t i=0; ((ssize_t)i)<N; i++, bag++) {
1458 value = bag->map.value;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001459
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001460 // Take care of resolving the found resource to its final value.
1461 ssize_t block = res.resolveReference(&value, bag->stringBlock, NULL);
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001462 if (kThrowOnBadId) {
1463 if (block == BAD_INDEX) {
1464 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
1465 return array;
1466 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001467 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001468 if (value.dataType >= Res_value::TYPE_FIRST_INT
1469 && value.dataType <= Res_value::TYPE_LAST_INT) {
1470 int intVal = value.data;
1471 env->SetIntArrayRegion(array, i, 1, &intVal);
1472 }
1473 }
1474 res.unlockBag(startOfBag);
1475 return array;
1476}
1477
Jon Miranda042ad632014-09-03 17:57:35 -07001478static jintArray android_content_AssetManager_getStyleAttributes(JNIEnv* env, jobject clazz,
1479 jint styleId)
1480{
1481 AssetManager* am = assetManagerForJavaObject(env, clazz);
1482 if (am == NULL) {
1483 return NULL;
1484 }
1485 const ResTable& res(am->getResources());
1486
1487 const ResTable::bag_entry* startOfBag;
1488 const ssize_t N = res.lockBag(styleId, &startOfBag);
1489 if (N < 0) {
1490 return NULL;
1491 }
1492
1493 jintArray array = env->NewIntArray(N);
1494 if (array == NULL) {
1495 res.unlockBag(startOfBag);
1496 return NULL;
1497 }
1498
Jon Miranda042ad632014-09-03 17:57:35 -07001499 const ResTable::bag_entry* bag = startOfBag;
1500 for (size_t i=0; ((ssize_t)i)<N; i++, bag++) {
1501 int resourceId = bag->map.name.ident;
1502 env->SetIntArrayRegion(array, i, 1, &resourceId);
1503 }
1504 res.unlockBag(startOfBag);
1505 return array;
1506}
1507
Mårten Kongstad48d22322014-01-31 14:43:27 +01001508static void android_content_AssetManager_init(JNIEnv* env, jobject clazz, jboolean isSystem)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001509{
1510 AssetManager* am = new AssetManager();
1511 if (am == NULL) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001512 jniThrowException(env, "java/lang/OutOfMemoryError", "");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001513 return;
1514 }
1515
1516 am->addDefaultAssets();
1517
Steve Block71f2cf12011-10-20 11:56:00 +01001518 ALOGV("Created AssetManager %p for Java object %p\n", am, clazz);
Ashok Bhat896043d2014-01-17 16:02:38 +00001519 env->SetLongField(clazz, gAssetManagerOffsets.mObject, reinterpret_cast<jlong>(am));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001520}
1521
1522static void android_content_AssetManager_destroy(JNIEnv* env, jobject clazz)
1523{
1524 AssetManager* am = (AssetManager*)
Ashok Bhat896043d2014-01-17 16:02:38 +00001525 (env->GetLongField(clazz, gAssetManagerOffsets.mObject));
Steve Block71f2cf12011-10-20 11:56:00 +01001526 ALOGV("Destroying AssetManager %p for Java object %p\n", am, clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001527 if (am != NULL) {
1528 delete am;
Ashok Bhat896043d2014-01-17 16:02:38 +00001529 env->SetLongField(clazz, gAssetManagerOffsets.mObject, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001530 }
1531}
1532
1533static jint android_content_AssetManager_getGlobalAssetCount(JNIEnv* env, jobject clazz)
1534{
1535 return Asset::getGlobalCount();
1536}
1537
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07001538static jobject android_content_AssetManager_getAssetAllocations(JNIEnv* env, jobject clazz)
1539{
1540 String8 alloc = Asset::getAssetAllocations();
1541 if (alloc.length() <= 0) {
1542 return NULL;
1543 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001544
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07001545 jstring str = env->NewStringUTF(alloc.string());
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07001546 return str;
1547}
1548
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001549static jint android_content_AssetManager_getGlobalAssetManagerCount(JNIEnv* env, jobject clazz)
1550{
1551 return AssetManager::getGlobalCount();
1552}
1553
1554// ----------------------------------------------------------------------------
1555
1556/*
1557 * JNI registration.
1558 */
Daniel Micay76f6a862015-09-19 17:31:01 -04001559static const JNINativeMethod gAssetManagerMethods[] = {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001560 /* name, signature, funcPtr */
1561
1562 // Basic asset stuff.
Ashok Bhat896043d2014-01-17 16:02:38 +00001563 { "openAsset", "(Ljava/lang/String;I)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001564 (void*) android_content_AssetManager_openAsset },
1565 { "openAssetFd", "(Ljava/lang/String;[J)Landroid/os/ParcelFileDescriptor;",
1566 (void*) android_content_AssetManager_openAssetFd },
Ashok Bhat896043d2014-01-17 16:02:38 +00001567 { "openNonAssetNative", "(ILjava/lang/String;I)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001568 (void*) android_content_AssetManager_openNonAssetNative },
1569 { "openNonAssetFdNative", "(ILjava/lang/String;[J)Landroid/os/ParcelFileDescriptor;",
1570 (void*) android_content_AssetManager_openNonAssetFdNative },
1571 { "list", "(Ljava/lang/String;)[Ljava/lang/String;",
1572 (void*) android_content_AssetManager_list },
Ashok Bhat896043d2014-01-17 16:02:38 +00001573 { "destroyAsset", "(J)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001574 (void*) android_content_AssetManager_destroyAsset },
Ashok Bhat896043d2014-01-17 16:02:38 +00001575 { "readAssetChar", "(J)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001576 (void*) android_content_AssetManager_readAssetChar },
Ashok Bhat896043d2014-01-17 16:02:38 +00001577 { "readAsset", "(J[BII)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001578 (void*) android_content_AssetManager_readAsset },
Ashok Bhat896043d2014-01-17 16:02:38 +00001579 { "seekAsset", "(JJI)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001580 (void*) android_content_AssetManager_seekAsset },
John Reck32995222016-10-07 11:02:20 -07001581 { "getAssetLength", "(J)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001582 (void*) android_content_AssetManager_getAssetLength },
John Reck32995222016-10-07 11:02:20 -07001583 { "getAssetRemainingLength", "(J)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001584 (void*) android_content_AssetManager_getAssetRemainingLength },
Tao Baia6d7e3f2015-09-01 18:49:54 -07001585 { "addAssetPathNative", "(Ljava/lang/String;Z)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001586 (void*) android_content_AssetManager_addAssetPath },
Mårten Kongstad30113132014-11-07 10:52:17 +01001587 { "addOverlayPathNative", "(Ljava/lang/String;)I",
Mårten Kongstad48d22322014-01-31 14:43:27 +01001588 (void*) android_content_AssetManager_addOverlayPath },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001589 { "isUpToDate", "()Z",
1590 (void*) android_content_AssetManager_isUpToDate },
1591
1592 // Resources.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001593 { "getLocales", "()[Ljava/lang/String;",
1594 (void*) android_content_AssetManager_getLocales },
Roozbeh Pournader1c686f22015-12-18 14:22:14 -08001595 { "getNonSystemLocales", "()[Ljava/lang/String;",
1596 (void*) android_content_AssetManager_getNonSystemLocales },
Filip Gruszczynski23493322015-07-29 17:02:59 -07001597 { "getSizeConfigurations", "()[Landroid/content/res/Configuration;",
1598 (void*) android_content_AssetManager_getSizeConfigurations },
Romain Guy408afbf2017-01-25 10:23:03 -08001599 { "setConfiguration", "(IILjava/lang/String;IIIIIIIIIIIIIII)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001600 (void*) android_content_AssetManager_setConfiguration },
John Reck32995222016-10-07 11:02:20 -07001601 { "getResourceIdentifier","(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001602 (void*) android_content_AssetManager_getResourceIdentifier },
John Reck32995222016-10-07 11:02:20 -07001603 { "getResourceName","(I)Ljava/lang/String;",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001604 (void*) android_content_AssetManager_getResourceName },
John Reck32995222016-10-07 11:02:20 -07001605 { "getResourcePackageName","(I)Ljava/lang/String;",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001606 (void*) android_content_AssetManager_getResourcePackageName },
John Reck32995222016-10-07 11:02:20 -07001607 { "getResourceTypeName","(I)Ljava/lang/String;",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001608 (void*) android_content_AssetManager_getResourceTypeName },
John Reck32995222016-10-07 11:02:20 -07001609 { "getResourceEntryName","(I)Ljava/lang/String;",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001610 (void*) android_content_AssetManager_getResourceEntryName },
John Reck32995222016-10-07 11:02:20 -07001611 { "loadResourceValue","(ISLandroid/util/TypedValue;Z)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001612 (void*) android_content_AssetManager_loadResourceValue },
John Reck32995222016-10-07 11:02:20 -07001613 { "loadResourceBagValue","(IILandroid/util/TypedValue;Z)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001614 (void*) android_content_AssetManager_loadResourceBagValue },
John Reck32995222016-10-07 11:02:20 -07001615 { "getStringBlockCount","()I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001616 (void*) android_content_AssetManager_getStringBlockCount },
John Reck32995222016-10-07 11:02:20 -07001617 { "getNativeStringBlock","(I)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001618 (void*) android_content_AssetManager_getNativeStringBlock },
1619 { "getCookieName","(I)Ljava/lang/String;",
1620 (void*) android_content_AssetManager_getCookieName },
Adam Lesinskide898ff2014-01-29 18:20:45 -08001621 { "getAssignedPackageIdentifiers","()Landroid/util/SparseArray;",
1622 (void*) android_content_AssetManager_getAssignedPackageIdentifiers },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001623
1624 // Themes.
Ashok Bhat896043d2014-01-17 16:02:38 +00001625 { "newTheme", "()J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001626 (void*) android_content_AssetManager_newTheme },
Ashok Bhat896043d2014-01-17 16:02:38 +00001627 { "deleteTheme", "(J)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001628 (void*) android_content_AssetManager_deleteTheme },
Ashok Bhat896043d2014-01-17 16:02:38 +00001629 { "applyThemeStyle", "(JIZ)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001630 (void*) android_content_AssetManager_applyThemeStyle },
Ashok Bhat896043d2014-01-17 16:02:38 +00001631 { "copyTheme", "(JJ)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001632 (void*) android_content_AssetManager_copyTheme },
Alan Viverettee54d2452015-05-06 10:41:43 -07001633 { "clearTheme", "(J)V",
1634 (void*) android_content_AssetManager_clearTheme },
John Reck32995222016-10-07 11:02:20 -07001635 { "loadThemeAttributeValue", "(JILandroid/util/TypedValue;Z)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001636 (void*) android_content_AssetManager_loadThemeAttributeValue },
John Reck32995222016-10-07 11:02:20 -07001637 { "getThemeChangingConfigurations", "(J)I",
Alan Viverettec1d52792015-05-05 09:49:03 -07001638 (void*) android_content_AssetManager_getThemeChangingConfigurations },
Ashok Bhat896043d2014-01-17 16:02:38 +00001639 { "dumpTheme", "(JILjava/lang/String;Ljava/lang/String;)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001640 (void*) android_content_AssetManager_dumpTheme },
John Reckf32adf42016-11-23 10:39:40 -08001641 { "applyStyle","(JIIJ[IIJJ)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001642 (void*) android_content_AssetManager_applyStyle },
John Reck32995222016-10-07 11:02:20 -07001643 { "resolveAttrs","(JII[I[I[I[I)Z",
Alan Viverette607bd842014-09-12 12:36:35 -07001644 (void*) android_content_AssetManager_resolveAttrs },
John Reck32995222016-10-07 11:02:20 -07001645 { "retrieveAttributes","(J[I[I[I)Z",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001646 (void*) android_content_AssetManager_retrieveAttributes },
John Reck32995222016-10-07 11:02:20 -07001647 { "getArraySize","(I)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001648 (void*) android_content_AssetManager_getArraySize },
John Reck32995222016-10-07 11:02:20 -07001649 { "retrieveArray","(I[I)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001650 (void*) android_content_AssetManager_retrieveArray },
1651
1652 // XML files.
Ashok Bhat896043d2014-01-17 16:02:38 +00001653 { "openXmlAssetNative", "(ILjava/lang/String;)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001654 (void*) android_content_AssetManager_openXmlAssetNative },
1655
1656 // Arrays.
1657 { "getArrayStringResource","(I)[Ljava/lang/String;",
1658 (void*) android_content_AssetManager_getArrayStringResource },
John Reck32995222016-10-07 11:02:20 -07001659 { "getArrayStringInfo","(I)[I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001660 (void*) android_content_AssetManager_getArrayStringInfo },
John Reck32995222016-10-07 11:02:20 -07001661 { "getArrayIntResource","(I)[I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001662 (void*) android_content_AssetManager_getArrayIntResource },
John Reck32995222016-10-07 11:02:20 -07001663 { "getStyleAttributes","(I)[I",
Jon Miranda042ad632014-09-03 17:57:35 -07001664 (void*) android_content_AssetManager_getStyleAttributes },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001665
1666 // Bookkeeping.
Mårten Kongstad48d22322014-01-31 14:43:27 +01001667 { "init", "(Z)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001668 (void*) android_content_AssetManager_init },
1669 { "destroy", "()V",
1670 (void*) android_content_AssetManager_destroy },
1671 { "getGlobalAssetCount", "()I",
1672 (void*) android_content_AssetManager_getGlobalAssetCount },
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07001673 { "getAssetAllocations", "()Ljava/lang/String;",
1674 (void*) android_content_AssetManager_getAssetAllocations },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001675 { "getGlobalAssetManagerCount", "()I",
Andreas Gampe32812612014-11-11 00:16:00 -08001676 (void*) android_content_AssetManager_getGlobalAssetManagerCount },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001677};
1678
1679int register_android_content_AssetManager(JNIEnv* env)
1680{
Andreas Gampe987f79f2014-11-18 17:29:46 -08001681 jclass typedValue = FindClassOrDie(env, "android/util/TypedValue");
1682 gTypedValueOffsets.mType = GetFieldIDOrDie(env, typedValue, "type", "I");
1683 gTypedValueOffsets.mData = GetFieldIDOrDie(env, typedValue, "data", "I");
1684 gTypedValueOffsets.mString = GetFieldIDOrDie(env, typedValue, "string",
1685 "Ljava/lang/CharSequence;");
1686 gTypedValueOffsets.mAssetCookie = GetFieldIDOrDie(env, typedValue, "assetCookie", "I");
1687 gTypedValueOffsets.mResourceId = GetFieldIDOrDie(env, typedValue, "resourceId", "I");
1688 gTypedValueOffsets.mChangingConfigurations = GetFieldIDOrDie(env, typedValue,
1689 "changingConfigurations", "I");
1690 gTypedValueOffsets.mDensity = GetFieldIDOrDie(env, typedValue, "density", "I");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001691
Andreas Gampe987f79f2014-11-18 17:29:46 -08001692 jclass assetFd = FindClassOrDie(env, "android/content/res/AssetFileDescriptor");
1693 gAssetFileDescriptorOffsets.mFd = GetFieldIDOrDie(env, assetFd, "mFd",
1694 "Landroid/os/ParcelFileDescriptor;");
1695 gAssetFileDescriptorOffsets.mStartOffset = GetFieldIDOrDie(env, assetFd, "mStartOffset", "J");
1696 gAssetFileDescriptorOffsets.mLength = GetFieldIDOrDie(env, assetFd, "mLength", "J");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001697
Andreas Gampe987f79f2014-11-18 17:29:46 -08001698 jclass assetManager = FindClassOrDie(env, "android/content/res/AssetManager");
1699 gAssetManagerOffsets.mObject = GetFieldIDOrDie(env, assetManager, "mObject", "J");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001700
Andreas Gampe987f79f2014-11-18 17:29:46 -08001701 jclass stringClass = FindClassOrDie(env, "java/lang/String");
1702 g_stringClass = MakeGlobalRefOrDie(env, stringClass);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001703
Andreas Gampe987f79f2014-11-18 17:29:46 -08001704 jclass sparseArrayClass = FindClassOrDie(env, "android/util/SparseArray");
1705 gSparseArrayOffsets.classObject = MakeGlobalRefOrDie(env, sparseArrayClass);
1706 gSparseArrayOffsets.constructor = GetMethodIDOrDie(env, gSparseArrayOffsets.classObject,
1707 "<init>", "()V");
1708 gSparseArrayOffsets.put = GetMethodIDOrDie(env, gSparseArrayOffsets.classObject, "put",
1709 "(ILjava/lang/Object;)V");
Adam Lesinskide898ff2014-01-29 18:20:45 -08001710
Filip Gruszczynski23493322015-07-29 17:02:59 -07001711 jclass configurationClass = FindClassOrDie(env, "android/content/res/Configuration");
1712 gConfigurationOffsets.classObject = MakeGlobalRefOrDie(env, configurationClass);
1713 gConfigurationOffsets.constructor = GetMethodIDOrDie(env, configurationClass,
1714 "<init>", "()V");
1715 gConfigurationOffsets.mSmallestScreenWidthDpOffset = GetFieldIDOrDie(env, configurationClass,
1716 "smallestScreenWidthDp", "I");
1717 gConfigurationOffsets.mScreenWidthDpOffset = GetFieldIDOrDie(env, configurationClass,
1718 "screenWidthDp", "I");
1719 gConfigurationOffsets.mScreenHeightDpOffset = GetFieldIDOrDie(env, configurationClass,
1720 "screenHeightDp", "I");
1721
Andreas Gampe987f79f2014-11-18 17:29:46 -08001722 return RegisterMethodsOrDie(env, "android/content/res/AssetManager", gAssetManagerMethods,
1723 NELEM(gAssetManagerMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001724}
1725
1726}; // namespace android