blob: d382f245e0d78c101a3d3970bc1d447a6f1fcca4 [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
Mårten Kongstad48d22322014-01-31 14:43:27 +0100122// This is called by zygote (running as user root) as part of preloadResources.
123static void verifySystemIdmaps()
124{
125 pid_t pid;
126 char system_id[10];
127
128 snprintf(system_id, sizeof(system_id), "%d", AID_SYSTEM);
129
130 switch (pid = fork()) {
131 case -1:
132 ALOGE("failed to fork for idmap: %s", strerror(errno));
133 break;
134 case 0: // child
135 {
136 struct __user_cap_header_struct capheader;
137 struct __user_cap_data_struct capdata;
138
139 memset(&capheader, 0, sizeof(capheader));
140 memset(&capdata, 0, sizeof(capdata));
141
142 capheader.version = _LINUX_CAPABILITY_VERSION;
143 capheader.pid = 0;
144
145 if (capget(&capheader, &capdata) != 0) {
146 ALOGE("capget: %s\n", strerror(errno));
147 exit(1);
148 }
149
150 capdata.effective = capdata.permitted;
151 if (capset(&capheader, &capdata) != 0) {
152 ALOGE("capset: %s\n", strerror(errno));
153 exit(1);
154 }
155
156 if (setgid(AID_SYSTEM) != 0) {
157 ALOGE("setgid: %s\n", strerror(errno));
158 exit(1);
159 }
160
161 if (setuid(AID_SYSTEM) != 0) {
162 ALOGE("setuid: %s\n", strerror(errno));
163 exit(1);
164 }
165
Mårten Kongstad83ab0d72015-03-20 12:57:36 +0100166 // Generic idmap parameters
Jakub Adamek56b99872016-10-20 15:07:57 +0100167 const char* argv[8];
Mårten Kongstad83ab0d72015-03-20 12:57:36 +0100168 int argc = 0;
169 struct stat st;
170
171 memset(argv, NULL, sizeof(argv));
172 argv[argc++] = AssetManager::IDMAP_BIN;
173 argv[argc++] = "--scan";
174 argv[argc++] = AssetManager::TARGET_PACKAGE_NAME;
175 argv[argc++] = AssetManager::TARGET_APK_PATH;
176 argv[argc++] = AssetManager::IDMAP_DIR;
177
Jakub Adamek54dcaab2016-10-19 11:46:13 +0100178 // Directories to scan for overlays: if OVERLAY_THEME_DIR_PROPERTY is defined,
179 // use OVERLAY_DIR/<value of OVERLAY_THEME_DIR_PROPERTY> in addition to OVERLAY_DIR.
Jakub Adamek1c15c632016-09-23 09:07:11 +0100180 char subdir[PROP_VALUE_MAX];
Jason Monk2dc804be2016-11-07 11:17:02 -0500181 int len = __system_property_get(AssetManager::OVERLAY_THEME_DIR_PERSIST_PROPERTY,
182 subdir);
183 if (len == 0) {
184 len = __system_property_get(AssetManager::OVERLAY_THEME_DIR_PROPERTY, subdir);
185 }
Jakub Adamek1c15c632016-09-23 09:07:11 +0100186 if (len > 0) {
Jakub Adamek1f36a212016-10-17 14:53:40 +0100187 String8 overlayPath = String8(AssetManager::OVERLAY_DIR) + "/" + subdir;
188 if (stat(overlayPath.string(), &st) == 0) {
189 argv[argc++] = overlayPath.string();
190 }
Jakub Adamekc03d9482016-09-30 09:19:09 +0100191 }
Jakub Adamek1f36a212016-10-17 14:53:40 +0100192 if (stat(AssetManager::OVERLAY_DIR, &st) == 0) {
193 argv[argc++] = AssetManager::OVERLAY_DIR;
Jakub Adamek1c15c632016-09-23 09:07:11 +0100194 }
Mårten Kongstad83ab0d72015-03-20 12:57:36 +0100195
196 // Finally, invoke idmap (if any overlay directory exists)
197 if (argc > 5) {
198 execv(AssetManager::IDMAP_BIN, (char* const*)argv);
Jakub Adamek56b99872016-10-20 15:07:57 +0100199 ALOGE("failed to execv for idmap: %s", strerror(errno));
Mårten Kongstad83ab0d72015-03-20 12:57:36 +0100200 exit(1); // should never get here
201 } else {
202 exit(0);
203 }
Mårten Kongstad48d22322014-01-31 14:43:27 +0100204 }
205 break;
206 default: // parent
207 waitpid(pid, NULL, 0);
208 break;
209 }
210}
211
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800212// ----------------------------------------------------------------------------
213
214// this guy is exported to other jni routines
215AssetManager* assetManagerForJavaObject(JNIEnv* env, jobject obj)
216{
Ashok Bhat896043d2014-01-17 16:02:38 +0000217 jlong amHandle = env->GetLongField(obj, gAssetManagerOffsets.mObject);
218 AssetManager* am = reinterpret_cast<AssetManager*>(amHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800219 if (am != NULL) {
220 return am;
221 }
222 jniThrowException(env, "java/lang/IllegalStateException", "AssetManager has been finalized!");
223 return NULL;
224}
225
Ashok Bhat896043d2014-01-17 16:02:38 +0000226static jlong android_content_AssetManager_openAsset(JNIEnv* env, jobject clazz,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800227 jstring fileName, jint mode)
228{
229 AssetManager* am = assetManagerForJavaObject(env, clazz);
230 if (am == NULL) {
231 return 0;
232 }
233
Steve Block71f2cf12011-10-20 11:56:00 +0100234 ALOGV("openAsset in %p (Java object %p)\n", am, clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800235
Elliott Hughes69a017b2011-04-08 14:10:28 -0700236 ScopedUtfChars fileName8(env, fileName);
237 if (fileName8.c_str() == NULL) {
Ashok Bhat896043d2014-01-17 16:02:38 +0000238 jniThrowException(env, "java/lang/IllegalArgumentException", "Empty file name");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800239 return -1;
240 }
241
242 if (mode != Asset::ACCESS_UNKNOWN && mode != Asset::ACCESS_RANDOM
243 && mode != Asset::ACCESS_STREAMING && mode != Asset::ACCESS_BUFFER) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -0700244 jniThrowException(env, "java/lang/IllegalArgumentException", "Bad access mode");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800245 return -1;
246 }
247
Elliott Hughes69a017b2011-04-08 14:10:28 -0700248 Asset* a = am->open(fileName8.c_str(), (Asset::AccessMode)mode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800249
250 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700251 jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800252 return -1;
253 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800254
255 //printf("Created Asset Stream: %p\n", a);
256
Ashok Bhat896043d2014-01-17 16:02:38 +0000257 return reinterpret_cast<jlong>(a);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800258}
259
260static jobject returnParcelFileDescriptor(JNIEnv* env, Asset* a, jlongArray outOffsets)
261{
Kenny Rootddb76c42010-11-24 12:56:06 -0800262 off64_t startOffset, length;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800263 int fd = a->openFileDescriptor(&startOffset, &length);
264 delete a;
Elliott Hughes69a017b2011-04-08 14:10:28 -0700265
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800266 if (fd < 0) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -0700267 jniThrowException(env, "java/io/FileNotFoundException",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800268 "This file can not be opened as a file descriptor; it is probably compressed");
269 return NULL;
270 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700271
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800272 jlong* offsets = (jlong*)env->GetPrimitiveArrayCritical(outOffsets, 0);
273 if (offsets == NULL) {
274 close(fd);
275 return NULL;
276 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700277
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800278 offsets[0] = startOffset;
279 offsets[1] = length;
Elliott Hughes69a017b2011-04-08 14:10:28 -0700280
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800281 env->ReleasePrimitiveArrayCritical(outOffsets, offsets, 0);
Elliott Hughes69a017b2011-04-08 14:10:28 -0700282
Elliott Hughesa3804cf2011-04-11 16:50:19 -0700283 jobject fileDesc = jniCreateFileDescriptor(env, fd);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800284 if (fileDesc == NULL) {
285 close(fd);
286 return NULL;
287 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700288
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800289 return newParcelFileDescriptor(env, fileDesc);
290}
291
292static jobject android_content_AssetManager_openAssetFd(JNIEnv* env, jobject clazz,
293 jstring fileName, jlongArray outOffsets)
294{
295 AssetManager* am = assetManagerForJavaObject(env, clazz);
296 if (am == NULL) {
297 return NULL;
298 }
299
Steve Block71f2cf12011-10-20 11:56:00 +0100300 ALOGV("openAssetFd in %p (Java object %p)\n", am, clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800301
Elliott Hughes69a017b2011-04-08 14:10:28 -0700302 ScopedUtfChars fileName8(env, fileName);
303 if (fileName8.c_str() == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800304 return NULL;
305 }
306
Elliott Hughes69a017b2011-04-08 14:10:28 -0700307 Asset* a = am->open(fileName8.c_str(), Asset::ACCESS_RANDOM);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800308
309 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700310 jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800311 return NULL;
312 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800313
314 //printf("Created Asset Stream: %p\n", a);
315
316 return returnParcelFileDescriptor(env, a, outOffsets);
317}
318
Ashok Bhat896043d2014-01-17 16:02:38 +0000319static jlong android_content_AssetManager_openNonAssetNative(JNIEnv* env, jobject clazz,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800320 jint cookie,
321 jstring fileName,
322 jint mode)
323{
324 AssetManager* am = assetManagerForJavaObject(env, clazz);
325 if (am == NULL) {
326 return 0;
327 }
328
Steve Block71f2cf12011-10-20 11:56:00 +0100329 ALOGV("openNonAssetNative in %p (Java object %p)\n", am, clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800330
Elliott Hughes69a017b2011-04-08 14:10:28 -0700331 ScopedUtfChars fileName8(env, fileName);
332 if (fileName8.c_str() == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800333 return -1;
334 }
335
336 if (mode != Asset::ACCESS_UNKNOWN && mode != Asset::ACCESS_RANDOM
337 && mode != Asset::ACCESS_STREAMING && mode != Asset::ACCESS_BUFFER) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -0700338 jniThrowException(env, "java/lang/IllegalArgumentException", "Bad access mode");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800339 return -1;
340 }
341
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800342 Asset* a = cookie
Narayan Kamath745d4ef2014-01-27 11:17:22 +0000343 ? am->openNonAsset(static_cast<int32_t>(cookie), fileName8.c_str(),
344 (Asset::AccessMode)mode)
Elliott Hughes69a017b2011-04-08 14:10:28 -0700345 : am->openNonAsset(fileName8.c_str(), (Asset::AccessMode)mode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800346
347 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700348 jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800349 return -1;
350 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800351
352 //printf("Created Asset Stream: %p\n", a);
353
Ashok Bhat896043d2014-01-17 16:02:38 +0000354 return reinterpret_cast<jlong>(a);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800355}
356
357static jobject android_content_AssetManager_openNonAssetFdNative(JNIEnv* env, jobject clazz,
358 jint cookie,
359 jstring fileName,
360 jlongArray outOffsets)
361{
362 AssetManager* am = assetManagerForJavaObject(env, clazz);
363 if (am == NULL) {
364 return NULL;
365 }
366
Steve Block71f2cf12011-10-20 11:56:00 +0100367 ALOGV("openNonAssetFd in %p (Java object %p)\n", am, clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800368
Elliott Hughes69a017b2011-04-08 14:10:28 -0700369 ScopedUtfChars fileName8(env, fileName);
370 if (fileName8.c_str() == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800371 return NULL;
372 }
373
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800374 Asset* a = cookie
Narayan Kamath745d4ef2014-01-27 11:17:22 +0000375 ? am->openNonAsset(static_cast<int32_t>(cookie), fileName8.c_str(), Asset::ACCESS_RANDOM)
Elliott Hughes69a017b2011-04-08 14:10:28 -0700376 : am->openNonAsset(fileName8.c_str(), Asset::ACCESS_RANDOM);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800377
378 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700379 jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800380 return NULL;
381 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800382
383 //printf("Created Asset Stream: %p\n", a);
384
385 return returnParcelFileDescriptor(env, a, outOffsets);
386}
387
388static jobjectArray android_content_AssetManager_list(JNIEnv* env, jobject clazz,
389 jstring fileName)
390{
391 AssetManager* am = assetManagerForJavaObject(env, clazz);
392 if (am == NULL) {
393 return NULL;
394 }
395
Elliott Hughes69a017b2011-04-08 14:10:28 -0700396 ScopedUtfChars fileName8(env, fileName);
397 if (fileName8.c_str() == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800398 return NULL;
399 }
400
Elliott Hughes69a017b2011-04-08 14:10:28 -0700401 AssetDir* dir = am->openDir(fileName8.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800402
403 if (dir == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700404 jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800405 return NULL;
406 }
407
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800408 size_t N = dir->getFileCount();
409
410 jobjectArray array = env->NewObjectArray(dir->getFileCount(),
Vladimir Markoaa5fe3d2013-06-17 12:46:22 +0100411 g_stringClass, NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800412 if (array == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800413 delete dir;
414 return NULL;
415 }
416
417 for (size_t i=0; i<N; i++) {
418 const String8& name = dir->getFileName(i);
419 jstring str = env->NewStringUTF(name.string());
420 if (str == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800421 delete dir;
422 return NULL;
423 }
424 env->SetObjectArrayElement(array, i, str);
Gilles Debunne4d4040b2010-08-26 15:59:54 -0700425 env->DeleteLocalRef(str);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800426 }
427
428 delete dir;
429
430 return array;
431}
432
433static void android_content_AssetManager_destroyAsset(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +0000434 jlong assetHandle)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800435{
Ashok Bhat896043d2014-01-17 16:02:38 +0000436 Asset* a = reinterpret_cast<Asset*>(assetHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800437
438 //printf("Destroying Asset Stream: %p\n", a);
439
440 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700441 jniThrowNullPointerException(env, "asset");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800442 return;
443 }
444
445 delete a;
446}
447
448static jint android_content_AssetManager_readAssetChar(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +0000449 jlong assetHandle)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800450{
Ashok Bhat896043d2014-01-17 16:02:38 +0000451 Asset* a = reinterpret_cast<Asset*>(assetHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800452
453 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700454 jniThrowNullPointerException(env, "asset");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800455 return -1;
456 }
457
458 uint8_t b;
459 ssize_t res = a->read(&b, 1);
460 return res == 1 ? b : -1;
461}
462
463static jint android_content_AssetManager_readAsset(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +0000464 jlong assetHandle, jbyteArray bArray,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800465 jint off, jint len)
466{
Ashok Bhat896043d2014-01-17 16:02:38 +0000467 Asset* a = reinterpret_cast<Asset*>(assetHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800468
469 if (a == NULL || bArray == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700470 jniThrowNullPointerException(env, "asset");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800471 return -1;
472 }
473
474 if (len == 0) {
475 return 0;
476 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700477
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800478 jsize bLen = env->GetArrayLength(bArray);
479 if (off < 0 || off >= bLen || len < 0 || len > bLen || (off+len) > bLen) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -0700480 jniThrowException(env, "java/lang/IndexOutOfBoundsException", "");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800481 return -1;
482 }
483
484 jbyte* b = env->GetByteArrayElements(bArray, NULL);
485 ssize_t res = a->read(b+off, len);
486 env->ReleaseByteArrayElements(bArray, b, 0);
487
Ashok Bhat896043d2014-01-17 16:02:38 +0000488 if (res > 0) return static_cast<jint>(res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800489
490 if (res < 0) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -0700491 jniThrowException(env, "java/io/IOException", "");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800492 }
493 return -1;
494}
495
496static jlong android_content_AssetManager_seekAsset(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +0000497 jlong assetHandle,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800498 jlong offset, jint whence)
499{
Ashok Bhat896043d2014-01-17 16:02:38 +0000500 Asset* a = reinterpret_cast<Asset*>(assetHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800501
502 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700503 jniThrowNullPointerException(env, "asset");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800504 return -1;
505 }
506
507 return a->seek(
508 offset, (whence > 0) ? SEEK_END : (whence < 0 ? SEEK_SET : SEEK_CUR));
509}
510
511static jlong android_content_AssetManager_getAssetLength(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +0000512 jlong assetHandle)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800513{
Ashok Bhat896043d2014-01-17 16:02:38 +0000514 Asset* a = reinterpret_cast<Asset*>(assetHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800515
516 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700517 jniThrowNullPointerException(env, "asset");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800518 return -1;
519 }
520
521 return a->getLength();
522}
523
524static jlong android_content_AssetManager_getAssetRemainingLength(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +0000525 jlong assetHandle)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800526{
Ashok Bhat896043d2014-01-17 16:02:38 +0000527 Asset* a = reinterpret_cast<Asset*>(assetHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800528
529 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700530 jniThrowNullPointerException(env, "asset");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800531 return -1;
532 }
533
534 return a->getRemainingLength();
535}
536
537static jint android_content_AssetManager_addAssetPath(JNIEnv* env, jobject clazz,
Tao Baia6d7e3f2015-09-01 18:49:54 -0700538 jstring path, jboolean appAsLib)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800539{
Elliott Hughes69a017b2011-04-08 14:10:28 -0700540 ScopedUtfChars path8(env, path);
541 if (path8.c_str() == NULL) {
Glenn Kasten129e19c2012-01-10 17:57:36 -0800542 return 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800543 }
544
545 AssetManager* am = assetManagerForJavaObject(env, clazz);
546 if (am == NULL) {
Glenn Kasten129e19c2012-01-10 17:57:36 -0800547 return 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800548 }
549
Narayan Kamath745d4ef2014-01-27 11:17:22 +0000550 int32_t cookie;
Tao Baia6d7e3f2015-09-01 18:49:54 -0700551 bool res = am->addAssetPath(String8(path8.c_str()), &cookie, appAsLib);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800552
Narayan Kamath745d4ef2014-01-27 11:17:22 +0000553 return (res) ? static_cast<jint>(cookie) : 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800554}
555
Mårten Kongstad48d22322014-01-31 14:43:27 +0100556static jint android_content_AssetManager_addOverlayPath(JNIEnv* env, jobject clazz,
557 jstring idmapPath)
558{
559 ScopedUtfChars idmapPath8(env, idmapPath);
560 if (idmapPath8.c_str() == NULL) {
561 return 0;
562 }
563
564 AssetManager* am = assetManagerForJavaObject(env, clazz);
565 if (am == NULL) {
566 return 0;
567 }
568
569 int32_t cookie;
570 bool res = am->addOverlayPath(String8(idmapPath8.c_str()), &cookie);
571
572 return (res) ? (jint)cookie : 0;
573}
574
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800575static jboolean android_content_AssetManager_isUpToDate(JNIEnv* env, jobject clazz)
576{
577 AssetManager* am = assetManagerForJavaObject(env, clazz);
578 if (am == NULL) {
579 return JNI_TRUE;
580 }
581 return am->isUpToDate() ? JNI_TRUE : JNI_FALSE;
582}
583
Roozbeh Pournader1c686f22015-12-18 14:22:14 -0800584static jobjectArray getLocales(JNIEnv* env, jobject clazz, bool includeSystemLocales)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800585{
586 Vector<String8> locales;
587
588 AssetManager* am = assetManagerForJavaObject(env, clazz);
589 if (am == NULL) {
590 return NULL;
591 }
592
Roozbeh Pournader1c686f22015-12-18 14:22:14 -0800593 am->getLocales(&locales, includeSystemLocales);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800594
595 const int N = locales.size();
596
597 jobjectArray result = env->NewObjectArray(N, g_stringClass, NULL);
598 if (result == NULL) {
599 return NULL;
600 }
601
602 for (int i=0; i<N; i++) {
Gilles Debunne0db187a2010-08-27 11:51:34 -0700603 jstring str = env->NewStringUTF(locales[i].string());
Gilles Debunne4d4040b2010-08-26 15:59:54 -0700604 if (str == NULL) {
605 return NULL;
606 }
607 env->SetObjectArrayElement(result, i, str);
608 env->DeleteLocalRef(str);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800609 }
610
611 return result;
612}
613
Roozbeh Pournader1c686f22015-12-18 14:22:14 -0800614static jobjectArray android_content_AssetManager_getLocales(JNIEnv* env, jobject clazz)
615{
616 return getLocales(env, clazz, true /* include system locales */);
617}
618
619static jobjectArray android_content_AssetManager_getNonSystemLocales(JNIEnv* env, jobject clazz)
620{
621 return getLocales(env, clazz, false /* don't include system locales */);
622}
623
Filip Gruszczynski23493322015-07-29 17:02:59 -0700624static jobject constructConfigurationObject(JNIEnv* env, const ResTable_config& config) {
625 jobject result = env->NewObject(gConfigurationOffsets.classObject,
626 gConfigurationOffsets.constructor);
627 if (result == NULL) {
628 return NULL;
629 }
630
631 env->SetIntField(result, gConfigurationOffsets.mSmallestScreenWidthDpOffset,
632 config.smallestScreenWidthDp);
633 env->SetIntField(result, gConfigurationOffsets.mScreenWidthDpOffset, config.screenWidthDp);
634 env->SetIntField(result, gConfigurationOffsets.mScreenHeightDpOffset, config.screenHeightDp);
635
636 return result;
637}
638
639static jobjectArray getSizeConfigurationsInternal(JNIEnv* env,
640 const Vector<ResTable_config>& configs) {
641 const int N = configs.size();
642 jobjectArray result = env->NewObjectArray(N, gConfigurationOffsets.classObject, NULL);
643 if (result == NULL) {
644 return NULL;
645 }
646
647 for (int i=0; i<N; i++) {
648 jobject config = constructConfigurationObject(env, configs[i]);
649 if (config == NULL) {
650 env->DeleteLocalRef(result);
651 return NULL;
652 }
653
654 env->SetObjectArrayElement(result, i, config);
655 env->DeleteLocalRef(config);
656 }
657
658 return result;
659}
660
661static jobjectArray android_content_AssetManager_getSizeConfigurations(JNIEnv* env, jobject clazz) {
662 AssetManager* am = assetManagerForJavaObject(env, clazz);
663 if (am == NULL) {
664 return NULL;
665 }
666
667 const ResTable& res(am->getResources());
668 Vector<ResTable_config> configs;
669 res.getConfigurations(&configs, false /* ignoreMipmap */, true /* ignoreAndroidPackage */);
670
671 return getSizeConfigurationsInternal(env, configs);
672}
673
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800674static void android_content_AssetManager_setConfiguration(JNIEnv* env, jobject clazz,
675 jint mcc, jint mnc,
676 jstring locale, jint orientation,
677 jint touchscreen, jint density,
678 jint keyboard, jint keyboardHidden,
679 jint navigation,
680 jint screenWidth, jint screenHeight,
Dianne Hackborn69cb8752011-05-19 18:13:32 -0700681 jint smallestScreenWidthDp,
Dianne Hackborn3fc982f2011-03-30 16:20:26 -0700682 jint screenWidthDp, jint screenHeightDp,
Tobias Haamel27b28b32010-02-09 23:09:17 +0100683 jint screenLayout, jint uiMode,
684 jint sdkVersion)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800685{
686 AssetManager* am = assetManagerForJavaObject(env, clazz);
687 if (am == NULL) {
688 return;
689 }
690
691 ResTable_config config;
692 memset(&config, 0, sizeof(config));
Elliott Hughes69a017b2011-04-08 14:10:28 -0700693
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800694 const char* locale8 = locale != NULL ? env->GetStringUTFChars(locale, NULL) : NULL;
Elliott Hughes69a017b2011-04-08 14:10:28 -0700695
Adam Lesinski2738c962015-05-14 14:25:36 -0700696 // Constants duplicated from Java class android.content.res.Configuration.
697 static const jint kScreenLayoutRoundMask = 0x300;
698 static const jint kScreenLayoutRoundShift = 8;
699
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800700 config.mcc = (uint16_t)mcc;
701 config.mnc = (uint16_t)mnc;
702 config.orientation = (uint8_t)orientation;
703 config.touchscreen = (uint8_t)touchscreen;
704 config.density = (uint16_t)density;
705 config.keyboard = (uint8_t)keyboard;
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700706 config.inputFlags = (uint8_t)keyboardHidden;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800707 config.navigation = (uint8_t)navigation;
708 config.screenWidth = (uint16_t)screenWidth;
709 config.screenHeight = (uint16_t)screenHeight;
Dianne Hackborn69cb8752011-05-19 18:13:32 -0700710 config.smallestScreenWidthDp = (uint16_t)smallestScreenWidthDp;
Dianne Hackborn3fc982f2011-03-30 16:20:26 -0700711 config.screenWidthDp = (uint16_t)screenWidthDp;
712 config.screenHeightDp = (uint16_t)screenHeightDp;
Dianne Hackborn723738c2009-06-25 19:48:04 -0700713 config.screenLayout = (uint8_t)screenLayout;
Tobias Haamel27b28b32010-02-09 23:09:17 +0100714 config.uiMode = (uint8_t)uiMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800715 config.sdkVersion = (uint16_t)sdkVersion;
716 config.minorVersion = 0;
Adam Lesinski2738c962015-05-14 14:25:36 -0700717
718 // In Java, we use a 32bit integer for screenLayout, while we only use an 8bit integer
719 // in C++. We must extract the round qualifier out of the Java screenLayout and put it
720 // into screenLayout2.
721 config.screenLayout2 =
722 (uint8_t)((screenLayout & kScreenLayoutRoundMask) >> kScreenLayoutRoundShift);
723
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800724 am->setConfiguration(config, locale8);
Elliott Hughes69a017b2011-04-08 14:10:28 -0700725
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800726 if (locale != NULL) env->ReleaseStringUTFChars(locale, locale8);
727}
728
729static jint android_content_AssetManager_getResourceIdentifier(JNIEnv* env, jobject clazz,
730 jstring name,
731 jstring defType,
732 jstring defPackage)
733{
Elliott Hughes69a017b2011-04-08 14:10:28 -0700734 ScopedStringChars name16(env, name);
735 if (name16.get() == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800736 return 0;
737 }
738
739 AssetManager* am = assetManagerForJavaObject(env, clazz);
740 if (am == NULL) {
741 return 0;
742 }
743
Dan Albert66987492014-11-20 11:41:21 -0800744 const char16_t* defType16 = reinterpret_cast<const char16_t*>(defType)
745 ? reinterpret_cast<const char16_t*>(env->GetStringChars(defType, NULL))
746 : NULL;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800747 jsize defTypeLen = defType
748 ? env->GetStringLength(defType) : 0;
Dan Albert66987492014-11-20 11:41:21 -0800749 const char16_t* defPackage16 = reinterpret_cast<const char16_t*>(defPackage)
750 ? reinterpret_cast<const char16_t*>(env->GetStringChars(defPackage,
751 NULL))
752 : NULL;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800753 jsize defPackageLen = defPackage
754 ? env->GetStringLength(defPackage) : 0;
755
756 jint ident = am->getResources().identifierForName(
Dan Albert66987492014-11-20 11:41:21 -0800757 reinterpret_cast<const char16_t*>(name16.get()), name16.size(),
758 defType16, defTypeLen, defPackage16, defPackageLen);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800759
760 if (defPackage16) {
Dan Albert66987492014-11-20 11:41:21 -0800761 env->ReleaseStringChars(defPackage,
762 reinterpret_cast<const jchar*>(defPackage16));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800763 }
764 if (defType16) {
Dan Albert66987492014-11-20 11:41:21 -0800765 env->ReleaseStringChars(defType,
766 reinterpret_cast<const jchar*>(defType16));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800767 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800768
769 return ident;
770}
771
772static jstring android_content_AssetManager_getResourceName(JNIEnv* env, jobject clazz,
773 jint resid)
774{
775 AssetManager* am = assetManagerForJavaObject(env, clazz);
776 if (am == NULL) {
777 return NULL;
778 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700779
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800780 ResTable::resource_name name;
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700781 if (!am->getResources().getResourceName(resid, true, &name)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800782 return NULL;
783 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700784
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800785 String16 str;
786 if (name.package != NULL) {
787 str.setTo(name.package, name.packageLen);
788 }
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700789 if (name.type8 != NULL || name.type != NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800790 if (str.size() > 0) {
791 char16_t div = ':';
792 str.append(&div, 1);
793 }
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700794 if (name.type8 != NULL) {
795 str.append(String16(name.type8, name.typeLen));
796 } else {
797 str.append(name.type, name.typeLen);
798 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800799 }
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700800 if (name.name8 != NULL || name.name != NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800801 if (str.size() > 0) {
802 char16_t div = '/';
803 str.append(&div, 1);
804 }
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700805 if (name.name8 != NULL) {
806 str.append(String16(name.name8, name.nameLen));
807 } else {
808 str.append(name.name, name.nameLen);
809 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800810 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700811
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800812 return env->NewString((const jchar*)str.string(), str.size());
813}
814
815static jstring android_content_AssetManager_getResourcePackageName(JNIEnv* env, jobject clazz,
816 jint resid)
817{
818 AssetManager* am = assetManagerForJavaObject(env, clazz);
819 if (am == NULL) {
820 return NULL;
821 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700822
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800823 ResTable::resource_name name;
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700824 if (!am->getResources().getResourceName(resid, true, &name)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800825 return NULL;
826 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700827
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800828 if (name.package != NULL) {
829 return env->NewString((const jchar*)name.package, name.packageLen);
830 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700831
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800832 return NULL;
833}
834
835static jstring android_content_AssetManager_getResourceTypeName(JNIEnv* env, jobject clazz,
836 jint resid)
837{
838 AssetManager* am = assetManagerForJavaObject(env, clazz);
839 if (am == NULL) {
840 return NULL;
841 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700842
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800843 ResTable::resource_name name;
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700844 if (!am->getResources().getResourceName(resid, true, &name)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800845 return NULL;
846 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700847
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700848 if (name.type8 != NULL) {
849 return env->NewStringUTF(name.type8);
850 }
851
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800852 if (name.type != NULL) {
853 return env->NewString((const jchar*)name.type, name.typeLen);
854 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700855
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800856 return NULL;
857}
858
859static jstring android_content_AssetManager_getResourceEntryName(JNIEnv* env, jobject clazz,
860 jint resid)
861{
862 AssetManager* am = assetManagerForJavaObject(env, clazz);
863 if (am == NULL) {
864 return NULL;
865 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700866
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800867 ResTable::resource_name name;
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700868 if (!am->getResources().getResourceName(resid, true, &name)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800869 return NULL;
870 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700871
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700872 if (name.name8 != NULL) {
873 return env->NewStringUTF(name.name8);
874 }
875
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800876 if (name.name != NULL) {
877 return env->NewString((const jchar*)name.name, name.nameLen);
878 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700879
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800880 return NULL;
881}
882
883static jint android_content_AssetManager_loadResourceValue(JNIEnv* env, jobject clazz,
884 jint ident,
Kenny Root55fc8502010-10-28 14:47:01 -0700885 jshort density,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800886 jobject outValue,
887 jboolean resolve)
888{
Dianne Hackborn1f7d3072013-02-11 17:03:32 -0800889 if (outValue == NULL) {
Dianne Hackborne5b50a62013-02-11 16:18:42 -0800890 jniThrowNullPointerException(env, "outValue");
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700891 return 0;
Dianne Hackborne5b50a62013-02-11 16:18:42 -0800892 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800893 AssetManager* am = assetManagerForJavaObject(env, clazz);
894 if (am == NULL) {
895 return 0;
896 }
897 const ResTable& res(am->getResources());
898
899 Res_value value;
900 ResTable_config config;
901 uint32_t typeSpecFlags;
Kenny Root55fc8502010-10-28 14:47:01 -0700902 ssize_t block = res.getResource(ident, &value, false, density, &typeSpecFlags, &config);
Andreas Gampe0f0b4912014-11-12 08:03:48 -0800903 if (kThrowOnBadId) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -0800904 if (block == BAD_INDEX) {
905 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
906 return 0;
907 }
Andreas Gampe0f0b4912014-11-12 08:03:48 -0800908 }
909 uint32_t ref = ident;
910 if (resolve) {
911 block = res.resolveReference(&value, block, &ref, &typeSpecFlags, &config);
912 if (kThrowOnBadId) {
913 if (block == BAD_INDEX) {
914 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
915 return 0;
916 }
917 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800918 }
Ashok Bhat896043d2014-01-17 16:02:38 +0000919 if (block >= 0) {
920 return copyValue(env, outValue, &res, value, ref, block, typeSpecFlags, &config);
921 }
922
923 return static_cast<jint>(block);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800924}
925
926static jint android_content_AssetManager_loadResourceBagValue(JNIEnv* env, jobject clazz,
927 jint ident, jint bagEntryId,
928 jobject outValue, jboolean resolve)
929{
930 AssetManager* am = assetManagerForJavaObject(env, clazz);
931 if (am == NULL) {
932 return 0;
933 }
934 const ResTable& res(am->getResources());
Elliott Hughes69a017b2011-04-08 14:10:28 -0700935
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800936 // Now lock down the resource object and start pulling stuff from it.
937 res.lock();
Elliott Hughes69a017b2011-04-08 14:10:28 -0700938
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800939 ssize_t block = -1;
940 Res_value value;
941
942 const ResTable::bag_entry* entry = NULL;
943 uint32_t typeSpecFlags;
944 ssize_t entryCount = res.getBagLocked(ident, &entry, &typeSpecFlags);
945
946 for (ssize_t i=0; i<entryCount; i++) {
947 if (((uint32_t)bagEntryId) == entry->map.name.ident) {
948 block = entry->stringBlock;
949 value = entry->map.value;
950 }
951 entry++;
952 }
953
954 res.unlock();
955
956 if (block < 0) {
Ashok Bhat896043d2014-01-17 16:02:38 +0000957 return static_cast<jint>(block);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800958 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700959
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800960 uint32_t ref = ident;
961 if (resolve) {
962 block = res.resolveReference(&value, block, &ref, &typeSpecFlags);
Andreas Gampe0f0b4912014-11-12 08:03:48 -0800963 if (kThrowOnBadId) {
964 if (block == BAD_INDEX) {
965 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
966 return 0;
967 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -0800968 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800969 }
Ashok Bhat896043d2014-01-17 16:02:38 +0000970 if (block >= 0) {
971 return copyValue(env, outValue, &res, value, ref, block, typeSpecFlags);
972 }
973
974 return static_cast<jint>(block);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800975}
976
977static jint android_content_AssetManager_getStringBlockCount(JNIEnv* env, jobject clazz)
978{
979 AssetManager* am = assetManagerForJavaObject(env, clazz);
980 if (am == NULL) {
981 return 0;
982 }
983 return am->getResources().getTableCount();
984}
985
Ashok Bhat896043d2014-01-17 16:02:38 +0000986static jlong android_content_AssetManager_getNativeStringBlock(JNIEnv* env, jobject clazz,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800987 jint block)
988{
989 AssetManager* am = assetManagerForJavaObject(env, clazz);
990 if (am == NULL) {
991 return 0;
992 }
Ashok Bhat896043d2014-01-17 16:02:38 +0000993 return reinterpret_cast<jlong>(am->getResources().getTableStringBlock(block));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800994}
995
996static jstring android_content_AssetManager_getCookieName(JNIEnv* env, jobject clazz,
997 jint cookie)
998{
999 AssetManager* am = assetManagerForJavaObject(env, clazz);
1000 if (am == NULL) {
1001 return NULL;
1002 }
Narayan Kamath745d4ef2014-01-27 11:17:22 +00001003 String8 name(am->getAssetPath(static_cast<int32_t>(cookie)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001004 if (name.length() == 0) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001005 jniThrowException(env, "java/lang/IndexOutOfBoundsException", "Empty cookie name");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001006 return NULL;
1007 }
1008 jstring str = env->NewStringUTF(name.string());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001009 return str;
1010}
1011
Adam Lesinskide898ff2014-01-29 18:20:45 -08001012static jobject android_content_AssetManager_getAssignedPackageIdentifiers(JNIEnv* env, jobject clazz)
1013{
1014 AssetManager* am = assetManagerForJavaObject(env, clazz);
1015 if (am == NULL) {
1016 return 0;
1017 }
1018
1019 const ResTable& res = am->getResources();
1020
1021 jobject sparseArray = env->NewObject(gSparseArrayOffsets.classObject,
1022 gSparseArrayOffsets.constructor);
1023 const size_t N = res.getBasePackageCount();
1024 for (size_t i = 0; i < N; i++) {
1025 const String16 name = res.getBasePackageName(i);
Dan Albert66987492014-11-20 11:41:21 -08001026 env->CallVoidMethod(
1027 sparseArray, gSparseArrayOffsets.put,
1028 static_cast<jint>(res.getBasePackageId(i)),
1029 env->NewString(reinterpret_cast<const jchar*>(name.string()),
1030 name.size()));
Adam Lesinskide898ff2014-01-29 18:20:45 -08001031 }
1032 return sparseArray;
1033}
1034
Ashok Bhat896043d2014-01-17 16:02:38 +00001035static jlong android_content_AssetManager_newTheme(JNIEnv* env, jobject clazz)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001036{
1037 AssetManager* am = assetManagerForJavaObject(env, clazz);
1038 if (am == NULL) {
1039 return 0;
1040 }
Ashok Bhat896043d2014-01-17 16:02:38 +00001041 return reinterpret_cast<jlong>(new ResTable::Theme(am->getResources()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001042}
1043
1044static void android_content_AssetManager_deleteTheme(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +00001045 jlong themeHandle)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001046{
Ashok Bhat896043d2014-01-17 16:02:38 +00001047 ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001048 delete theme;
1049}
1050
1051static void android_content_AssetManager_applyThemeStyle(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +00001052 jlong themeHandle,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001053 jint styleRes,
1054 jboolean force)
1055{
Ashok Bhat896043d2014-01-17 16:02:38 +00001056 ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001057 theme->applyStyle(styleRes, force ? true : false);
1058}
1059
1060static void android_content_AssetManager_copyTheme(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +00001061 jlong destHandle, jlong srcHandle)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001062{
Ashok Bhat896043d2014-01-17 16:02:38 +00001063 ResTable::Theme* dest = reinterpret_cast<ResTable::Theme*>(destHandle);
1064 ResTable::Theme* src = reinterpret_cast<ResTable::Theme*>(srcHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001065 dest->setTo(*src);
1066}
1067
Alan Viverettee54d2452015-05-06 10:41:43 -07001068static void android_content_AssetManager_clearTheme(JNIEnv* env, jobject clazz, jlong themeHandle)
1069{
1070 ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeHandle);
1071 theme->clear();
1072}
1073
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001074static jint android_content_AssetManager_loadThemeAttributeValue(
Ashok Bhat896043d2014-01-17 16:02:38 +00001075 JNIEnv* env, jobject clazz, jlong themeHandle, jint ident, jobject outValue, jboolean resolve)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001076{
Ashok Bhat896043d2014-01-17 16:02:38 +00001077 ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001078 const ResTable& res(theme->getResTable());
1079
1080 Res_value value;
1081 // XXX value could be different in different configs!
1082 uint32_t typeSpecFlags = 0;
1083 ssize_t block = theme->getAttribute(ident, &value, &typeSpecFlags);
1084 uint32_t ref = 0;
1085 if (resolve) {
1086 block = res.resolveReference(&value, block, &ref, &typeSpecFlags);
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001087 if (kThrowOnBadId) {
1088 if (block == BAD_INDEX) {
1089 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
1090 return 0;
1091 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001092 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001093 }
1094 return block >= 0 ? copyValue(env, outValue, &res, value, ref, block, typeSpecFlags) : block;
1095}
1096
Alan Viverettec1d52792015-05-05 09:49:03 -07001097static jint android_content_AssetManager_getThemeChangingConfigurations(JNIEnv* env, jobject clazz,
1098 jlong themeHandle)
1099{
1100 ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeHandle);
1101 return theme->getChangingConfigurations();
1102}
1103
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001104static void android_content_AssetManager_dumpTheme(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +00001105 jlong themeHandle, jint pri,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001106 jstring tag, jstring prefix)
1107{
Ashok Bhat896043d2014-01-17 16:02:38 +00001108 ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001109 const ResTable& res(theme->getResTable());
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001110 (void)res;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001111
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001112 // XXX Need to use params.
1113 theme->dumpToLog();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001114}
1115
Alan Viverette52b999f2014-03-24 18:00:26 -07001116static jboolean android_content_AssetManager_resolveAttrs(JNIEnv* env, jobject clazz,
1117 jlong themeToken,
1118 jint defStyleAttr,
1119 jint defStyleRes,
1120 jintArray inValues,
1121 jintArray attrs,
1122 jintArray outValues,
1123 jintArray outIndices)
1124{
1125 if (themeToken == 0) {
1126 jniThrowNullPointerException(env, "theme token");
1127 return JNI_FALSE;
1128 }
1129 if (attrs == NULL) {
1130 jniThrowNullPointerException(env, "attrs");
1131 return JNI_FALSE;
1132 }
1133 if (outValues == NULL) {
1134 jniThrowNullPointerException(env, "out values");
1135 return JNI_FALSE;
1136 }
1137
Alan Viverette52b999f2014-03-24 18:00:26 -07001138 const jsize NI = env->GetArrayLength(attrs);
1139 const jsize NV = env->GetArrayLength(outValues);
1140 if (NV < (NI*STYLE_NUM_ENTRIES)) {
1141 jniThrowException(env, "java/lang/IndexOutOfBoundsException", "out values too small");
1142 return JNI_FALSE;
1143 }
1144
1145 jint* src = (jint*)env->GetPrimitiveArrayCritical(attrs, 0);
1146 if (src == NULL) {
1147 return JNI_FALSE;
1148 }
1149
1150 jint* srcValues = (jint*)env->GetPrimitiveArrayCritical(inValues, 0);
1151 const jsize NSV = srcValues == NULL ? 0 : env->GetArrayLength(inValues);
1152
1153 jint* baseDest = (jint*)env->GetPrimitiveArrayCritical(outValues, 0);
Adam Lesinski4452e132016-10-12 07:47:28 -07001154 if (baseDest == NULL) {
Alan Viverette52b999f2014-03-24 18:00:26 -07001155 env->ReleasePrimitiveArrayCritical(attrs, src, 0);
1156 return JNI_FALSE;
1157 }
1158
1159 jint* indices = NULL;
Alan Viverette52b999f2014-03-24 18:00:26 -07001160 if (outIndices != NULL) {
1161 if (env->GetArrayLength(outIndices) > NI) {
1162 indices = (jint*)env->GetPrimitiveArrayCritical(outIndices, 0);
1163 }
1164 }
1165
Adam Lesinski4452e132016-10-12 07:47:28 -07001166 ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeToken);
Adam Lesinski7a37b742016-10-12 14:05:55 -07001167 bool result = ResolveAttrs(theme, defStyleAttr, defStyleRes,
Adam Lesinski4452e132016-10-12 07:47:28 -07001168 (uint32_t*) srcValues, NSV,
1169 (uint32_t*) src, NI,
1170 (uint32_t*) baseDest,
1171 (uint32_t*) indices);
Alan Viverette52b999f2014-03-24 18:00:26 -07001172
1173 if (indices != NULL) {
Alan Viverette52b999f2014-03-24 18:00:26 -07001174 env->ReleasePrimitiveArrayCritical(outIndices, indices, 0);
1175 }
1176 env->ReleasePrimitiveArrayCritical(outValues, baseDest, 0);
1177 env->ReleasePrimitiveArrayCritical(inValues, srcValues, 0);
1178 env->ReleasePrimitiveArrayCritical(attrs, src, 0);
Adam Lesinski4452e132016-10-12 07:47:28 -07001179 return result ? JNI_TRUE : JNI_FALSE;
Alan Viverette52b999f2014-03-24 18:00:26 -07001180}
1181
John Reckf32adf42016-11-23 10:39:40 -08001182static void android_content_AssetManager_applyStyle(JNIEnv* env, jobject, jlong themeToken,
1183 jint defStyleAttr, jint defStyleRes, jlong xmlParserToken, jintArray attrsObj, jint length,
1184 jlong outValuesAddress, jlong outIndicesAddress) {
1185 jint* attrs = env->GetIntArrayElements(attrsObj, 0);
Adam Lesinski4452e132016-10-12 07:47:28 -07001186 ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeToken);
1187 ResXMLParser* xmlParser = reinterpret_cast<ResXMLParser*>(xmlParserToken);
John Reckf32adf42016-11-23 10:39:40 -08001188 uint32_t* outValues = reinterpret_cast<uint32_t*>(static_cast<uintptr_t>(outValuesAddress));
1189 uint32_t* outIndices = reinterpret_cast<uint32_t*>(static_cast<uintptr_t>(outIndicesAddress));
1190 ApplyStyle(theme, xmlParser, defStyleAttr, defStyleRes,
1191 reinterpret_cast<const uint32_t*>(attrs), length, outValues, outIndices);
1192 env->ReleaseIntArrayElements(attrsObj, attrs, JNI_ABORT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001193}
1194
1195static jboolean android_content_AssetManager_retrieveAttributes(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +00001196 jlong xmlParserToken,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001197 jintArray attrs,
1198 jintArray outValues,
1199 jintArray outIndices)
1200{
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001201 if (xmlParserToken == 0) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001202 jniThrowNullPointerException(env, "xmlParserToken");
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001203 return JNI_FALSE;
1204 }
1205 if (attrs == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001206 jniThrowNullPointerException(env, "attrs");
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001207 return JNI_FALSE;
1208 }
1209 if (outValues == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001210 jniThrowNullPointerException(env, "out values");
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 AssetManager* am = assetManagerForJavaObject(env, clazz);
1215 if (am == NULL) {
1216 return JNI_FALSE;
1217 }
1218 const ResTable& res(am->getResources());
1219 ResXMLParser* xmlParser = (ResXMLParser*)xmlParserToken;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001220
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001221 const jsize NI = env->GetArrayLength(attrs);
1222 const jsize NV = env->GetArrayLength(outValues);
1223 if (NV < (NI*STYLE_NUM_ENTRIES)) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001224 jniThrowException(env, "java/lang/IndexOutOfBoundsException", "out values too small");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001225 return JNI_FALSE;
1226 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001227
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001228 jint* src = (jint*)env->GetPrimitiveArrayCritical(attrs, 0);
1229 if (src == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001230 return JNI_FALSE;
1231 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001232
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001233 jint* baseDest = (jint*)env->GetPrimitiveArrayCritical(outValues, 0);
Adam Lesinski4452e132016-10-12 07:47:28 -07001234 if (baseDest == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001235 env->ReleasePrimitiveArrayCritical(attrs, src, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001236 return JNI_FALSE;
1237 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001238
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001239 jint* indices = NULL;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001240 if (outIndices != NULL) {
1241 if (env->GetArrayLength(outIndices) > NI) {
1242 indices = (jint*)env->GetPrimitiveArrayCritical(outIndices, 0);
1243 }
1244 }
1245
Adam Lesinski7a37b742016-10-12 14:05:55 -07001246 bool result = RetrieveAttributes(&res, xmlParser,
Adam Lesinski4452e132016-10-12 07:47:28 -07001247 (uint32_t*) src, NI,
1248 (uint32_t*) baseDest,
1249 (uint32_t*) indices);
Elliott Hughes69a017b2011-04-08 14:10:28 -07001250
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001251 if (indices != NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001252 env->ReleasePrimitiveArrayCritical(outIndices, indices, 0);
1253 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001254 env->ReleasePrimitiveArrayCritical(outValues, baseDest, 0);
1255 env->ReleasePrimitiveArrayCritical(attrs, src, 0);
Adam Lesinski4452e132016-10-12 07:47:28 -07001256 return result ? JNI_TRUE : JNI_FALSE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001257}
1258
1259static jint android_content_AssetManager_getArraySize(JNIEnv* env, jobject clazz,
1260 jint id)
1261{
1262 AssetManager* am = assetManagerForJavaObject(env, clazz);
1263 if (am == NULL) {
Olivier Baillyd7c86722010-11-18 14:43:36 -08001264 return 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001265 }
1266 const ResTable& res(am->getResources());
Elliott Hughes69a017b2011-04-08 14:10:28 -07001267
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001268 res.lock();
1269 const ResTable::bag_entry* defStyleEnt = NULL;
1270 ssize_t bagOff = res.getBagLocked(id, &defStyleEnt);
1271 res.unlock();
Elliott Hughes69a017b2011-04-08 14:10:28 -07001272
Ashok Bhat896043d2014-01-17 16:02:38 +00001273 return static_cast<jint>(bagOff);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001274}
1275
1276static jint android_content_AssetManager_retrieveArray(JNIEnv* env, jobject clazz,
1277 jint id,
1278 jintArray outValues)
1279{
1280 if (outValues == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001281 jniThrowNullPointerException(env, "out values");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001282 return JNI_FALSE;
1283 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001284
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001285 AssetManager* am = assetManagerForJavaObject(env, clazz);
1286 if (am == NULL) {
1287 return JNI_FALSE;
1288 }
1289 const ResTable& res(am->getResources());
Dianne Hackborn0d221012009-07-29 15:41:19 -07001290 ResTable_config config;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001291 Res_value value;
1292 ssize_t block;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001293
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001294 const jsize NV = env->GetArrayLength(outValues);
Elliott Hughes69a017b2011-04-08 14:10:28 -07001295
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001296 jint* baseDest = (jint*)env->GetPrimitiveArrayCritical(outValues, 0);
1297 jint* dest = baseDest;
1298 if (dest == NULL) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001299 jniThrowException(env, "java/lang/OutOfMemoryError", "");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001300 return JNI_FALSE;
1301 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001302
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001303 // Now lock down the resource object and start pulling stuff from it.
1304 res.lock();
Elliott Hughes69a017b2011-04-08 14:10:28 -07001305
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001306 const ResTable::bag_entry* arrayEnt = NULL;
1307 uint32_t arrayTypeSetFlags = 0;
1308 ssize_t bagOff = res.getBagLocked(id, &arrayEnt, &arrayTypeSetFlags);
1309 const ResTable::bag_entry* endArrayEnt = arrayEnt +
1310 (bagOff >= 0 ? bagOff : 0);
Elliott Hughes69a017b2011-04-08 14:10:28 -07001311
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001312 int i = 0;
1313 uint32_t typeSetFlags;
1314 while (i < NV && arrayEnt < endArrayEnt) {
1315 block = arrayEnt->stringBlock;
1316 typeSetFlags = arrayTypeSetFlags;
Dianne Hackborn0d221012009-07-29 15:41:19 -07001317 config.density = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001318 value = arrayEnt->map.value;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001319
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001320 uint32_t resid = 0;
1321 if (value.dataType != Res_value::TYPE_NULL) {
1322 // Take care of resolving the found resource to its final value.
1323 //printf("Resolving attribute reference\n");
Dianne Hackborn0d221012009-07-29 15:41:19 -07001324 ssize_t newBlock = res.resolveReference(&value, block, &resid,
1325 &typeSetFlags, &config);
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001326 if (kThrowOnBadId) {
1327 if (newBlock == BAD_INDEX) {
1328 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
1329 return JNI_FALSE;
1330 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001331 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001332 if (newBlock >= 0) block = newBlock;
1333 }
1334
1335 // Deal with the special @null value -- it turns back to TYPE_NULL.
1336 if (value.dataType == Res_value::TYPE_REFERENCE && value.data == 0) {
1337 value.dataType = Res_value::TYPE_NULL;
Alan Viverettef2969402014-10-29 17:09:36 -07001338 value.data = Res_value::DATA_NULL_UNDEFINED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001339 }
1340
1341 //printf("Attribute 0x%08x: final type=0x%x, data=0x%08x\n", curIdent, value.dataType, value.data);
1342
1343 // Write the final value back to Java.
1344 dest[STYLE_TYPE] = value.dataType;
1345 dest[STYLE_DATA] = value.data;
Ashok Bhat896043d2014-01-17 16:02:38 +00001346 dest[STYLE_ASSET_COOKIE] = reinterpret_cast<jint>(res.getTableCookie(block));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001347 dest[STYLE_RESOURCE_ID] = resid;
1348 dest[STYLE_CHANGING_CONFIGURATIONS] = typeSetFlags;
Dianne Hackborn0d221012009-07-29 15:41:19 -07001349 dest[STYLE_DENSITY] = config.density;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001350 dest += STYLE_NUM_ENTRIES;
1351 i+= STYLE_NUM_ENTRIES;
1352 arrayEnt++;
1353 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001354
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001355 i /= STYLE_NUM_ENTRIES;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001356
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001357 res.unlock();
Elliott Hughes69a017b2011-04-08 14:10:28 -07001358
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001359 env->ReleasePrimitiveArrayCritical(outValues, baseDest, 0);
Elliott Hughes69a017b2011-04-08 14:10:28 -07001360
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001361 return i;
1362}
1363
Ashok Bhat896043d2014-01-17 16:02:38 +00001364static jlong android_content_AssetManager_openXmlAssetNative(JNIEnv* env, jobject clazz,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001365 jint cookie,
1366 jstring fileName)
1367{
1368 AssetManager* am = assetManagerForJavaObject(env, clazz);
1369 if (am == NULL) {
1370 return 0;
1371 }
1372
Steve Block71f2cf12011-10-20 11:56:00 +01001373 ALOGV("openXmlAsset in %p (Java object %p)\n", am, clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001374
Elliott Hughes69a017b2011-04-08 14:10:28 -07001375 ScopedUtfChars fileName8(env, fileName);
1376 if (fileName8.c_str() == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001377 return 0;
1378 }
1379
Adam Lesinskide898ff2014-01-29 18:20:45 -08001380 int32_t assetCookie = static_cast<int32_t>(cookie);
1381 Asset* a = assetCookie
1382 ? am->openNonAsset(assetCookie, fileName8.c_str(), Asset::ACCESS_BUFFER)
1383 : am->openNonAsset(fileName8.c_str(), Asset::ACCESS_BUFFER, &assetCookie);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001384
1385 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001386 jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001387 return 0;
1388 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001389
Adam Lesinskide898ff2014-01-29 18:20:45 -08001390 const DynamicRefTable* dynamicRefTable =
1391 am->getResources().getDynamicRefTableForCookie(assetCookie);
1392 ResXMLTree* block = new ResXMLTree(dynamicRefTable);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001393 status_t err = block->setTo(a->getBuffer(true), a->getLength(), true);
1394 a->close();
1395 delete a;
1396
1397 if (err != NO_ERROR) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001398 jniThrowException(env, "java/io/FileNotFoundException", "Corrupt XML binary file");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001399 return 0;
1400 }
1401
Ashok Bhat896043d2014-01-17 16:02:38 +00001402 return reinterpret_cast<jlong>(block);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001403}
1404
1405static jintArray android_content_AssetManager_getArrayStringInfo(JNIEnv* env, jobject clazz,
1406 jint arrayResId)
1407{
1408 AssetManager* am = assetManagerForJavaObject(env, clazz);
1409 if (am == NULL) {
1410 return NULL;
1411 }
1412 const ResTable& res(am->getResources());
1413
1414 const ResTable::bag_entry* startOfBag;
1415 const ssize_t N = res.lockBag(arrayResId, &startOfBag);
1416 if (N < 0) {
1417 return NULL;
1418 }
1419
1420 jintArray array = env->NewIntArray(N * 2);
1421 if (array == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001422 res.unlockBag(startOfBag);
1423 return NULL;
1424 }
1425
1426 Res_value value;
1427 const ResTable::bag_entry* bag = startOfBag;
1428 for (size_t i = 0, j = 0; ((ssize_t)i)<N; i++, bag++) {
1429 jint stringIndex = -1;
1430 jint stringBlock = 0;
1431 value = bag->map.value;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001432
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001433 // Take care of resolving the found resource to its final value.
1434 stringBlock = res.resolveReference(&value, bag->stringBlock, NULL);
1435 if (value.dataType == Res_value::TYPE_STRING) {
1436 stringIndex = value.data;
1437 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001438
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001439 if (kThrowOnBadId) {
1440 if (stringBlock == BAD_INDEX) {
1441 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
1442 return array;
1443 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001444 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001445
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001446 //todo: It might be faster to allocate a C array to contain
1447 // the blocknums and indices, put them in there and then
1448 // do just one SetIntArrayRegion()
1449 env->SetIntArrayRegion(array, j, 1, &stringBlock);
1450 env->SetIntArrayRegion(array, j + 1, 1, &stringIndex);
1451 j = j + 2;
1452 }
1453 res.unlockBag(startOfBag);
1454 return array;
1455}
1456
1457static jobjectArray android_content_AssetManager_getArrayStringResource(JNIEnv* env, jobject clazz,
1458 jint arrayResId)
1459{
1460 AssetManager* am = assetManagerForJavaObject(env, clazz);
1461 if (am == NULL) {
1462 return NULL;
1463 }
1464 const ResTable& res(am->getResources());
1465
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001466 const ResTable::bag_entry* startOfBag;
1467 const ssize_t N = res.lockBag(arrayResId, &startOfBag);
1468 if (N < 0) {
1469 return NULL;
1470 }
1471
Vladimir Markoaa5fe3d2013-06-17 12:46:22 +01001472 jobjectArray array = env->NewObjectArray(N, g_stringClass, NULL);
Kenny Root485dd212010-05-06 16:06:48 -07001473 if (env->ExceptionCheck()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001474 res.unlockBag(startOfBag);
1475 return NULL;
1476 }
1477
1478 Res_value value;
1479 const ResTable::bag_entry* bag = startOfBag;
1480 size_t strLen = 0;
1481 for (size_t i=0; ((ssize_t)i)<N; i++, bag++) {
1482 value = bag->map.value;
1483 jstring str = NULL;
Kenny Root780d2a12010-02-22 22:36:26 -08001484
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001485 // Take care of resolving the found resource to its final value.
1486 ssize_t block = res.resolveReference(&value, bag->stringBlock, NULL);
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001487 if (kThrowOnBadId) {
1488 if (block == BAD_INDEX) {
1489 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
1490 return array;
1491 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001492 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001493 if (value.dataType == Res_value::TYPE_STRING) {
Kenny Root780d2a12010-02-22 22:36:26 -08001494 const ResStringPool* pool = res.getTableStringBlock(block);
1495 const char* str8 = pool->string8At(value.data, &strLen);
1496 if (str8 != NULL) {
1497 str = env->NewStringUTF(str8);
1498 } else {
1499 const char16_t* str16 = pool->stringAt(value.data, &strLen);
Dan Albert66987492014-11-20 11:41:21 -08001500 str = env->NewString(reinterpret_cast<const jchar*>(str16),
1501 strLen);
Kenny Root485dd212010-05-06 16:06:48 -07001502 }
1503
1504 // If one of our NewString{UTF} calls failed due to memory, an
1505 // exception will be pending.
1506 if (env->ExceptionCheck()) {
1507 res.unlockBag(startOfBag);
1508 return NULL;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001509 }
Kenny Root780d2a12010-02-22 22:36:26 -08001510
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001511 env->SetObjectArrayElement(array, i, str);
Kenny Root485dd212010-05-06 16:06:48 -07001512
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001513 // str is not NULL at that point, otherwise ExceptionCheck would have been true.
1514 // If we have a large amount of strings in our array, we might
1515 // overflow the local reference table of the VM.
Kenny Root485dd212010-05-06 16:06:48 -07001516 env->DeleteLocalRef(str);
1517 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001518 }
1519 res.unlockBag(startOfBag);
1520 return array;
1521}
1522
1523static jintArray android_content_AssetManager_getArrayIntResource(JNIEnv* env, jobject clazz,
1524 jint arrayResId)
1525{
1526 AssetManager* am = assetManagerForJavaObject(env, clazz);
1527 if (am == NULL) {
1528 return NULL;
1529 }
1530 const ResTable& res(am->getResources());
1531
1532 const ResTable::bag_entry* startOfBag;
1533 const ssize_t N = res.lockBag(arrayResId, &startOfBag);
1534 if (N < 0) {
1535 return NULL;
1536 }
1537
1538 jintArray array = env->NewIntArray(N);
1539 if (array == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001540 res.unlockBag(startOfBag);
1541 return NULL;
1542 }
1543
1544 Res_value value;
1545 const ResTable::bag_entry* bag = startOfBag;
1546 for (size_t i=0; ((ssize_t)i)<N; i++, bag++) {
1547 value = bag->map.value;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001548
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001549 // Take care of resolving the found resource to its final value.
1550 ssize_t block = res.resolveReference(&value, bag->stringBlock, NULL);
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001551 if (kThrowOnBadId) {
1552 if (block == BAD_INDEX) {
1553 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
1554 return array;
1555 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001556 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001557 if (value.dataType >= Res_value::TYPE_FIRST_INT
1558 && value.dataType <= Res_value::TYPE_LAST_INT) {
1559 int intVal = value.data;
1560 env->SetIntArrayRegion(array, i, 1, &intVal);
1561 }
1562 }
1563 res.unlockBag(startOfBag);
1564 return array;
1565}
1566
Jon Miranda042ad632014-09-03 17:57:35 -07001567static jintArray android_content_AssetManager_getStyleAttributes(JNIEnv* env, jobject clazz,
1568 jint styleId)
1569{
1570 AssetManager* am = assetManagerForJavaObject(env, clazz);
1571 if (am == NULL) {
1572 return NULL;
1573 }
1574 const ResTable& res(am->getResources());
1575
1576 const ResTable::bag_entry* startOfBag;
1577 const ssize_t N = res.lockBag(styleId, &startOfBag);
1578 if (N < 0) {
1579 return NULL;
1580 }
1581
1582 jintArray array = env->NewIntArray(N);
1583 if (array == NULL) {
1584 res.unlockBag(startOfBag);
1585 return NULL;
1586 }
1587
Jon Miranda042ad632014-09-03 17:57:35 -07001588 const ResTable::bag_entry* bag = startOfBag;
1589 for (size_t i=0; ((ssize_t)i)<N; i++, bag++) {
1590 int resourceId = bag->map.name.ident;
1591 env->SetIntArrayRegion(array, i, 1, &resourceId);
1592 }
1593 res.unlockBag(startOfBag);
1594 return array;
1595}
1596
Mårten Kongstad48d22322014-01-31 14:43:27 +01001597static void android_content_AssetManager_init(JNIEnv* env, jobject clazz, jboolean isSystem)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001598{
Mårten Kongstad48d22322014-01-31 14:43:27 +01001599 if (isSystem) {
1600 verifySystemIdmaps();
1601 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001602 AssetManager* am = new AssetManager();
1603 if (am == NULL) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001604 jniThrowException(env, "java/lang/OutOfMemoryError", "");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001605 return;
1606 }
1607
1608 am->addDefaultAssets();
1609
Steve Block71f2cf12011-10-20 11:56:00 +01001610 ALOGV("Created AssetManager %p for Java object %p\n", am, clazz);
Ashok Bhat896043d2014-01-17 16:02:38 +00001611 env->SetLongField(clazz, gAssetManagerOffsets.mObject, reinterpret_cast<jlong>(am));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001612}
1613
1614static void android_content_AssetManager_destroy(JNIEnv* env, jobject clazz)
1615{
1616 AssetManager* am = (AssetManager*)
Ashok Bhat896043d2014-01-17 16:02:38 +00001617 (env->GetLongField(clazz, gAssetManagerOffsets.mObject));
Steve Block71f2cf12011-10-20 11:56:00 +01001618 ALOGV("Destroying AssetManager %p for Java object %p\n", am, clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001619 if (am != NULL) {
1620 delete am;
Ashok Bhat896043d2014-01-17 16:02:38 +00001621 env->SetLongField(clazz, gAssetManagerOffsets.mObject, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001622 }
1623}
1624
1625static jint android_content_AssetManager_getGlobalAssetCount(JNIEnv* env, jobject clazz)
1626{
1627 return Asset::getGlobalCount();
1628}
1629
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07001630static jobject android_content_AssetManager_getAssetAllocations(JNIEnv* env, jobject clazz)
1631{
1632 String8 alloc = Asset::getAssetAllocations();
1633 if (alloc.length() <= 0) {
1634 return NULL;
1635 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001636
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07001637 jstring str = env->NewStringUTF(alloc.string());
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07001638 return str;
1639}
1640
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001641static jint android_content_AssetManager_getGlobalAssetManagerCount(JNIEnv* env, jobject clazz)
1642{
1643 return AssetManager::getGlobalCount();
1644}
1645
1646// ----------------------------------------------------------------------------
1647
1648/*
1649 * JNI registration.
1650 */
Daniel Micay76f6a862015-09-19 17:31:01 -04001651static const JNINativeMethod gAssetManagerMethods[] = {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001652 /* name, signature, funcPtr */
1653
1654 // Basic asset stuff.
Ashok Bhat896043d2014-01-17 16:02:38 +00001655 { "openAsset", "(Ljava/lang/String;I)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001656 (void*) android_content_AssetManager_openAsset },
1657 { "openAssetFd", "(Ljava/lang/String;[J)Landroid/os/ParcelFileDescriptor;",
1658 (void*) android_content_AssetManager_openAssetFd },
Ashok Bhat896043d2014-01-17 16:02:38 +00001659 { "openNonAssetNative", "(ILjava/lang/String;I)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001660 (void*) android_content_AssetManager_openNonAssetNative },
1661 { "openNonAssetFdNative", "(ILjava/lang/String;[J)Landroid/os/ParcelFileDescriptor;",
1662 (void*) android_content_AssetManager_openNonAssetFdNative },
1663 { "list", "(Ljava/lang/String;)[Ljava/lang/String;",
1664 (void*) android_content_AssetManager_list },
Ashok Bhat896043d2014-01-17 16:02:38 +00001665 { "destroyAsset", "(J)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001666 (void*) android_content_AssetManager_destroyAsset },
Ashok Bhat896043d2014-01-17 16:02:38 +00001667 { "readAssetChar", "(J)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001668 (void*) android_content_AssetManager_readAssetChar },
Ashok Bhat896043d2014-01-17 16:02:38 +00001669 { "readAsset", "(J[BII)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001670 (void*) android_content_AssetManager_readAsset },
Ashok Bhat896043d2014-01-17 16:02:38 +00001671 { "seekAsset", "(JJI)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001672 (void*) android_content_AssetManager_seekAsset },
John Reck32995222016-10-07 11:02:20 -07001673 // @FastNative
1674 { "getAssetLength", "(J)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001675 (void*) android_content_AssetManager_getAssetLength },
John Reck32995222016-10-07 11:02:20 -07001676 // @FastNative
1677 { "getAssetRemainingLength", "(J)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001678 (void*) android_content_AssetManager_getAssetRemainingLength },
Tao Baia6d7e3f2015-09-01 18:49:54 -07001679 { "addAssetPathNative", "(Ljava/lang/String;Z)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001680 (void*) android_content_AssetManager_addAssetPath },
Mårten Kongstad30113132014-11-07 10:52:17 +01001681 { "addOverlayPathNative", "(Ljava/lang/String;)I",
Mårten Kongstad48d22322014-01-31 14:43:27 +01001682 (void*) android_content_AssetManager_addOverlayPath },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001683 { "isUpToDate", "()Z",
1684 (void*) android_content_AssetManager_isUpToDate },
1685
1686 // Resources.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001687 { "getLocales", "()[Ljava/lang/String;",
1688 (void*) android_content_AssetManager_getLocales },
Roozbeh Pournader1c686f22015-12-18 14:22:14 -08001689 { "getNonSystemLocales", "()[Ljava/lang/String;",
1690 (void*) android_content_AssetManager_getNonSystemLocales },
Filip Gruszczynski23493322015-07-29 17:02:59 -07001691 { "getSizeConfigurations", "()[Landroid/content/res/Configuration;",
1692 (void*) android_content_AssetManager_getSizeConfigurations },
John Reck32995222016-10-07 11:02:20 -07001693 // @FastNative
1694 { "setConfiguration", "(IILjava/lang/String;IIIIIIIIIIIIII)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001695 (void*) android_content_AssetManager_setConfiguration },
John Reck32995222016-10-07 11:02:20 -07001696 // @FastNative
1697 { "getResourceIdentifier","(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001698 (void*) android_content_AssetManager_getResourceIdentifier },
John Reck32995222016-10-07 11:02:20 -07001699 // @FastNative
1700 { "getResourceName","(I)Ljava/lang/String;",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001701 (void*) android_content_AssetManager_getResourceName },
John Reck32995222016-10-07 11:02:20 -07001702 // @FastNative
1703 { "getResourcePackageName","(I)Ljava/lang/String;",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001704 (void*) android_content_AssetManager_getResourcePackageName },
John Reck32995222016-10-07 11:02:20 -07001705 // @FastNative
1706 { "getResourceTypeName","(I)Ljava/lang/String;",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001707 (void*) android_content_AssetManager_getResourceTypeName },
John Reck32995222016-10-07 11:02:20 -07001708 // @FastNative
1709 { "getResourceEntryName","(I)Ljava/lang/String;",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001710 (void*) android_content_AssetManager_getResourceEntryName },
John Reck32995222016-10-07 11:02:20 -07001711 // @FastNative
1712 { "loadResourceValue","(ISLandroid/util/TypedValue;Z)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001713 (void*) android_content_AssetManager_loadResourceValue },
John Reck32995222016-10-07 11:02:20 -07001714 // @FastNative
1715 { "loadResourceBagValue","(IILandroid/util/TypedValue;Z)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001716 (void*) android_content_AssetManager_loadResourceBagValue },
John Reck32995222016-10-07 11:02:20 -07001717 // @FastNative
1718 { "getStringBlockCount","()I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001719 (void*) android_content_AssetManager_getStringBlockCount },
John Reck32995222016-10-07 11:02:20 -07001720 // @FastNative
1721 { "getNativeStringBlock","(I)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001722 (void*) android_content_AssetManager_getNativeStringBlock },
1723 { "getCookieName","(I)Ljava/lang/String;",
1724 (void*) android_content_AssetManager_getCookieName },
Adam Lesinskide898ff2014-01-29 18:20:45 -08001725 { "getAssignedPackageIdentifiers","()Landroid/util/SparseArray;",
1726 (void*) android_content_AssetManager_getAssignedPackageIdentifiers },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001727
1728 // Themes.
Ashok Bhat896043d2014-01-17 16:02:38 +00001729 { "newTheme", "()J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001730 (void*) android_content_AssetManager_newTheme },
Ashok Bhat896043d2014-01-17 16:02:38 +00001731 { "deleteTheme", "(J)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001732 (void*) android_content_AssetManager_deleteTheme },
Ashok Bhat896043d2014-01-17 16:02:38 +00001733 { "applyThemeStyle", "(JIZ)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001734 (void*) android_content_AssetManager_applyThemeStyle },
Ashok Bhat896043d2014-01-17 16:02:38 +00001735 { "copyTheme", "(JJ)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001736 (void*) android_content_AssetManager_copyTheme },
Alan Viverettee54d2452015-05-06 10:41:43 -07001737 { "clearTheme", "(J)V",
1738 (void*) android_content_AssetManager_clearTheme },
John Reck32995222016-10-07 11:02:20 -07001739 // @FastNative
1740 { "loadThemeAttributeValue", "(JILandroid/util/TypedValue;Z)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001741 (void*) android_content_AssetManager_loadThemeAttributeValue },
John Reck32995222016-10-07 11:02:20 -07001742 // @FastNative
1743 { "getThemeChangingConfigurations", "(J)I",
Alan Viverettec1d52792015-05-05 09:49:03 -07001744 (void*) android_content_AssetManager_getThemeChangingConfigurations },
Ashok Bhat896043d2014-01-17 16:02:38 +00001745 { "dumpTheme", "(JILjava/lang/String;Ljava/lang/String;)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001746 (void*) android_content_AssetManager_dumpTheme },
John Reck32995222016-10-07 11:02:20 -07001747 // @FastNative
John Reckf32adf42016-11-23 10:39:40 -08001748 { "applyStyle","(JIIJ[IIJJ)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001749 (void*) android_content_AssetManager_applyStyle },
John Reck32995222016-10-07 11:02:20 -07001750 // @FastNative
1751 { "resolveAttrs","(JII[I[I[I[I)Z",
Alan Viverette607bd842014-09-12 12:36:35 -07001752 (void*) android_content_AssetManager_resolveAttrs },
John Reck32995222016-10-07 11:02:20 -07001753 // @FastNative
1754 { "retrieveAttributes","(J[I[I[I)Z",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001755 (void*) android_content_AssetManager_retrieveAttributes },
John Reck32995222016-10-07 11:02:20 -07001756 // @FastNative
1757 { "getArraySize","(I)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001758 (void*) android_content_AssetManager_getArraySize },
John Reck32995222016-10-07 11:02:20 -07001759 // @FastNative
1760 { "retrieveArray","(I[I)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001761 (void*) android_content_AssetManager_retrieveArray },
1762
1763 // XML files.
Ashok Bhat896043d2014-01-17 16:02:38 +00001764 { "openXmlAssetNative", "(ILjava/lang/String;)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001765 (void*) android_content_AssetManager_openXmlAssetNative },
1766
1767 // Arrays.
1768 { "getArrayStringResource","(I)[Ljava/lang/String;",
1769 (void*) android_content_AssetManager_getArrayStringResource },
John Reck32995222016-10-07 11:02:20 -07001770 // @FastNative
1771 { "getArrayStringInfo","(I)[I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001772 (void*) android_content_AssetManager_getArrayStringInfo },
John Reck32995222016-10-07 11:02:20 -07001773 // @FastNative
1774 { "getArrayIntResource","(I)[I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001775 (void*) android_content_AssetManager_getArrayIntResource },
John Reck32995222016-10-07 11:02:20 -07001776 // @FastNative
1777 { "getStyleAttributes","(I)[I",
Jon Miranda042ad632014-09-03 17:57:35 -07001778 (void*) android_content_AssetManager_getStyleAttributes },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001779
1780 // Bookkeeping.
Mårten Kongstad48d22322014-01-31 14:43:27 +01001781 { "init", "(Z)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001782 (void*) android_content_AssetManager_init },
1783 { "destroy", "()V",
1784 (void*) android_content_AssetManager_destroy },
1785 { "getGlobalAssetCount", "()I",
1786 (void*) android_content_AssetManager_getGlobalAssetCount },
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07001787 { "getAssetAllocations", "()Ljava/lang/String;",
1788 (void*) android_content_AssetManager_getAssetAllocations },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001789 { "getGlobalAssetManagerCount", "()I",
Andreas Gampe32812612014-11-11 00:16:00 -08001790 (void*) android_content_AssetManager_getGlobalAssetManagerCount },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001791};
1792
1793int register_android_content_AssetManager(JNIEnv* env)
1794{
Andreas Gampe987f79f2014-11-18 17:29:46 -08001795 jclass typedValue = FindClassOrDie(env, "android/util/TypedValue");
1796 gTypedValueOffsets.mType = GetFieldIDOrDie(env, typedValue, "type", "I");
1797 gTypedValueOffsets.mData = GetFieldIDOrDie(env, typedValue, "data", "I");
1798 gTypedValueOffsets.mString = GetFieldIDOrDie(env, typedValue, "string",
1799 "Ljava/lang/CharSequence;");
1800 gTypedValueOffsets.mAssetCookie = GetFieldIDOrDie(env, typedValue, "assetCookie", "I");
1801 gTypedValueOffsets.mResourceId = GetFieldIDOrDie(env, typedValue, "resourceId", "I");
1802 gTypedValueOffsets.mChangingConfigurations = GetFieldIDOrDie(env, typedValue,
1803 "changingConfigurations", "I");
1804 gTypedValueOffsets.mDensity = GetFieldIDOrDie(env, typedValue, "density", "I");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001805
Andreas Gampe987f79f2014-11-18 17:29:46 -08001806 jclass assetFd = FindClassOrDie(env, "android/content/res/AssetFileDescriptor");
1807 gAssetFileDescriptorOffsets.mFd = GetFieldIDOrDie(env, assetFd, "mFd",
1808 "Landroid/os/ParcelFileDescriptor;");
1809 gAssetFileDescriptorOffsets.mStartOffset = GetFieldIDOrDie(env, assetFd, "mStartOffset", "J");
1810 gAssetFileDescriptorOffsets.mLength = GetFieldIDOrDie(env, assetFd, "mLength", "J");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001811
Andreas Gampe987f79f2014-11-18 17:29:46 -08001812 jclass assetManager = FindClassOrDie(env, "android/content/res/AssetManager");
1813 gAssetManagerOffsets.mObject = GetFieldIDOrDie(env, assetManager, "mObject", "J");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001814
Andreas Gampe987f79f2014-11-18 17:29:46 -08001815 jclass stringClass = FindClassOrDie(env, "java/lang/String");
1816 g_stringClass = MakeGlobalRefOrDie(env, stringClass);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001817
Andreas Gampe987f79f2014-11-18 17:29:46 -08001818 jclass sparseArrayClass = FindClassOrDie(env, "android/util/SparseArray");
1819 gSparseArrayOffsets.classObject = MakeGlobalRefOrDie(env, sparseArrayClass);
1820 gSparseArrayOffsets.constructor = GetMethodIDOrDie(env, gSparseArrayOffsets.classObject,
1821 "<init>", "()V");
1822 gSparseArrayOffsets.put = GetMethodIDOrDie(env, gSparseArrayOffsets.classObject, "put",
1823 "(ILjava/lang/Object;)V");
Adam Lesinskide898ff2014-01-29 18:20:45 -08001824
Filip Gruszczynski23493322015-07-29 17:02:59 -07001825 jclass configurationClass = FindClassOrDie(env, "android/content/res/Configuration");
1826 gConfigurationOffsets.classObject = MakeGlobalRefOrDie(env, configurationClass);
1827 gConfigurationOffsets.constructor = GetMethodIDOrDie(env, configurationClass,
1828 "<init>", "()V");
1829 gConfigurationOffsets.mSmallestScreenWidthDpOffset = GetFieldIDOrDie(env, configurationClass,
1830 "smallestScreenWidthDp", "I");
1831 gConfigurationOffsets.mScreenWidthDpOffset = GetFieldIDOrDie(env, configurationClass,
1832 "screenWidthDp", "I");
1833 gConfigurationOffsets.mScreenHeightDpOffset = GetFieldIDOrDie(env, configurationClass,
1834 "screenHeightDp", "I");
1835
Andreas Gampe987f79f2014-11-18 17:29:46 -08001836 return RegisterMethodsOrDie(env, "android/content/res/AssetManager", gAssetManagerMethods,
1837 NELEM(gAssetManagerMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001838}
1839
1840}; // namespace android