blob: f9e4e6c153d2cfa5899e2c6faa512521622d7bf2 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/* //device/libs/android_runtime/android_util_AssetManager.cpp
2**
3** Copyright 2006, The Android Open Source Project
4**
Elliott Hughes69a017b2011-04-08 14:10:28 -07005** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008**
Elliott Hughes69a017b2011-04-08 14:10:28 -07009** http://www.apache.org/licenses/LICENSE-2.0
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010**
Elliott Hughes69a017b2011-04-08 14:10:28 -070011** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015** limitations under the License.
16*/
17
18#define LOG_TAG "asset"
19
20#include <android_runtime/android_util_AssetManager.h>
21
Dan Albert46d84442014-11-18 16:07:51 -080022#include <inttypes.h>
23#include <linux/capability.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024#include <stdio.h>
Mårten Kongstad48d22322014-01-31 14:43:27 +010025#include <sys/types.h>
26#include <sys/wait.h>
Mårten Kongstad83ab0d72015-03-20 12:57:36 +010027#include <sys/stat.h>
Jakub Adamek1c15c632016-09-23 09:07:11 +010028#include <sys/system_properties.h>
Mårten Kongstad48d22322014-01-31 14:43:27 +010029
Dan Albert46d84442014-11-18 16:07:51 -080030#include <private/android_filesystem_config.h> // for AID_SYSTEM
31
Dan Albert3a091b72014-11-20 15:41:25 -080032#include "androidfw/Asset.h"
33#include "androidfw/AssetManager.h"
Adam Lesinski4452e132016-10-12 07:47:28 -070034#include "androidfw/AttributeResolution.h"
Dan Albert3a091b72014-11-20 15:41:25 -080035#include "androidfw/ResourceTypes.h"
36#include "android_runtime/AndroidRuntime.h"
37#include "android_util_Binder.h"
38#include "core_jni_helpers.h"
39#include "jni.h"
Dan Albert46d84442014-11-18 16:07:51 -080040#include "JNIHelp.h"
41#include "ScopedStringChars.h"
42#include "ScopedUtfChars.h"
Dan Albert46d84442014-11-18 16:07:51 -080043#include "utils/Log.h"
44#include "utils/misc.h"
Jakub Adamek1c15c632016-09-23 09:07:11 +010045#include "utils/String8.h"
Dan Albert46d84442014-11-18 16:07:51 -080046
Mårten Kongstad48d22322014-01-31 14:43:27 +010047extern "C" int capget(cap_user_header_t hdrp, cap_user_data_t datap);
48extern "C" int capset(cap_user_header_t hdrp, const cap_user_data_t datap);
49
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050
51namespace android {
52
Andreas Gampe0f0b4912014-11-12 08:03:48 -080053static const bool kThrowOnBadId = false;
Andreas Gampe0f0b4912014-11-12 08:03:48 -080054
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080055// ----------------------------------------------------------------------------
56
57static struct typedvalue_offsets_t
58{
59 jfieldID mType;
60 jfieldID mData;
61 jfieldID mString;
62 jfieldID mAssetCookie;
63 jfieldID mResourceId;
64 jfieldID mChangingConfigurations;
65 jfieldID mDensity;
66} gTypedValueOffsets;
67
68static struct assetfiledescriptor_offsets_t
69{
70 jfieldID mFd;
71 jfieldID mStartOffset;
72 jfieldID mLength;
73} gAssetFileDescriptorOffsets;
74
75static struct assetmanager_offsets_t
76{
77 jfieldID mObject;
78} gAssetManagerOffsets;
79
Adam Lesinskide898ff2014-01-29 18:20:45 -080080static struct sparsearray_offsets_t
81{
82 jclass classObject;
83 jmethodID constructor;
84 jmethodID put;
85} gSparseArrayOffsets;
86
Filip Gruszczynski23493322015-07-29 17:02:59 -070087static struct configuration_offsets_t
88{
89 jclass classObject;
90 jmethodID constructor;
91 jfieldID mSmallestScreenWidthDpOffset;
92 jfieldID mScreenWidthDpOffset;
93 jfieldID mScreenHeightDpOffset;
94} gConfigurationOffsets;
95
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080096jclass g_stringClass = NULL;
97
98// ----------------------------------------------------------------------------
99
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100static jint copyValue(JNIEnv* env, jobject outValue, const ResTable* table,
101 const Res_value& value, uint32_t ref, ssize_t block,
102 uint32_t typeSpecFlags, ResTable_config* config = NULL);
103
104jint copyValue(JNIEnv* env, jobject outValue, const ResTable* table,
105 const Res_value& value, uint32_t ref, ssize_t block,
106 uint32_t typeSpecFlags, ResTable_config* config)
107{
108 env->SetIntField(outValue, gTypedValueOffsets.mType, value.dataType);
109 env->SetIntField(outValue, gTypedValueOffsets.mAssetCookie,
Ashok Bhat896043d2014-01-17 16:02:38 +0000110 static_cast<jint>(table->getTableCookie(block)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800111 env->SetIntField(outValue, gTypedValueOffsets.mData, value.data);
112 env->SetObjectField(outValue, gTypedValueOffsets.mString, NULL);
113 env->SetIntField(outValue, gTypedValueOffsets.mResourceId, ref);
114 env->SetIntField(outValue, gTypedValueOffsets.mChangingConfigurations,
115 typeSpecFlags);
116 if (config != NULL) {
117 env->SetIntField(outValue, gTypedValueOffsets.mDensity, config->density);
118 }
119 return block;
120}
121
Mårten Kongstad48d22322014-01-31 14:43:27 +0100122// This is called by zygote (running as user root) as part of preloadResources.
123static void verifySystemIdmaps()
124{
125 pid_t pid;
126 char system_id[10];
127
128 snprintf(system_id, sizeof(system_id), "%d", AID_SYSTEM);
129
130 switch (pid = fork()) {
131 case -1:
132 ALOGE("failed to fork for idmap: %s", strerror(errno));
133 break;
134 case 0: // child
135 {
136 struct __user_cap_header_struct capheader;
137 struct __user_cap_data_struct capdata;
138
139 memset(&capheader, 0, sizeof(capheader));
140 memset(&capdata, 0, sizeof(capdata));
141
142 capheader.version = _LINUX_CAPABILITY_VERSION;
143 capheader.pid = 0;
144
145 if (capget(&capheader, &capdata) != 0) {
146 ALOGE("capget: %s\n", strerror(errno));
147 exit(1);
148 }
149
150 capdata.effective = capdata.permitted;
151 if (capset(&capheader, &capdata) != 0) {
152 ALOGE("capset: %s\n", strerror(errno));
153 exit(1);
154 }
155
156 if (setgid(AID_SYSTEM) != 0) {
157 ALOGE("setgid: %s\n", strerror(errno));
158 exit(1);
159 }
160
161 if (setuid(AID_SYSTEM) != 0) {
162 ALOGE("setuid: %s\n", strerror(errno));
163 exit(1);
164 }
165
Mårten Kongstad83ab0d72015-03-20 12:57:36 +0100166 // Generic idmap parameters
167 const char* argv[7];
168 int argc = 0;
169 struct stat st;
170
171 memset(argv, NULL, sizeof(argv));
172 argv[argc++] = AssetManager::IDMAP_BIN;
173 argv[argc++] = "--scan";
174 argv[argc++] = AssetManager::TARGET_PACKAGE_NAME;
175 argv[argc++] = AssetManager::TARGET_APK_PATH;
176 argv[argc++] = AssetManager::IDMAP_DIR;
177
Jakub Adamekc03d9482016-09-30 09:19:09 +0100178 // Directories to scan for overlays: if OVERLAY_SKU_DIR_PROPERTY is defined,
179 // use OVERLAY_DIR/<value of OVERLAY_SKU_DIR_PROPERTY> if exists, otherwise
Jakub Adamek1c15c632016-09-23 09:07:11 +0100180 // use OVERLAY_DIR if exists.
181 char subdir[PROP_VALUE_MAX];
Jakub Adamekc03d9482016-09-30 09:19:09 +0100182 int len = __system_property_get(AssetManager::OVERLAY_SKU_DIR_PROPERTY, subdir);
183 String8 overlayPath;
Jakub Adamek1c15c632016-09-23 09:07:11 +0100184 if (len > 0) {
Jakub Adamekc03d9482016-09-30 09:19:09 +0100185 overlayPath = String8(AssetManager::OVERLAY_DIR) + "/" + subdir;
186 } else {
187 overlayPath = String8(AssetManager::OVERLAY_DIR);
188 }
189 if (stat(overlayPath.string(), &st) == 0) {
190 argv[argc++] = overlayPath.string();
Jakub Adamek1c15c632016-09-23 09:07:11 +0100191 }
Mårten Kongstad83ab0d72015-03-20 12:57:36 +0100192
193 // Finally, invoke idmap (if any overlay directory exists)
194 if (argc > 5) {
195 execv(AssetManager::IDMAP_BIN, (char* const*)argv);
196 ALOGE("failed to execl for idmap: %s", strerror(errno));
197 exit(1); // should never get here
198 } else {
199 exit(0);
200 }
Mårten Kongstad48d22322014-01-31 14:43:27 +0100201 }
202 break;
203 default: // parent
204 waitpid(pid, NULL, 0);
205 break;
206 }
207}
208
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800209// ----------------------------------------------------------------------------
210
211// this guy is exported to other jni routines
212AssetManager* assetManagerForJavaObject(JNIEnv* env, jobject obj)
213{
Ashok Bhat896043d2014-01-17 16:02:38 +0000214 jlong amHandle = env->GetLongField(obj, gAssetManagerOffsets.mObject);
215 AssetManager* am = reinterpret_cast<AssetManager*>(amHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800216 if (am != NULL) {
217 return am;
218 }
219 jniThrowException(env, "java/lang/IllegalStateException", "AssetManager has been finalized!");
220 return NULL;
221}
222
Ashok Bhat896043d2014-01-17 16:02:38 +0000223static jlong android_content_AssetManager_openAsset(JNIEnv* env, jobject clazz,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800224 jstring fileName, jint mode)
225{
226 AssetManager* am = assetManagerForJavaObject(env, clazz);
227 if (am == NULL) {
228 return 0;
229 }
230
Steve Block71f2cf12011-10-20 11:56:00 +0100231 ALOGV("openAsset in %p (Java object %p)\n", am, clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800232
Elliott Hughes69a017b2011-04-08 14:10:28 -0700233 ScopedUtfChars fileName8(env, fileName);
234 if (fileName8.c_str() == NULL) {
Ashok Bhat896043d2014-01-17 16:02:38 +0000235 jniThrowException(env, "java/lang/IllegalArgumentException", "Empty file name");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800236 return -1;
237 }
238
239 if (mode != Asset::ACCESS_UNKNOWN && mode != Asset::ACCESS_RANDOM
240 && mode != Asset::ACCESS_STREAMING && mode != Asset::ACCESS_BUFFER) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -0700241 jniThrowException(env, "java/lang/IllegalArgumentException", "Bad access mode");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800242 return -1;
243 }
244
Elliott Hughes69a017b2011-04-08 14:10:28 -0700245 Asset* a = am->open(fileName8.c_str(), (Asset::AccessMode)mode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800246
247 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700248 jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800249 return -1;
250 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800251
252 //printf("Created Asset Stream: %p\n", a);
253
Ashok Bhat896043d2014-01-17 16:02:38 +0000254 return reinterpret_cast<jlong>(a);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800255}
256
257static jobject returnParcelFileDescriptor(JNIEnv* env, Asset* a, jlongArray outOffsets)
258{
Kenny Rootddb76c42010-11-24 12:56:06 -0800259 off64_t startOffset, length;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800260 int fd = a->openFileDescriptor(&startOffset, &length);
261 delete a;
Elliott Hughes69a017b2011-04-08 14:10:28 -0700262
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800263 if (fd < 0) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -0700264 jniThrowException(env, "java/io/FileNotFoundException",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800265 "This file can not be opened as a file descriptor; it is probably compressed");
266 return NULL;
267 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700268
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800269 jlong* offsets = (jlong*)env->GetPrimitiveArrayCritical(outOffsets, 0);
270 if (offsets == NULL) {
271 close(fd);
272 return NULL;
273 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700274
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800275 offsets[0] = startOffset;
276 offsets[1] = length;
Elliott Hughes69a017b2011-04-08 14:10:28 -0700277
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800278 env->ReleasePrimitiveArrayCritical(outOffsets, offsets, 0);
Elliott Hughes69a017b2011-04-08 14:10:28 -0700279
Elliott Hughesa3804cf2011-04-11 16:50:19 -0700280 jobject fileDesc = jniCreateFileDescriptor(env, fd);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800281 if (fileDesc == NULL) {
282 close(fd);
283 return NULL;
284 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700285
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800286 return newParcelFileDescriptor(env, fileDesc);
287}
288
289static jobject android_content_AssetManager_openAssetFd(JNIEnv* env, jobject clazz,
290 jstring fileName, jlongArray outOffsets)
291{
292 AssetManager* am = assetManagerForJavaObject(env, clazz);
293 if (am == NULL) {
294 return NULL;
295 }
296
Steve Block71f2cf12011-10-20 11:56:00 +0100297 ALOGV("openAssetFd in %p (Java object %p)\n", am, clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800298
Elliott Hughes69a017b2011-04-08 14:10:28 -0700299 ScopedUtfChars fileName8(env, fileName);
300 if (fileName8.c_str() == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800301 return NULL;
302 }
303
Elliott Hughes69a017b2011-04-08 14:10:28 -0700304 Asset* a = am->open(fileName8.c_str(), Asset::ACCESS_RANDOM);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800305
306 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700307 jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800308 return NULL;
309 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800310
311 //printf("Created Asset Stream: %p\n", a);
312
313 return returnParcelFileDescriptor(env, a, outOffsets);
314}
315
Ashok Bhat896043d2014-01-17 16:02:38 +0000316static jlong android_content_AssetManager_openNonAssetNative(JNIEnv* env, jobject clazz,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800317 jint cookie,
318 jstring fileName,
319 jint mode)
320{
321 AssetManager* am = assetManagerForJavaObject(env, clazz);
322 if (am == NULL) {
323 return 0;
324 }
325
Steve Block71f2cf12011-10-20 11:56:00 +0100326 ALOGV("openNonAssetNative in %p (Java object %p)\n", am, clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800327
Elliott Hughes69a017b2011-04-08 14:10:28 -0700328 ScopedUtfChars fileName8(env, fileName);
329 if (fileName8.c_str() == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800330 return -1;
331 }
332
333 if (mode != Asset::ACCESS_UNKNOWN && mode != Asset::ACCESS_RANDOM
334 && mode != Asset::ACCESS_STREAMING && mode != Asset::ACCESS_BUFFER) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -0700335 jniThrowException(env, "java/lang/IllegalArgumentException", "Bad access mode");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800336 return -1;
337 }
338
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800339 Asset* a = cookie
Narayan Kamath745d4ef2014-01-27 11:17:22 +0000340 ? am->openNonAsset(static_cast<int32_t>(cookie), fileName8.c_str(),
341 (Asset::AccessMode)mode)
Elliott Hughes69a017b2011-04-08 14:10:28 -0700342 : am->openNonAsset(fileName8.c_str(), (Asset::AccessMode)mode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800343
344 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700345 jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800346 return -1;
347 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800348
349 //printf("Created Asset Stream: %p\n", a);
350
Ashok Bhat896043d2014-01-17 16:02:38 +0000351 return reinterpret_cast<jlong>(a);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800352}
353
354static jobject android_content_AssetManager_openNonAssetFdNative(JNIEnv* env, jobject clazz,
355 jint cookie,
356 jstring fileName,
357 jlongArray outOffsets)
358{
359 AssetManager* am = assetManagerForJavaObject(env, clazz);
360 if (am == NULL) {
361 return NULL;
362 }
363
Steve Block71f2cf12011-10-20 11:56:00 +0100364 ALOGV("openNonAssetFd in %p (Java object %p)\n", am, clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800365
Elliott Hughes69a017b2011-04-08 14:10:28 -0700366 ScopedUtfChars fileName8(env, fileName);
367 if (fileName8.c_str() == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800368 return NULL;
369 }
370
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800371 Asset* a = cookie
Narayan Kamath745d4ef2014-01-27 11:17:22 +0000372 ? am->openNonAsset(static_cast<int32_t>(cookie), fileName8.c_str(), Asset::ACCESS_RANDOM)
Elliott Hughes69a017b2011-04-08 14:10:28 -0700373 : am->openNonAsset(fileName8.c_str(), Asset::ACCESS_RANDOM);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800374
375 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700376 jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800377 return NULL;
378 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800379
380 //printf("Created Asset Stream: %p\n", a);
381
382 return returnParcelFileDescriptor(env, a, outOffsets);
383}
384
385static jobjectArray android_content_AssetManager_list(JNIEnv* env, jobject clazz,
386 jstring fileName)
387{
388 AssetManager* am = assetManagerForJavaObject(env, clazz);
389 if (am == NULL) {
390 return NULL;
391 }
392
Elliott Hughes69a017b2011-04-08 14:10:28 -0700393 ScopedUtfChars fileName8(env, fileName);
394 if (fileName8.c_str() == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800395 return NULL;
396 }
397
Elliott Hughes69a017b2011-04-08 14:10:28 -0700398 AssetDir* dir = am->openDir(fileName8.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800399
400 if (dir == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700401 jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800402 return NULL;
403 }
404
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800405 size_t N = dir->getFileCount();
406
407 jobjectArray array = env->NewObjectArray(dir->getFileCount(),
Vladimir Markoaa5fe3d2013-06-17 12:46:22 +0100408 g_stringClass, NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800409 if (array == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800410 delete dir;
411 return NULL;
412 }
413
414 for (size_t i=0; i<N; i++) {
415 const String8& name = dir->getFileName(i);
416 jstring str = env->NewStringUTF(name.string());
417 if (str == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800418 delete dir;
419 return NULL;
420 }
421 env->SetObjectArrayElement(array, i, str);
Gilles Debunne4d4040b2010-08-26 15:59:54 -0700422 env->DeleteLocalRef(str);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800423 }
424
425 delete dir;
426
427 return array;
428}
429
430static void android_content_AssetManager_destroyAsset(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +0000431 jlong assetHandle)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800432{
Ashok Bhat896043d2014-01-17 16:02:38 +0000433 Asset* a = reinterpret_cast<Asset*>(assetHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800434
435 //printf("Destroying Asset Stream: %p\n", a);
436
437 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700438 jniThrowNullPointerException(env, "asset");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800439 return;
440 }
441
442 delete a;
443}
444
445static jint android_content_AssetManager_readAssetChar(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +0000446 jlong assetHandle)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800447{
Ashok Bhat896043d2014-01-17 16:02:38 +0000448 Asset* a = reinterpret_cast<Asset*>(assetHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800449
450 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700451 jniThrowNullPointerException(env, "asset");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800452 return -1;
453 }
454
455 uint8_t b;
456 ssize_t res = a->read(&b, 1);
457 return res == 1 ? b : -1;
458}
459
460static jint android_content_AssetManager_readAsset(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +0000461 jlong assetHandle, jbyteArray bArray,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800462 jint off, jint len)
463{
Ashok Bhat896043d2014-01-17 16:02:38 +0000464 Asset* a = reinterpret_cast<Asset*>(assetHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800465
466 if (a == NULL || bArray == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700467 jniThrowNullPointerException(env, "asset");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800468 return -1;
469 }
470
471 if (len == 0) {
472 return 0;
473 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700474
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800475 jsize bLen = env->GetArrayLength(bArray);
476 if (off < 0 || off >= bLen || len < 0 || len > bLen || (off+len) > bLen) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -0700477 jniThrowException(env, "java/lang/IndexOutOfBoundsException", "");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800478 return -1;
479 }
480
481 jbyte* b = env->GetByteArrayElements(bArray, NULL);
482 ssize_t res = a->read(b+off, len);
483 env->ReleaseByteArrayElements(bArray, b, 0);
484
Ashok Bhat896043d2014-01-17 16:02:38 +0000485 if (res > 0) return static_cast<jint>(res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800486
487 if (res < 0) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -0700488 jniThrowException(env, "java/io/IOException", "");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800489 }
490 return -1;
491}
492
493static jlong android_content_AssetManager_seekAsset(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +0000494 jlong assetHandle,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800495 jlong offset, jint whence)
496{
Ashok Bhat896043d2014-01-17 16:02:38 +0000497 Asset* a = reinterpret_cast<Asset*>(assetHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800498
499 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700500 jniThrowNullPointerException(env, "asset");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800501 return -1;
502 }
503
504 return a->seek(
505 offset, (whence > 0) ? SEEK_END : (whence < 0 ? SEEK_SET : SEEK_CUR));
506}
507
508static jlong android_content_AssetManager_getAssetLength(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +0000509 jlong assetHandle)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800510{
Ashok Bhat896043d2014-01-17 16:02:38 +0000511 Asset* a = reinterpret_cast<Asset*>(assetHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800512
513 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700514 jniThrowNullPointerException(env, "asset");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800515 return -1;
516 }
517
518 return a->getLength();
519}
520
521static jlong android_content_AssetManager_getAssetRemainingLength(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +0000522 jlong assetHandle)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800523{
Ashok Bhat896043d2014-01-17 16:02:38 +0000524 Asset* a = reinterpret_cast<Asset*>(assetHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800525
526 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700527 jniThrowNullPointerException(env, "asset");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800528 return -1;
529 }
530
531 return a->getRemainingLength();
532}
533
534static jint android_content_AssetManager_addAssetPath(JNIEnv* env, jobject clazz,
Tao Baia6d7e3f2015-09-01 18:49:54 -0700535 jstring path, jboolean appAsLib)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800536{
Elliott Hughes69a017b2011-04-08 14:10:28 -0700537 ScopedUtfChars path8(env, path);
538 if (path8.c_str() == NULL) {
Glenn Kasten129e19c2012-01-10 17:57:36 -0800539 return 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800540 }
541
542 AssetManager* am = assetManagerForJavaObject(env, clazz);
543 if (am == NULL) {
Glenn Kasten129e19c2012-01-10 17:57:36 -0800544 return 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800545 }
546
Narayan Kamath745d4ef2014-01-27 11:17:22 +0000547 int32_t cookie;
Tao Baia6d7e3f2015-09-01 18:49:54 -0700548 bool res = am->addAssetPath(String8(path8.c_str()), &cookie, appAsLib);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800549
Narayan Kamath745d4ef2014-01-27 11:17:22 +0000550 return (res) ? static_cast<jint>(cookie) : 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800551}
552
Mårten Kongstad48d22322014-01-31 14:43:27 +0100553static jint android_content_AssetManager_addOverlayPath(JNIEnv* env, jobject clazz,
554 jstring idmapPath)
555{
556 ScopedUtfChars idmapPath8(env, idmapPath);
557 if (idmapPath8.c_str() == NULL) {
558 return 0;
559 }
560
561 AssetManager* am = assetManagerForJavaObject(env, clazz);
562 if (am == NULL) {
563 return 0;
564 }
565
566 int32_t cookie;
567 bool res = am->addOverlayPath(String8(idmapPath8.c_str()), &cookie);
568
569 return (res) ? (jint)cookie : 0;
570}
571
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800572static jboolean android_content_AssetManager_isUpToDate(JNIEnv* env, jobject clazz)
573{
574 AssetManager* am = assetManagerForJavaObject(env, clazz);
575 if (am == NULL) {
576 return JNI_TRUE;
577 }
578 return am->isUpToDate() ? JNI_TRUE : JNI_FALSE;
579}
580
Roozbeh Pournader1c686f22015-12-18 14:22:14 -0800581static jobjectArray getLocales(JNIEnv* env, jobject clazz, bool includeSystemLocales)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800582{
583 Vector<String8> locales;
584
585 AssetManager* am = assetManagerForJavaObject(env, clazz);
586 if (am == NULL) {
587 return NULL;
588 }
589
Roozbeh Pournader1c686f22015-12-18 14:22:14 -0800590 am->getLocales(&locales, includeSystemLocales);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800591
592 const int N = locales.size();
593
594 jobjectArray result = env->NewObjectArray(N, g_stringClass, NULL);
595 if (result == NULL) {
596 return NULL;
597 }
598
599 for (int i=0; i<N; i++) {
Gilles Debunne0db187a2010-08-27 11:51:34 -0700600 jstring str = env->NewStringUTF(locales[i].string());
Gilles Debunne4d4040b2010-08-26 15:59:54 -0700601 if (str == NULL) {
602 return NULL;
603 }
604 env->SetObjectArrayElement(result, i, str);
605 env->DeleteLocalRef(str);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800606 }
607
608 return result;
609}
610
Roozbeh Pournader1c686f22015-12-18 14:22:14 -0800611static jobjectArray android_content_AssetManager_getLocales(JNIEnv* env, jobject clazz)
612{
613 return getLocales(env, clazz, true /* include system locales */);
614}
615
616static jobjectArray android_content_AssetManager_getNonSystemLocales(JNIEnv* env, jobject clazz)
617{
618 return getLocales(env, clazz, false /* don't include system locales */);
619}
620
Filip Gruszczynski23493322015-07-29 17:02:59 -0700621static jobject constructConfigurationObject(JNIEnv* env, const ResTable_config& config) {
622 jobject result = env->NewObject(gConfigurationOffsets.classObject,
623 gConfigurationOffsets.constructor);
624 if (result == NULL) {
625 return NULL;
626 }
627
628 env->SetIntField(result, gConfigurationOffsets.mSmallestScreenWidthDpOffset,
629 config.smallestScreenWidthDp);
630 env->SetIntField(result, gConfigurationOffsets.mScreenWidthDpOffset, config.screenWidthDp);
631 env->SetIntField(result, gConfigurationOffsets.mScreenHeightDpOffset, config.screenHeightDp);
632
633 return result;
634}
635
636static jobjectArray getSizeConfigurationsInternal(JNIEnv* env,
637 const Vector<ResTable_config>& configs) {
638 const int N = configs.size();
639 jobjectArray result = env->NewObjectArray(N, gConfigurationOffsets.classObject, NULL);
640 if (result == NULL) {
641 return NULL;
642 }
643
644 for (int i=0; i<N; i++) {
645 jobject config = constructConfigurationObject(env, configs[i]);
646 if (config == NULL) {
647 env->DeleteLocalRef(result);
648 return NULL;
649 }
650
651 env->SetObjectArrayElement(result, i, config);
652 env->DeleteLocalRef(config);
653 }
654
655 return result;
656}
657
658static jobjectArray android_content_AssetManager_getSizeConfigurations(JNIEnv* env, jobject clazz) {
659 AssetManager* am = assetManagerForJavaObject(env, clazz);
660 if (am == NULL) {
661 return NULL;
662 }
663
664 const ResTable& res(am->getResources());
665 Vector<ResTable_config> configs;
666 res.getConfigurations(&configs, false /* ignoreMipmap */, true /* ignoreAndroidPackage */);
667
668 return getSizeConfigurationsInternal(env, configs);
669}
670
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800671static void android_content_AssetManager_setConfiguration(JNIEnv* env, jobject clazz,
672 jint mcc, jint mnc,
673 jstring locale, jint orientation,
674 jint touchscreen, jint density,
675 jint keyboard, jint keyboardHidden,
676 jint navigation,
677 jint screenWidth, jint screenHeight,
Dianne Hackborn69cb8752011-05-19 18:13:32 -0700678 jint smallestScreenWidthDp,
Dianne Hackborn3fc982f2011-03-30 16:20:26 -0700679 jint screenWidthDp, jint screenHeightDp,
Tobias Haamel27b28b32010-02-09 23:09:17 +0100680 jint screenLayout, jint uiMode,
681 jint sdkVersion)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800682{
683 AssetManager* am = assetManagerForJavaObject(env, clazz);
684 if (am == NULL) {
685 return;
686 }
687
688 ResTable_config config;
689 memset(&config, 0, sizeof(config));
Elliott Hughes69a017b2011-04-08 14:10:28 -0700690
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800691 const char* locale8 = locale != NULL ? env->GetStringUTFChars(locale, NULL) : NULL;
Elliott Hughes69a017b2011-04-08 14:10:28 -0700692
Adam Lesinski2738c962015-05-14 14:25:36 -0700693 // Constants duplicated from Java class android.content.res.Configuration.
694 static const jint kScreenLayoutRoundMask = 0x300;
695 static const jint kScreenLayoutRoundShift = 8;
696
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800697 config.mcc = (uint16_t)mcc;
698 config.mnc = (uint16_t)mnc;
699 config.orientation = (uint8_t)orientation;
700 config.touchscreen = (uint8_t)touchscreen;
701 config.density = (uint16_t)density;
702 config.keyboard = (uint8_t)keyboard;
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700703 config.inputFlags = (uint8_t)keyboardHidden;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800704 config.navigation = (uint8_t)navigation;
705 config.screenWidth = (uint16_t)screenWidth;
706 config.screenHeight = (uint16_t)screenHeight;
Dianne Hackborn69cb8752011-05-19 18:13:32 -0700707 config.smallestScreenWidthDp = (uint16_t)smallestScreenWidthDp;
Dianne Hackborn3fc982f2011-03-30 16:20:26 -0700708 config.screenWidthDp = (uint16_t)screenWidthDp;
709 config.screenHeightDp = (uint16_t)screenHeightDp;
Dianne Hackborn723738c2009-06-25 19:48:04 -0700710 config.screenLayout = (uint8_t)screenLayout;
Tobias Haamel27b28b32010-02-09 23:09:17 +0100711 config.uiMode = (uint8_t)uiMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800712 config.sdkVersion = (uint16_t)sdkVersion;
713 config.minorVersion = 0;
Adam Lesinski2738c962015-05-14 14:25:36 -0700714
715 // In Java, we use a 32bit integer for screenLayout, while we only use an 8bit integer
716 // in C++. We must extract the round qualifier out of the Java screenLayout and put it
717 // into screenLayout2.
718 config.screenLayout2 =
719 (uint8_t)((screenLayout & kScreenLayoutRoundMask) >> kScreenLayoutRoundShift);
720
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800721 am->setConfiguration(config, locale8);
Elliott Hughes69a017b2011-04-08 14:10:28 -0700722
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800723 if (locale != NULL) env->ReleaseStringUTFChars(locale, locale8);
724}
725
726static jint android_content_AssetManager_getResourceIdentifier(JNIEnv* env, jobject clazz,
727 jstring name,
728 jstring defType,
729 jstring defPackage)
730{
Elliott Hughes69a017b2011-04-08 14:10:28 -0700731 ScopedStringChars name16(env, name);
732 if (name16.get() == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800733 return 0;
734 }
735
736 AssetManager* am = assetManagerForJavaObject(env, clazz);
737 if (am == NULL) {
738 return 0;
739 }
740
Dan Albert66987492014-11-20 11:41:21 -0800741 const char16_t* defType16 = reinterpret_cast<const char16_t*>(defType)
742 ? reinterpret_cast<const char16_t*>(env->GetStringChars(defType, NULL))
743 : NULL;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800744 jsize defTypeLen = defType
745 ? env->GetStringLength(defType) : 0;
Dan Albert66987492014-11-20 11:41:21 -0800746 const char16_t* defPackage16 = reinterpret_cast<const char16_t*>(defPackage)
747 ? reinterpret_cast<const char16_t*>(env->GetStringChars(defPackage,
748 NULL))
749 : NULL;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800750 jsize defPackageLen = defPackage
751 ? env->GetStringLength(defPackage) : 0;
752
753 jint ident = am->getResources().identifierForName(
Dan Albert66987492014-11-20 11:41:21 -0800754 reinterpret_cast<const char16_t*>(name16.get()), name16.size(),
755 defType16, defTypeLen, defPackage16, defPackageLen);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800756
757 if (defPackage16) {
Dan Albert66987492014-11-20 11:41:21 -0800758 env->ReleaseStringChars(defPackage,
759 reinterpret_cast<const jchar*>(defPackage16));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800760 }
761 if (defType16) {
Dan Albert66987492014-11-20 11:41:21 -0800762 env->ReleaseStringChars(defType,
763 reinterpret_cast<const jchar*>(defType16));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800764 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800765
766 return ident;
767}
768
769static jstring android_content_AssetManager_getResourceName(JNIEnv* env, jobject clazz,
770 jint resid)
771{
772 AssetManager* am = assetManagerForJavaObject(env, clazz);
773 if (am == NULL) {
774 return NULL;
775 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700776
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800777 ResTable::resource_name name;
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700778 if (!am->getResources().getResourceName(resid, true, &name)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800779 return NULL;
780 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700781
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800782 String16 str;
783 if (name.package != NULL) {
784 str.setTo(name.package, name.packageLen);
785 }
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700786 if (name.type8 != NULL || name.type != NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800787 if (str.size() > 0) {
788 char16_t div = ':';
789 str.append(&div, 1);
790 }
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700791 if (name.type8 != NULL) {
792 str.append(String16(name.type8, name.typeLen));
793 } else {
794 str.append(name.type, name.typeLen);
795 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800796 }
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700797 if (name.name8 != NULL || name.name != NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800798 if (str.size() > 0) {
799 char16_t div = '/';
800 str.append(&div, 1);
801 }
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700802 if (name.name8 != NULL) {
803 str.append(String16(name.name8, name.nameLen));
804 } else {
805 str.append(name.name, name.nameLen);
806 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800807 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700808
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800809 return env->NewString((const jchar*)str.string(), str.size());
810}
811
812static jstring android_content_AssetManager_getResourcePackageName(JNIEnv* env, jobject clazz,
813 jint resid)
814{
815 AssetManager* am = assetManagerForJavaObject(env, clazz);
816 if (am == NULL) {
817 return NULL;
818 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700819
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800820 ResTable::resource_name name;
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700821 if (!am->getResources().getResourceName(resid, true, &name)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800822 return NULL;
823 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700824
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800825 if (name.package != NULL) {
826 return env->NewString((const jchar*)name.package, name.packageLen);
827 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700828
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800829 return NULL;
830}
831
832static jstring android_content_AssetManager_getResourceTypeName(JNIEnv* env, jobject clazz,
833 jint resid)
834{
835 AssetManager* am = assetManagerForJavaObject(env, clazz);
836 if (am == NULL) {
837 return NULL;
838 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700839
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800840 ResTable::resource_name name;
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700841 if (!am->getResources().getResourceName(resid, true, &name)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800842 return NULL;
843 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700844
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700845 if (name.type8 != NULL) {
846 return env->NewStringUTF(name.type8);
847 }
848
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800849 if (name.type != NULL) {
850 return env->NewString((const jchar*)name.type, name.typeLen);
851 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700852
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800853 return NULL;
854}
855
856static jstring android_content_AssetManager_getResourceEntryName(JNIEnv* env, jobject clazz,
857 jint resid)
858{
859 AssetManager* am = assetManagerForJavaObject(env, clazz);
860 if (am == NULL) {
861 return NULL;
862 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700863
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800864 ResTable::resource_name name;
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700865 if (!am->getResources().getResourceName(resid, true, &name)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800866 return NULL;
867 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700868
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700869 if (name.name8 != NULL) {
870 return env->NewStringUTF(name.name8);
871 }
872
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800873 if (name.name != NULL) {
874 return env->NewString((const jchar*)name.name, name.nameLen);
875 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700876
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800877 return NULL;
878}
879
880static jint android_content_AssetManager_loadResourceValue(JNIEnv* env, jobject clazz,
881 jint ident,
Kenny Root55fc8502010-10-28 14:47:01 -0700882 jshort density,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800883 jobject outValue,
884 jboolean resolve)
885{
Dianne Hackborn1f7d3072013-02-11 17:03:32 -0800886 if (outValue == NULL) {
Dianne Hackborne5b50a62013-02-11 16:18:42 -0800887 jniThrowNullPointerException(env, "outValue");
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700888 return 0;
Dianne Hackborne5b50a62013-02-11 16:18:42 -0800889 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800890 AssetManager* am = assetManagerForJavaObject(env, clazz);
891 if (am == NULL) {
892 return 0;
893 }
894 const ResTable& res(am->getResources());
895
896 Res_value value;
897 ResTable_config config;
898 uint32_t typeSpecFlags;
Kenny Root55fc8502010-10-28 14:47:01 -0700899 ssize_t block = res.getResource(ident, &value, false, density, &typeSpecFlags, &config);
Andreas Gampe0f0b4912014-11-12 08:03:48 -0800900 if (kThrowOnBadId) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -0800901 if (block == BAD_INDEX) {
902 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
903 return 0;
904 }
Andreas Gampe0f0b4912014-11-12 08:03:48 -0800905 }
906 uint32_t ref = ident;
907 if (resolve) {
908 block = res.resolveReference(&value, block, &ref, &typeSpecFlags, &config);
909 if (kThrowOnBadId) {
910 if (block == BAD_INDEX) {
911 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
912 return 0;
913 }
914 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800915 }
Ashok Bhat896043d2014-01-17 16:02:38 +0000916 if (block >= 0) {
917 return copyValue(env, outValue, &res, value, ref, block, typeSpecFlags, &config);
918 }
919
920 return static_cast<jint>(block);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800921}
922
923static jint android_content_AssetManager_loadResourceBagValue(JNIEnv* env, jobject clazz,
924 jint ident, jint bagEntryId,
925 jobject outValue, jboolean resolve)
926{
927 AssetManager* am = assetManagerForJavaObject(env, clazz);
928 if (am == NULL) {
929 return 0;
930 }
931 const ResTable& res(am->getResources());
Elliott Hughes69a017b2011-04-08 14:10:28 -0700932
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800933 // Now lock down the resource object and start pulling stuff from it.
934 res.lock();
Elliott Hughes69a017b2011-04-08 14:10:28 -0700935
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800936 ssize_t block = -1;
937 Res_value value;
938
939 const ResTable::bag_entry* entry = NULL;
940 uint32_t typeSpecFlags;
941 ssize_t entryCount = res.getBagLocked(ident, &entry, &typeSpecFlags);
942
943 for (ssize_t i=0; i<entryCount; i++) {
944 if (((uint32_t)bagEntryId) == entry->map.name.ident) {
945 block = entry->stringBlock;
946 value = entry->map.value;
947 }
948 entry++;
949 }
950
951 res.unlock();
952
953 if (block < 0) {
Ashok Bhat896043d2014-01-17 16:02:38 +0000954 return static_cast<jint>(block);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800955 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700956
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800957 uint32_t ref = ident;
958 if (resolve) {
959 block = res.resolveReference(&value, block, &ref, &typeSpecFlags);
Andreas Gampe0f0b4912014-11-12 08:03:48 -0800960 if (kThrowOnBadId) {
961 if (block == BAD_INDEX) {
962 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
963 return 0;
964 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -0800965 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800966 }
Ashok Bhat896043d2014-01-17 16:02:38 +0000967 if (block >= 0) {
968 return copyValue(env, outValue, &res, value, ref, block, typeSpecFlags);
969 }
970
971 return static_cast<jint>(block);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800972}
973
974static jint android_content_AssetManager_getStringBlockCount(JNIEnv* env, jobject clazz)
975{
976 AssetManager* am = assetManagerForJavaObject(env, clazz);
977 if (am == NULL) {
978 return 0;
979 }
980 return am->getResources().getTableCount();
981}
982
Ashok Bhat896043d2014-01-17 16:02:38 +0000983static jlong android_content_AssetManager_getNativeStringBlock(JNIEnv* env, jobject clazz,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800984 jint block)
985{
986 AssetManager* am = assetManagerForJavaObject(env, clazz);
987 if (am == NULL) {
988 return 0;
989 }
Ashok Bhat896043d2014-01-17 16:02:38 +0000990 return reinterpret_cast<jlong>(am->getResources().getTableStringBlock(block));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800991}
992
993static jstring android_content_AssetManager_getCookieName(JNIEnv* env, jobject clazz,
994 jint cookie)
995{
996 AssetManager* am = assetManagerForJavaObject(env, clazz);
997 if (am == NULL) {
998 return NULL;
999 }
Narayan Kamath745d4ef2014-01-27 11:17:22 +00001000 String8 name(am->getAssetPath(static_cast<int32_t>(cookie)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001001 if (name.length() == 0) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001002 jniThrowException(env, "java/lang/IndexOutOfBoundsException", "Empty cookie name");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001003 return NULL;
1004 }
1005 jstring str = env->NewStringUTF(name.string());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001006 return str;
1007}
1008
Adam Lesinskide898ff2014-01-29 18:20:45 -08001009static jobject android_content_AssetManager_getAssignedPackageIdentifiers(JNIEnv* env, jobject clazz)
1010{
1011 AssetManager* am = assetManagerForJavaObject(env, clazz);
1012 if (am == NULL) {
1013 return 0;
1014 }
1015
1016 const ResTable& res = am->getResources();
1017
1018 jobject sparseArray = env->NewObject(gSparseArrayOffsets.classObject,
1019 gSparseArrayOffsets.constructor);
1020 const size_t N = res.getBasePackageCount();
1021 for (size_t i = 0; i < N; i++) {
1022 const String16 name = res.getBasePackageName(i);
Dan Albert66987492014-11-20 11:41:21 -08001023 env->CallVoidMethod(
1024 sparseArray, gSparseArrayOffsets.put,
1025 static_cast<jint>(res.getBasePackageId(i)),
1026 env->NewString(reinterpret_cast<const jchar*>(name.string()),
1027 name.size()));
Adam Lesinskide898ff2014-01-29 18:20:45 -08001028 }
1029 return sparseArray;
1030}
1031
Ashok Bhat896043d2014-01-17 16:02:38 +00001032static jlong android_content_AssetManager_newTheme(JNIEnv* env, jobject clazz)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001033{
1034 AssetManager* am = assetManagerForJavaObject(env, clazz);
1035 if (am == NULL) {
1036 return 0;
1037 }
Ashok Bhat896043d2014-01-17 16:02:38 +00001038 return reinterpret_cast<jlong>(new ResTable::Theme(am->getResources()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001039}
1040
1041static void android_content_AssetManager_deleteTheme(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +00001042 jlong themeHandle)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001043{
Ashok Bhat896043d2014-01-17 16:02:38 +00001044 ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001045 delete theme;
1046}
1047
1048static void android_content_AssetManager_applyThemeStyle(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +00001049 jlong themeHandle,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001050 jint styleRes,
1051 jboolean force)
1052{
Ashok Bhat896043d2014-01-17 16:02:38 +00001053 ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001054 theme->applyStyle(styleRes, force ? true : false);
1055}
1056
1057static void android_content_AssetManager_copyTheme(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +00001058 jlong destHandle, jlong srcHandle)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001059{
Ashok Bhat896043d2014-01-17 16:02:38 +00001060 ResTable::Theme* dest = reinterpret_cast<ResTable::Theme*>(destHandle);
1061 ResTable::Theme* src = reinterpret_cast<ResTable::Theme*>(srcHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001062 dest->setTo(*src);
1063}
1064
Alan Viverettee54d2452015-05-06 10:41:43 -07001065static void android_content_AssetManager_clearTheme(JNIEnv* env, jobject clazz, jlong themeHandle)
1066{
1067 ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeHandle);
1068 theme->clear();
1069}
1070
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001071static jint android_content_AssetManager_loadThemeAttributeValue(
Ashok Bhat896043d2014-01-17 16:02:38 +00001072 JNIEnv* env, jobject clazz, jlong themeHandle, jint ident, jobject outValue, jboolean resolve)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001073{
Ashok Bhat896043d2014-01-17 16:02:38 +00001074 ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001075 const ResTable& res(theme->getResTable());
1076
1077 Res_value value;
1078 // XXX value could be different in different configs!
1079 uint32_t typeSpecFlags = 0;
1080 ssize_t block = theme->getAttribute(ident, &value, &typeSpecFlags);
1081 uint32_t ref = 0;
1082 if (resolve) {
1083 block = res.resolveReference(&value, block, &ref, &typeSpecFlags);
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001084 if (kThrowOnBadId) {
1085 if (block == BAD_INDEX) {
1086 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
1087 return 0;
1088 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001089 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001090 }
1091 return block >= 0 ? copyValue(env, outValue, &res, value, ref, block, typeSpecFlags) : block;
1092}
1093
Alan Viverettec1d52792015-05-05 09:49:03 -07001094static jint android_content_AssetManager_getThemeChangingConfigurations(JNIEnv* env, jobject clazz,
1095 jlong themeHandle)
1096{
1097 ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeHandle);
1098 return theme->getChangingConfigurations();
1099}
1100
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001101static void android_content_AssetManager_dumpTheme(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +00001102 jlong themeHandle, jint pri,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001103 jstring tag, jstring prefix)
1104{
Ashok Bhat896043d2014-01-17 16:02:38 +00001105 ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001106 const ResTable& res(theme->getResTable());
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001107 (void)res;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001108
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001109 // XXX Need to use params.
1110 theme->dumpToLog();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001111}
1112
Alan Viverette52b999f2014-03-24 18:00:26 -07001113static jboolean android_content_AssetManager_resolveAttrs(JNIEnv* env, jobject clazz,
1114 jlong themeToken,
1115 jint defStyleAttr,
1116 jint defStyleRes,
1117 jintArray inValues,
1118 jintArray attrs,
1119 jintArray outValues,
1120 jintArray outIndices)
1121{
1122 if (themeToken == 0) {
1123 jniThrowNullPointerException(env, "theme token");
1124 return JNI_FALSE;
1125 }
1126 if (attrs == NULL) {
1127 jniThrowNullPointerException(env, "attrs");
1128 return JNI_FALSE;
1129 }
1130 if (outValues == NULL) {
1131 jniThrowNullPointerException(env, "out values");
1132 return JNI_FALSE;
1133 }
1134
Alan Viverette52b999f2014-03-24 18:00:26 -07001135 const jsize NI = env->GetArrayLength(attrs);
1136 const jsize NV = env->GetArrayLength(outValues);
1137 if (NV < (NI*STYLE_NUM_ENTRIES)) {
1138 jniThrowException(env, "java/lang/IndexOutOfBoundsException", "out values too small");
1139 return JNI_FALSE;
1140 }
1141
1142 jint* src = (jint*)env->GetPrimitiveArrayCritical(attrs, 0);
1143 if (src == NULL) {
1144 return JNI_FALSE;
1145 }
1146
1147 jint* srcValues = (jint*)env->GetPrimitiveArrayCritical(inValues, 0);
1148 const jsize NSV = srcValues == NULL ? 0 : env->GetArrayLength(inValues);
1149
1150 jint* baseDest = (jint*)env->GetPrimitiveArrayCritical(outValues, 0);
Adam Lesinski4452e132016-10-12 07:47:28 -07001151 if (baseDest == NULL) {
Alan Viverette52b999f2014-03-24 18:00:26 -07001152 env->ReleasePrimitiveArrayCritical(attrs, src, 0);
1153 return JNI_FALSE;
1154 }
1155
1156 jint* indices = NULL;
Alan Viverette52b999f2014-03-24 18:00:26 -07001157 if (outIndices != NULL) {
1158 if (env->GetArrayLength(outIndices) > NI) {
1159 indices = (jint*)env->GetPrimitiveArrayCritical(outIndices, 0);
1160 }
1161 }
1162
Adam Lesinski4452e132016-10-12 07:47:28 -07001163 ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeToken);
Adam Lesinski7a37b742016-10-12 14:05:55 -07001164 bool result = ResolveAttrs(theme, defStyleAttr, defStyleRes,
Adam Lesinski4452e132016-10-12 07:47:28 -07001165 (uint32_t*) srcValues, NSV,
1166 (uint32_t*) src, NI,
1167 (uint32_t*) baseDest,
1168 (uint32_t*) indices);
Alan Viverette52b999f2014-03-24 18:00:26 -07001169
1170 if (indices != NULL) {
Alan Viverette52b999f2014-03-24 18:00:26 -07001171 env->ReleasePrimitiveArrayCritical(outIndices, indices, 0);
1172 }
1173 env->ReleasePrimitiveArrayCritical(outValues, baseDest, 0);
1174 env->ReleasePrimitiveArrayCritical(inValues, srcValues, 0);
1175 env->ReleasePrimitiveArrayCritical(attrs, src, 0);
Adam Lesinski4452e132016-10-12 07:47:28 -07001176 return result ? JNI_TRUE : JNI_FALSE;
Alan Viverette52b999f2014-03-24 18:00:26 -07001177}
1178
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001179static jboolean android_content_AssetManager_applyStyle(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +00001180 jlong themeToken,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001181 jint defStyleAttr,
1182 jint defStyleRes,
Ashok Bhat896043d2014-01-17 16:02:38 +00001183 jlong xmlParserToken,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001184 jintArray attrs,
1185 jintArray outValues,
1186 jintArray outIndices)
1187{
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001188 if (themeToken == 0) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001189 jniThrowNullPointerException(env, "theme token");
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001190 return JNI_FALSE;
1191 }
1192 if (attrs == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001193 jniThrowNullPointerException(env, "attrs");
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001194 return JNI_FALSE;
1195 }
1196 if (outValues == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001197 jniThrowNullPointerException(env, "out values");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001198 return JNI_FALSE;
1199 }
1200
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001201 const jsize NI = env->GetArrayLength(attrs);
1202 const jsize NV = env->GetArrayLength(outValues);
1203 if (NV < (NI*STYLE_NUM_ENTRIES)) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001204 jniThrowException(env, "java/lang/IndexOutOfBoundsException", "out values too small");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001205 return JNI_FALSE;
1206 }
1207
1208 jint* src = (jint*)env->GetPrimitiveArrayCritical(attrs, 0);
1209 if (src == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001210 return JNI_FALSE;
1211 }
1212
1213 jint* baseDest = (jint*)env->GetPrimitiveArrayCritical(outValues, 0);
Adam Lesinski4452e132016-10-12 07:47:28 -07001214 if (baseDest == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001215 env->ReleasePrimitiveArrayCritical(attrs, src, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001216 return JNI_FALSE;
1217 }
1218
1219 jint* indices = NULL;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001220 if (outIndices != NULL) {
1221 if (env->GetArrayLength(outIndices) > NI) {
1222 indices = (jint*)env->GetPrimitiveArrayCritical(outIndices, 0);
1223 }
1224 }
1225
Adam Lesinski4452e132016-10-12 07:47:28 -07001226 ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeToken);
1227 ResXMLParser* xmlParser = reinterpret_cast<ResXMLParser*>(xmlParserToken);
Adam Lesinski7a37b742016-10-12 14:05:55 -07001228 bool result = ApplyStyle(theme, xmlParser,
Adam Lesinski4452e132016-10-12 07:47:28 -07001229 defStyleAttr, defStyleRes,
1230 (uint32_t*) src, NI,
1231 (uint32_t*) baseDest,
1232 (uint32_t*) indices);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001233
1234 if (indices != NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001235 env->ReleasePrimitiveArrayCritical(outIndices, indices, 0);
1236 }
1237 env->ReleasePrimitiveArrayCritical(outValues, baseDest, 0);
1238 env->ReleasePrimitiveArrayCritical(attrs, src, 0);
Adam Lesinski4452e132016-10-12 07:47:28 -07001239 return result ? JNI_TRUE : JNI_FALSE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001240}
1241
1242static jboolean android_content_AssetManager_retrieveAttributes(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +00001243 jlong xmlParserToken,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001244 jintArray attrs,
1245 jintArray outValues,
1246 jintArray outIndices)
1247{
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001248 if (xmlParserToken == 0) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001249 jniThrowNullPointerException(env, "xmlParserToken");
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001250 return JNI_FALSE;
1251 }
1252 if (attrs == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001253 jniThrowNullPointerException(env, "attrs");
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001254 return JNI_FALSE;
1255 }
1256 if (outValues == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001257 jniThrowNullPointerException(env, "out values");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001258 return JNI_FALSE;
1259 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001260
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001261 AssetManager* am = assetManagerForJavaObject(env, clazz);
1262 if (am == NULL) {
1263 return JNI_FALSE;
1264 }
1265 const ResTable& res(am->getResources());
1266 ResXMLParser* xmlParser = (ResXMLParser*)xmlParserToken;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001267
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001268 const jsize NI = env->GetArrayLength(attrs);
1269 const jsize NV = env->GetArrayLength(outValues);
1270 if (NV < (NI*STYLE_NUM_ENTRIES)) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001271 jniThrowException(env, "java/lang/IndexOutOfBoundsException", "out values too small");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001272 return JNI_FALSE;
1273 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001274
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001275 jint* src = (jint*)env->GetPrimitiveArrayCritical(attrs, 0);
1276 if (src == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001277 return JNI_FALSE;
1278 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001279
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001280 jint* baseDest = (jint*)env->GetPrimitiveArrayCritical(outValues, 0);
Adam Lesinski4452e132016-10-12 07:47:28 -07001281 if (baseDest == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001282 env->ReleasePrimitiveArrayCritical(attrs, src, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001283 return JNI_FALSE;
1284 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001285
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001286 jint* indices = NULL;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001287 if (outIndices != NULL) {
1288 if (env->GetArrayLength(outIndices) > NI) {
1289 indices = (jint*)env->GetPrimitiveArrayCritical(outIndices, 0);
1290 }
1291 }
1292
Adam Lesinski7a37b742016-10-12 14:05:55 -07001293 bool result = RetrieveAttributes(&res, xmlParser,
Adam Lesinski4452e132016-10-12 07:47:28 -07001294 (uint32_t*) src, NI,
1295 (uint32_t*) baseDest,
1296 (uint32_t*) indices);
Elliott Hughes69a017b2011-04-08 14:10:28 -07001297
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001298 if (indices != NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001299 env->ReleasePrimitiveArrayCritical(outIndices, indices, 0);
1300 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001301 env->ReleasePrimitiveArrayCritical(outValues, baseDest, 0);
1302 env->ReleasePrimitiveArrayCritical(attrs, src, 0);
Adam Lesinski4452e132016-10-12 07:47:28 -07001303 return result ? JNI_TRUE : JNI_FALSE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001304}
1305
1306static jint android_content_AssetManager_getArraySize(JNIEnv* env, jobject clazz,
1307 jint id)
1308{
1309 AssetManager* am = assetManagerForJavaObject(env, clazz);
1310 if (am == NULL) {
Olivier Baillyd7c86722010-11-18 14:43:36 -08001311 return 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001312 }
1313 const ResTable& res(am->getResources());
Elliott Hughes69a017b2011-04-08 14:10:28 -07001314
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001315 res.lock();
1316 const ResTable::bag_entry* defStyleEnt = NULL;
1317 ssize_t bagOff = res.getBagLocked(id, &defStyleEnt);
1318 res.unlock();
Elliott Hughes69a017b2011-04-08 14:10:28 -07001319
Ashok Bhat896043d2014-01-17 16:02:38 +00001320 return static_cast<jint>(bagOff);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001321}
1322
1323static jint android_content_AssetManager_retrieveArray(JNIEnv* env, jobject clazz,
1324 jint id,
1325 jintArray outValues)
1326{
1327 if (outValues == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001328 jniThrowNullPointerException(env, "out values");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001329 return JNI_FALSE;
1330 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001331
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001332 AssetManager* am = assetManagerForJavaObject(env, clazz);
1333 if (am == NULL) {
1334 return JNI_FALSE;
1335 }
1336 const ResTable& res(am->getResources());
Dianne Hackborn0d221012009-07-29 15:41:19 -07001337 ResTable_config config;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001338 Res_value value;
1339 ssize_t block;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001340
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001341 const jsize NV = env->GetArrayLength(outValues);
Elliott Hughes69a017b2011-04-08 14:10:28 -07001342
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001343 jint* baseDest = (jint*)env->GetPrimitiveArrayCritical(outValues, 0);
1344 jint* dest = baseDest;
1345 if (dest == NULL) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001346 jniThrowException(env, "java/lang/OutOfMemoryError", "");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001347 return JNI_FALSE;
1348 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001349
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001350 // Now lock down the resource object and start pulling stuff from it.
1351 res.lock();
Elliott Hughes69a017b2011-04-08 14:10:28 -07001352
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001353 const ResTable::bag_entry* arrayEnt = NULL;
1354 uint32_t arrayTypeSetFlags = 0;
1355 ssize_t bagOff = res.getBagLocked(id, &arrayEnt, &arrayTypeSetFlags);
1356 const ResTable::bag_entry* endArrayEnt = arrayEnt +
1357 (bagOff >= 0 ? bagOff : 0);
Elliott Hughes69a017b2011-04-08 14:10:28 -07001358
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001359 int i = 0;
1360 uint32_t typeSetFlags;
1361 while (i < NV && arrayEnt < endArrayEnt) {
1362 block = arrayEnt->stringBlock;
1363 typeSetFlags = arrayTypeSetFlags;
Dianne Hackborn0d221012009-07-29 15:41:19 -07001364 config.density = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001365 value = arrayEnt->map.value;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001366
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001367 uint32_t resid = 0;
1368 if (value.dataType != Res_value::TYPE_NULL) {
1369 // Take care of resolving the found resource to its final value.
1370 //printf("Resolving attribute reference\n");
Dianne Hackborn0d221012009-07-29 15:41:19 -07001371 ssize_t newBlock = res.resolveReference(&value, block, &resid,
1372 &typeSetFlags, &config);
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001373 if (kThrowOnBadId) {
1374 if (newBlock == BAD_INDEX) {
1375 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
1376 return JNI_FALSE;
1377 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001378 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001379 if (newBlock >= 0) block = newBlock;
1380 }
1381
1382 // Deal with the special @null value -- it turns back to TYPE_NULL.
1383 if (value.dataType == Res_value::TYPE_REFERENCE && value.data == 0) {
1384 value.dataType = Res_value::TYPE_NULL;
Alan Viverettef2969402014-10-29 17:09:36 -07001385 value.data = Res_value::DATA_NULL_UNDEFINED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001386 }
1387
1388 //printf("Attribute 0x%08x: final type=0x%x, data=0x%08x\n", curIdent, value.dataType, value.data);
1389
1390 // Write the final value back to Java.
1391 dest[STYLE_TYPE] = value.dataType;
1392 dest[STYLE_DATA] = value.data;
Ashok Bhat896043d2014-01-17 16:02:38 +00001393 dest[STYLE_ASSET_COOKIE] = reinterpret_cast<jint>(res.getTableCookie(block));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001394 dest[STYLE_RESOURCE_ID] = resid;
1395 dest[STYLE_CHANGING_CONFIGURATIONS] = typeSetFlags;
Dianne Hackborn0d221012009-07-29 15:41:19 -07001396 dest[STYLE_DENSITY] = config.density;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001397 dest += STYLE_NUM_ENTRIES;
1398 i+= STYLE_NUM_ENTRIES;
1399 arrayEnt++;
1400 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001401
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001402 i /= STYLE_NUM_ENTRIES;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001403
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001404 res.unlock();
Elliott Hughes69a017b2011-04-08 14:10:28 -07001405
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001406 env->ReleasePrimitiveArrayCritical(outValues, baseDest, 0);
Elliott Hughes69a017b2011-04-08 14:10:28 -07001407
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001408 return i;
1409}
1410
Ashok Bhat896043d2014-01-17 16:02:38 +00001411static jlong android_content_AssetManager_openXmlAssetNative(JNIEnv* env, jobject clazz,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001412 jint cookie,
1413 jstring fileName)
1414{
1415 AssetManager* am = assetManagerForJavaObject(env, clazz);
1416 if (am == NULL) {
1417 return 0;
1418 }
1419
Steve Block71f2cf12011-10-20 11:56:00 +01001420 ALOGV("openXmlAsset in %p (Java object %p)\n", am, clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001421
Elliott Hughes69a017b2011-04-08 14:10:28 -07001422 ScopedUtfChars fileName8(env, fileName);
1423 if (fileName8.c_str() == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001424 return 0;
1425 }
1426
Adam Lesinskide898ff2014-01-29 18:20:45 -08001427 int32_t assetCookie = static_cast<int32_t>(cookie);
1428 Asset* a = assetCookie
1429 ? am->openNonAsset(assetCookie, fileName8.c_str(), Asset::ACCESS_BUFFER)
1430 : am->openNonAsset(fileName8.c_str(), Asset::ACCESS_BUFFER, &assetCookie);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001431
1432 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001433 jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001434 return 0;
1435 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001436
Adam Lesinskide898ff2014-01-29 18:20:45 -08001437 const DynamicRefTable* dynamicRefTable =
1438 am->getResources().getDynamicRefTableForCookie(assetCookie);
1439 ResXMLTree* block = new ResXMLTree(dynamicRefTable);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001440 status_t err = block->setTo(a->getBuffer(true), a->getLength(), true);
1441 a->close();
1442 delete a;
1443
1444 if (err != NO_ERROR) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001445 jniThrowException(env, "java/io/FileNotFoundException", "Corrupt XML binary file");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001446 return 0;
1447 }
1448
Ashok Bhat896043d2014-01-17 16:02:38 +00001449 return reinterpret_cast<jlong>(block);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001450}
1451
1452static jintArray android_content_AssetManager_getArrayStringInfo(JNIEnv* env, jobject clazz,
1453 jint arrayResId)
1454{
1455 AssetManager* am = assetManagerForJavaObject(env, clazz);
1456 if (am == NULL) {
1457 return NULL;
1458 }
1459 const ResTable& res(am->getResources());
1460
1461 const ResTable::bag_entry* startOfBag;
1462 const ssize_t N = res.lockBag(arrayResId, &startOfBag);
1463 if (N < 0) {
1464 return NULL;
1465 }
1466
1467 jintArray array = env->NewIntArray(N * 2);
1468 if (array == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001469 res.unlockBag(startOfBag);
1470 return NULL;
1471 }
1472
1473 Res_value value;
1474 const ResTable::bag_entry* bag = startOfBag;
1475 for (size_t i = 0, j = 0; ((ssize_t)i)<N; i++, bag++) {
1476 jint stringIndex = -1;
1477 jint stringBlock = 0;
1478 value = bag->map.value;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001479
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001480 // Take care of resolving the found resource to its final value.
1481 stringBlock = res.resolveReference(&value, bag->stringBlock, NULL);
1482 if (value.dataType == Res_value::TYPE_STRING) {
1483 stringIndex = value.data;
1484 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001485
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001486 if (kThrowOnBadId) {
1487 if (stringBlock == BAD_INDEX) {
1488 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
1489 return array;
1490 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001491 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001492
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001493 //todo: It might be faster to allocate a C array to contain
1494 // the blocknums and indices, put them in there and then
1495 // do just one SetIntArrayRegion()
1496 env->SetIntArrayRegion(array, j, 1, &stringBlock);
1497 env->SetIntArrayRegion(array, j + 1, 1, &stringIndex);
1498 j = j + 2;
1499 }
1500 res.unlockBag(startOfBag);
1501 return array;
1502}
1503
1504static jobjectArray android_content_AssetManager_getArrayStringResource(JNIEnv* env, jobject clazz,
1505 jint arrayResId)
1506{
1507 AssetManager* am = assetManagerForJavaObject(env, clazz);
1508 if (am == NULL) {
1509 return NULL;
1510 }
1511 const ResTable& res(am->getResources());
1512
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001513 const ResTable::bag_entry* startOfBag;
1514 const ssize_t N = res.lockBag(arrayResId, &startOfBag);
1515 if (N < 0) {
1516 return NULL;
1517 }
1518
Vladimir Markoaa5fe3d2013-06-17 12:46:22 +01001519 jobjectArray array = env->NewObjectArray(N, g_stringClass, NULL);
Kenny Root485dd212010-05-06 16:06:48 -07001520 if (env->ExceptionCheck()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001521 res.unlockBag(startOfBag);
1522 return NULL;
1523 }
1524
1525 Res_value value;
1526 const ResTable::bag_entry* bag = startOfBag;
1527 size_t strLen = 0;
1528 for (size_t i=0; ((ssize_t)i)<N; i++, bag++) {
1529 value = bag->map.value;
1530 jstring str = NULL;
Kenny Root780d2a12010-02-22 22:36:26 -08001531
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001532 // Take care of resolving the found resource to its final value.
1533 ssize_t block = res.resolveReference(&value, bag->stringBlock, NULL);
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001534 if (kThrowOnBadId) {
1535 if (block == BAD_INDEX) {
1536 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
1537 return array;
1538 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001539 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001540 if (value.dataType == Res_value::TYPE_STRING) {
Kenny Root780d2a12010-02-22 22:36:26 -08001541 const ResStringPool* pool = res.getTableStringBlock(block);
1542 const char* str8 = pool->string8At(value.data, &strLen);
1543 if (str8 != NULL) {
1544 str = env->NewStringUTF(str8);
1545 } else {
1546 const char16_t* str16 = pool->stringAt(value.data, &strLen);
Dan Albert66987492014-11-20 11:41:21 -08001547 str = env->NewString(reinterpret_cast<const jchar*>(str16),
1548 strLen);
Kenny Root485dd212010-05-06 16:06:48 -07001549 }
1550
1551 // If one of our NewString{UTF} calls failed due to memory, an
1552 // exception will be pending.
1553 if (env->ExceptionCheck()) {
1554 res.unlockBag(startOfBag);
1555 return NULL;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001556 }
Kenny Root780d2a12010-02-22 22:36:26 -08001557
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001558 env->SetObjectArrayElement(array, i, str);
Kenny Root485dd212010-05-06 16:06:48 -07001559
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001560 // str is not NULL at that point, otherwise ExceptionCheck would have been true.
1561 // If we have a large amount of strings in our array, we might
1562 // overflow the local reference table of the VM.
Kenny Root485dd212010-05-06 16:06:48 -07001563 env->DeleteLocalRef(str);
1564 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001565 }
1566 res.unlockBag(startOfBag);
1567 return array;
1568}
1569
1570static jintArray android_content_AssetManager_getArrayIntResource(JNIEnv* env, jobject clazz,
1571 jint arrayResId)
1572{
1573 AssetManager* am = assetManagerForJavaObject(env, clazz);
1574 if (am == NULL) {
1575 return NULL;
1576 }
1577 const ResTable& res(am->getResources());
1578
1579 const ResTable::bag_entry* startOfBag;
1580 const ssize_t N = res.lockBag(arrayResId, &startOfBag);
1581 if (N < 0) {
1582 return NULL;
1583 }
1584
1585 jintArray array = env->NewIntArray(N);
1586 if (array == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001587 res.unlockBag(startOfBag);
1588 return NULL;
1589 }
1590
1591 Res_value value;
1592 const ResTable::bag_entry* bag = startOfBag;
1593 for (size_t i=0; ((ssize_t)i)<N; i++, bag++) {
1594 value = bag->map.value;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001595
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001596 // Take care of resolving the found resource to its final value.
1597 ssize_t block = res.resolveReference(&value, bag->stringBlock, NULL);
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001598 if (kThrowOnBadId) {
1599 if (block == BAD_INDEX) {
1600 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
1601 return array;
1602 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001603 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001604 if (value.dataType >= Res_value::TYPE_FIRST_INT
1605 && value.dataType <= Res_value::TYPE_LAST_INT) {
1606 int intVal = value.data;
1607 env->SetIntArrayRegion(array, i, 1, &intVal);
1608 }
1609 }
1610 res.unlockBag(startOfBag);
1611 return array;
1612}
1613
Jon Miranda042ad632014-09-03 17:57:35 -07001614static jintArray android_content_AssetManager_getStyleAttributes(JNIEnv* env, jobject clazz,
1615 jint styleId)
1616{
1617 AssetManager* am = assetManagerForJavaObject(env, clazz);
1618 if (am == NULL) {
1619 return NULL;
1620 }
1621 const ResTable& res(am->getResources());
1622
1623 const ResTable::bag_entry* startOfBag;
1624 const ssize_t N = res.lockBag(styleId, &startOfBag);
1625 if (N < 0) {
1626 return NULL;
1627 }
1628
1629 jintArray array = env->NewIntArray(N);
1630 if (array == NULL) {
1631 res.unlockBag(startOfBag);
1632 return NULL;
1633 }
1634
Jon Miranda042ad632014-09-03 17:57:35 -07001635 const ResTable::bag_entry* bag = startOfBag;
1636 for (size_t i=0; ((ssize_t)i)<N; i++, bag++) {
1637 int resourceId = bag->map.name.ident;
1638 env->SetIntArrayRegion(array, i, 1, &resourceId);
1639 }
1640 res.unlockBag(startOfBag);
1641 return array;
1642}
1643
Mårten Kongstad48d22322014-01-31 14:43:27 +01001644static void android_content_AssetManager_init(JNIEnv* env, jobject clazz, jboolean isSystem)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001645{
Mårten Kongstad48d22322014-01-31 14:43:27 +01001646 if (isSystem) {
1647 verifySystemIdmaps();
1648 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001649 AssetManager* am = new AssetManager();
1650 if (am == NULL) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001651 jniThrowException(env, "java/lang/OutOfMemoryError", "");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001652 return;
1653 }
1654
1655 am->addDefaultAssets();
1656
Steve Block71f2cf12011-10-20 11:56:00 +01001657 ALOGV("Created AssetManager %p for Java object %p\n", am, clazz);
Ashok Bhat896043d2014-01-17 16:02:38 +00001658 env->SetLongField(clazz, gAssetManagerOffsets.mObject, reinterpret_cast<jlong>(am));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001659}
1660
1661static void android_content_AssetManager_destroy(JNIEnv* env, jobject clazz)
1662{
1663 AssetManager* am = (AssetManager*)
Ashok Bhat896043d2014-01-17 16:02:38 +00001664 (env->GetLongField(clazz, gAssetManagerOffsets.mObject));
Steve Block71f2cf12011-10-20 11:56:00 +01001665 ALOGV("Destroying AssetManager %p for Java object %p\n", am, clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001666 if (am != NULL) {
1667 delete am;
Ashok Bhat896043d2014-01-17 16:02:38 +00001668 env->SetLongField(clazz, gAssetManagerOffsets.mObject, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001669 }
1670}
1671
1672static jint android_content_AssetManager_getGlobalAssetCount(JNIEnv* env, jobject clazz)
1673{
1674 return Asset::getGlobalCount();
1675}
1676
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07001677static jobject android_content_AssetManager_getAssetAllocations(JNIEnv* env, jobject clazz)
1678{
1679 String8 alloc = Asset::getAssetAllocations();
1680 if (alloc.length() <= 0) {
1681 return NULL;
1682 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001683
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07001684 jstring str = env->NewStringUTF(alloc.string());
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07001685 return str;
1686}
1687
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001688static jint android_content_AssetManager_getGlobalAssetManagerCount(JNIEnv* env, jobject clazz)
1689{
1690 return AssetManager::getGlobalCount();
1691}
1692
1693// ----------------------------------------------------------------------------
1694
1695/*
1696 * JNI registration.
1697 */
Daniel Micay76f6a862015-09-19 17:31:01 -04001698static const JNINativeMethod gAssetManagerMethods[] = {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001699 /* name, signature, funcPtr */
1700
1701 // Basic asset stuff.
Ashok Bhat896043d2014-01-17 16:02:38 +00001702 { "openAsset", "(Ljava/lang/String;I)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001703 (void*) android_content_AssetManager_openAsset },
1704 { "openAssetFd", "(Ljava/lang/String;[J)Landroid/os/ParcelFileDescriptor;",
1705 (void*) android_content_AssetManager_openAssetFd },
Ashok Bhat896043d2014-01-17 16:02:38 +00001706 { "openNonAssetNative", "(ILjava/lang/String;I)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001707 (void*) android_content_AssetManager_openNonAssetNative },
1708 { "openNonAssetFdNative", "(ILjava/lang/String;[J)Landroid/os/ParcelFileDescriptor;",
1709 (void*) android_content_AssetManager_openNonAssetFdNative },
1710 { "list", "(Ljava/lang/String;)[Ljava/lang/String;",
1711 (void*) android_content_AssetManager_list },
Ashok Bhat896043d2014-01-17 16:02:38 +00001712 { "destroyAsset", "(J)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001713 (void*) android_content_AssetManager_destroyAsset },
Ashok Bhat896043d2014-01-17 16:02:38 +00001714 { "readAssetChar", "(J)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001715 (void*) android_content_AssetManager_readAssetChar },
Ashok Bhat896043d2014-01-17 16:02:38 +00001716 { "readAsset", "(J[BII)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001717 (void*) android_content_AssetManager_readAsset },
Ashok Bhat896043d2014-01-17 16:02:38 +00001718 { "seekAsset", "(JJI)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001719 (void*) android_content_AssetManager_seekAsset },
John Reck32995222016-10-07 11:02:20 -07001720 // @FastNative
1721 { "getAssetLength", "(J)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001722 (void*) android_content_AssetManager_getAssetLength },
John Reck32995222016-10-07 11:02:20 -07001723 // @FastNative
1724 { "getAssetRemainingLength", "(J)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001725 (void*) android_content_AssetManager_getAssetRemainingLength },
Tao Baia6d7e3f2015-09-01 18:49:54 -07001726 { "addAssetPathNative", "(Ljava/lang/String;Z)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001727 (void*) android_content_AssetManager_addAssetPath },
Mårten Kongstad30113132014-11-07 10:52:17 +01001728 { "addOverlayPathNative", "(Ljava/lang/String;)I",
Mårten Kongstad48d22322014-01-31 14:43:27 +01001729 (void*) android_content_AssetManager_addOverlayPath },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001730 { "isUpToDate", "()Z",
1731 (void*) android_content_AssetManager_isUpToDate },
1732
1733 // Resources.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001734 { "getLocales", "()[Ljava/lang/String;",
1735 (void*) android_content_AssetManager_getLocales },
Roozbeh Pournader1c686f22015-12-18 14:22:14 -08001736 { "getNonSystemLocales", "()[Ljava/lang/String;",
1737 (void*) android_content_AssetManager_getNonSystemLocales },
Filip Gruszczynski23493322015-07-29 17:02:59 -07001738 { "getSizeConfigurations", "()[Landroid/content/res/Configuration;",
1739 (void*) android_content_AssetManager_getSizeConfigurations },
John Reck32995222016-10-07 11:02:20 -07001740 // @FastNative
1741 { "setConfiguration", "(IILjava/lang/String;IIIIIIIIIIIIII)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001742 (void*) android_content_AssetManager_setConfiguration },
John Reck32995222016-10-07 11:02:20 -07001743 // @FastNative
1744 { "getResourceIdentifier","(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001745 (void*) android_content_AssetManager_getResourceIdentifier },
John Reck32995222016-10-07 11:02:20 -07001746 // @FastNative
1747 { "getResourceName","(I)Ljava/lang/String;",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001748 (void*) android_content_AssetManager_getResourceName },
John Reck32995222016-10-07 11:02:20 -07001749 // @FastNative
1750 { "getResourcePackageName","(I)Ljava/lang/String;",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001751 (void*) android_content_AssetManager_getResourcePackageName },
John Reck32995222016-10-07 11:02:20 -07001752 // @FastNative
1753 { "getResourceTypeName","(I)Ljava/lang/String;",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001754 (void*) android_content_AssetManager_getResourceTypeName },
John Reck32995222016-10-07 11:02:20 -07001755 // @FastNative
1756 { "getResourceEntryName","(I)Ljava/lang/String;",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001757 (void*) android_content_AssetManager_getResourceEntryName },
John Reck32995222016-10-07 11:02:20 -07001758 // @FastNative
1759 { "loadResourceValue","(ISLandroid/util/TypedValue;Z)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001760 (void*) android_content_AssetManager_loadResourceValue },
John Reck32995222016-10-07 11:02:20 -07001761 // @FastNative
1762 { "loadResourceBagValue","(IILandroid/util/TypedValue;Z)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001763 (void*) android_content_AssetManager_loadResourceBagValue },
John Reck32995222016-10-07 11:02:20 -07001764 // @FastNative
1765 { "getStringBlockCount","()I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001766 (void*) android_content_AssetManager_getStringBlockCount },
John Reck32995222016-10-07 11:02:20 -07001767 // @FastNative
1768 { "getNativeStringBlock","(I)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001769 (void*) android_content_AssetManager_getNativeStringBlock },
1770 { "getCookieName","(I)Ljava/lang/String;",
1771 (void*) android_content_AssetManager_getCookieName },
Adam Lesinskide898ff2014-01-29 18:20:45 -08001772 { "getAssignedPackageIdentifiers","()Landroid/util/SparseArray;",
1773 (void*) android_content_AssetManager_getAssignedPackageIdentifiers },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001774
1775 // Themes.
Ashok Bhat896043d2014-01-17 16:02:38 +00001776 { "newTheme", "()J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001777 (void*) android_content_AssetManager_newTheme },
Ashok Bhat896043d2014-01-17 16:02:38 +00001778 { "deleteTheme", "(J)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001779 (void*) android_content_AssetManager_deleteTheme },
Ashok Bhat896043d2014-01-17 16:02:38 +00001780 { "applyThemeStyle", "(JIZ)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001781 (void*) android_content_AssetManager_applyThemeStyle },
Ashok Bhat896043d2014-01-17 16:02:38 +00001782 { "copyTheme", "(JJ)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001783 (void*) android_content_AssetManager_copyTheme },
Alan Viverettee54d2452015-05-06 10:41:43 -07001784 { "clearTheme", "(J)V",
1785 (void*) android_content_AssetManager_clearTheme },
John Reck32995222016-10-07 11:02:20 -07001786 // @FastNative
1787 { "loadThemeAttributeValue", "(JILandroid/util/TypedValue;Z)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001788 (void*) android_content_AssetManager_loadThemeAttributeValue },
John Reck32995222016-10-07 11:02:20 -07001789 // @FastNative
1790 { "getThemeChangingConfigurations", "(J)I",
Alan Viverettec1d52792015-05-05 09:49:03 -07001791 (void*) android_content_AssetManager_getThemeChangingConfigurations },
Ashok Bhat896043d2014-01-17 16:02:38 +00001792 { "dumpTheme", "(JILjava/lang/String;Ljava/lang/String;)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001793 (void*) android_content_AssetManager_dumpTheme },
John Reck32995222016-10-07 11:02:20 -07001794 // @FastNative
1795 { "applyStyle","(JIIJ[I[I[I)Z",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001796 (void*) android_content_AssetManager_applyStyle },
John Reck32995222016-10-07 11:02:20 -07001797 // @FastNative
1798 { "resolveAttrs","(JII[I[I[I[I)Z",
Alan Viverette607bd842014-09-12 12:36:35 -07001799 (void*) android_content_AssetManager_resolveAttrs },
John Reck32995222016-10-07 11:02:20 -07001800 // @FastNative
1801 { "retrieveAttributes","(J[I[I[I)Z",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001802 (void*) android_content_AssetManager_retrieveAttributes },
John Reck32995222016-10-07 11:02:20 -07001803 // @FastNative
1804 { "getArraySize","(I)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001805 (void*) android_content_AssetManager_getArraySize },
John Reck32995222016-10-07 11:02:20 -07001806 // @FastNative
1807 { "retrieveArray","(I[I)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001808 (void*) android_content_AssetManager_retrieveArray },
1809
1810 // XML files.
Ashok Bhat896043d2014-01-17 16:02:38 +00001811 { "openXmlAssetNative", "(ILjava/lang/String;)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001812 (void*) android_content_AssetManager_openXmlAssetNative },
1813
1814 // Arrays.
1815 { "getArrayStringResource","(I)[Ljava/lang/String;",
1816 (void*) android_content_AssetManager_getArrayStringResource },
John Reck32995222016-10-07 11:02:20 -07001817 // @FastNative
1818 { "getArrayStringInfo","(I)[I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001819 (void*) android_content_AssetManager_getArrayStringInfo },
John Reck32995222016-10-07 11:02:20 -07001820 // @FastNative
1821 { "getArrayIntResource","(I)[I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001822 (void*) android_content_AssetManager_getArrayIntResource },
John Reck32995222016-10-07 11:02:20 -07001823 // @FastNative
1824 { "getStyleAttributes","(I)[I",
Jon Miranda042ad632014-09-03 17:57:35 -07001825 (void*) android_content_AssetManager_getStyleAttributes },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001826
1827 // Bookkeeping.
Mårten Kongstad48d22322014-01-31 14:43:27 +01001828 { "init", "(Z)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001829 (void*) android_content_AssetManager_init },
1830 { "destroy", "()V",
1831 (void*) android_content_AssetManager_destroy },
1832 { "getGlobalAssetCount", "()I",
1833 (void*) android_content_AssetManager_getGlobalAssetCount },
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07001834 { "getAssetAllocations", "()Ljava/lang/String;",
1835 (void*) android_content_AssetManager_getAssetAllocations },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001836 { "getGlobalAssetManagerCount", "()I",
Andreas Gampe32812612014-11-11 00:16:00 -08001837 (void*) android_content_AssetManager_getGlobalAssetManagerCount },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001838};
1839
1840int register_android_content_AssetManager(JNIEnv* env)
1841{
Andreas Gampe987f79f2014-11-18 17:29:46 -08001842 jclass typedValue = FindClassOrDie(env, "android/util/TypedValue");
1843 gTypedValueOffsets.mType = GetFieldIDOrDie(env, typedValue, "type", "I");
1844 gTypedValueOffsets.mData = GetFieldIDOrDie(env, typedValue, "data", "I");
1845 gTypedValueOffsets.mString = GetFieldIDOrDie(env, typedValue, "string",
1846 "Ljava/lang/CharSequence;");
1847 gTypedValueOffsets.mAssetCookie = GetFieldIDOrDie(env, typedValue, "assetCookie", "I");
1848 gTypedValueOffsets.mResourceId = GetFieldIDOrDie(env, typedValue, "resourceId", "I");
1849 gTypedValueOffsets.mChangingConfigurations = GetFieldIDOrDie(env, typedValue,
1850 "changingConfigurations", "I");
1851 gTypedValueOffsets.mDensity = GetFieldIDOrDie(env, typedValue, "density", "I");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001852
Andreas Gampe987f79f2014-11-18 17:29:46 -08001853 jclass assetFd = FindClassOrDie(env, "android/content/res/AssetFileDescriptor");
1854 gAssetFileDescriptorOffsets.mFd = GetFieldIDOrDie(env, assetFd, "mFd",
1855 "Landroid/os/ParcelFileDescriptor;");
1856 gAssetFileDescriptorOffsets.mStartOffset = GetFieldIDOrDie(env, assetFd, "mStartOffset", "J");
1857 gAssetFileDescriptorOffsets.mLength = GetFieldIDOrDie(env, assetFd, "mLength", "J");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001858
Andreas Gampe987f79f2014-11-18 17:29:46 -08001859 jclass assetManager = FindClassOrDie(env, "android/content/res/AssetManager");
1860 gAssetManagerOffsets.mObject = GetFieldIDOrDie(env, assetManager, "mObject", "J");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001861
Andreas Gampe987f79f2014-11-18 17:29:46 -08001862 jclass stringClass = FindClassOrDie(env, "java/lang/String");
1863 g_stringClass = MakeGlobalRefOrDie(env, stringClass);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001864
Andreas Gampe987f79f2014-11-18 17:29:46 -08001865 jclass sparseArrayClass = FindClassOrDie(env, "android/util/SparseArray");
1866 gSparseArrayOffsets.classObject = MakeGlobalRefOrDie(env, sparseArrayClass);
1867 gSparseArrayOffsets.constructor = GetMethodIDOrDie(env, gSparseArrayOffsets.classObject,
1868 "<init>", "()V");
1869 gSparseArrayOffsets.put = GetMethodIDOrDie(env, gSparseArrayOffsets.classObject, "put",
1870 "(ILjava/lang/Object;)V");
Adam Lesinskide898ff2014-01-29 18:20:45 -08001871
Filip Gruszczynski23493322015-07-29 17:02:59 -07001872 jclass configurationClass = FindClassOrDie(env, "android/content/res/Configuration");
1873 gConfigurationOffsets.classObject = MakeGlobalRefOrDie(env, configurationClass);
1874 gConfigurationOffsets.constructor = GetMethodIDOrDie(env, configurationClass,
1875 "<init>", "()V");
1876 gConfigurationOffsets.mSmallestScreenWidthDpOffset = GetFieldIDOrDie(env, configurationClass,
1877 "smallestScreenWidthDp", "I");
1878 gConfigurationOffsets.mScreenWidthDpOffset = GetFieldIDOrDie(env, configurationClass,
1879 "screenWidthDp", "I");
1880 gConfigurationOffsets.mScreenHeightDpOffset = GetFieldIDOrDie(env, configurationClass,
1881 "screenHeightDp", "I");
1882
Andreas Gampe987f79f2014-11-18 17:29:46 -08001883 return RegisterMethodsOrDie(env, "android/content/res/AssetManager", gAssetManagerMethods,
1884 NELEM(gAssetManagerMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001885}
1886
1887}; // namespace android