blob: 5a4348e478dd805ab4d484f54c93b9d7fef5839c [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 -0800100enum {
Dianne Hackborn0d221012009-07-29 15:41:19 -0700101 STYLE_NUM_ENTRIES = 6,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102 STYLE_TYPE = 0,
103 STYLE_DATA = 1,
104 STYLE_ASSET_COOKIE = 2,
105 STYLE_RESOURCE_ID = 3,
Dianne Hackborn0d221012009-07-29 15:41:19 -0700106 STYLE_CHANGING_CONFIGURATIONS = 4,
107 STYLE_DENSITY = 5
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108};
109
110static jint copyValue(JNIEnv* env, jobject outValue, const ResTable* table,
111 const Res_value& value, uint32_t ref, ssize_t block,
112 uint32_t typeSpecFlags, ResTable_config* config = NULL);
113
114jint copyValue(JNIEnv* env, jobject outValue, const ResTable* table,
115 const Res_value& value, uint32_t ref, ssize_t block,
116 uint32_t typeSpecFlags, ResTable_config* config)
117{
118 env->SetIntField(outValue, gTypedValueOffsets.mType, value.dataType);
119 env->SetIntField(outValue, gTypedValueOffsets.mAssetCookie,
Ashok Bhat896043d2014-01-17 16:02:38 +0000120 static_cast<jint>(table->getTableCookie(block)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800121 env->SetIntField(outValue, gTypedValueOffsets.mData, value.data);
122 env->SetObjectField(outValue, gTypedValueOffsets.mString, NULL);
123 env->SetIntField(outValue, gTypedValueOffsets.mResourceId, ref);
124 env->SetIntField(outValue, gTypedValueOffsets.mChangingConfigurations,
125 typeSpecFlags);
126 if (config != NULL) {
127 env->SetIntField(outValue, gTypedValueOffsets.mDensity, config->density);
128 }
129 return block;
130}
131
Mårten Kongstad48d22322014-01-31 14:43:27 +0100132// This is called by zygote (running as user root) as part of preloadResources.
133static void verifySystemIdmaps()
134{
135 pid_t pid;
136 char system_id[10];
137
138 snprintf(system_id, sizeof(system_id), "%d", AID_SYSTEM);
139
140 switch (pid = fork()) {
141 case -1:
142 ALOGE("failed to fork for idmap: %s", strerror(errno));
143 break;
144 case 0: // child
145 {
146 struct __user_cap_header_struct capheader;
147 struct __user_cap_data_struct capdata;
148
149 memset(&capheader, 0, sizeof(capheader));
150 memset(&capdata, 0, sizeof(capdata));
151
152 capheader.version = _LINUX_CAPABILITY_VERSION;
153 capheader.pid = 0;
154
155 if (capget(&capheader, &capdata) != 0) {
156 ALOGE("capget: %s\n", strerror(errno));
157 exit(1);
158 }
159
160 capdata.effective = capdata.permitted;
161 if (capset(&capheader, &capdata) != 0) {
162 ALOGE("capset: %s\n", strerror(errno));
163 exit(1);
164 }
165
166 if (setgid(AID_SYSTEM) != 0) {
167 ALOGE("setgid: %s\n", strerror(errno));
168 exit(1);
169 }
170
171 if (setuid(AID_SYSTEM) != 0) {
172 ALOGE("setuid: %s\n", strerror(errno));
173 exit(1);
174 }
175
Mårten Kongstad83ab0d72015-03-20 12:57:36 +0100176 // Generic idmap parameters
177 const char* argv[7];
178 int argc = 0;
179 struct stat st;
180
181 memset(argv, NULL, sizeof(argv));
182 argv[argc++] = AssetManager::IDMAP_BIN;
183 argv[argc++] = "--scan";
184 argv[argc++] = AssetManager::TARGET_PACKAGE_NAME;
185 argv[argc++] = AssetManager::TARGET_APK_PATH;
186 argv[argc++] = AssetManager::IDMAP_DIR;
187
Jakub Adamekc03d9482016-09-30 09:19:09 +0100188 // Directories to scan for overlays: if OVERLAY_SKU_DIR_PROPERTY is defined,
189 // use OVERLAY_DIR/<value of OVERLAY_SKU_DIR_PROPERTY> if exists, otherwise
Jakub Adamek1c15c632016-09-23 09:07:11 +0100190 // use OVERLAY_DIR if exists.
191 char subdir[PROP_VALUE_MAX];
Jakub Adamekc03d9482016-09-30 09:19:09 +0100192 int len = __system_property_get(AssetManager::OVERLAY_SKU_DIR_PROPERTY, subdir);
193 String8 overlayPath;
Jakub Adamek1c15c632016-09-23 09:07:11 +0100194 if (len > 0) {
Jakub Adamekc03d9482016-09-30 09:19:09 +0100195 overlayPath = String8(AssetManager::OVERLAY_DIR) + "/" + subdir;
196 } else {
197 overlayPath = String8(AssetManager::OVERLAY_DIR);
198 }
199 if (stat(overlayPath.string(), &st) == 0) {
200 argv[argc++] = overlayPath.string();
Jakub Adamek1c15c632016-09-23 09:07:11 +0100201 }
Mårten Kongstad83ab0d72015-03-20 12:57:36 +0100202
203 // Finally, invoke idmap (if any overlay directory exists)
204 if (argc > 5) {
205 execv(AssetManager::IDMAP_BIN, (char* const*)argv);
206 ALOGE("failed to execl for idmap: %s", strerror(errno));
207 exit(1); // should never get here
208 } else {
209 exit(0);
210 }
Mårten Kongstad48d22322014-01-31 14:43:27 +0100211 }
212 break;
213 default: // parent
214 waitpid(pid, NULL, 0);
215 break;
216 }
217}
218
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800219// ----------------------------------------------------------------------------
220
221// this guy is exported to other jni routines
222AssetManager* assetManagerForJavaObject(JNIEnv* env, jobject obj)
223{
Ashok Bhat896043d2014-01-17 16:02:38 +0000224 jlong amHandle = env->GetLongField(obj, gAssetManagerOffsets.mObject);
225 AssetManager* am = reinterpret_cast<AssetManager*>(amHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800226 if (am != NULL) {
227 return am;
228 }
229 jniThrowException(env, "java/lang/IllegalStateException", "AssetManager has been finalized!");
230 return NULL;
231}
232
Ashok Bhat896043d2014-01-17 16:02:38 +0000233static jlong android_content_AssetManager_openAsset(JNIEnv* env, jobject clazz,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800234 jstring fileName, jint mode)
235{
236 AssetManager* am = assetManagerForJavaObject(env, clazz);
237 if (am == NULL) {
238 return 0;
239 }
240
Steve Block71f2cf12011-10-20 11:56:00 +0100241 ALOGV("openAsset in %p (Java object %p)\n", am, clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800242
Elliott Hughes69a017b2011-04-08 14:10:28 -0700243 ScopedUtfChars fileName8(env, fileName);
244 if (fileName8.c_str() == NULL) {
Ashok Bhat896043d2014-01-17 16:02:38 +0000245 jniThrowException(env, "java/lang/IllegalArgumentException", "Empty file name");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800246 return -1;
247 }
248
249 if (mode != Asset::ACCESS_UNKNOWN && mode != Asset::ACCESS_RANDOM
250 && mode != Asset::ACCESS_STREAMING && mode != Asset::ACCESS_BUFFER) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -0700251 jniThrowException(env, "java/lang/IllegalArgumentException", "Bad access mode");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800252 return -1;
253 }
254
Elliott Hughes69a017b2011-04-08 14:10:28 -0700255 Asset* a = am->open(fileName8.c_str(), (Asset::AccessMode)mode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800256
257 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700258 jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800259 return -1;
260 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800261
262 //printf("Created Asset Stream: %p\n", a);
263
Ashok Bhat896043d2014-01-17 16:02:38 +0000264 return reinterpret_cast<jlong>(a);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800265}
266
267static jobject returnParcelFileDescriptor(JNIEnv* env, Asset* a, jlongArray outOffsets)
268{
Kenny Rootddb76c42010-11-24 12:56:06 -0800269 off64_t startOffset, length;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800270 int fd = a->openFileDescriptor(&startOffset, &length);
271 delete a;
Elliott Hughes69a017b2011-04-08 14:10:28 -0700272
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800273 if (fd < 0) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -0700274 jniThrowException(env, "java/io/FileNotFoundException",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800275 "This file can not be opened as a file descriptor; it is probably compressed");
276 return NULL;
277 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700278
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800279 jlong* offsets = (jlong*)env->GetPrimitiveArrayCritical(outOffsets, 0);
280 if (offsets == NULL) {
281 close(fd);
282 return NULL;
283 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700284
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800285 offsets[0] = startOffset;
286 offsets[1] = length;
Elliott Hughes69a017b2011-04-08 14:10:28 -0700287
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800288 env->ReleasePrimitiveArrayCritical(outOffsets, offsets, 0);
Elliott Hughes69a017b2011-04-08 14:10:28 -0700289
Elliott Hughesa3804cf2011-04-11 16:50:19 -0700290 jobject fileDesc = jniCreateFileDescriptor(env, fd);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800291 if (fileDesc == NULL) {
292 close(fd);
293 return NULL;
294 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700295
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800296 return newParcelFileDescriptor(env, fileDesc);
297}
298
299static jobject android_content_AssetManager_openAssetFd(JNIEnv* env, jobject clazz,
300 jstring fileName, jlongArray outOffsets)
301{
302 AssetManager* am = assetManagerForJavaObject(env, clazz);
303 if (am == NULL) {
304 return NULL;
305 }
306
Steve Block71f2cf12011-10-20 11:56:00 +0100307 ALOGV("openAssetFd in %p (Java object %p)\n", am, clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800308
Elliott Hughes69a017b2011-04-08 14:10:28 -0700309 ScopedUtfChars fileName8(env, fileName);
310 if (fileName8.c_str() == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800311 return NULL;
312 }
313
Elliott Hughes69a017b2011-04-08 14:10:28 -0700314 Asset* a = am->open(fileName8.c_str(), Asset::ACCESS_RANDOM);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800315
316 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700317 jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800318 return NULL;
319 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800320
321 //printf("Created Asset Stream: %p\n", a);
322
323 return returnParcelFileDescriptor(env, a, outOffsets);
324}
325
Ashok Bhat896043d2014-01-17 16:02:38 +0000326static jlong android_content_AssetManager_openNonAssetNative(JNIEnv* env, jobject clazz,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800327 jint cookie,
328 jstring fileName,
329 jint mode)
330{
331 AssetManager* am = assetManagerForJavaObject(env, clazz);
332 if (am == NULL) {
333 return 0;
334 }
335
Steve Block71f2cf12011-10-20 11:56:00 +0100336 ALOGV("openNonAssetNative in %p (Java object %p)\n", am, clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800337
Elliott Hughes69a017b2011-04-08 14:10:28 -0700338 ScopedUtfChars fileName8(env, fileName);
339 if (fileName8.c_str() == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800340 return -1;
341 }
342
343 if (mode != Asset::ACCESS_UNKNOWN && mode != Asset::ACCESS_RANDOM
344 && mode != Asset::ACCESS_STREAMING && mode != Asset::ACCESS_BUFFER) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -0700345 jniThrowException(env, "java/lang/IllegalArgumentException", "Bad access mode");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800346 return -1;
347 }
348
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800349 Asset* a = cookie
Narayan Kamath745d4ef2014-01-27 11:17:22 +0000350 ? am->openNonAsset(static_cast<int32_t>(cookie), fileName8.c_str(),
351 (Asset::AccessMode)mode)
Elliott Hughes69a017b2011-04-08 14:10:28 -0700352 : am->openNonAsset(fileName8.c_str(), (Asset::AccessMode)mode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800353
354 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700355 jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800356 return -1;
357 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800358
359 //printf("Created Asset Stream: %p\n", a);
360
Ashok Bhat896043d2014-01-17 16:02:38 +0000361 return reinterpret_cast<jlong>(a);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800362}
363
364static jobject android_content_AssetManager_openNonAssetFdNative(JNIEnv* env, jobject clazz,
365 jint cookie,
366 jstring fileName,
367 jlongArray outOffsets)
368{
369 AssetManager* am = assetManagerForJavaObject(env, clazz);
370 if (am == NULL) {
371 return NULL;
372 }
373
Steve Block71f2cf12011-10-20 11:56:00 +0100374 ALOGV("openNonAssetFd in %p (Java object %p)\n", am, clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800375
Elliott Hughes69a017b2011-04-08 14:10:28 -0700376 ScopedUtfChars fileName8(env, fileName);
377 if (fileName8.c_str() == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800378 return NULL;
379 }
380
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800381 Asset* a = cookie
Narayan Kamath745d4ef2014-01-27 11:17:22 +0000382 ? am->openNonAsset(static_cast<int32_t>(cookie), fileName8.c_str(), Asset::ACCESS_RANDOM)
Elliott Hughes69a017b2011-04-08 14:10:28 -0700383 : am->openNonAsset(fileName8.c_str(), Asset::ACCESS_RANDOM);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800384
385 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700386 jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800387 return NULL;
388 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800389
390 //printf("Created Asset Stream: %p\n", a);
391
392 return returnParcelFileDescriptor(env, a, outOffsets);
393}
394
395static jobjectArray android_content_AssetManager_list(JNIEnv* env, jobject clazz,
396 jstring fileName)
397{
398 AssetManager* am = assetManagerForJavaObject(env, clazz);
399 if (am == NULL) {
400 return NULL;
401 }
402
Elliott Hughes69a017b2011-04-08 14:10:28 -0700403 ScopedUtfChars fileName8(env, fileName);
404 if (fileName8.c_str() == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800405 return NULL;
406 }
407
Elliott Hughes69a017b2011-04-08 14:10:28 -0700408 AssetDir* dir = am->openDir(fileName8.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800409
410 if (dir == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700411 jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800412 return NULL;
413 }
414
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800415 size_t N = dir->getFileCount();
416
417 jobjectArray array = env->NewObjectArray(dir->getFileCount(),
Vladimir Markoaa5fe3d2013-06-17 12:46:22 +0100418 g_stringClass, NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800419 if (array == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800420 delete dir;
421 return NULL;
422 }
423
424 for (size_t i=0; i<N; i++) {
425 const String8& name = dir->getFileName(i);
426 jstring str = env->NewStringUTF(name.string());
427 if (str == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800428 delete dir;
429 return NULL;
430 }
431 env->SetObjectArrayElement(array, i, str);
Gilles Debunne4d4040b2010-08-26 15:59:54 -0700432 env->DeleteLocalRef(str);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800433 }
434
435 delete dir;
436
437 return array;
438}
439
440static void android_content_AssetManager_destroyAsset(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +0000441 jlong assetHandle)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800442{
Ashok Bhat896043d2014-01-17 16:02:38 +0000443 Asset* a = reinterpret_cast<Asset*>(assetHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800444
445 //printf("Destroying Asset Stream: %p\n", a);
446
447 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700448 jniThrowNullPointerException(env, "asset");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800449 return;
450 }
451
452 delete a;
453}
454
455static jint android_content_AssetManager_readAssetChar(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +0000456 jlong assetHandle)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800457{
Ashok Bhat896043d2014-01-17 16:02:38 +0000458 Asset* a = reinterpret_cast<Asset*>(assetHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800459
460 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700461 jniThrowNullPointerException(env, "asset");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800462 return -1;
463 }
464
465 uint8_t b;
466 ssize_t res = a->read(&b, 1);
467 return res == 1 ? b : -1;
468}
469
470static jint android_content_AssetManager_readAsset(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +0000471 jlong assetHandle, jbyteArray bArray,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800472 jint off, jint len)
473{
Ashok Bhat896043d2014-01-17 16:02:38 +0000474 Asset* a = reinterpret_cast<Asset*>(assetHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800475
476 if (a == NULL || bArray == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700477 jniThrowNullPointerException(env, "asset");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800478 return -1;
479 }
480
481 if (len == 0) {
482 return 0;
483 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700484
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800485 jsize bLen = env->GetArrayLength(bArray);
486 if (off < 0 || off >= bLen || len < 0 || len > bLen || (off+len) > bLen) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -0700487 jniThrowException(env, "java/lang/IndexOutOfBoundsException", "");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800488 return -1;
489 }
490
491 jbyte* b = env->GetByteArrayElements(bArray, NULL);
492 ssize_t res = a->read(b+off, len);
493 env->ReleaseByteArrayElements(bArray, b, 0);
494
Ashok Bhat896043d2014-01-17 16:02:38 +0000495 if (res > 0) return static_cast<jint>(res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800496
497 if (res < 0) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -0700498 jniThrowException(env, "java/io/IOException", "");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800499 }
500 return -1;
501}
502
503static jlong android_content_AssetManager_seekAsset(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +0000504 jlong assetHandle,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800505 jlong offset, jint whence)
506{
Ashok Bhat896043d2014-01-17 16:02:38 +0000507 Asset* a = reinterpret_cast<Asset*>(assetHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800508
509 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700510 jniThrowNullPointerException(env, "asset");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800511 return -1;
512 }
513
514 return a->seek(
515 offset, (whence > 0) ? SEEK_END : (whence < 0 ? SEEK_SET : SEEK_CUR));
516}
517
518static jlong android_content_AssetManager_getAssetLength(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +0000519 jlong assetHandle)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800520{
Ashok Bhat896043d2014-01-17 16:02:38 +0000521 Asset* a = reinterpret_cast<Asset*>(assetHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800522
523 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700524 jniThrowNullPointerException(env, "asset");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800525 return -1;
526 }
527
528 return a->getLength();
529}
530
531static jlong android_content_AssetManager_getAssetRemainingLength(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +0000532 jlong assetHandle)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800533{
Ashok Bhat896043d2014-01-17 16:02:38 +0000534 Asset* a = reinterpret_cast<Asset*>(assetHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800535
536 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700537 jniThrowNullPointerException(env, "asset");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800538 return -1;
539 }
540
541 return a->getRemainingLength();
542}
543
544static jint android_content_AssetManager_addAssetPath(JNIEnv* env, jobject clazz,
Tao Baia6d7e3f2015-09-01 18:49:54 -0700545 jstring path, jboolean appAsLib)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800546{
Elliott Hughes69a017b2011-04-08 14:10:28 -0700547 ScopedUtfChars path8(env, path);
548 if (path8.c_str() == NULL) {
Glenn Kasten129e19c2012-01-10 17:57:36 -0800549 return 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800550 }
551
552 AssetManager* am = assetManagerForJavaObject(env, clazz);
553 if (am == NULL) {
Glenn Kasten129e19c2012-01-10 17:57:36 -0800554 return 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800555 }
556
Narayan Kamath745d4ef2014-01-27 11:17:22 +0000557 int32_t cookie;
Tao Baia6d7e3f2015-09-01 18:49:54 -0700558 bool res = am->addAssetPath(String8(path8.c_str()), &cookie, appAsLib);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800559
Narayan Kamath745d4ef2014-01-27 11:17:22 +0000560 return (res) ? static_cast<jint>(cookie) : 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800561}
562
Mårten Kongstad48d22322014-01-31 14:43:27 +0100563static jint android_content_AssetManager_addOverlayPath(JNIEnv* env, jobject clazz,
564 jstring idmapPath)
565{
566 ScopedUtfChars idmapPath8(env, idmapPath);
567 if (idmapPath8.c_str() == NULL) {
568 return 0;
569 }
570
571 AssetManager* am = assetManagerForJavaObject(env, clazz);
572 if (am == NULL) {
573 return 0;
574 }
575
576 int32_t cookie;
577 bool res = am->addOverlayPath(String8(idmapPath8.c_str()), &cookie);
578
579 return (res) ? (jint)cookie : 0;
580}
581
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800582static jboolean android_content_AssetManager_isUpToDate(JNIEnv* env, jobject clazz)
583{
584 AssetManager* am = assetManagerForJavaObject(env, clazz);
585 if (am == NULL) {
586 return JNI_TRUE;
587 }
588 return am->isUpToDate() ? JNI_TRUE : JNI_FALSE;
589}
590
Roozbeh Pournader1c686f22015-12-18 14:22:14 -0800591static jobjectArray getLocales(JNIEnv* env, jobject clazz, bool includeSystemLocales)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800592{
593 Vector<String8> locales;
594
595 AssetManager* am = assetManagerForJavaObject(env, clazz);
596 if (am == NULL) {
597 return NULL;
598 }
599
Roozbeh Pournader1c686f22015-12-18 14:22:14 -0800600 am->getLocales(&locales, includeSystemLocales);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800601
602 const int N = locales.size();
603
604 jobjectArray result = env->NewObjectArray(N, g_stringClass, NULL);
605 if (result == NULL) {
606 return NULL;
607 }
608
609 for (int i=0; i<N; i++) {
Gilles Debunne0db187a2010-08-27 11:51:34 -0700610 jstring str = env->NewStringUTF(locales[i].string());
Gilles Debunne4d4040b2010-08-26 15:59:54 -0700611 if (str == NULL) {
612 return NULL;
613 }
614 env->SetObjectArrayElement(result, i, str);
615 env->DeleteLocalRef(str);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800616 }
617
618 return result;
619}
620
Roozbeh Pournader1c686f22015-12-18 14:22:14 -0800621static jobjectArray android_content_AssetManager_getLocales(JNIEnv* env, jobject clazz)
622{
623 return getLocales(env, clazz, true /* include system locales */);
624}
625
626static jobjectArray android_content_AssetManager_getNonSystemLocales(JNIEnv* env, jobject clazz)
627{
628 return getLocales(env, clazz, false /* don't include system locales */);
629}
630
Filip Gruszczynski23493322015-07-29 17:02:59 -0700631static jobject constructConfigurationObject(JNIEnv* env, const ResTable_config& config) {
632 jobject result = env->NewObject(gConfigurationOffsets.classObject,
633 gConfigurationOffsets.constructor);
634 if (result == NULL) {
635 return NULL;
636 }
637
638 env->SetIntField(result, gConfigurationOffsets.mSmallestScreenWidthDpOffset,
639 config.smallestScreenWidthDp);
640 env->SetIntField(result, gConfigurationOffsets.mScreenWidthDpOffset, config.screenWidthDp);
641 env->SetIntField(result, gConfigurationOffsets.mScreenHeightDpOffset, config.screenHeightDp);
642
643 return result;
644}
645
646static jobjectArray getSizeConfigurationsInternal(JNIEnv* env,
647 const Vector<ResTable_config>& configs) {
648 const int N = configs.size();
649 jobjectArray result = env->NewObjectArray(N, gConfigurationOffsets.classObject, NULL);
650 if (result == NULL) {
651 return NULL;
652 }
653
654 for (int i=0; i<N; i++) {
655 jobject config = constructConfigurationObject(env, configs[i]);
656 if (config == NULL) {
657 env->DeleteLocalRef(result);
658 return NULL;
659 }
660
661 env->SetObjectArrayElement(result, i, config);
662 env->DeleteLocalRef(config);
663 }
664
665 return result;
666}
667
668static jobjectArray android_content_AssetManager_getSizeConfigurations(JNIEnv* env, jobject clazz) {
669 AssetManager* am = assetManagerForJavaObject(env, clazz);
670 if (am == NULL) {
671 return NULL;
672 }
673
674 const ResTable& res(am->getResources());
675 Vector<ResTable_config> configs;
676 res.getConfigurations(&configs, false /* ignoreMipmap */, true /* ignoreAndroidPackage */);
677
678 return getSizeConfigurationsInternal(env, configs);
679}
680
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800681static void android_content_AssetManager_setConfiguration(JNIEnv* env, jobject clazz,
682 jint mcc, jint mnc,
683 jstring locale, jint orientation,
684 jint touchscreen, jint density,
685 jint keyboard, jint keyboardHidden,
686 jint navigation,
687 jint screenWidth, jint screenHeight,
Dianne Hackborn69cb8752011-05-19 18:13:32 -0700688 jint smallestScreenWidthDp,
Dianne Hackborn3fc982f2011-03-30 16:20:26 -0700689 jint screenWidthDp, jint screenHeightDp,
Tobias Haamel27b28b32010-02-09 23:09:17 +0100690 jint screenLayout, jint uiMode,
691 jint sdkVersion)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800692{
693 AssetManager* am = assetManagerForJavaObject(env, clazz);
694 if (am == NULL) {
695 return;
696 }
697
698 ResTable_config config;
699 memset(&config, 0, sizeof(config));
Elliott Hughes69a017b2011-04-08 14:10:28 -0700700
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800701 const char* locale8 = locale != NULL ? env->GetStringUTFChars(locale, NULL) : NULL;
Elliott Hughes69a017b2011-04-08 14:10:28 -0700702
Adam Lesinski2738c962015-05-14 14:25:36 -0700703 // Constants duplicated from Java class android.content.res.Configuration.
704 static const jint kScreenLayoutRoundMask = 0x300;
705 static const jint kScreenLayoutRoundShift = 8;
706
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800707 config.mcc = (uint16_t)mcc;
708 config.mnc = (uint16_t)mnc;
709 config.orientation = (uint8_t)orientation;
710 config.touchscreen = (uint8_t)touchscreen;
711 config.density = (uint16_t)density;
712 config.keyboard = (uint8_t)keyboard;
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700713 config.inputFlags = (uint8_t)keyboardHidden;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800714 config.navigation = (uint8_t)navigation;
715 config.screenWidth = (uint16_t)screenWidth;
716 config.screenHeight = (uint16_t)screenHeight;
Dianne Hackborn69cb8752011-05-19 18:13:32 -0700717 config.smallestScreenWidthDp = (uint16_t)smallestScreenWidthDp;
Dianne Hackborn3fc982f2011-03-30 16:20:26 -0700718 config.screenWidthDp = (uint16_t)screenWidthDp;
719 config.screenHeightDp = (uint16_t)screenHeightDp;
Dianne Hackborn723738c2009-06-25 19:48:04 -0700720 config.screenLayout = (uint8_t)screenLayout;
Tobias Haamel27b28b32010-02-09 23:09:17 +0100721 config.uiMode = (uint8_t)uiMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800722 config.sdkVersion = (uint16_t)sdkVersion;
723 config.minorVersion = 0;
Adam Lesinski2738c962015-05-14 14:25:36 -0700724
725 // In Java, we use a 32bit integer for screenLayout, while we only use an 8bit integer
726 // in C++. We must extract the round qualifier out of the Java screenLayout and put it
727 // into screenLayout2.
728 config.screenLayout2 =
729 (uint8_t)((screenLayout & kScreenLayoutRoundMask) >> kScreenLayoutRoundShift);
730
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800731 am->setConfiguration(config, locale8);
Elliott Hughes69a017b2011-04-08 14:10:28 -0700732
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800733 if (locale != NULL) env->ReleaseStringUTFChars(locale, locale8);
734}
735
736static jint android_content_AssetManager_getResourceIdentifier(JNIEnv* env, jobject clazz,
737 jstring name,
738 jstring defType,
739 jstring defPackage)
740{
Elliott Hughes69a017b2011-04-08 14:10:28 -0700741 ScopedStringChars name16(env, name);
742 if (name16.get() == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800743 return 0;
744 }
745
746 AssetManager* am = assetManagerForJavaObject(env, clazz);
747 if (am == NULL) {
748 return 0;
749 }
750
Dan Albert66987492014-11-20 11:41:21 -0800751 const char16_t* defType16 = reinterpret_cast<const char16_t*>(defType)
752 ? reinterpret_cast<const char16_t*>(env->GetStringChars(defType, NULL))
753 : NULL;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800754 jsize defTypeLen = defType
755 ? env->GetStringLength(defType) : 0;
Dan Albert66987492014-11-20 11:41:21 -0800756 const char16_t* defPackage16 = reinterpret_cast<const char16_t*>(defPackage)
757 ? reinterpret_cast<const char16_t*>(env->GetStringChars(defPackage,
758 NULL))
759 : NULL;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800760 jsize defPackageLen = defPackage
761 ? env->GetStringLength(defPackage) : 0;
762
763 jint ident = am->getResources().identifierForName(
Dan Albert66987492014-11-20 11:41:21 -0800764 reinterpret_cast<const char16_t*>(name16.get()), name16.size(),
765 defType16, defTypeLen, defPackage16, defPackageLen);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800766
767 if (defPackage16) {
Dan Albert66987492014-11-20 11:41:21 -0800768 env->ReleaseStringChars(defPackage,
769 reinterpret_cast<const jchar*>(defPackage16));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800770 }
771 if (defType16) {
Dan Albert66987492014-11-20 11:41:21 -0800772 env->ReleaseStringChars(defType,
773 reinterpret_cast<const jchar*>(defType16));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800774 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800775
776 return ident;
777}
778
779static jstring android_content_AssetManager_getResourceName(JNIEnv* env, jobject clazz,
780 jint resid)
781{
782 AssetManager* am = assetManagerForJavaObject(env, clazz);
783 if (am == NULL) {
784 return NULL;
785 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700786
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800787 ResTable::resource_name name;
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700788 if (!am->getResources().getResourceName(resid, true, &name)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800789 return NULL;
790 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700791
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800792 String16 str;
793 if (name.package != NULL) {
794 str.setTo(name.package, name.packageLen);
795 }
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700796 if (name.type8 != NULL || name.type != NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800797 if (str.size() > 0) {
798 char16_t div = ':';
799 str.append(&div, 1);
800 }
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700801 if (name.type8 != NULL) {
802 str.append(String16(name.type8, name.typeLen));
803 } else {
804 str.append(name.type, name.typeLen);
805 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800806 }
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700807 if (name.name8 != NULL || name.name != NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800808 if (str.size() > 0) {
809 char16_t div = '/';
810 str.append(&div, 1);
811 }
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700812 if (name.name8 != NULL) {
813 str.append(String16(name.name8, name.nameLen));
814 } else {
815 str.append(name.name, name.nameLen);
816 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800817 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700818
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800819 return env->NewString((const jchar*)str.string(), str.size());
820}
821
822static jstring android_content_AssetManager_getResourcePackageName(JNIEnv* env, jobject clazz,
823 jint resid)
824{
825 AssetManager* am = assetManagerForJavaObject(env, clazz);
826 if (am == NULL) {
827 return NULL;
828 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700829
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800830 ResTable::resource_name name;
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700831 if (!am->getResources().getResourceName(resid, true, &name)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800832 return NULL;
833 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700834
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800835 if (name.package != NULL) {
836 return env->NewString((const jchar*)name.package, name.packageLen);
837 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700838
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800839 return NULL;
840}
841
842static jstring android_content_AssetManager_getResourceTypeName(JNIEnv* env, jobject clazz,
843 jint resid)
844{
845 AssetManager* am = assetManagerForJavaObject(env, clazz);
846 if (am == NULL) {
847 return NULL;
848 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700849
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800850 ResTable::resource_name name;
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700851 if (!am->getResources().getResourceName(resid, true, &name)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800852 return NULL;
853 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700854
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700855 if (name.type8 != NULL) {
856 return env->NewStringUTF(name.type8);
857 }
858
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800859 if (name.type != NULL) {
860 return env->NewString((const jchar*)name.type, name.typeLen);
861 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700862
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800863 return NULL;
864}
865
866static jstring android_content_AssetManager_getResourceEntryName(JNIEnv* env, jobject clazz,
867 jint resid)
868{
869 AssetManager* am = assetManagerForJavaObject(env, clazz);
870 if (am == NULL) {
871 return NULL;
872 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700873
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800874 ResTable::resource_name name;
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700875 if (!am->getResources().getResourceName(resid, true, &name)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800876 return NULL;
877 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700878
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700879 if (name.name8 != NULL) {
880 return env->NewStringUTF(name.name8);
881 }
882
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800883 if (name.name != NULL) {
884 return env->NewString((const jchar*)name.name, name.nameLen);
885 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700886
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800887 return NULL;
888}
889
890static jint android_content_AssetManager_loadResourceValue(JNIEnv* env, jobject clazz,
891 jint ident,
Kenny Root55fc8502010-10-28 14:47:01 -0700892 jshort density,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800893 jobject outValue,
894 jboolean resolve)
895{
Dianne Hackborn1f7d3072013-02-11 17:03:32 -0800896 if (outValue == NULL) {
Dianne Hackborne5b50a62013-02-11 16:18:42 -0800897 jniThrowNullPointerException(env, "outValue");
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700898 return 0;
Dianne Hackborne5b50a62013-02-11 16:18:42 -0800899 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800900 AssetManager* am = assetManagerForJavaObject(env, clazz);
901 if (am == NULL) {
902 return 0;
903 }
904 const ResTable& res(am->getResources());
905
906 Res_value value;
907 ResTable_config config;
908 uint32_t typeSpecFlags;
Kenny Root55fc8502010-10-28 14:47:01 -0700909 ssize_t block = res.getResource(ident, &value, false, density, &typeSpecFlags, &config);
Andreas Gampe0f0b4912014-11-12 08:03:48 -0800910 if (kThrowOnBadId) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -0800911 if (block == BAD_INDEX) {
912 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
913 return 0;
914 }
Andreas Gampe0f0b4912014-11-12 08:03:48 -0800915 }
916 uint32_t ref = ident;
917 if (resolve) {
918 block = res.resolveReference(&value, block, &ref, &typeSpecFlags, &config);
919 if (kThrowOnBadId) {
920 if (block == BAD_INDEX) {
921 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
922 return 0;
923 }
924 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800925 }
Ashok Bhat896043d2014-01-17 16:02:38 +0000926 if (block >= 0) {
927 return copyValue(env, outValue, &res, value, ref, block, typeSpecFlags, &config);
928 }
929
930 return static_cast<jint>(block);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800931}
932
933static jint android_content_AssetManager_loadResourceBagValue(JNIEnv* env, jobject clazz,
934 jint ident, jint bagEntryId,
935 jobject outValue, jboolean resolve)
936{
937 AssetManager* am = assetManagerForJavaObject(env, clazz);
938 if (am == NULL) {
939 return 0;
940 }
941 const ResTable& res(am->getResources());
Elliott Hughes69a017b2011-04-08 14:10:28 -0700942
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800943 // Now lock down the resource object and start pulling stuff from it.
944 res.lock();
Elliott Hughes69a017b2011-04-08 14:10:28 -0700945
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800946 ssize_t block = -1;
947 Res_value value;
948
949 const ResTable::bag_entry* entry = NULL;
950 uint32_t typeSpecFlags;
951 ssize_t entryCount = res.getBagLocked(ident, &entry, &typeSpecFlags);
952
953 for (ssize_t i=0; i<entryCount; i++) {
954 if (((uint32_t)bagEntryId) == entry->map.name.ident) {
955 block = entry->stringBlock;
956 value = entry->map.value;
957 }
958 entry++;
959 }
960
961 res.unlock();
962
963 if (block < 0) {
Ashok Bhat896043d2014-01-17 16:02:38 +0000964 return static_cast<jint>(block);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800965 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700966
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800967 uint32_t ref = ident;
968 if (resolve) {
969 block = res.resolveReference(&value, block, &ref, &typeSpecFlags);
Andreas Gampe0f0b4912014-11-12 08:03:48 -0800970 if (kThrowOnBadId) {
971 if (block == BAD_INDEX) {
972 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
973 return 0;
974 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -0800975 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800976 }
Ashok Bhat896043d2014-01-17 16:02:38 +0000977 if (block >= 0) {
978 return copyValue(env, outValue, &res, value, ref, block, typeSpecFlags);
979 }
980
981 return static_cast<jint>(block);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800982}
983
984static jint android_content_AssetManager_getStringBlockCount(JNIEnv* env, jobject clazz)
985{
986 AssetManager* am = assetManagerForJavaObject(env, clazz);
987 if (am == NULL) {
988 return 0;
989 }
990 return am->getResources().getTableCount();
991}
992
Ashok Bhat896043d2014-01-17 16:02:38 +0000993static jlong android_content_AssetManager_getNativeStringBlock(JNIEnv* env, jobject clazz,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800994 jint block)
995{
996 AssetManager* am = assetManagerForJavaObject(env, clazz);
997 if (am == NULL) {
998 return 0;
999 }
Ashok Bhat896043d2014-01-17 16:02:38 +00001000 return reinterpret_cast<jlong>(am->getResources().getTableStringBlock(block));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001001}
1002
1003static jstring android_content_AssetManager_getCookieName(JNIEnv* env, jobject clazz,
1004 jint cookie)
1005{
1006 AssetManager* am = assetManagerForJavaObject(env, clazz);
1007 if (am == NULL) {
1008 return NULL;
1009 }
Narayan Kamath745d4ef2014-01-27 11:17:22 +00001010 String8 name(am->getAssetPath(static_cast<int32_t>(cookie)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001011 if (name.length() == 0) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001012 jniThrowException(env, "java/lang/IndexOutOfBoundsException", "Empty cookie name");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001013 return NULL;
1014 }
1015 jstring str = env->NewStringUTF(name.string());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001016 return str;
1017}
1018
Adam Lesinskide898ff2014-01-29 18:20:45 -08001019static jobject android_content_AssetManager_getAssignedPackageIdentifiers(JNIEnv* env, jobject clazz)
1020{
1021 AssetManager* am = assetManagerForJavaObject(env, clazz);
1022 if (am == NULL) {
1023 return 0;
1024 }
1025
1026 const ResTable& res = am->getResources();
1027
1028 jobject sparseArray = env->NewObject(gSparseArrayOffsets.classObject,
1029 gSparseArrayOffsets.constructor);
1030 const size_t N = res.getBasePackageCount();
1031 for (size_t i = 0; i < N; i++) {
1032 const String16 name = res.getBasePackageName(i);
Dan Albert66987492014-11-20 11:41:21 -08001033 env->CallVoidMethod(
1034 sparseArray, gSparseArrayOffsets.put,
1035 static_cast<jint>(res.getBasePackageId(i)),
1036 env->NewString(reinterpret_cast<const jchar*>(name.string()),
1037 name.size()));
Adam Lesinskide898ff2014-01-29 18:20:45 -08001038 }
1039 return sparseArray;
1040}
1041
Ashok Bhat896043d2014-01-17 16:02:38 +00001042static jlong android_content_AssetManager_newTheme(JNIEnv* env, jobject clazz)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001043{
1044 AssetManager* am = assetManagerForJavaObject(env, clazz);
1045 if (am == NULL) {
1046 return 0;
1047 }
Ashok Bhat896043d2014-01-17 16:02:38 +00001048 return reinterpret_cast<jlong>(new ResTable::Theme(am->getResources()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001049}
1050
1051static void android_content_AssetManager_deleteTheme(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{
Ashok Bhat896043d2014-01-17 16:02:38 +00001054 ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001055 delete theme;
1056}
1057
1058static void android_content_AssetManager_applyThemeStyle(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +00001059 jlong themeHandle,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001060 jint styleRes,
1061 jboolean force)
1062{
Ashok Bhat896043d2014-01-17 16:02:38 +00001063 ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001064 theme->applyStyle(styleRes, force ? true : false);
1065}
1066
1067static void android_content_AssetManager_copyTheme(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +00001068 jlong destHandle, jlong srcHandle)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001069{
Ashok Bhat896043d2014-01-17 16:02:38 +00001070 ResTable::Theme* dest = reinterpret_cast<ResTable::Theme*>(destHandle);
1071 ResTable::Theme* src = reinterpret_cast<ResTable::Theme*>(srcHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001072 dest->setTo(*src);
1073}
1074
Alan Viverettee54d2452015-05-06 10:41:43 -07001075static void android_content_AssetManager_clearTheme(JNIEnv* env, jobject clazz, jlong themeHandle)
1076{
1077 ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeHandle);
1078 theme->clear();
1079}
1080
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001081static jint android_content_AssetManager_loadThemeAttributeValue(
Ashok Bhat896043d2014-01-17 16:02:38 +00001082 JNIEnv* env, jobject clazz, jlong themeHandle, jint ident, jobject outValue, jboolean resolve)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001083{
Ashok Bhat896043d2014-01-17 16:02:38 +00001084 ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001085 const ResTable& res(theme->getResTable());
1086
1087 Res_value value;
1088 // XXX value could be different in different configs!
1089 uint32_t typeSpecFlags = 0;
1090 ssize_t block = theme->getAttribute(ident, &value, &typeSpecFlags);
1091 uint32_t ref = 0;
1092 if (resolve) {
1093 block = res.resolveReference(&value, block, &ref, &typeSpecFlags);
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001094 if (kThrowOnBadId) {
1095 if (block == BAD_INDEX) {
1096 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
1097 return 0;
1098 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001099 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001100 }
1101 return block >= 0 ? copyValue(env, outValue, &res, value, ref, block, typeSpecFlags) : block;
1102}
1103
Alan Viverettec1d52792015-05-05 09:49:03 -07001104static jint android_content_AssetManager_getThemeChangingConfigurations(JNIEnv* env, jobject clazz,
1105 jlong themeHandle)
1106{
1107 ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeHandle);
1108 return theme->getChangingConfigurations();
1109}
1110
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001111static void android_content_AssetManager_dumpTheme(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +00001112 jlong themeHandle, jint pri,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001113 jstring tag, jstring prefix)
1114{
Ashok Bhat896043d2014-01-17 16:02:38 +00001115 ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001116 const ResTable& res(theme->getResTable());
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001117 (void)res;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001118
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001119 // XXX Need to use params.
1120 theme->dumpToLog();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001121}
1122
Alan Viverette52b999f2014-03-24 18:00:26 -07001123static jboolean android_content_AssetManager_resolveAttrs(JNIEnv* env, jobject clazz,
1124 jlong themeToken,
1125 jint defStyleAttr,
1126 jint defStyleRes,
1127 jintArray inValues,
1128 jintArray attrs,
1129 jintArray outValues,
1130 jintArray outIndices)
1131{
1132 if (themeToken == 0) {
1133 jniThrowNullPointerException(env, "theme token");
1134 return JNI_FALSE;
1135 }
1136 if (attrs == NULL) {
1137 jniThrowNullPointerException(env, "attrs");
1138 return JNI_FALSE;
1139 }
1140 if (outValues == NULL) {
1141 jniThrowNullPointerException(env, "out values");
1142 return JNI_FALSE;
1143 }
1144
Alan Viverette52b999f2014-03-24 18:00:26 -07001145 const jsize NI = env->GetArrayLength(attrs);
1146 const jsize NV = env->GetArrayLength(outValues);
1147 if (NV < (NI*STYLE_NUM_ENTRIES)) {
1148 jniThrowException(env, "java/lang/IndexOutOfBoundsException", "out values too small");
1149 return JNI_FALSE;
1150 }
1151
1152 jint* src = (jint*)env->GetPrimitiveArrayCritical(attrs, 0);
1153 if (src == NULL) {
1154 return JNI_FALSE;
1155 }
1156
1157 jint* srcValues = (jint*)env->GetPrimitiveArrayCritical(inValues, 0);
1158 const jsize NSV = srcValues == NULL ? 0 : env->GetArrayLength(inValues);
1159
1160 jint* baseDest = (jint*)env->GetPrimitiveArrayCritical(outValues, 0);
Adam Lesinski4452e132016-10-12 07:47:28 -07001161 if (baseDest == NULL) {
Alan Viverette52b999f2014-03-24 18:00:26 -07001162 env->ReleasePrimitiveArrayCritical(attrs, src, 0);
1163 return JNI_FALSE;
1164 }
1165
1166 jint* indices = NULL;
Alan Viverette52b999f2014-03-24 18:00:26 -07001167 if (outIndices != NULL) {
1168 if (env->GetArrayLength(outIndices) > NI) {
1169 indices = (jint*)env->GetPrimitiveArrayCritical(outIndices, 0);
1170 }
1171 }
1172
Adam Lesinski4452e132016-10-12 07:47:28 -07001173 ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeToken);
1174 bool result = resolveAttrs(theme, defStyleAttr, defStyleRes,
1175 (uint32_t*) srcValues, NSV,
1176 (uint32_t*) src, NI,
1177 (uint32_t*) baseDest,
1178 (uint32_t*) indices);
Alan Viverette52b999f2014-03-24 18:00:26 -07001179
1180 if (indices != NULL) {
Alan Viverette52b999f2014-03-24 18:00:26 -07001181 env->ReleasePrimitiveArrayCritical(outIndices, indices, 0);
1182 }
1183 env->ReleasePrimitiveArrayCritical(outValues, baseDest, 0);
1184 env->ReleasePrimitiveArrayCritical(inValues, srcValues, 0);
1185 env->ReleasePrimitiveArrayCritical(attrs, src, 0);
Adam Lesinski4452e132016-10-12 07:47:28 -07001186 return result ? JNI_TRUE : JNI_FALSE;
Alan Viverette52b999f2014-03-24 18:00:26 -07001187}
1188
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001189static jboolean android_content_AssetManager_applyStyle(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +00001190 jlong themeToken,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001191 jint defStyleAttr,
1192 jint defStyleRes,
Ashok Bhat896043d2014-01-17 16:02:38 +00001193 jlong xmlParserToken,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001194 jintArray attrs,
1195 jintArray outValues,
1196 jintArray outIndices)
1197{
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001198 if (themeToken == 0) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001199 jniThrowNullPointerException(env, "theme token");
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001200 return JNI_FALSE;
1201 }
1202 if (attrs == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001203 jniThrowNullPointerException(env, "attrs");
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001204 return JNI_FALSE;
1205 }
1206 if (outValues == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001207 jniThrowNullPointerException(env, "out values");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001208 return JNI_FALSE;
1209 }
1210
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001211 const jsize NI = env->GetArrayLength(attrs);
1212 const jsize NV = env->GetArrayLength(outValues);
1213 if (NV < (NI*STYLE_NUM_ENTRIES)) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001214 jniThrowException(env, "java/lang/IndexOutOfBoundsException", "out values too small");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001215 return JNI_FALSE;
1216 }
1217
1218 jint* src = (jint*)env->GetPrimitiveArrayCritical(attrs, 0);
1219 if (src == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001220 return JNI_FALSE;
1221 }
1222
1223 jint* baseDest = (jint*)env->GetPrimitiveArrayCritical(outValues, 0);
Adam Lesinski4452e132016-10-12 07:47:28 -07001224 if (baseDest == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001225 env->ReleasePrimitiveArrayCritical(attrs, src, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001226 return JNI_FALSE;
1227 }
1228
1229 jint* indices = NULL;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001230 if (outIndices != NULL) {
1231 if (env->GetArrayLength(outIndices) > NI) {
1232 indices = (jint*)env->GetPrimitiveArrayCritical(outIndices, 0);
1233 }
1234 }
1235
Adam Lesinski4452e132016-10-12 07:47:28 -07001236 ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeToken);
1237 ResXMLParser* xmlParser = reinterpret_cast<ResXMLParser*>(xmlParserToken);
1238 bool result = applyStyle(theme, xmlParser,
1239 defStyleAttr, defStyleRes,
1240 (uint32_t*) src, NI,
1241 (uint32_t*) baseDest,
1242 (uint32_t*) indices);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001243
1244 if (indices != NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001245 env->ReleasePrimitiveArrayCritical(outIndices, indices, 0);
1246 }
1247 env->ReleasePrimitiveArrayCritical(outValues, baseDest, 0);
1248 env->ReleasePrimitiveArrayCritical(attrs, src, 0);
Adam Lesinski4452e132016-10-12 07:47:28 -07001249 return result ? JNI_TRUE : JNI_FALSE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001250}
1251
1252static jboolean android_content_AssetManager_retrieveAttributes(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +00001253 jlong xmlParserToken,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001254 jintArray attrs,
1255 jintArray outValues,
1256 jintArray outIndices)
1257{
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001258 if (xmlParserToken == 0) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001259 jniThrowNullPointerException(env, "xmlParserToken");
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001260 return JNI_FALSE;
1261 }
1262 if (attrs == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001263 jniThrowNullPointerException(env, "attrs");
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001264 return JNI_FALSE;
1265 }
1266 if (outValues == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001267 jniThrowNullPointerException(env, "out values");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001268 return JNI_FALSE;
1269 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001270
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001271 AssetManager* am = assetManagerForJavaObject(env, clazz);
1272 if (am == NULL) {
1273 return JNI_FALSE;
1274 }
1275 const ResTable& res(am->getResources());
1276 ResXMLParser* xmlParser = (ResXMLParser*)xmlParserToken;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001277
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001278 const jsize NI = env->GetArrayLength(attrs);
1279 const jsize NV = env->GetArrayLength(outValues);
1280 if (NV < (NI*STYLE_NUM_ENTRIES)) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001281 jniThrowException(env, "java/lang/IndexOutOfBoundsException", "out values too small");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001282 return JNI_FALSE;
1283 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001284
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001285 jint* src = (jint*)env->GetPrimitiveArrayCritical(attrs, 0);
1286 if (src == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001287 return JNI_FALSE;
1288 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001289
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001290 jint* baseDest = (jint*)env->GetPrimitiveArrayCritical(outValues, 0);
Adam Lesinski4452e132016-10-12 07:47:28 -07001291 if (baseDest == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001292 env->ReleasePrimitiveArrayCritical(attrs, src, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001293 return JNI_FALSE;
1294 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001295
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001296 jint* indices = NULL;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001297 if (outIndices != NULL) {
1298 if (env->GetArrayLength(outIndices) > NI) {
1299 indices = (jint*)env->GetPrimitiveArrayCritical(outIndices, 0);
1300 }
1301 }
1302
Adam Lesinski4452e132016-10-12 07:47:28 -07001303 bool result = retrieveAttributes(&res, xmlParser,
1304 (uint32_t*) src, NI,
1305 (uint32_t*) baseDest,
1306 (uint32_t*) indices);
Elliott Hughes69a017b2011-04-08 14:10:28 -07001307
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001308 if (indices != NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001309 env->ReleasePrimitiveArrayCritical(outIndices, indices, 0);
1310 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001311 env->ReleasePrimitiveArrayCritical(outValues, baseDest, 0);
1312 env->ReleasePrimitiveArrayCritical(attrs, src, 0);
Adam Lesinski4452e132016-10-12 07:47:28 -07001313 return result ? JNI_TRUE : JNI_FALSE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001314}
1315
1316static jint android_content_AssetManager_getArraySize(JNIEnv* env, jobject clazz,
1317 jint id)
1318{
1319 AssetManager* am = assetManagerForJavaObject(env, clazz);
1320 if (am == NULL) {
Olivier Baillyd7c86722010-11-18 14:43:36 -08001321 return 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001322 }
1323 const ResTable& res(am->getResources());
Elliott Hughes69a017b2011-04-08 14:10:28 -07001324
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001325 res.lock();
1326 const ResTable::bag_entry* defStyleEnt = NULL;
1327 ssize_t bagOff = res.getBagLocked(id, &defStyleEnt);
1328 res.unlock();
Elliott Hughes69a017b2011-04-08 14:10:28 -07001329
Ashok Bhat896043d2014-01-17 16:02:38 +00001330 return static_cast<jint>(bagOff);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001331}
1332
1333static jint android_content_AssetManager_retrieveArray(JNIEnv* env, jobject clazz,
1334 jint id,
1335 jintArray outValues)
1336{
1337 if (outValues == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001338 jniThrowNullPointerException(env, "out values");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001339 return JNI_FALSE;
1340 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001341
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001342 AssetManager* am = assetManagerForJavaObject(env, clazz);
1343 if (am == NULL) {
1344 return JNI_FALSE;
1345 }
1346 const ResTable& res(am->getResources());
Dianne Hackborn0d221012009-07-29 15:41:19 -07001347 ResTable_config config;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001348 Res_value value;
1349 ssize_t block;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001350
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001351 const jsize NV = env->GetArrayLength(outValues);
Elliott Hughes69a017b2011-04-08 14:10:28 -07001352
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001353 jint* baseDest = (jint*)env->GetPrimitiveArrayCritical(outValues, 0);
1354 jint* dest = baseDest;
1355 if (dest == NULL) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001356 jniThrowException(env, "java/lang/OutOfMemoryError", "");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001357 return JNI_FALSE;
1358 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001359
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001360 // Now lock down the resource object and start pulling stuff from it.
1361 res.lock();
Elliott Hughes69a017b2011-04-08 14:10:28 -07001362
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001363 const ResTable::bag_entry* arrayEnt = NULL;
1364 uint32_t arrayTypeSetFlags = 0;
1365 ssize_t bagOff = res.getBagLocked(id, &arrayEnt, &arrayTypeSetFlags);
1366 const ResTable::bag_entry* endArrayEnt = arrayEnt +
1367 (bagOff >= 0 ? bagOff : 0);
Elliott Hughes69a017b2011-04-08 14:10:28 -07001368
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001369 int i = 0;
1370 uint32_t typeSetFlags;
1371 while (i < NV && arrayEnt < endArrayEnt) {
1372 block = arrayEnt->stringBlock;
1373 typeSetFlags = arrayTypeSetFlags;
Dianne Hackborn0d221012009-07-29 15:41:19 -07001374 config.density = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001375 value = arrayEnt->map.value;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001376
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001377 uint32_t resid = 0;
1378 if (value.dataType != Res_value::TYPE_NULL) {
1379 // Take care of resolving the found resource to its final value.
1380 //printf("Resolving attribute reference\n");
Dianne Hackborn0d221012009-07-29 15:41:19 -07001381 ssize_t newBlock = res.resolveReference(&value, block, &resid,
1382 &typeSetFlags, &config);
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001383 if (kThrowOnBadId) {
1384 if (newBlock == BAD_INDEX) {
1385 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
1386 return JNI_FALSE;
1387 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001388 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001389 if (newBlock >= 0) block = newBlock;
1390 }
1391
1392 // Deal with the special @null value -- it turns back to TYPE_NULL.
1393 if (value.dataType == Res_value::TYPE_REFERENCE && value.data == 0) {
1394 value.dataType = Res_value::TYPE_NULL;
Alan Viverettef2969402014-10-29 17:09:36 -07001395 value.data = Res_value::DATA_NULL_UNDEFINED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001396 }
1397
1398 //printf("Attribute 0x%08x: final type=0x%x, data=0x%08x\n", curIdent, value.dataType, value.data);
1399
1400 // Write the final value back to Java.
1401 dest[STYLE_TYPE] = value.dataType;
1402 dest[STYLE_DATA] = value.data;
Ashok Bhat896043d2014-01-17 16:02:38 +00001403 dest[STYLE_ASSET_COOKIE] = reinterpret_cast<jint>(res.getTableCookie(block));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001404 dest[STYLE_RESOURCE_ID] = resid;
1405 dest[STYLE_CHANGING_CONFIGURATIONS] = typeSetFlags;
Dianne Hackborn0d221012009-07-29 15:41:19 -07001406 dest[STYLE_DENSITY] = config.density;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001407 dest += STYLE_NUM_ENTRIES;
1408 i+= STYLE_NUM_ENTRIES;
1409 arrayEnt++;
1410 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001411
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001412 i /= STYLE_NUM_ENTRIES;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001413
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001414 res.unlock();
Elliott Hughes69a017b2011-04-08 14:10:28 -07001415
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001416 env->ReleasePrimitiveArrayCritical(outValues, baseDest, 0);
Elliott Hughes69a017b2011-04-08 14:10:28 -07001417
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001418 return i;
1419}
1420
Ashok Bhat896043d2014-01-17 16:02:38 +00001421static jlong android_content_AssetManager_openXmlAssetNative(JNIEnv* env, jobject clazz,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001422 jint cookie,
1423 jstring fileName)
1424{
1425 AssetManager* am = assetManagerForJavaObject(env, clazz);
1426 if (am == NULL) {
1427 return 0;
1428 }
1429
Steve Block71f2cf12011-10-20 11:56:00 +01001430 ALOGV("openXmlAsset in %p (Java object %p)\n", am, clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001431
Elliott Hughes69a017b2011-04-08 14:10:28 -07001432 ScopedUtfChars fileName8(env, fileName);
1433 if (fileName8.c_str() == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001434 return 0;
1435 }
1436
Adam Lesinskide898ff2014-01-29 18:20:45 -08001437 int32_t assetCookie = static_cast<int32_t>(cookie);
1438 Asset* a = assetCookie
1439 ? am->openNonAsset(assetCookie, fileName8.c_str(), Asset::ACCESS_BUFFER)
1440 : am->openNonAsset(fileName8.c_str(), Asset::ACCESS_BUFFER, &assetCookie);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001441
1442 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001443 jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001444 return 0;
1445 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001446
Adam Lesinskide898ff2014-01-29 18:20:45 -08001447 const DynamicRefTable* dynamicRefTable =
1448 am->getResources().getDynamicRefTableForCookie(assetCookie);
1449 ResXMLTree* block = new ResXMLTree(dynamicRefTable);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001450 status_t err = block->setTo(a->getBuffer(true), a->getLength(), true);
1451 a->close();
1452 delete a;
1453
1454 if (err != NO_ERROR) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001455 jniThrowException(env, "java/io/FileNotFoundException", "Corrupt XML binary file");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001456 return 0;
1457 }
1458
Ashok Bhat896043d2014-01-17 16:02:38 +00001459 return reinterpret_cast<jlong>(block);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001460}
1461
1462static jintArray android_content_AssetManager_getArrayStringInfo(JNIEnv* env, jobject clazz,
1463 jint arrayResId)
1464{
1465 AssetManager* am = assetManagerForJavaObject(env, clazz);
1466 if (am == NULL) {
1467 return NULL;
1468 }
1469 const ResTable& res(am->getResources());
1470
1471 const ResTable::bag_entry* startOfBag;
1472 const ssize_t N = res.lockBag(arrayResId, &startOfBag);
1473 if (N < 0) {
1474 return NULL;
1475 }
1476
1477 jintArray array = env->NewIntArray(N * 2);
1478 if (array == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001479 res.unlockBag(startOfBag);
1480 return NULL;
1481 }
1482
1483 Res_value value;
1484 const ResTable::bag_entry* bag = startOfBag;
1485 for (size_t i = 0, j = 0; ((ssize_t)i)<N; i++, bag++) {
1486 jint stringIndex = -1;
1487 jint stringBlock = 0;
1488 value = bag->map.value;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001489
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001490 // Take care of resolving the found resource to its final value.
1491 stringBlock = res.resolveReference(&value, bag->stringBlock, NULL);
1492 if (value.dataType == Res_value::TYPE_STRING) {
1493 stringIndex = value.data;
1494 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001495
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001496 if (kThrowOnBadId) {
1497 if (stringBlock == BAD_INDEX) {
1498 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
1499 return array;
1500 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001501 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001502
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001503 //todo: It might be faster to allocate a C array to contain
1504 // the blocknums and indices, put them in there and then
1505 // do just one SetIntArrayRegion()
1506 env->SetIntArrayRegion(array, j, 1, &stringBlock);
1507 env->SetIntArrayRegion(array, j + 1, 1, &stringIndex);
1508 j = j + 2;
1509 }
1510 res.unlockBag(startOfBag);
1511 return array;
1512}
1513
1514static jobjectArray android_content_AssetManager_getArrayStringResource(JNIEnv* env, jobject clazz,
1515 jint arrayResId)
1516{
1517 AssetManager* am = assetManagerForJavaObject(env, clazz);
1518 if (am == NULL) {
1519 return NULL;
1520 }
1521 const ResTable& res(am->getResources());
1522
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001523 const ResTable::bag_entry* startOfBag;
1524 const ssize_t N = res.lockBag(arrayResId, &startOfBag);
1525 if (N < 0) {
1526 return NULL;
1527 }
1528
Vladimir Markoaa5fe3d2013-06-17 12:46:22 +01001529 jobjectArray array = env->NewObjectArray(N, g_stringClass, NULL);
Kenny Root485dd212010-05-06 16:06:48 -07001530 if (env->ExceptionCheck()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001531 res.unlockBag(startOfBag);
1532 return NULL;
1533 }
1534
1535 Res_value value;
1536 const ResTable::bag_entry* bag = startOfBag;
1537 size_t strLen = 0;
1538 for (size_t i=0; ((ssize_t)i)<N; i++, bag++) {
1539 value = bag->map.value;
1540 jstring str = NULL;
Kenny Root780d2a12010-02-22 22:36:26 -08001541
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001542 // Take care of resolving the found resource to its final value.
1543 ssize_t block = res.resolveReference(&value, bag->stringBlock, NULL);
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001544 if (kThrowOnBadId) {
1545 if (block == BAD_INDEX) {
1546 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
1547 return array;
1548 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001549 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001550 if (value.dataType == Res_value::TYPE_STRING) {
Kenny Root780d2a12010-02-22 22:36:26 -08001551 const ResStringPool* pool = res.getTableStringBlock(block);
1552 const char* str8 = pool->string8At(value.data, &strLen);
1553 if (str8 != NULL) {
1554 str = env->NewStringUTF(str8);
1555 } else {
1556 const char16_t* str16 = pool->stringAt(value.data, &strLen);
Dan Albert66987492014-11-20 11:41:21 -08001557 str = env->NewString(reinterpret_cast<const jchar*>(str16),
1558 strLen);
Kenny Root485dd212010-05-06 16:06:48 -07001559 }
1560
1561 // If one of our NewString{UTF} calls failed due to memory, an
1562 // exception will be pending.
1563 if (env->ExceptionCheck()) {
1564 res.unlockBag(startOfBag);
1565 return NULL;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001566 }
Kenny Root780d2a12010-02-22 22:36:26 -08001567
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001568 env->SetObjectArrayElement(array, i, str);
Kenny Root485dd212010-05-06 16:06:48 -07001569
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001570 // str is not NULL at that point, otherwise ExceptionCheck would have been true.
1571 // If we have a large amount of strings in our array, we might
1572 // overflow the local reference table of the VM.
Kenny Root485dd212010-05-06 16:06:48 -07001573 env->DeleteLocalRef(str);
1574 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001575 }
1576 res.unlockBag(startOfBag);
1577 return array;
1578}
1579
1580static jintArray android_content_AssetManager_getArrayIntResource(JNIEnv* env, jobject clazz,
1581 jint arrayResId)
1582{
1583 AssetManager* am = assetManagerForJavaObject(env, clazz);
1584 if (am == NULL) {
1585 return NULL;
1586 }
1587 const ResTable& res(am->getResources());
1588
1589 const ResTable::bag_entry* startOfBag;
1590 const ssize_t N = res.lockBag(arrayResId, &startOfBag);
1591 if (N < 0) {
1592 return NULL;
1593 }
1594
1595 jintArray array = env->NewIntArray(N);
1596 if (array == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001597 res.unlockBag(startOfBag);
1598 return NULL;
1599 }
1600
1601 Res_value value;
1602 const ResTable::bag_entry* bag = startOfBag;
1603 for (size_t i=0; ((ssize_t)i)<N; i++, bag++) {
1604 value = bag->map.value;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001605
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001606 // Take care of resolving the found resource to its final value.
1607 ssize_t block = res.resolveReference(&value, bag->stringBlock, NULL);
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001608 if (kThrowOnBadId) {
1609 if (block == BAD_INDEX) {
1610 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
1611 return array;
1612 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001613 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001614 if (value.dataType >= Res_value::TYPE_FIRST_INT
1615 && value.dataType <= Res_value::TYPE_LAST_INT) {
1616 int intVal = value.data;
1617 env->SetIntArrayRegion(array, i, 1, &intVal);
1618 }
1619 }
1620 res.unlockBag(startOfBag);
1621 return array;
1622}
1623
Jon Miranda042ad632014-09-03 17:57:35 -07001624static jintArray android_content_AssetManager_getStyleAttributes(JNIEnv* env, jobject clazz,
1625 jint styleId)
1626{
1627 AssetManager* am = assetManagerForJavaObject(env, clazz);
1628 if (am == NULL) {
1629 return NULL;
1630 }
1631 const ResTable& res(am->getResources());
1632
1633 const ResTable::bag_entry* startOfBag;
1634 const ssize_t N = res.lockBag(styleId, &startOfBag);
1635 if (N < 0) {
1636 return NULL;
1637 }
1638
1639 jintArray array = env->NewIntArray(N);
1640 if (array == NULL) {
1641 res.unlockBag(startOfBag);
1642 return NULL;
1643 }
1644
Jon Miranda042ad632014-09-03 17:57:35 -07001645 const ResTable::bag_entry* bag = startOfBag;
1646 for (size_t i=0; ((ssize_t)i)<N; i++, bag++) {
1647 int resourceId = bag->map.name.ident;
1648 env->SetIntArrayRegion(array, i, 1, &resourceId);
1649 }
1650 res.unlockBag(startOfBag);
1651 return array;
1652}
1653
Mårten Kongstad48d22322014-01-31 14:43:27 +01001654static void android_content_AssetManager_init(JNIEnv* env, jobject clazz, jboolean isSystem)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001655{
Mårten Kongstad48d22322014-01-31 14:43:27 +01001656 if (isSystem) {
1657 verifySystemIdmaps();
1658 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001659 AssetManager* am = new AssetManager();
1660 if (am == NULL) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001661 jniThrowException(env, "java/lang/OutOfMemoryError", "");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001662 return;
1663 }
1664
1665 am->addDefaultAssets();
1666
Steve Block71f2cf12011-10-20 11:56:00 +01001667 ALOGV("Created AssetManager %p for Java object %p\n", am, clazz);
Ashok Bhat896043d2014-01-17 16:02:38 +00001668 env->SetLongField(clazz, gAssetManagerOffsets.mObject, reinterpret_cast<jlong>(am));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001669}
1670
1671static void android_content_AssetManager_destroy(JNIEnv* env, jobject clazz)
1672{
1673 AssetManager* am = (AssetManager*)
Ashok Bhat896043d2014-01-17 16:02:38 +00001674 (env->GetLongField(clazz, gAssetManagerOffsets.mObject));
Steve Block71f2cf12011-10-20 11:56:00 +01001675 ALOGV("Destroying AssetManager %p for Java object %p\n", am, clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001676 if (am != NULL) {
1677 delete am;
Ashok Bhat896043d2014-01-17 16:02:38 +00001678 env->SetLongField(clazz, gAssetManagerOffsets.mObject, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001679 }
1680}
1681
1682static jint android_content_AssetManager_getGlobalAssetCount(JNIEnv* env, jobject clazz)
1683{
1684 return Asset::getGlobalCount();
1685}
1686
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07001687static jobject android_content_AssetManager_getAssetAllocations(JNIEnv* env, jobject clazz)
1688{
1689 String8 alloc = Asset::getAssetAllocations();
1690 if (alloc.length() <= 0) {
1691 return NULL;
1692 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001693
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07001694 jstring str = env->NewStringUTF(alloc.string());
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07001695 return str;
1696}
1697
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001698static jint android_content_AssetManager_getGlobalAssetManagerCount(JNIEnv* env, jobject clazz)
1699{
1700 return AssetManager::getGlobalCount();
1701}
1702
1703// ----------------------------------------------------------------------------
1704
1705/*
1706 * JNI registration.
1707 */
Daniel Micay76f6a862015-09-19 17:31:01 -04001708static const JNINativeMethod gAssetManagerMethods[] = {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001709 /* name, signature, funcPtr */
1710
1711 // Basic asset stuff.
Ashok Bhat896043d2014-01-17 16:02:38 +00001712 { "openAsset", "(Ljava/lang/String;I)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001713 (void*) android_content_AssetManager_openAsset },
1714 { "openAssetFd", "(Ljava/lang/String;[J)Landroid/os/ParcelFileDescriptor;",
1715 (void*) android_content_AssetManager_openAssetFd },
Ashok Bhat896043d2014-01-17 16:02:38 +00001716 { "openNonAssetNative", "(ILjava/lang/String;I)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001717 (void*) android_content_AssetManager_openNonAssetNative },
1718 { "openNonAssetFdNative", "(ILjava/lang/String;[J)Landroid/os/ParcelFileDescriptor;",
1719 (void*) android_content_AssetManager_openNonAssetFdNative },
1720 { "list", "(Ljava/lang/String;)[Ljava/lang/String;",
1721 (void*) android_content_AssetManager_list },
Ashok Bhat896043d2014-01-17 16:02:38 +00001722 { "destroyAsset", "(J)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001723 (void*) android_content_AssetManager_destroyAsset },
Ashok Bhat896043d2014-01-17 16:02:38 +00001724 { "readAssetChar", "(J)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001725 (void*) android_content_AssetManager_readAssetChar },
Ashok Bhat896043d2014-01-17 16:02:38 +00001726 { "readAsset", "(J[BII)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001727 (void*) android_content_AssetManager_readAsset },
Ashok Bhat896043d2014-01-17 16:02:38 +00001728 { "seekAsset", "(JJI)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001729 (void*) android_content_AssetManager_seekAsset },
John Reck32995222016-10-07 11:02:20 -07001730 // @FastNative
1731 { "getAssetLength", "(J)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001732 (void*) android_content_AssetManager_getAssetLength },
John Reck32995222016-10-07 11:02:20 -07001733 // @FastNative
1734 { "getAssetRemainingLength", "(J)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001735 (void*) android_content_AssetManager_getAssetRemainingLength },
Tao Baia6d7e3f2015-09-01 18:49:54 -07001736 { "addAssetPathNative", "(Ljava/lang/String;Z)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001737 (void*) android_content_AssetManager_addAssetPath },
Mårten Kongstad30113132014-11-07 10:52:17 +01001738 { "addOverlayPathNative", "(Ljava/lang/String;)I",
Mårten Kongstad48d22322014-01-31 14:43:27 +01001739 (void*) android_content_AssetManager_addOverlayPath },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001740 { "isUpToDate", "()Z",
1741 (void*) android_content_AssetManager_isUpToDate },
1742
1743 // Resources.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001744 { "getLocales", "()[Ljava/lang/String;",
1745 (void*) android_content_AssetManager_getLocales },
Roozbeh Pournader1c686f22015-12-18 14:22:14 -08001746 { "getNonSystemLocales", "()[Ljava/lang/String;",
1747 (void*) android_content_AssetManager_getNonSystemLocales },
Filip Gruszczynski23493322015-07-29 17:02:59 -07001748 { "getSizeConfigurations", "()[Landroid/content/res/Configuration;",
1749 (void*) android_content_AssetManager_getSizeConfigurations },
John Reck32995222016-10-07 11:02:20 -07001750 // @FastNative
1751 { "setConfiguration", "(IILjava/lang/String;IIIIIIIIIIIIII)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001752 (void*) android_content_AssetManager_setConfiguration },
John Reck32995222016-10-07 11:02:20 -07001753 // @FastNative
1754 { "getResourceIdentifier","(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001755 (void*) android_content_AssetManager_getResourceIdentifier },
John Reck32995222016-10-07 11:02:20 -07001756 // @FastNative
1757 { "getResourceName","(I)Ljava/lang/String;",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001758 (void*) android_content_AssetManager_getResourceName },
John Reck32995222016-10-07 11:02:20 -07001759 // @FastNative
1760 { "getResourcePackageName","(I)Ljava/lang/String;",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001761 (void*) android_content_AssetManager_getResourcePackageName },
John Reck32995222016-10-07 11:02:20 -07001762 // @FastNative
1763 { "getResourceTypeName","(I)Ljava/lang/String;",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001764 (void*) android_content_AssetManager_getResourceTypeName },
John Reck32995222016-10-07 11:02:20 -07001765 // @FastNative
1766 { "getResourceEntryName","(I)Ljava/lang/String;",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001767 (void*) android_content_AssetManager_getResourceEntryName },
John Reck32995222016-10-07 11:02:20 -07001768 // @FastNative
1769 { "loadResourceValue","(ISLandroid/util/TypedValue;Z)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001770 (void*) android_content_AssetManager_loadResourceValue },
John Reck32995222016-10-07 11:02:20 -07001771 // @FastNative
1772 { "loadResourceBagValue","(IILandroid/util/TypedValue;Z)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001773 (void*) android_content_AssetManager_loadResourceBagValue },
John Reck32995222016-10-07 11:02:20 -07001774 // @FastNative
1775 { "getStringBlockCount","()I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001776 (void*) android_content_AssetManager_getStringBlockCount },
John Reck32995222016-10-07 11:02:20 -07001777 // @FastNative
1778 { "getNativeStringBlock","(I)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001779 (void*) android_content_AssetManager_getNativeStringBlock },
1780 { "getCookieName","(I)Ljava/lang/String;",
1781 (void*) android_content_AssetManager_getCookieName },
Adam Lesinskide898ff2014-01-29 18:20:45 -08001782 { "getAssignedPackageIdentifiers","()Landroid/util/SparseArray;",
1783 (void*) android_content_AssetManager_getAssignedPackageIdentifiers },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001784
1785 // Themes.
Ashok Bhat896043d2014-01-17 16:02:38 +00001786 { "newTheme", "()J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001787 (void*) android_content_AssetManager_newTheme },
Ashok Bhat896043d2014-01-17 16:02:38 +00001788 { "deleteTheme", "(J)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001789 (void*) android_content_AssetManager_deleteTheme },
Ashok Bhat896043d2014-01-17 16:02:38 +00001790 { "applyThemeStyle", "(JIZ)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001791 (void*) android_content_AssetManager_applyThemeStyle },
Ashok Bhat896043d2014-01-17 16:02:38 +00001792 { "copyTheme", "(JJ)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001793 (void*) android_content_AssetManager_copyTheme },
Alan Viverettee54d2452015-05-06 10:41:43 -07001794 { "clearTheme", "(J)V",
1795 (void*) android_content_AssetManager_clearTheme },
John Reck32995222016-10-07 11:02:20 -07001796 // @FastNative
1797 { "loadThemeAttributeValue", "(JILandroid/util/TypedValue;Z)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001798 (void*) android_content_AssetManager_loadThemeAttributeValue },
John Reck32995222016-10-07 11:02:20 -07001799 // @FastNative
1800 { "getThemeChangingConfigurations", "(J)I",
Alan Viverettec1d52792015-05-05 09:49:03 -07001801 (void*) android_content_AssetManager_getThemeChangingConfigurations },
Ashok Bhat896043d2014-01-17 16:02:38 +00001802 { "dumpTheme", "(JILjava/lang/String;Ljava/lang/String;)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001803 (void*) android_content_AssetManager_dumpTheme },
John Reck32995222016-10-07 11:02:20 -07001804 // @FastNative
1805 { "applyStyle","(JIIJ[I[I[I)Z",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001806 (void*) android_content_AssetManager_applyStyle },
John Reck32995222016-10-07 11:02:20 -07001807 // @FastNative
1808 { "resolveAttrs","(JII[I[I[I[I)Z",
Alan Viverette607bd842014-09-12 12:36:35 -07001809 (void*) android_content_AssetManager_resolveAttrs },
John Reck32995222016-10-07 11:02:20 -07001810 // @FastNative
1811 { "retrieveAttributes","(J[I[I[I)Z",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001812 (void*) android_content_AssetManager_retrieveAttributes },
John Reck32995222016-10-07 11:02:20 -07001813 // @FastNative
1814 { "getArraySize","(I)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001815 (void*) android_content_AssetManager_getArraySize },
John Reck32995222016-10-07 11:02:20 -07001816 // @FastNative
1817 { "retrieveArray","(I[I)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001818 (void*) android_content_AssetManager_retrieveArray },
1819
1820 // XML files.
Ashok Bhat896043d2014-01-17 16:02:38 +00001821 { "openXmlAssetNative", "(ILjava/lang/String;)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001822 (void*) android_content_AssetManager_openXmlAssetNative },
1823
1824 // Arrays.
1825 { "getArrayStringResource","(I)[Ljava/lang/String;",
1826 (void*) android_content_AssetManager_getArrayStringResource },
John Reck32995222016-10-07 11:02:20 -07001827 // @FastNative
1828 { "getArrayStringInfo","(I)[I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001829 (void*) android_content_AssetManager_getArrayStringInfo },
John Reck32995222016-10-07 11:02:20 -07001830 // @FastNative
1831 { "getArrayIntResource","(I)[I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001832 (void*) android_content_AssetManager_getArrayIntResource },
John Reck32995222016-10-07 11:02:20 -07001833 // @FastNative
1834 { "getStyleAttributes","(I)[I",
Jon Miranda042ad632014-09-03 17:57:35 -07001835 (void*) android_content_AssetManager_getStyleAttributes },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001836
1837 // Bookkeeping.
Mårten Kongstad48d22322014-01-31 14:43:27 +01001838 { "init", "(Z)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001839 (void*) android_content_AssetManager_init },
1840 { "destroy", "()V",
1841 (void*) android_content_AssetManager_destroy },
1842 { "getGlobalAssetCount", "()I",
1843 (void*) android_content_AssetManager_getGlobalAssetCount },
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07001844 { "getAssetAllocations", "()Ljava/lang/String;",
1845 (void*) android_content_AssetManager_getAssetAllocations },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001846 { "getGlobalAssetManagerCount", "()I",
Andreas Gampe32812612014-11-11 00:16:00 -08001847 (void*) android_content_AssetManager_getGlobalAssetManagerCount },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001848};
1849
1850int register_android_content_AssetManager(JNIEnv* env)
1851{
Andreas Gampe987f79f2014-11-18 17:29:46 -08001852 jclass typedValue = FindClassOrDie(env, "android/util/TypedValue");
1853 gTypedValueOffsets.mType = GetFieldIDOrDie(env, typedValue, "type", "I");
1854 gTypedValueOffsets.mData = GetFieldIDOrDie(env, typedValue, "data", "I");
1855 gTypedValueOffsets.mString = GetFieldIDOrDie(env, typedValue, "string",
1856 "Ljava/lang/CharSequence;");
1857 gTypedValueOffsets.mAssetCookie = GetFieldIDOrDie(env, typedValue, "assetCookie", "I");
1858 gTypedValueOffsets.mResourceId = GetFieldIDOrDie(env, typedValue, "resourceId", "I");
1859 gTypedValueOffsets.mChangingConfigurations = GetFieldIDOrDie(env, typedValue,
1860 "changingConfigurations", "I");
1861 gTypedValueOffsets.mDensity = GetFieldIDOrDie(env, typedValue, "density", "I");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001862
Andreas Gampe987f79f2014-11-18 17:29:46 -08001863 jclass assetFd = FindClassOrDie(env, "android/content/res/AssetFileDescriptor");
1864 gAssetFileDescriptorOffsets.mFd = GetFieldIDOrDie(env, assetFd, "mFd",
1865 "Landroid/os/ParcelFileDescriptor;");
1866 gAssetFileDescriptorOffsets.mStartOffset = GetFieldIDOrDie(env, assetFd, "mStartOffset", "J");
1867 gAssetFileDescriptorOffsets.mLength = GetFieldIDOrDie(env, assetFd, "mLength", "J");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001868
Andreas Gampe987f79f2014-11-18 17:29:46 -08001869 jclass assetManager = FindClassOrDie(env, "android/content/res/AssetManager");
1870 gAssetManagerOffsets.mObject = GetFieldIDOrDie(env, assetManager, "mObject", "J");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001871
Andreas Gampe987f79f2014-11-18 17:29:46 -08001872 jclass stringClass = FindClassOrDie(env, "java/lang/String");
1873 g_stringClass = MakeGlobalRefOrDie(env, stringClass);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001874
Andreas Gampe987f79f2014-11-18 17:29:46 -08001875 jclass sparseArrayClass = FindClassOrDie(env, "android/util/SparseArray");
1876 gSparseArrayOffsets.classObject = MakeGlobalRefOrDie(env, sparseArrayClass);
1877 gSparseArrayOffsets.constructor = GetMethodIDOrDie(env, gSparseArrayOffsets.classObject,
1878 "<init>", "()V");
1879 gSparseArrayOffsets.put = GetMethodIDOrDie(env, gSparseArrayOffsets.classObject, "put",
1880 "(ILjava/lang/Object;)V");
Adam Lesinskide898ff2014-01-29 18:20:45 -08001881
Filip Gruszczynski23493322015-07-29 17:02:59 -07001882 jclass configurationClass = FindClassOrDie(env, "android/content/res/Configuration");
1883 gConfigurationOffsets.classObject = MakeGlobalRefOrDie(env, configurationClass);
1884 gConfigurationOffsets.constructor = GetMethodIDOrDie(env, configurationClass,
1885 "<init>", "()V");
1886 gConfigurationOffsets.mSmallestScreenWidthDpOffset = GetFieldIDOrDie(env, configurationClass,
1887 "smallestScreenWidthDp", "I");
1888 gConfigurationOffsets.mScreenWidthDpOffset = GetFieldIDOrDie(env, configurationClass,
1889 "screenWidthDp", "I");
1890 gConfigurationOffsets.mScreenHeightDpOffset = GetFieldIDOrDie(env, configurationClass,
1891 "screenHeightDp", "I");
1892
Andreas Gampe987f79f2014-11-18 17:29:46 -08001893 return RegisterMethodsOrDie(env, "android/content/res/AssetManager", gAssetManagerMethods,
1894 NELEM(gAssetManagerMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001895}
1896
1897}; // namespace android