blob: d70fbb9d3915aabc88052398e79c01df65ab93f2 [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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001182static jboolean android_content_AssetManager_applyStyle(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +00001183 jlong themeToken,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001184 jint defStyleAttr,
1185 jint defStyleRes,
Ashok Bhat896043d2014-01-17 16:02:38 +00001186 jlong xmlParserToken,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001187 jintArray attrs,
1188 jintArray outValues,
1189 jintArray outIndices)
1190{
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001191 if (themeToken == 0) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001192 jniThrowNullPointerException(env, "theme token");
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001193 return JNI_FALSE;
1194 }
1195 if (attrs == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001196 jniThrowNullPointerException(env, "attrs");
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001197 return JNI_FALSE;
1198 }
1199 if (outValues == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001200 jniThrowNullPointerException(env, "out values");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001201 return JNI_FALSE;
1202 }
1203
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001204 const jsize NI = env->GetArrayLength(attrs);
1205 const jsize NV = env->GetArrayLength(outValues);
1206 if (NV < (NI*STYLE_NUM_ENTRIES)) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001207 jniThrowException(env, "java/lang/IndexOutOfBoundsException", "out values too small");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001208 return JNI_FALSE;
1209 }
1210
1211 jint* src = (jint*)env->GetPrimitiveArrayCritical(attrs, 0);
1212 if (src == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001213 return JNI_FALSE;
1214 }
1215
1216 jint* baseDest = (jint*)env->GetPrimitiveArrayCritical(outValues, 0);
Adam Lesinski4452e132016-10-12 07:47:28 -07001217 if (baseDest == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001218 env->ReleasePrimitiveArrayCritical(attrs, src, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001219 return JNI_FALSE;
1220 }
1221
1222 jint* indices = NULL;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001223 if (outIndices != NULL) {
1224 if (env->GetArrayLength(outIndices) > NI) {
1225 indices = (jint*)env->GetPrimitiveArrayCritical(outIndices, 0);
1226 }
1227 }
1228
Adam Lesinski4452e132016-10-12 07:47:28 -07001229 ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeToken);
1230 ResXMLParser* xmlParser = reinterpret_cast<ResXMLParser*>(xmlParserToken);
Adam Lesinski7a37b742016-10-12 14:05:55 -07001231 bool result = ApplyStyle(theme, xmlParser,
Adam Lesinski4452e132016-10-12 07:47:28 -07001232 defStyleAttr, defStyleRes,
1233 (uint32_t*) src, NI,
1234 (uint32_t*) baseDest,
1235 (uint32_t*) indices);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001236
1237 if (indices != NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001238 env->ReleasePrimitiveArrayCritical(outIndices, indices, 0);
1239 }
1240 env->ReleasePrimitiveArrayCritical(outValues, baseDest, 0);
1241 env->ReleasePrimitiveArrayCritical(attrs, src, 0);
Adam Lesinski4452e132016-10-12 07:47:28 -07001242 return result ? JNI_TRUE : JNI_FALSE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001243}
1244
1245static jboolean android_content_AssetManager_retrieveAttributes(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +00001246 jlong xmlParserToken,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001247 jintArray attrs,
1248 jintArray outValues,
1249 jintArray outIndices)
1250{
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001251 if (xmlParserToken == 0) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001252 jniThrowNullPointerException(env, "xmlParserToken");
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001253 return JNI_FALSE;
1254 }
1255 if (attrs == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001256 jniThrowNullPointerException(env, "attrs");
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001257 return JNI_FALSE;
1258 }
1259 if (outValues == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001260 jniThrowNullPointerException(env, "out values");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001261 return JNI_FALSE;
1262 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001263
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001264 AssetManager* am = assetManagerForJavaObject(env, clazz);
1265 if (am == NULL) {
1266 return JNI_FALSE;
1267 }
1268 const ResTable& res(am->getResources());
1269 ResXMLParser* xmlParser = (ResXMLParser*)xmlParserToken;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001270
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001271 const jsize NI = env->GetArrayLength(attrs);
1272 const jsize NV = env->GetArrayLength(outValues);
1273 if (NV < (NI*STYLE_NUM_ENTRIES)) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001274 jniThrowException(env, "java/lang/IndexOutOfBoundsException", "out values too small");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001275 return JNI_FALSE;
1276 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001277
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001278 jint* src = (jint*)env->GetPrimitiveArrayCritical(attrs, 0);
1279 if (src == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001280 return JNI_FALSE;
1281 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001282
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001283 jint* baseDest = (jint*)env->GetPrimitiveArrayCritical(outValues, 0);
Adam Lesinski4452e132016-10-12 07:47:28 -07001284 if (baseDest == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001285 env->ReleasePrimitiveArrayCritical(attrs, src, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001286 return JNI_FALSE;
1287 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001288
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001289 jint* indices = NULL;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001290 if (outIndices != NULL) {
1291 if (env->GetArrayLength(outIndices) > NI) {
1292 indices = (jint*)env->GetPrimitiveArrayCritical(outIndices, 0);
1293 }
1294 }
1295
Adam Lesinski7a37b742016-10-12 14:05:55 -07001296 bool result = RetrieveAttributes(&res, xmlParser,
Adam Lesinski4452e132016-10-12 07:47:28 -07001297 (uint32_t*) src, NI,
1298 (uint32_t*) baseDest,
1299 (uint32_t*) indices);
Elliott Hughes69a017b2011-04-08 14:10:28 -07001300
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001301 if (indices != NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001302 env->ReleasePrimitiveArrayCritical(outIndices, indices, 0);
1303 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001304 env->ReleasePrimitiveArrayCritical(outValues, baseDest, 0);
1305 env->ReleasePrimitiveArrayCritical(attrs, src, 0);
Adam Lesinski4452e132016-10-12 07:47:28 -07001306 return result ? JNI_TRUE : JNI_FALSE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001307}
1308
1309static jint android_content_AssetManager_getArraySize(JNIEnv* env, jobject clazz,
1310 jint id)
1311{
1312 AssetManager* am = assetManagerForJavaObject(env, clazz);
1313 if (am == NULL) {
Olivier Baillyd7c86722010-11-18 14:43:36 -08001314 return 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001315 }
1316 const ResTable& res(am->getResources());
Elliott Hughes69a017b2011-04-08 14:10:28 -07001317
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001318 res.lock();
1319 const ResTable::bag_entry* defStyleEnt = NULL;
1320 ssize_t bagOff = res.getBagLocked(id, &defStyleEnt);
1321 res.unlock();
Elliott Hughes69a017b2011-04-08 14:10:28 -07001322
Ashok Bhat896043d2014-01-17 16:02:38 +00001323 return static_cast<jint>(bagOff);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001324}
1325
1326static jint android_content_AssetManager_retrieveArray(JNIEnv* env, jobject clazz,
1327 jint id,
1328 jintArray outValues)
1329{
1330 if (outValues == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001331 jniThrowNullPointerException(env, "out values");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001332 return JNI_FALSE;
1333 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001334
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001335 AssetManager* am = assetManagerForJavaObject(env, clazz);
1336 if (am == NULL) {
1337 return JNI_FALSE;
1338 }
1339 const ResTable& res(am->getResources());
Dianne Hackborn0d221012009-07-29 15:41:19 -07001340 ResTable_config config;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001341 Res_value value;
1342 ssize_t block;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001343
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001344 const jsize NV = env->GetArrayLength(outValues);
Elliott Hughes69a017b2011-04-08 14:10:28 -07001345
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001346 jint* baseDest = (jint*)env->GetPrimitiveArrayCritical(outValues, 0);
1347 jint* dest = baseDest;
1348 if (dest == NULL) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001349 jniThrowException(env, "java/lang/OutOfMemoryError", "");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001350 return JNI_FALSE;
1351 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001352
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001353 // Now lock down the resource object and start pulling stuff from it.
1354 res.lock();
Elliott Hughes69a017b2011-04-08 14:10:28 -07001355
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001356 const ResTable::bag_entry* arrayEnt = NULL;
1357 uint32_t arrayTypeSetFlags = 0;
1358 ssize_t bagOff = res.getBagLocked(id, &arrayEnt, &arrayTypeSetFlags);
1359 const ResTable::bag_entry* endArrayEnt = arrayEnt +
1360 (bagOff >= 0 ? bagOff : 0);
Elliott Hughes69a017b2011-04-08 14:10:28 -07001361
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001362 int i = 0;
1363 uint32_t typeSetFlags;
1364 while (i < NV && arrayEnt < endArrayEnt) {
1365 block = arrayEnt->stringBlock;
1366 typeSetFlags = arrayTypeSetFlags;
Dianne Hackborn0d221012009-07-29 15:41:19 -07001367 config.density = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001368 value = arrayEnt->map.value;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001369
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001370 uint32_t resid = 0;
1371 if (value.dataType != Res_value::TYPE_NULL) {
1372 // Take care of resolving the found resource to its final value.
1373 //printf("Resolving attribute reference\n");
Dianne Hackborn0d221012009-07-29 15:41:19 -07001374 ssize_t newBlock = res.resolveReference(&value, block, &resid,
1375 &typeSetFlags, &config);
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001376 if (kThrowOnBadId) {
1377 if (newBlock == BAD_INDEX) {
1378 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
1379 return JNI_FALSE;
1380 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001381 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001382 if (newBlock >= 0) block = newBlock;
1383 }
1384
1385 // Deal with the special @null value -- it turns back to TYPE_NULL.
1386 if (value.dataType == Res_value::TYPE_REFERENCE && value.data == 0) {
1387 value.dataType = Res_value::TYPE_NULL;
Alan Viverettef2969402014-10-29 17:09:36 -07001388 value.data = Res_value::DATA_NULL_UNDEFINED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001389 }
1390
1391 //printf("Attribute 0x%08x: final type=0x%x, data=0x%08x\n", curIdent, value.dataType, value.data);
1392
1393 // Write the final value back to Java.
1394 dest[STYLE_TYPE] = value.dataType;
1395 dest[STYLE_DATA] = value.data;
Ashok Bhat896043d2014-01-17 16:02:38 +00001396 dest[STYLE_ASSET_COOKIE] = reinterpret_cast<jint>(res.getTableCookie(block));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001397 dest[STYLE_RESOURCE_ID] = resid;
1398 dest[STYLE_CHANGING_CONFIGURATIONS] = typeSetFlags;
Dianne Hackborn0d221012009-07-29 15:41:19 -07001399 dest[STYLE_DENSITY] = config.density;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001400 dest += STYLE_NUM_ENTRIES;
1401 i+= STYLE_NUM_ENTRIES;
1402 arrayEnt++;
1403 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001404
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001405 i /= STYLE_NUM_ENTRIES;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001406
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001407 res.unlock();
Elliott Hughes69a017b2011-04-08 14:10:28 -07001408
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001409 env->ReleasePrimitiveArrayCritical(outValues, baseDest, 0);
Elliott Hughes69a017b2011-04-08 14:10:28 -07001410
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001411 return i;
1412}
1413
Ashok Bhat896043d2014-01-17 16:02:38 +00001414static jlong android_content_AssetManager_openXmlAssetNative(JNIEnv* env, jobject clazz,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001415 jint cookie,
1416 jstring fileName)
1417{
1418 AssetManager* am = assetManagerForJavaObject(env, clazz);
1419 if (am == NULL) {
1420 return 0;
1421 }
1422
Steve Block71f2cf12011-10-20 11:56:00 +01001423 ALOGV("openXmlAsset in %p (Java object %p)\n", am, clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001424
Elliott Hughes69a017b2011-04-08 14:10:28 -07001425 ScopedUtfChars fileName8(env, fileName);
1426 if (fileName8.c_str() == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001427 return 0;
1428 }
1429
Adam Lesinskide898ff2014-01-29 18:20:45 -08001430 int32_t assetCookie = static_cast<int32_t>(cookie);
1431 Asset* a = assetCookie
1432 ? am->openNonAsset(assetCookie, fileName8.c_str(), Asset::ACCESS_BUFFER)
1433 : am->openNonAsset(fileName8.c_str(), Asset::ACCESS_BUFFER, &assetCookie);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001434
1435 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001436 jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001437 return 0;
1438 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001439
Adam Lesinskide898ff2014-01-29 18:20:45 -08001440 const DynamicRefTable* dynamicRefTable =
1441 am->getResources().getDynamicRefTableForCookie(assetCookie);
1442 ResXMLTree* block = new ResXMLTree(dynamicRefTable);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001443 status_t err = block->setTo(a->getBuffer(true), a->getLength(), true);
1444 a->close();
1445 delete a;
1446
1447 if (err != NO_ERROR) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001448 jniThrowException(env, "java/io/FileNotFoundException", "Corrupt XML binary file");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001449 return 0;
1450 }
1451
Ashok Bhat896043d2014-01-17 16:02:38 +00001452 return reinterpret_cast<jlong>(block);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001453}
1454
1455static jintArray android_content_AssetManager_getArrayStringInfo(JNIEnv* env, jobject clazz,
1456 jint arrayResId)
1457{
1458 AssetManager* am = assetManagerForJavaObject(env, clazz);
1459 if (am == NULL) {
1460 return NULL;
1461 }
1462 const ResTable& res(am->getResources());
1463
1464 const ResTable::bag_entry* startOfBag;
1465 const ssize_t N = res.lockBag(arrayResId, &startOfBag);
1466 if (N < 0) {
1467 return NULL;
1468 }
1469
1470 jintArray array = env->NewIntArray(N * 2);
1471 if (array == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001472 res.unlockBag(startOfBag);
1473 return NULL;
1474 }
1475
1476 Res_value value;
1477 const ResTable::bag_entry* bag = startOfBag;
1478 for (size_t i = 0, j = 0; ((ssize_t)i)<N; i++, bag++) {
1479 jint stringIndex = -1;
1480 jint stringBlock = 0;
1481 value = bag->map.value;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001482
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001483 // Take care of resolving the found resource to its final value.
1484 stringBlock = res.resolveReference(&value, bag->stringBlock, NULL);
1485 if (value.dataType == Res_value::TYPE_STRING) {
1486 stringIndex = value.data;
1487 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001488
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001489 if (kThrowOnBadId) {
1490 if (stringBlock == BAD_INDEX) {
1491 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
1492 return array;
1493 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001494 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001495
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001496 //todo: It might be faster to allocate a C array to contain
1497 // the blocknums and indices, put them in there and then
1498 // do just one SetIntArrayRegion()
1499 env->SetIntArrayRegion(array, j, 1, &stringBlock);
1500 env->SetIntArrayRegion(array, j + 1, 1, &stringIndex);
1501 j = j + 2;
1502 }
1503 res.unlockBag(startOfBag);
1504 return array;
1505}
1506
1507static jobjectArray android_content_AssetManager_getArrayStringResource(JNIEnv* env, jobject clazz,
1508 jint arrayResId)
1509{
1510 AssetManager* am = assetManagerForJavaObject(env, clazz);
1511 if (am == NULL) {
1512 return NULL;
1513 }
1514 const ResTable& res(am->getResources());
1515
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001516 const ResTable::bag_entry* startOfBag;
1517 const ssize_t N = res.lockBag(arrayResId, &startOfBag);
1518 if (N < 0) {
1519 return NULL;
1520 }
1521
Vladimir Markoaa5fe3d2013-06-17 12:46:22 +01001522 jobjectArray array = env->NewObjectArray(N, g_stringClass, NULL);
Kenny Root485dd212010-05-06 16:06:48 -07001523 if (env->ExceptionCheck()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001524 res.unlockBag(startOfBag);
1525 return NULL;
1526 }
1527
1528 Res_value value;
1529 const ResTable::bag_entry* bag = startOfBag;
1530 size_t strLen = 0;
1531 for (size_t i=0; ((ssize_t)i)<N; i++, bag++) {
1532 value = bag->map.value;
1533 jstring str = NULL;
Kenny Root780d2a12010-02-22 22:36:26 -08001534
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001535 // Take care of resolving the found resource to its final value.
1536 ssize_t block = res.resolveReference(&value, bag->stringBlock, NULL);
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001537 if (kThrowOnBadId) {
1538 if (block == BAD_INDEX) {
1539 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
1540 return array;
1541 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001542 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001543 if (value.dataType == Res_value::TYPE_STRING) {
Kenny Root780d2a12010-02-22 22:36:26 -08001544 const ResStringPool* pool = res.getTableStringBlock(block);
1545 const char* str8 = pool->string8At(value.data, &strLen);
1546 if (str8 != NULL) {
1547 str = env->NewStringUTF(str8);
1548 } else {
1549 const char16_t* str16 = pool->stringAt(value.data, &strLen);
Dan Albert66987492014-11-20 11:41:21 -08001550 str = env->NewString(reinterpret_cast<const jchar*>(str16),
1551 strLen);
Kenny Root485dd212010-05-06 16:06:48 -07001552 }
1553
1554 // If one of our NewString{UTF} calls failed due to memory, an
1555 // exception will be pending.
1556 if (env->ExceptionCheck()) {
1557 res.unlockBag(startOfBag);
1558 return NULL;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001559 }
Kenny Root780d2a12010-02-22 22:36:26 -08001560
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001561 env->SetObjectArrayElement(array, i, str);
Kenny Root485dd212010-05-06 16:06:48 -07001562
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001563 // str is not NULL at that point, otherwise ExceptionCheck would have been true.
1564 // If we have a large amount of strings in our array, we might
1565 // overflow the local reference table of the VM.
Kenny Root485dd212010-05-06 16:06:48 -07001566 env->DeleteLocalRef(str);
1567 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001568 }
1569 res.unlockBag(startOfBag);
1570 return array;
1571}
1572
1573static jintArray android_content_AssetManager_getArrayIntResource(JNIEnv* env, jobject clazz,
1574 jint arrayResId)
1575{
1576 AssetManager* am = assetManagerForJavaObject(env, clazz);
1577 if (am == NULL) {
1578 return NULL;
1579 }
1580 const ResTable& res(am->getResources());
1581
1582 const ResTable::bag_entry* startOfBag;
1583 const ssize_t N = res.lockBag(arrayResId, &startOfBag);
1584 if (N < 0) {
1585 return NULL;
1586 }
1587
1588 jintArray array = env->NewIntArray(N);
1589 if (array == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001590 res.unlockBag(startOfBag);
1591 return NULL;
1592 }
1593
1594 Res_value value;
1595 const ResTable::bag_entry* bag = startOfBag;
1596 for (size_t i=0; ((ssize_t)i)<N; i++, bag++) {
1597 value = bag->map.value;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001598
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001599 // Take care of resolving the found resource to its final value.
1600 ssize_t block = res.resolveReference(&value, bag->stringBlock, NULL);
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001601 if (kThrowOnBadId) {
1602 if (block == BAD_INDEX) {
1603 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
1604 return array;
1605 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001606 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001607 if (value.dataType >= Res_value::TYPE_FIRST_INT
1608 && value.dataType <= Res_value::TYPE_LAST_INT) {
1609 int intVal = value.data;
1610 env->SetIntArrayRegion(array, i, 1, &intVal);
1611 }
1612 }
1613 res.unlockBag(startOfBag);
1614 return array;
1615}
1616
Jon Miranda042ad632014-09-03 17:57:35 -07001617static jintArray android_content_AssetManager_getStyleAttributes(JNIEnv* env, jobject clazz,
1618 jint styleId)
1619{
1620 AssetManager* am = assetManagerForJavaObject(env, clazz);
1621 if (am == NULL) {
1622 return NULL;
1623 }
1624 const ResTable& res(am->getResources());
1625
1626 const ResTable::bag_entry* startOfBag;
1627 const ssize_t N = res.lockBag(styleId, &startOfBag);
1628 if (N < 0) {
1629 return NULL;
1630 }
1631
1632 jintArray array = env->NewIntArray(N);
1633 if (array == NULL) {
1634 res.unlockBag(startOfBag);
1635 return NULL;
1636 }
1637
Jon Miranda042ad632014-09-03 17:57:35 -07001638 const ResTable::bag_entry* bag = startOfBag;
1639 for (size_t i=0; ((ssize_t)i)<N; i++, bag++) {
1640 int resourceId = bag->map.name.ident;
1641 env->SetIntArrayRegion(array, i, 1, &resourceId);
1642 }
1643 res.unlockBag(startOfBag);
1644 return array;
1645}
1646
Mårten Kongstad48d22322014-01-31 14:43:27 +01001647static void android_content_AssetManager_init(JNIEnv* env, jobject clazz, jboolean isSystem)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001648{
Mårten Kongstad48d22322014-01-31 14:43:27 +01001649 if (isSystem) {
1650 verifySystemIdmaps();
1651 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001652 AssetManager* am = new AssetManager();
1653 if (am == NULL) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001654 jniThrowException(env, "java/lang/OutOfMemoryError", "");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001655 return;
1656 }
1657
1658 am->addDefaultAssets();
1659
Steve Block71f2cf12011-10-20 11:56:00 +01001660 ALOGV("Created AssetManager %p for Java object %p\n", am, clazz);
Ashok Bhat896043d2014-01-17 16:02:38 +00001661 env->SetLongField(clazz, gAssetManagerOffsets.mObject, reinterpret_cast<jlong>(am));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001662}
1663
1664static void android_content_AssetManager_destroy(JNIEnv* env, jobject clazz)
1665{
1666 AssetManager* am = (AssetManager*)
Ashok Bhat896043d2014-01-17 16:02:38 +00001667 (env->GetLongField(clazz, gAssetManagerOffsets.mObject));
Steve Block71f2cf12011-10-20 11:56:00 +01001668 ALOGV("Destroying AssetManager %p for Java object %p\n", am, clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001669 if (am != NULL) {
1670 delete am;
Ashok Bhat896043d2014-01-17 16:02:38 +00001671 env->SetLongField(clazz, gAssetManagerOffsets.mObject, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001672 }
1673}
1674
1675static jint android_content_AssetManager_getGlobalAssetCount(JNIEnv* env, jobject clazz)
1676{
1677 return Asset::getGlobalCount();
1678}
1679
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07001680static jobject android_content_AssetManager_getAssetAllocations(JNIEnv* env, jobject clazz)
1681{
1682 String8 alloc = Asset::getAssetAllocations();
1683 if (alloc.length() <= 0) {
1684 return NULL;
1685 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001686
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07001687 jstring str = env->NewStringUTF(alloc.string());
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07001688 return str;
1689}
1690
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001691static jint android_content_AssetManager_getGlobalAssetManagerCount(JNIEnv* env, jobject clazz)
1692{
1693 return AssetManager::getGlobalCount();
1694}
1695
1696// ----------------------------------------------------------------------------
1697
1698/*
1699 * JNI registration.
1700 */
Daniel Micay76f6a862015-09-19 17:31:01 -04001701static const JNINativeMethod gAssetManagerMethods[] = {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001702 /* name, signature, funcPtr */
1703
1704 // Basic asset stuff.
Ashok Bhat896043d2014-01-17 16:02:38 +00001705 { "openAsset", "(Ljava/lang/String;I)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001706 (void*) android_content_AssetManager_openAsset },
1707 { "openAssetFd", "(Ljava/lang/String;[J)Landroid/os/ParcelFileDescriptor;",
1708 (void*) android_content_AssetManager_openAssetFd },
Ashok Bhat896043d2014-01-17 16:02:38 +00001709 { "openNonAssetNative", "(ILjava/lang/String;I)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001710 (void*) android_content_AssetManager_openNonAssetNative },
1711 { "openNonAssetFdNative", "(ILjava/lang/String;[J)Landroid/os/ParcelFileDescriptor;",
1712 (void*) android_content_AssetManager_openNonAssetFdNative },
1713 { "list", "(Ljava/lang/String;)[Ljava/lang/String;",
1714 (void*) android_content_AssetManager_list },
Ashok Bhat896043d2014-01-17 16:02:38 +00001715 { "destroyAsset", "(J)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001716 (void*) android_content_AssetManager_destroyAsset },
Ashok Bhat896043d2014-01-17 16:02:38 +00001717 { "readAssetChar", "(J)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001718 (void*) android_content_AssetManager_readAssetChar },
Ashok Bhat896043d2014-01-17 16:02:38 +00001719 { "readAsset", "(J[BII)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001720 (void*) android_content_AssetManager_readAsset },
Ashok Bhat896043d2014-01-17 16:02:38 +00001721 { "seekAsset", "(JJI)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001722 (void*) android_content_AssetManager_seekAsset },
John Reck32995222016-10-07 11:02:20 -07001723 // @FastNative
1724 { "getAssetLength", "(J)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001725 (void*) android_content_AssetManager_getAssetLength },
John Reck32995222016-10-07 11:02:20 -07001726 // @FastNative
1727 { "getAssetRemainingLength", "(J)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001728 (void*) android_content_AssetManager_getAssetRemainingLength },
Tao Baia6d7e3f2015-09-01 18:49:54 -07001729 { "addAssetPathNative", "(Ljava/lang/String;Z)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001730 (void*) android_content_AssetManager_addAssetPath },
Mårten Kongstad30113132014-11-07 10:52:17 +01001731 { "addOverlayPathNative", "(Ljava/lang/String;)I",
Mårten Kongstad48d22322014-01-31 14:43:27 +01001732 (void*) android_content_AssetManager_addOverlayPath },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001733 { "isUpToDate", "()Z",
1734 (void*) android_content_AssetManager_isUpToDate },
1735
1736 // Resources.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001737 { "getLocales", "()[Ljava/lang/String;",
1738 (void*) android_content_AssetManager_getLocales },
Roozbeh Pournader1c686f22015-12-18 14:22:14 -08001739 { "getNonSystemLocales", "()[Ljava/lang/String;",
1740 (void*) android_content_AssetManager_getNonSystemLocales },
Filip Gruszczynski23493322015-07-29 17:02:59 -07001741 { "getSizeConfigurations", "()[Landroid/content/res/Configuration;",
1742 (void*) android_content_AssetManager_getSizeConfigurations },
John Reck32995222016-10-07 11:02:20 -07001743 // @FastNative
1744 { "setConfiguration", "(IILjava/lang/String;IIIIIIIIIIIIII)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001745 (void*) android_content_AssetManager_setConfiguration },
John Reck32995222016-10-07 11:02:20 -07001746 // @FastNative
1747 { "getResourceIdentifier","(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001748 (void*) android_content_AssetManager_getResourceIdentifier },
John Reck32995222016-10-07 11:02:20 -07001749 // @FastNative
1750 { "getResourceName","(I)Ljava/lang/String;",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001751 (void*) android_content_AssetManager_getResourceName },
John Reck32995222016-10-07 11:02:20 -07001752 // @FastNative
1753 { "getResourcePackageName","(I)Ljava/lang/String;",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001754 (void*) android_content_AssetManager_getResourcePackageName },
John Reck32995222016-10-07 11:02:20 -07001755 // @FastNative
1756 { "getResourceTypeName","(I)Ljava/lang/String;",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001757 (void*) android_content_AssetManager_getResourceTypeName },
John Reck32995222016-10-07 11:02:20 -07001758 // @FastNative
1759 { "getResourceEntryName","(I)Ljava/lang/String;",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001760 (void*) android_content_AssetManager_getResourceEntryName },
John Reck32995222016-10-07 11:02:20 -07001761 // @FastNative
1762 { "loadResourceValue","(ISLandroid/util/TypedValue;Z)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001763 (void*) android_content_AssetManager_loadResourceValue },
John Reck32995222016-10-07 11:02:20 -07001764 // @FastNative
1765 { "loadResourceBagValue","(IILandroid/util/TypedValue;Z)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001766 (void*) android_content_AssetManager_loadResourceBagValue },
John Reck32995222016-10-07 11:02:20 -07001767 // @FastNative
1768 { "getStringBlockCount","()I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001769 (void*) android_content_AssetManager_getStringBlockCount },
John Reck32995222016-10-07 11:02:20 -07001770 // @FastNative
1771 { "getNativeStringBlock","(I)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001772 (void*) android_content_AssetManager_getNativeStringBlock },
1773 { "getCookieName","(I)Ljava/lang/String;",
1774 (void*) android_content_AssetManager_getCookieName },
Adam Lesinskide898ff2014-01-29 18:20:45 -08001775 { "getAssignedPackageIdentifiers","()Landroid/util/SparseArray;",
1776 (void*) android_content_AssetManager_getAssignedPackageIdentifiers },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001777
1778 // Themes.
Ashok Bhat896043d2014-01-17 16:02:38 +00001779 { "newTheme", "()J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001780 (void*) android_content_AssetManager_newTheme },
Ashok Bhat896043d2014-01-17 16:02:38 +00001781 { "deleteTheme", "(J)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001782 (void*) android_content_AssetManager_deleteTheme },
Ashok Bhat896043d2014-01-17 16:02:38 +00001783 { "applyThemeStyle", "(JIZ)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001784 (void*) android_content_AssetManager_applyThemeStyle },
Ashok Bhat896043d2014-01-17 16:02:38 +00001785 { "copyTheme", "(JJ)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001786 (void*) android_content_AssetManager_copyTheme },
Alan Viverettee54d2452015-05-06 10:41:43 -07001787 { "clearTheme", "(J)V",
1788 (void*) android_content_AssetManager_clearTheme },
John Reck32995222016-10-07 11:02:20 -07001789 // @FastNative
1790 { "loadThemeAttributeValue", "(JILandroid/util/TypedValue;Z)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001791 (void*) android_content_AssetManager_loadThemeAttributeValue },
John Reck32995222016-10-07 11:02:20 -07001792 // @FastNative
1793 { "getThemeChangingConfigurations", "(J)I",
Alan Viverettec1d52792015-05-05 09:49:03 -07001794 (void*) android_content_AssetManager_getThemeChangingConfigurations },
Ashok Bhat896043d2014-01-17 16:02:38 +00001795 { "dumpTheme", "(JILjava/lang/String;Ljava/lang/String;)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001796 (void*) android_content_AssetManager_dumpTheme },
John Reck32995222016-10-07 11:02:20 -07001797 // @FastNative
1798 { "applyStyle","(JIIJ[I[I[I)Z",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001799 (void*) android_content_AssetManager_applyStyle },
John Reck32995222016-10-07 11:02:20 -07001800 // @FastNative
1801 { "resolveAttrs","(JII[I[I[I[I)Z",
Alan Viverette607bd842014-09-12 12:36:35 -07001802 (void*) android_content_AssetManager_resolveAttrs },
John Reck32995222016-10-07 11:02:20 -07001803 // @FastNative
1804 { "retrieveAttributes","(J[I[I[I)Z",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001805 (void*) android_content_AssetManager_retrieveAttributes },
John Reck32995222016-10-07 11:02:20 -07001806 // @FastNative
1807 { "getArraySize","(I)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001808 (void*) android_content_AssetManager_getArraySize },
John Reck32995222016-10-07 11:02:20 -07001809 // @FastNative
1810 { "retrieveArray","(I[I)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001811 (void*) android_content_AssetManager_retrieveArray },
1812
1813 // XML files.
Ashok Bhat896043d2014-01-17 16:02:38 +00001814 { "openXmlAssetNative", "(ILjava/lang/String;)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001815 (void*) android_content_AssetManager_openXmlAssetNative },
1816
1817 // Arrays.
1818 { "getArrayStringResource","(I)[Ljava/lang/String;",
1819 (void*) android_content_AssetManager_getArrayStringResource },
John Reck32995222016-10-07 11:02:20 -07001820 // @FastNative
1821 { "getArrayStringInfo","(I)[I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001822 (void*) android_content_AssetManager_getArrayStringInfo },
John Reck32995222016-10-07 11:02:20 -07001823 // @FastNative
1824 { "getArrayIntResource","(I)[I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001825 (void*) android_content_AssetManager_getArrayIntResource },
John Reck32995222016-10-07 11:02:20 -07001826 // @FastNative
1827 { "getStyleAttributes","(I)[I",
Jon Miranda042ad632014-09-03 17:57:35 -07001828 (void*) android_content_AssetManager_getStyleAttributes },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001829
1830 // Bookkeeping.
Mårten Kongstad48d22322014-01-31 14:43:27 +01001831 { "init", "(Z)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001832 (void*) android_content_AssetManager_init },
1833 { "destroy", "()V",
1834 (void*) android_content_AssetManager_destroy },
1835 { "getGlobalAssetCount", "()I",
1836 (void*) android_content_AssetManager_getGlobalAssetCount },
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07001837 { "getAssetAllocations", "()Ljava/lang/String;",
1838 (void*) android_content_AssetManager_getAssetAllocations },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001839 { "getGlobalAssetManagerCount", "()I",
Andreas Gampe32812612014-11-11 00:16:00 -08001840 (void*) android_content_AssetManager_getGlobalAssetManagerCount },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001841};
1842
1843int register_android_content_AssetManager(JNIEnv* env)
1844{
Andreas Gampe987f79f2014-11-18 17:29:46 -08001845 jclass typedValue = FindClassOrDie(env, "android/util/TypedValue");
1846 gTypedValueOffsets.mType = GetFieldIDOrDie(env, typedValue, "type", "I");
1847 gTypedValueOffsets.mData = GetFieldIDOrDie(env, typedValue, "data", "I");
1848 gTypedValueOffsets.mString = GetFieldIDOrDie(env, typedValue, "string",
1849 "Ljava/lang/CharSequence;");
1850 gTypedValueOffsets.mAssetCookie = GetFieldIDOrDie(env, typedValue, "assetCookie", "I");
1851 gTypedValueOffsets.mResourceId = GetFieldIDOrDie(env, typedValue, "resourceId", "I");
1852 gTypedValueOffsets.mChangingConfigurations = GetFieldIDOrDie(env, typedValue,
1853 "changingConfigurations", "I");
1854 gTypedValueOffsets.mDensity = GetFieldIDOrDie(env, typedValue, "density", "I");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001855
Andreas Gampe987f79f2014-11-18 17:29:46 -08001856 jclass assetFd = FindClassOrDie(env, "android/content/res/AssetFileDescriptor");
1857 gAssetFileDescriptorOffsets.mFd = GetFieldIDOrDie(env, assetFd, "mFd",
1858 "Landroid/os/ParcelFileDescriptor;");
1859 gAssetFileDescriptorOffsets.mStartOffset = GetFieldIDOrDie(env, assetFd, "mStartOffset", "J");
1860 gAssetFileDescriptorOffsets.mLength = GetFieldIDOrDie(env, assetFd, "mLength", "J");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001861
Andreas Gampe987f79f2014-11-18 17:29:46 -08001862 jclass assetManager = FindClassOrDie(env, "android/content/res/AssetManager");
1863 gAssetManagerOffsets.mObject = GetFieldIDOrDie(env, assetManager, "mObject", "J");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001864
Andreas Gampe987f79f2014-11-18 17:29:46 -08001865 jclass stringClass = FindClassOrDie(env, "java/lang/String");
1866 g_stringClass = MakeGlobalRefOrDie(env, stringClass);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001867
Andreas Gampe987f79f2014-11-18 17:29:46 -08001868 jclass sparseArrayClass = FindClassOrDie(env, "android/util/SparseArray");
1869 gSparseArrayOffsets.classObject = MakeGlobalRefOrDie(env, sparseArrayClass);
1870 gSparseArrayOffsets.constructor = GetMethodIDOrDie(env, gSparseArrayOffsets.classObject,
1871 "<init>", "()V");
1872 gSparseArrayOffsets.put = GetMethodIDOrDie(env, gSparseArrayOffsets.classObject, "put",
1873 "(ILjava/lang/Object;)V");
Adam Lesinskide898ff2014-01-29 18:20:45 -08001874
Filip Gruszczynski23493322015-07-29 17:02:59 -07001875 jclass configurationClass = FindClassOrDie(env, "android/content/res/Configuration");
1876 gConfigurationOffsets.classObject = MakeGlobalRefOrDie(env, configurationClass);
1877 gConfigurationOffsets.constructor = GetMethodIDOrDie(env, configurationClass,
1878 "<init>", "()V");
1879 gConfigurationOffsets.mSmallestScreenWidthDpOffset = GetFieldIDOrDie(env, configurationClass,
1880 "smallestScreenWidthDp", "I");
1881 gConfigurationOffsets.mScreenWidthDpOffset = GetFieldIDOrDie(env, configurationClass,
1882 "screenWidthDp", "I");
1883 gConfigurationOffsets.mScreenHeightDpOffset = GetFieldIDOrDie(env, configurationClass,
1884 "screenHeightDp", "I");
1885
Andreas Gampe987f79f2014-11-18 17:29:46 -08001886 return RegisterMethodsOrDie(env, "android/content/res/AssetManager", gAssetManagerMethods,
1887 NELEM(gAssetManagerMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001888}
1889
1890}; // namespace android