blob: b137da3ef792b4d5c55028515b5a01b914c8a98d [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"
Steven Moreland2279b252017-07-19 09:50:45 -070040#include <nativehelper/JNIHelp.h>
41#include <nativehelper/ScopedStringChars.h>
42#include <nativehelper/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
Jaekyun Seok7de2f9c2017-03-02 12:45:10 +0900122// 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
166 // Generic idmap parameters
167 const char* argv[8];
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
178 // Directories to scan for overlays: if OVERLAY_THEME_DIR_PROPERTY is defined,
179 // use OVERLAY_DIR/<value of OVERLAY_THEME_DIR_PROPERTY> in addition to OVERLAY_DIR.
180 char subdir[PROP_VALUE_MAX];
Jason Monkcc5a7312017-03-23 11:13:22 -0400181 int len = __system_property_get(AssetManager::OVERLAY_THEME_DIR_PROPERTY, subdir);
Jaekyun Seok7de2f9c2017-03-02 12:45:10 +0900182 if (len > 0) {
183 String8 overlayPath = String8(AssetManager::OVERLAY_DIR) + "/" + subdir;
184 if (stat(overlayPath.string(), &st) == 0) {
185 argv[argc++] = overlayPath.string();
186 }
187 }
188 if (stat(AssetManager::OVERLAY_DIR, &st) == 0) {
189 argv[argc++] = AssetManager::OVERLAY_DIR;
190 }
191
192 // Finally, invoke idmap (if any overlay directory exists)
193 if (argc > 5) {
194 execv(AssetManager::IDMAP_BIN, (char* const*)argv);
195 ALOGE("failed to execv for idmap: %s", strerror(errno));
196 exit(1); // should never get here
197 } else {
198 exit(0);
199 }
200 }
201 break;
202 default: // parent
203 waitpid(pid, NULL, 0);
204 break;
205 }
206}
207
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800208// ----------------------------------------------------------------------------
209
210// this guy is exported to other jni routines
211AssetManager* assetManagerForJavaObject(JNIEnv* env, jobject obj)
212{
Ashok Bhat896043d2014-01-17 16:02:38 +0000213 jlong amHandle = env->GetLongField(obj, gAssetManagerOffsets.mObject);
214 AssetManager* am = reinterpret_cast<AssetManager*>(amHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800215 if (am != NULL) {
216 return am;
217 }
218 jniThrowException(env, "java/lang/IllegalStateException", "AssetManager has been finalized!");
219 return NULL;
220}
221
Ashok Bhat896043d2014-01-17 16:02:38 +0000222static jlong android_content_AssetManager_openAsset(JNIEnv* env, jobject clazz,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800223 jstring fileName, jint mode)
224{
225 AssetManager* am = assetManagerForJavaObject(env, clazz);
226 if (am == NULL) {
227 return 0;
228 }
229
Steve Block71f2cf12011-10-20 11:56:00 +0100230 ALOGV("openAsset in %p (Java object %p)\n", am, clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800231
Elliott Hughes69a017b2011-04-08 14:10:28 -0700232 ScopedUtfChars fileName8(env, fileName);
233 if (fileName8.c_str() == NULL) {
Ashok Bhat896043d2014-01-17 16:02:38 +0000234 jniThrowException(env, "java/lang/IllegalArgumentException", "Empty file name");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800235 return -1;
236 }
237
238 if (mode != Asset::ACCESS_UNKNOWN && mode != Asset::ACCESS_RANDOM
239 && mode != Asset::ACCESS_STREAMING && mode != Asset::ACCESS_BUFFER) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -0700240 jniThrowException(env, "java/lang/IllegalArgumentException", "Bad access mode");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800241 return -1;
242 }
243
Elliott Hughes69a017b2011-04-08 14:10:28 -0700244 Asset* a = am->open(fileName8.c_str(), (Asset::AccessMode)mode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800245
246 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700247 jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800248 return -1;
249 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800250
251 //printf("Created Asset Stream: %p\n", a);
252
Ashok Bhat896043d2014-01-17 16:02:38 +0000253 return reinterpret_cast<jlong>(a);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800254}
255
256static jobject returnParcelFileDescriptor(JNIEnv* env, Asset* a, jlongArray outOffsets)
257{
Kenny Rootddb76c42010-11-24 12:56:06 -0800258 off64_t startOffset, length;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800259 int fd = a->openFileDescriptor(&startOffset, &length);
260 delete a;
Elliott Hughes69a017b2011-04-08 14:10:28 -0700261
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800262 if (fd < 0) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -0700263 jniThrowException(env, "java/io/FileNotFoundException",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800264 "This file can not be opened as a file descriptor; it is probably compressed");
265 return NULL;
266 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700267
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800268 jlong* offsets = (jlong*)env->GetPrimitiveArrayCritical(outOffsets, 0);
269 if (offsets == NULL) {
270 close(fd);
271 return NULL;
272 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700273
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800274 offsets[0] = startOffset;
275 offsets[1] = length;
Elliott Hughes69a017b2011-04-08 14:10:28 -0700276
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800277 env->ReleasePrimitiveArrayCritical(outOffsets, offsets, 0);
Elliott Hughes69a017b2011-04-08 14:10:28 -0700278
Elliott Hughesa3804cf2011-04-11 16:50:19 -0700279 jobject fileDesc = jniCreateFileDescriptor(env, fd);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800280 if (fileDesc == NULL) {
281 close(fd);
282 return NULL;
283 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700284
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800285 return newParcelFileDescriptor(env, fileDesc);
286}
287
288static jobject android_content_AssetManager_openAssetFd(JNIEnv* env, jobject clazz,
289 jstring fileName, jlongArray outOffsets)
290{
291 AssetManager* am = assetManagerForJavaObject(env, clazz);
292 if (am == NULL) {
293 return NULL;
294 }
295
Steve Block71f2cf12011-10-20 11:56:00 +0100296 ALOGV("openAssetFd in %p (Java object %p)\n", am, clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800297
Elliott Hughes69a017b2011-04-08 14:10:28 -0700298 ScopedUtfChars fileName8(env, fileName);
299 if (fileName8.c_str() == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800300 return NULL;
301 }
302
Elliott Hughes69a017b2011-04-08 14:10:28 -0700303 Asset* a = am->open(fileName8.c_str(), Asset::ACCESS_RANDOM);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800304
305 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700306 jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800307 return NULL;
308 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800309
310 //printf("Created Asset Stream: %p\n", a);
311
312 return returnParcelFileDescriptor(env, a, outOffsets);
313}
314
Ashok Bhat896043d2014-01-17 16:02:38 +0000315static jlong android_content_AssetManager_openNonAssetNative(JNIEnv* env, jobject clazz,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800316 jint cookie,
317 jstring fileName,
318 jint mode)
319{
320 AssetManager* am = assetManagerForJavaObject(env, clazz);
321 if (am == NULL) {
322 return 0;
323 }
324
Steve Block71f2cf12011-10-20 11:56:00 +0100325 ALOGV("openNonAssetNative in %p (Java object %p)\n", am, clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800326
Elliott Hughes69a017b2011-04-08 14:10:28 -0700327 ScopedUtfChars fileName8(env, fileName);
328 if (fileName8.c_str() == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800329 return -1;
330 }
331
332 if (mode != Asset::ACCESS_UNKNOWN && mode != Asset::ACCESS_RANDOM
333 && mode != Asset::ACCESS_STREAMING && mode != Asset::ACCESS_BUFFER) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -0700334 jniThrowException(env, "java/lang/IllegalArgumentException", "Bad access mode");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800335 return -1;
336 }
337
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800338 Asset* a = cookie
Narayan Kamath745d4ef2014-01-27 11:17:22 +0000339 ? am->openNonAsset(static_cast<int32_t>(cookie), fileName8.c_str(),
340 (Asset::AccessMode)mode)
Elliott Hughes69a017b2011-04-08 14:10:28 -0700341 : am->openNonAsset(fileName8.c_str(), (Asset::AccessMode)mode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800342
343 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700344 jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800345 return -1;
346 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800347
348 //printf("Created Asset Stream: %p\n", a);
349
Ashok Bhat896043d2014-01-17 16:02:38 +0000350 return reinterpret_cast<jlong>(a);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800351}
352
353static jobject android_content_AssetManager_openNonAssetFdNative(JNIEnv* env, jobject clazz,
354 jint cookie,
355 jstring fileName,
356 jlongArray outOffsets)
357{
358 AssetManager* am = assetManagerForJavaObject(env, clazz);
359 if (am == NULL) {
360 return NULL;
361 }
362
Steve Block71f2cf12011-10-20 11:56:00 +0100363 ALOGV("openNonAssetFd in %p (Java object %p)\n", am, clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800364
Elliott Hughes69a017b2011-04-08 14:10:28 -0700365 ScopedUtfChars fileName8(env, fileName);
366 if (fileName8.c_str() == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800367 return NULL;
368 }
369
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800370 Asset* a = cookie
Narayan Kamath745d4ef2014-01-27 11:17:22 +0000371 ? am->openNonAsset(static_cast<int32_t>(cookie), fileName8.c_str(), Asset::ACCESS_RANDOM)
Elliott Hughes69a017b2011-04-08 14:10:28 -0700372 : am->openNonAsset(fileName8.c_str(), Asset::ACCESS_RANDOM);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800373
374 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700375 jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800376 return NULL;
377 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800378
379 //printf("Created Asset Stream: %p\n", a);
380
381 return returnParcelFileDescriptor(env, a, outOffsets);
382}
383
384static jobjectArray android_content_AssetManager_list(JNIEnv* env, jobject clazz,
385 jstring fileName)
386{
387 AssetManager* am = assetManagerForJavaObject(env, clazz);
388 if (am == NULL) {
389 return NULL;
390 }
391
Elliott Hughes69a017b2011-04-08 14:10:28 -0700392 ScopedUtfChars fileName8(env, fileName);
393 if (fileName8.c_str() == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800394 return NULL;
395 }
396
Elliott Hughes69a017b2011-04-08 14:10:28 -0700397 AssetDir* dir = am->openDir(fileName8.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800398
399 if (dir == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700400 jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800401 return NULL;
402 }
403
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800404 size_t N = dir->getFileCount();
405
406 jobjectArray array = env->NewObjectArray(dir->getFileCount(),
Vladimir Markoaa5fe3d2013-06-17 12:46:22 +0100407 g_stringClass, NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800408 if (array == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800409 delete dir;
410 return NULL;
411 }
412
413 for (size_t i=0; i<N; i++) {
414 const String8& name = dir->getFileName(i);
415 jstring str = env->NewStringUTF(name.string());
416 if (str == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800417 delete dir;
418 return NULL;
419 }
420 env->SetObjectArrayElement(array, i, str);
Gilles Debunne4d4040b2010-08-26 15:59:54 -0700421 env->DeleteLocalRef(str);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800422 }
423
424 delete dir;
425
426 return array;
427}
428
429static void android_content_AssetManager_destroyAsset(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +0000430 jlong assetHandle)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800431{
Ashok Bhat896043d2014-01-17 16:02:38 +0000432 Asset* a = reinterpret_cast<Asset*>(assetHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800433
434 //printf("Destroying Asset Stream: %p\n", a);
435
436 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700437 jniThrowNullPointerException(env, "asset");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800438 return;
439 }
440
441 delete a;
442}
443
444static jint android_content_AssetManager_readAssetChar(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +0000445 jlong assetHandle)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800446{
Ashok Bhat896043d2014-01-17 16:02:38 +0000447 Asset* a = reinterpret_cast<Asset*>(assetHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800448
449 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700450 jniThrowNullPointerException(env, "asset");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800451 return -1;
452 }
453
454 uint8_t b;
455 ssize_t res = a->read(&b, 1);
456 return res == 1 ? b : -1;
457}
458
459static jint android_content_AssetManager_readAsset(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +0000460 jlong assetHandle, jbyteArray bArray,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800461 jint off, jint len)
462{
Ashok Bhat896043d2014-01-17 16:02:38 +0000463 Asset* a = reinterpret_cast<Asset*>(assetHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800464
465 if (a == NULL || bArray == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700466 jniThrowNullPointerException(env, "asset");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800467 return -1;
468 }
469
470 if (len == 0) {
471 return 0;
472 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700473
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800474 jsize bLen = env->GetArrayLength(bArray);
475 if (off < 0 || off >= bLen || len < 0 || len > bLen || (off+len) > bLen) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -0700476 jniThrowException(env, "java/lang/IndexOutOfBoundsException", "");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800477 return -1;
478 }
479
480 jbyte* b = env->GetByteArrayElements(bArray, NULL);
481 ssize_t res = a->read(b+off, len);
482 env->ReleaseByteArrayElements(bArray, b, 0);
483
Ashok Bhat896043d2014-01-17 16:02:38 +0000484 if (res > 0) return static_cast<jint>(res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800485
486 if (res < 0) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -0700487 jniThrowException(env, "java/io/IOException", "");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800488 }
489 return -1;
490}
491
492static jlong android_content_AssetManager_seekAsset(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +0000493 jlong assetHandle,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800494 jlong offset, jint whence)
495{
Ashok Bhat896043d2014-01-17 16:02:38 +0000496 Asset* a = reinterpret_cast<Asset*>(assetHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800497
498 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700499 jniThrowNullPointerException(env, "asset");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800500 return -1;
501 }
502
503 return a->seek(
504 offset, (whence > 0) ? SEEK_END : (whence < 0 ? SEEK_SET : SEEK_CUR));
505}
506
507static jlong android_content_AssetManager_getAssetLength(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +0000508 jlong assetHandle)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800509{
Ashok Bhat896043d2014-01-17 16:02:38 +0000510 Asset* a = reinterpret_cast<Asset*>(assetHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800511
512 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700513 jniThrowNullPointerException(env, "asset");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800514 return -1;
515 }
516
517 return a->getLength();
518}
519
520static jlong android_content_AssetManager_getAssetRemainingLength(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +0000521 jlong assetHandle)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800522{
Ashok Bhat896043d2014-01-17 16:02:38 +0000523 Asset* a = reinterpret_cast<Asset*>(assetHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800524
525 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700526 jniThrowNullPointerException(env, "asset");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800527 return -1;
528 }
529
530 return a->getRemainingLength();
531}
532
533static jint android_content_AssetManager_addAssetPath(JNIEnv* env, jobject clazz,
Tao Baia6d7e3f2015-09-01 18:49:54 -0700534 jstring path, jboolean appAsLib)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800535{
Elliott Hughes69a017b2011-04-08 14:10:28 -0700536 ScopedUtfChars path8(env, path);
537 if (path8.c_str() == NULL) {
Glenn Kasten129e19c2012-01-10 17:57:36 -0800538 return 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800539 }
540
541 AssetManager* am = assetManagerForJavaObject(env, clazz);
542 if (am == NULL) {
Glenn Kasten129e19c2012-01-10 17:57:36 -0800543 return 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800544 }
545
Narayan Kamath745d4ef2014-01-27 11:17:22 +0000546 int32_t cookie;
Tao Baia6d7e3f2015-09-01 18:49:54 -0700547 bool res = am->addAssetPath(String8(path8.c_str()), &cookie, appAsLib);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800548
Narayan Kamath745d4ef2014-01-27 11:17:22 +0000549 return (res) ? static_cast<jint>(cookie) : 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800550}
551
Mårten Kongstad48d22322014-01-31 14:43:27 +0100552static jint android_content_AssetManager_addOverlayPath(JNIEnv* env, jobject clazz,
553 jstring idmapPath)
554{
555 ScopedUtfChars idmapPath8(env, idmapPath);
556 if (idmapPath8.c_str() == NULL) {
557 return 0;
558 }
559
560 AssetManager* am = assetManagerForJavaObject(env, clazz);
561 if (am == NULL) {
562 return 0;
563 }
564
565 int32_t cookie;
566 bool res = am->addOverlayPath(String8(idmapPath8.c_str()), &cookie);
567
568 return (res) ? (jint)cookie : 0;
569}
570
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800571static jboolean android_content_AssetManager_isUpToDate(JNIEnv* env, jobject clazz)
572{
573 AssetManager* am = assetManagerForJavaObject(env, clazz);
574 if (am == NULL) {
575 return JNI_TRUE;
576 }
577 return am->isUpToDate() ? JNI_TRUE : JNI_FALSE;
578}
579
Roozbeh Pournader1c686f22015-12-18 14:22:14 -0800580static jobjectArray getLocales(JNIEnv* env, jobject clazz, bool includeSystemLocales)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800581{
582 Vector<String8> locales;
583
584 AssetManager* am = assetManagerForJavaObject(env, clazz);
585 if (am == NULL) {
586 return NULL;
587 }
588
Roozbeh Pournader1c686f22015-12-18 14:22:14 -0800589 am->getLocales(&locales, includeSystemLocales);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800590
591 const int N = locales.size();
592
593 jobjectArray result = env->NewObjectArray(N, g_stringClass, NULL);
594 if (result == NULL) {
595 return NULL;
596 }
597
598 for (int i=0; i<N; i++) {
Gilles Debunne0db187a2010-08-27 11:51:34 -0700599 jstring str = env->NewStringUTF(locales[i].string());
Gilles Debunne4d4040b2010-08-26 15:59:54 -0700600 if (str == NULL) {
601 return NULL;
602 }
603 env->SetObjectArrayElement(result, i, str);
604 env->DeleteLocalRef(str);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800605 }
606
607 return result;
608}
609
Roozbeh Pournader1c686f22015-12-18 14:22:14 -0800610static jobjectArray android_content_AssetManager_getLocales(JNIEnv* env, jobject clazz)
611{
612 return getLocales(env, clazz, true /* include system locales */);
613}
614
615static jobjectArray android_content_AssetManager_getNonSystemLocales(JNIEnv* env, jobject clazz)
616{
617 return getLocales(env, clazz, false /* don't include system locales */);
618}
619
Filip Gruszczynski23493322015-07-29 17:02:59 -0700620static jobject constructConfigurationObject(JNIEnv* env, const ResTable_config& config) {
621 jobject result = env->NewObject(gConfigurationOffsets.classObject,
622 gConfigurationOffsets.constructor);
623 if (result == NULL) {
624 return NULL;
625 }
626
627 env->SetIntField(result, gConfigurationOffsets.mSmallestScreenWidthDpOffset,
628 config.smallestScreenWidthDp);
629 env->SetIntField(result, gConfigurationOffsets.mScreenWidthDpOffset, config.screenWidthDp);
630 env->SetIntField(result, gConfigurationOffsets.mScreenHeightDpOffset, config.screenHeightDp);
631
632 return result;
633}
634
635static jobjectArray getSizeConfigurationsInternal(JNIEnv* env,
636 const Vector<ResTable_config>& configs) {
637 const int N = configs.size();
638 jobjectArray result = env->NewObjectArray(N, gConfigurationOffsets.classObject, NULL);
639 if (result == NULL) {
640 return NULL;
641 }
642
643 for (int i=0; i<N; i++) {
644 jobject config = constructConfigurationObject(env, configs[i]);
645 if (config == NULL) {
646 env->DeleteLocalRef(result);
647 return NULL;
648 }
649
650 env->SetObjectArrayElement(result, i, config);
651 env->DeleteLocalRef(config);
652 }
653
654 return result;
655}
656
657static jobjectArray android_content_AssetManager_getSizeConfigurations(JNIEnv* env, jobject clazz) {
658 AssetManager* am = assetManagerForJavaObject(env, clazz);
659 if (am == NULL) {
660 return NULL;
661 }
662
663 const ResTable& res(am->getResources());
664 Vector<ResTable_config> configs;
665 res.getConfigurations(&configs, false /* ignoreMipmap */, true /* ignoreAndroidPackage */);
666
667 return getSizeConfigurationsInternal(env, configs);
668}
669
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800670static void android_content_AssetManager_setConfiguration(JNIEnv* env, jobject clazz,
671 jint mcc, jint mnc,
672 jstring locale, jint orientation,
673 jint touchscreen, jint density,
674 jint keyboard, jint keyboardHidden,
675 jint navigation,
676 jint screenWidth, jint screenHeight,
Dianne Hackborn69cb8752011-05-19 18:13:32 -0700677 jint smallestScreenWidthDp,
Dianne Hackborn3fc982f2011-03-30 16:20:26 -0700678 jint screenWidthDp, jint screenHeightDp,
Tobias Haamel27b28b32010-02-09 23:09:17 +0100679 jint screenLayout, jint uiMode,
Romain Guy408afbf2017-01-25 10:23:03 -0800680 jint colorMode, jint sdkVersion)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800681{
682 AssetManager* am = assetManagerForJavaObject(env, clazz);
683 if (am == NULL) {
684 return;
685 }
686
687 ResTable_config config;
688 memset(&config, 0, sizeof(config));
Elliott Hughes69a017b2011-04-08 14:10:28 -0700689
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800690 const char* locale8 = locale != NULL ? env->GetStringUTFChars(locale, NULL) : NULL;
Elliott Hughes69a017b2011-04-08 14:10:28 -0700691
Adam Lesinski2738c962015-05-14 14:25:36 -0700692 // Constants duplicated from Java class android.content.res.Configuration.
693 static const jint kScreenLayoutRoundMask = 0x300;
694 static const jint kScreenLayoutRoundShift = 8;
695
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800696 config.mcc = (uint16_t)mcc;
697 config.mnc = (uint16_t)mnc;
698 config.orientation = (uint8_t)orientation;
699 config.touchscreen = (uint8_t)touchscreen;
700 config.density = (uint16_t)density;
701 config.keyboard = (uint8_t)keyboard;
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700702 config.inputFlags = (uint8_t)keyboardHidden;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800703 config.navigation = (uint8_t)navigation;
704 config.screenWidth = (uint16_t)screenWidth;
705 config.screenHeight = (uint16_t)screenHeight;
Dianne Hackborn69cb8752011-05-19 18:13:32 -0700706 config.smallestScreenWidthDp = (uint16_t)smallestScreenWidthDp;
Dianne Hackborn3fc982f2011-03-30 16:20:26 -0700707 config.screenWidthDp = (uint16_t)screenWidthDp;
708 config.screenHeightDp = (uint16_t)screenHeightDp;
Dianne Hackborn723738c2009-06-25 19:48:04 -0700709 config.screenLayout = (uint8_t)screenLayout;
Tobias Haamel27b28b32010-02-09 23:09:17 +0100710 config.uiMode = (uint8_t)uiMode;
Romain Guy408afbf2017-01-25 10:23:03 -0800711 config.colorMode = (uint8_t)colorMode;
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
John Reckf32adf42016-11-23 10:39:40 -08001179static void android_content_AssetManager_applyStyle(JNIEnv* env, jobject, jlong themeToken,
1180 jint defStyleAttr, jint defStyleRes, jlong xmlParserToken, jintArray attrsObj, jint length,
1181 jlong outValuesAddress, jlong outIndicesAddress) {
1182 jint* attrs = env->GetIntArrayElements(attrsObj, 0);
Adam Lesinski4452e132016-10-12 07:47:28 -07001183 ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeToken);
1184 ResXMLParser* xmlParser = reinterpret_cast<ResXMLParser*>(xmlParserToken);
John Reckf32adf42016-11-23 10:39:40 -08001185 uint32_t* outValues = reinterpret_cast<uint32_t*>(static_cast<uintptr_t>(outValuesAddress));
1186 uint32_t* outIndices = reinterpret_cast<uint32_t*>(static_cast<uintptr_t>(outIndicesAddress));
1187 ApplyStyle(theme, xmlParser, defStyleAttr, defStyleRes,
1188 reinterpret_cast<const uint32_t*>(attrs), length, outValues, outIndices);
1189 env->ReleaseIntArrayElements(attrsObj, attrs, JNI_ABORT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001190}
1191
1192static jboolean android_content_AssetManager_retrieveAttributes(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +00001193 jlong xmlParserToken,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001194 jintArray attrs,
1195 jintArray outValues,
1196 jintArray outIndices)
1197{
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001198 if (xmlParserToken == 0) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001199 jniThrowNullPointerException(env, "xmlParserToken");
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001200 return JNI_FALSE;
1201 }
1202 if (attrs == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001203 jniThrowNullPointerException(env, "attrs");
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001204 return JNI_FALSE;
1205 }
1206 if (outValues == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001207 jniThrowNullPointerException(env, "out values");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001208 return JNI_FALSE;
1209 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001210
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001211 AssetManager* am = assetManagerForJavaObject(env, clazz);
1212 if (am == NULL) {
1213 return JNI_FALSE;
1214 }
1215 const ResTable& res(am->getResources());
1216 ResXMLParser* xmlParser = (ResXMLParser*)xmlParserToken;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001217
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001218 const jsize NI = env->GetArrayLength(attrs);
1219 const jsize NV = env->GetArrayLength(outValues);
1220 if (NV < (NI*STYLE_NUM_ENTRIES)) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001221 jniThrowException(env, "java/lang/IndexOutOfBoundsException", "out values too small");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001222 return JNI_FALSE;
1223 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001224
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001225 jint* src = (jint*)env->GetPrimitiveArrayCritical(attrs, 0);
1226 if (src == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001227 return JNI_FALSE;
1228 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001229
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001230 jint* baseDest = (jint*)env->GetPrimitiveArrayCritical(outValues, 0);
Adam Lesinski4452e132016-10-12 07:47:28 -07001231 if (baseDest == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001232 env->ReleasePrimitiveArrayCritical(attrs, src, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001233 return JNI_FALSE;
1234 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001235
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001236 jint* indices = NULL;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001237 if (outIndices != NULL) {
1238 if (env->GetArrayLength(outIndices) > NI) {
1239 indices = (jint*)env->GetPrimitiveArrayCritical(outIndices, 0);
1240 }
1241 }
1242
Adam Lesinski7a37b742016-10-12 14:05:55 -07001243 bool result = RetrieveAttributes(&res, xmlParser,
Adam Lesinski4452e132016-10-12 07:47:28 -07001244 (uint32_t*) src, NI,
1245 (uint32_t*) baseDest,
1246 (uint32_t*) indices);
Elliott Hughes69a017b2011-04-08 14:10:28 -07001247
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001248 if (indices != NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001249 env->ReleasePrimitiveArrayCritical(outIndices, indices, 0);
1250 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001251 env->ReleasePrimitiveArrayCritical(outValues, baseDest, 0);
1252 env->ReleasePrimitiveArrayCritical(attrs, src, 0);
Adam Lesinski4452e132016-10-12 07:47:28 -07001253 return result ? JNI_TRUE : JNI_FALSE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001254}
1255
1256static jint android_content_AssetManager_getArraySize(JNIEnv* env, jobject clazz,
1257 jint id)
1258{
1259 AssetManager* am = assetManagerForJavaObject(env, clazz);
1260 if (am == NULL) {
Olivier Baillyd7c86722010-11-18 14:43:36 -08001261 return 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001262 }
1263 const ResTable& res(am->getResources());
Elliott Hughes69a017b2011-04-08 14:10:28 -07001264
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001265 res.lock();
1266 const ResTable::bag_entry* defStyleEnt = NULL;
1267 ssize_t bagOff = res.getBagLocked(id, &defStyleEnt);
1268 res.unlock();
Elliott Hughes69a017b2011-04-08 14:10:28 -07001269
Ashok Bhat896043d2014-01-17 16:02:38 +00001270 return static_cast<jint>(bagOff);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001271}
1272
1273static jint android_content_AssetManager_retrieveArray(JNIEnv* env, jobject clazz,
1274 jint id,
1275 jintArray outValues)
1276{
1277 if (outValues == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001278 jniThrowNullPointerException(env, "out values");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001279 return JNI_FALSE;
1280 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001281
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001282 AssetManager* am = assetManagerForJavaObject(env, clazz);
1283 if (am == NULL) {
1284 return JNI_FALSE;
1285 }
1286 const ResTable& res(am->getResources());
Dianne Hackborn0d221012009-07-29 15:41:19 -07001287 ResTable_config config;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001288 Res_value value;
1289 ssize_t block;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001290
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001291 const jsize NV = env->GetArrayLength(outValues);
Elliott Hughes69a017b2011-04-08 14:10:28 -07001292
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001293 jint* baseDest = (jint*)env->GetPrimitiveArrayCritical(outValues, 0);
1294 jint* dest = baseDest;
1295 if (dest == NULL) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001296 jniThrowException(env, "java/lang/OutOfMemoryError", "");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001297 return JNI_FALSE;
1298 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001299
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001300 // Now lock down the resource object and start pulling stuff from it.
1301 res.lock();
Elliott Hughes69a017b2011-04-08 14:10:28 -07001302
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001303 const ResTable::bag_entry* arrayEnt = NULL;
1304 uint32_t arrayTypeSetFlags = 0;
1305 ssize_t bagOff = res.getBagLocked(id, &arrayEnt, &arrayTypeSetFlags);
1306 const ResTable::bag_entry* endArrayEnt = arrayEnt +
1307 (bagOff >= 0 ? bagOff : 0);
Elliott Hughes69a017b2011-04-08 14:10:28 -07001308
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001309 int i = 0;
1310 uint32_t typeSetFlags;
1311 while (i < NV && arrayEnt < endArrayEnt) {
1312 block = arrayEnt->stringBlock;
1313 typeSetFlags = arrayTypeSetFlags;
Dianne Hackborn0d221012009-07-29 15:41:19 -07001314 config.density = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001315 value = arrayEnt->map.value;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001316
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001317 uint32_t resid = 0;
1318 if (value.dataType != Res_value::TYPE_NULL) {
1319 // Take care of resolving the found resource to its final value.
1320 //printf("Resolving attribute reference\n");
Dianne Hackborn0d221012009-07-29 15:41:19 -07001321 ssize_t newBlock = res.resolveReference(&value, block, &resid,
1322 &typeSetFlags, &config);
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001323 if (kThrowOnBadId) {
1324 if (newBlock == BAD_INDEX) {
1325 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
1326 return JNI_FALSE;
1327 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001328 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001329 if (newBlock >= 0) block = newBlock;
1330 }
1331
1332 // Deal with the special @null value -- it turns back to TYPE_NULL.
1333 if (value.dataType == Res_value::TYPE_REFERENCE && value.data == 0) {
1334 value.dataType = Res_value::TYPE_NULL;
Alan Viverettef2969402014-10-29 17:09:36 -07001335 value.data = Res_value::DATA_NULL_UNDEFINED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001336 }
1337
1338 //printf("Attribute 0x%08x: final type=0x%x, data=0x%08x\n", curIdent, value.dataType, value.data);
1339
1340 // Write the final value back to Java.
1341 dest[STYLE_TYPE] = value.dataType;
1342 dest[STYLE_DATA] = value.data;
Ashok Bhat896043d2014-01-17 16:02:38 +00001343 dest[STYLE_ASSET_COOKIE] = reinterpret_cast<jint>(res.getTableCookie(block));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001344 dest[STYLE_RESOURCE_ID] = resid;
1345 dest[STYLE_CHANGING_CONFIGURATIONS] = typeSetFlags;
Dianne Hackborn0d221012009-07-29 15:41:19 -07001346 dest[STYLE_DENSITY] = config.density;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001347 dest += STYLE_NUM_ENTRIES;
1348 i+= STYLE_NUM_ENTRIES;
1349 arrayEnt++;
1350 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001351
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001352 i /= STYLE_NUM_ENTRIES;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001353
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001354 res.unlock();
Elliott Hughes69a017b2011-04-08 14:10:28 -07001355
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001356 env->ReleasePrimitiveArrayCritical(outValues, baseDest, 0);
Elliott Hughes69a017b2011-04-08 14:10:28 -07001357
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001358 return i;
1359}
1360
Ashok Bhat896043d2014-01-17 16:02:38 +00001361static jlong android_content_AssetManager_openXmlAssetNative(JNIEnv* env, jobject clazz,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001362 jint cookie,
1363 jstring fileName)
1364{
1365 AssetManager* am = assetManagerForJavaObject(env, clazz);
1366 if (am == NULL) {
1367 return 0;
1368 }
1369
Steve Block71f2cf12011-10-20 11:56:00 +01001370 ALOGV("openXmlAsset in %p (Java object %p)\n", am, clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001371
Elliott Hughes69a017b2011-04-08 14:10:28 -07001372 ScopedUtfChars fileName8(env, fileName);
1373 if (fileName8.c_str() == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001374 return 0;
1375 }
1376
Adam Lesinskide898ff2014-01-29 18:20:45 -08001377 int32_t assetCookie = static_cast<int32_t>(cookie);
1378 Asset* a = assetCookie
1379 ? am->openNonAsset(assetCookie, fileName8.c_str(), Asset::ACCESS_BUFFER)
1380 : am->openNonAsset(fileName8.c_str(), Asset::ACCESS_BUFFER, &assetCookie);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001381
1382 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001383 jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001384 return 0;
1385 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001386
Adam Lesinskide898ff2014-01-29 18:20:45 -08001387 const DynamicRefTable* dynamicRefTable =
1388 am->getResources().getDynamicRefTableForCookie(assetCookie);
1389 ResXMLTree* block = new ResXMLTree(dynamicRefTable);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001390 status_t err = block->setTo(a->getBuffer(true), a->getLength(), true);
1391 a->close();
1392 delete a;
1393
1394 if (err != NO_ERROR) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001395 jniThrowException(env, "java/io/FileNotFoundException", "Corrupt XML binary file");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001396 return 0;
1397 }
1398
Ashok Bhat896043d2014-01-17 16:02:38 +00001399 return reinterpret_cast<jlong>(block);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001400}
1401
1402static jintArray android_content_AssetManager_getArrayStringInfo(JNIEnv* env, jobject clazz,
1403 jint arrayResId)
1404{
1405 AssetManager* am = assetManagerForJavaObject(env, clazz);
1406 if (am == NULL) {
1407 return NULL;
1408 }
1409 const ResTable& res(am->getResources());
1410
1411 const ResTable::bag_entry* startOfBag;
1412 const ssize_t N = res.lockBag(arrayResId, &startOfBag);
1413 if (N < 0) {
1414 return NULL;
1415 }
1416
1417 jintArray array = env->NewIntArray(N * 2);
1418 if (array == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001419 res.unlockBag(startOfBag);
1420 return NULL;
1421 }
1422
1423 Res_value value;
1424 const ResTable::bag_entry* bag = startOfBag;
1425 for (size_t i = 0, j = 0; ((ssize_t)i)<N; i++, bag++) {
1426 jint stringIndex = -1;
1427 jint stringBlock = 0;
1428 value = bag->map.value;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001429
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001430 // Take care of resolving the found resource to its final value.
1431 stringBlock = res.resolveReference(&value, bag->stringBlock, NULL);
1432 if (value.dataType == Res_value::TYPE_STRING) {
1433 stringIndex = value.data;
1434 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001435
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001436 if (kThrowOnBadId) {
1437 if (stringBlock == BAD_INDEX) {
1438 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
1439 return array;
1440 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001441 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001442
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001443 //todo: It might be faster to allocate a C array to contain
1444 // the blocknums and indices, put them in there and then
1445 // do just one SetIntArrayRegion()
1446 env->SetIntArrayRegion(array, j, 1, &stringBlock);
1447 env->SetIntArrayRegion(array, j + 1, 1, &stringIndex);
1448 j = j + 2;
1449 }
1450 res.unlockBag(startOfBag);
1451 return array;
1452}
1453
1454static jobjectArray android_content_AssetManager_getArrayStringResource(JNIEnv* env, jobject clazz,
1455 jint arrayResId)
1456{
1457 AssetManager* am = assetManagerForJavaObject(env, clazz);
1458 if (am == NULL) {
1459 return NULL;
1460 }
1461 const ResTable& res(am->getResources());
1462
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001463 const ResTable::bag_entry* startOfBag;
1464 const ssize_t N = res.lockBag(arrayResId, &startOfBag);
1465 if (N < 0) {
1466 return NULL;
1467 }
1468
Vladimir Markoaa5fe3d2013-06-17 12:46:22 +01001469 jobjectArray array = env->NewObjectArray(N, g_stringClass, NULL);
Kenny Root485dd212010-05-06 16:06:48 -07001470 if (env->ExceptionCheck()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001471 res.unlockBag(startOfBag);
1472 return NULL;
1473 }
1474
1475 Res_value value;
1476 const ResTable::bag_entry* bag = startOfBag;
1477 size_t strLen = 0;
1478 for (size_t i=0; ((ssize_t)i)<N; i++, bag++) {
1479 value = bag->map.value;
1480 jstring str = NULL;
Kenny Root780d2a12010-02-22 22:36:26 -08001481
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001482 // Take care of resolving the found resource to its final value.
1483 ssize_t block = res.resolveReference(&value, bag->stringBlock, NULL);
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001484 if (kThrowOnBadId) {
1485 if (block == BAD_INDEX) {
1486 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
1487 return array;
1488 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001489 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001490 if (value.dataType == Res_value::TYPE_STRING) {
Kenny Root780d2a12010-02-22 22:36:26 -08001491 const ResStringPool* pool = res.getTableStringBlock(block);
1492 const char* str8 = pool->string8At(value.data, &strLen);
1493 if (str8 != NULL) {
1494 str = env->NewStringUTF(str8);
1495 } else {
1496 const char16_t* str16 = pool->stringAt(value.data, &strLen);
Dan Albert66987492014-11-20 11:41:21 -08001497 str = env->NewString(reinterpret_cast<const jchar*>(str16),
1498 strLen);
Kenny Root485dd212010-05-06 16:06:48 -07001499 }
1500
1501 // If one of our NewString{UTF} calls failed due to memory, an
1502 // exception will be pending.
1503 if (env->ExceptionCheck()) {
1504 res.unlockBag(startOfBag);
1505 return NULL;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001506 }
Kenny Root780d2a12010-02-22 22:36:26 -08001507
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001508 env->SetObjectArrayElement(array, i, str);
Kenny Root485dd212010-05-06 16:06:48 -07001509
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001510 // str is not NULL at that point, otherwise ExceptionCheck would have been true.
1511 // If we have a large amount of strings in our array, we might
1512 // overflow the local reference table of the VM.
Kenny Root485dd212010-05-06 16:06:48 -07001513 env->DeleteLocalRef(str);
1514 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001515 }
1516 res.unlockBag(startOfBag);
1517 return array;
1518}
1519
1520static jintArray android_content_AssetManager_getArrayIntResource(JNIEnv* env, jobject clazz,
1521 jint arrayResId)
1522{
1523 AssetManager* am = assetManagerForJavaObject(env, clazz);
1524 if (am == NULL) {
1525 return NULL;
1526 }
1527 const ResTable& res(am->getResources());
1528
1529 const ResTable::bag_entry* startOfBag;
1530 const ssize_t N = res.lockBag(arrayResId, &startOfBag);
1531 if (N < 0) {
1532 return NULL;
1533 }
1534
1535 jintArray array = env->NewIntArray(N);
1536 if (array == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001537 res.unlockBag(startOfBag);
1538 return NULL;
1539 }
1540
1541 Res_value value;
1542 const ResTable::bag_entry* bag = startOfBag;
1543 for (size_t i=0; ((ssize_t)i)<N; i++, bag++) {
1544 value = bag->map.value;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001545
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001546 // Take care of resolving the found resource to its final value.
1547 ssize_t block = res.resolveReference(&value, bag->stringBlock, NULL);
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001548 if (kThrowOnBadId) {
1549 if (block == BAD_INDEX) {
1550 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
1551 return array;
1552 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001553 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001554 if (value.dataType >= Res_value::TYPE_FIRST_INT
1555 && value.dataType <= Res_value::TYPE_LAST_INT) {
1556 int intVal = value.data;
1557 env->SetIntArrayRegion(array, i, 1, &intVal);
1558 }
1559 }
1560 res.unlockBag(startOfBag);
1561 return array;
1562}
1563
Jon Miranda042ad632014-09-03 17:57:35 -07001564static jintArray android_content_AssetManager_getStyleAttributes(JNIEnv* env, jobject clazz,
1565 jint styleId)
1566{
1567 AssetManager* am = assetManagerForJavaObject(env, clazz);
1568 if (am == NULL) {
1569 return NULL;
1570 }
1571 const ResTable& res(am->getResources());
1572
1573 const ResTable::bag_entry* startOfBag;
1574 const ssize_t N = res.lockBag(styleId, &startOfBag);
1575 if (N < 0) {
1576 return NULL;
1577 }
1578
1579 jintArray array = env->NewIntArray(N);
1580 if (array == NULL) {
1581 res.unlockBag(startOfBag);
1582 return NULL;
1583 }
1584
Jon Miranda042ad632014-09-03 17:57:35 -07001585 const ResTable::bag_entry* bag = startOfBag;
1586 for (size_t i=0; ((ssize_t)i)<N; i++, bag++) {
1587 int resourceId = bag->map.name.ident;
1588 env->SetIntArrayRegion(array, i, 1, &resourceId);
1589 }
1590 res.unlockBag(startOfBag);
1591 return array;
1592}
1593
Mårten Kongstad48d22322014-01-31 14:43:27 +01001594static void android_content_AssetManager_init(JNIEnv* env, jobject clazz, jboolean isSystem)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001595{
Jaekyun Seok7de2f9c2017-03-02 12:45:10 +09001596 if (isSystem) {
1597 verifySystemIdmaps();
1598 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001599 AssetManager* am = new AssetManager();
1600 if (am == NULL) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001601 jniThrowException(env, "java/lang/OutOfMemoryError", "");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001602 return;
1603 }
1604
1605 am->addDefaultAssets();
1606
Steve Block71f2cf12011-10-20 11:56:00 +01001607 ALOGV("Created AssetManager %p for Java object %p\n", am, clazz);
Ashok Bhat896043d2014-01-17 16:02:38 +00001608 env->SetLongField(clazz, gAssetManagerOffsets.mObject, reinterpret_cast<jlong>(am));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001609}
1610
1611static void android_content_AssetManager_destroy(JNIEnv* env, jobject clazz)
1612{
1613 AssetManager* am = (AssetManager*)
Ashok Bhat896043d2014-01-17 16:02:38 +00001614 (env->GetLongField(clazz, gAssetManagerOffsets.mObject));
Steve Block71f2cf12011-10-20 11:56:00 +01001615 ALOGV("Destroying AssetManager %p for Java object %p\n", am, clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001616 if (am != NULL) {
1617 delete am;
Ashok Bhat896043d2014-01-17 16:02:38 +00001618 env->SetLongField(clazz, gAssetManagerOffsets.mObject, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001619 }
1620}
1621
1622static jint android_content_AssetManager_getGlobalAssetCount(JNIEnv* env, jobject clazz)
1623{
1624 return Asset::getGlobalCount();
1625}
1626
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07001627static jobject android_content_AssetManager_getAssetAllocations(JNIEnv* env, jobject clazz)
1628{
1629 String8 alloc = Asset::getAssetAllocations();
1630 if (alloc.length() <= 0) {
1631 return NULL;
1632 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001633
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07001634 jstring str = env->NewStringUTF(alloc.string());
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07001635 return str;
1636}
1637
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001638static jint android_content_AssetManager_getGlobalAssetManagerCount(JNIEnv* env, jobject clazz)
1639{
1640 return AssetManager::getGlobalCount();
1641}
1642
1643// ----------------------------------------------------------------------------
1644
1645/*
1646 * JNI registration.
1647 */
Daniel Micay76f6a862015-09-19 17:31:01 -04001648static const JNINativeMethod gAssetManagerMethods[] = {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001649 /* name, signature, funcPtr */
1650
1651 // Basic asset stuff.
Ashok Bhat896043d2014-01-17 16:02:38 +00001652 { "openAsset", "(Ljava/lang/String;I)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001653 (void*) android_content_AssetManager_openAsset },
1654 { "openAssetFd", "(Ljava/lang/String;[J)Landroid/os/ParcelFileDescriptor;",
1655 (void*) android_content_AssetManager_openAssetFd },
Ashok Bhat896043d2014-01-17 16:02:38 +00001656 { "openNonAssetNative", "(ILjava/lang/String;I)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001657 (void*) android_content_AssetManager_openNonAssetNative },
1658 { "openNonAssetFdNative", "(ILjava/lang/String;[J)Landroid/os/ParcelFileDescriptor;",
1659 (void*) android_content_AssetManager_openNonAssetFdNative },
1660 { "list", "(Ljava/lang/String;)[Ljava/lang/String;",
1661 (void*) android_content_AssetManager_list },
Ashok Bhat896043d2014-01-17 16:02:38 +00001662 { "destroyAsset", "(J)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001663 (void*) android_content_AssetManager_destroyAsset },
Ashok Bhat896043d2014-01-17 16:02:38 +00001664 { "readAssetChar", "(J)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001665 (void*) android_content_AssetManager_readAssetChar },
Ashok Bhat896043d2014-01-17 16:02:38 +00001666 { "readAsset", "(J[BII)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001667 (void*) android_content_AssetManager_readAsset },
Ashok Bhat896043d2014-01-17 16:02:38 +00001668 { "seekAsset", "(JJI)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001669 (void*) android_content_AssetManager_seekAsset },
John Reck32995222016-10-07 11:02:20 -07001670 { "getAssetLength", "(J)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001671 (void*) android_content_AssetManager_getAssetLength },
John Reck32995222016-10-07 11:02:20 -07001672 { "getAssetRemainingLength", "(J)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001673 (void*) android_content_AssetManager_getAssetRemainingLength },
Tao Baia6d7e3f2015-09-01 18:49:54 -07001674 { "addAssetPathNative", "(Ljava/lang/String;Z)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001675 (void*) android_content_AssetManager_addAssetPath },
Mårten Kongstad30113132014-11-07 10:52:17 +01001676 { "addOverlayPathNative", "(Ljava/lang/String;)I",
Mårten Kongstad48d22322014-01-31 14:43:27 +01001677 (void*) android_content_AssetManager_addOverlayPath },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001678 { "isUpToDate", "()Z",
1679 (void*) android_content_AssetManager_isUpToDate },
1680
1681 // Resources.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001682 { "getLocales", "()[Ljava/lang/String;",
1683 (void*) android_content_AssetManager_getLocales },
Roozbeh Pournader1c686f22015-12-18 14:22:14 -08001684 { "getNonSystemLocales", "()[Ljava/lang/String;",
1685 (void*) android_content_AssetManager_getNonSystemLocales },
Filip Gruszczynski23493322015-07-29 17:02:59 -07001686 { "getSizeConfigurations", "()[Landroid/content/res/Configuration;",
1687 (void*) android_content_AssetManager_getSizeConfigurations },
Romain Guy408afbf2017-01-25 10:23:03 -08001688 { "setConfiguration", "(IILjava/lang/String;IIIIIIIIIIIIIII)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001689 (void*) android_content_AssetManager_setConfiguration },
John Reck32995222016-10-07 11:02:20 -07001690 { "getResourceIdentifier","(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001691 (void*) android_content_AssetManager_getResourceIdentifier },
John Reck32995222016-10-07 11:02:20 -07001692 { "getResourceName","(I)Ljava/lang/String;",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001693 (void*) android_content_AssetManager_getResourceName },
John Reck32995222016-10-07 11:02:20 -07001694 { "getResourcePackageName","(I)Ljava/lang/String;",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001695 (void*) android_content_AssetManager_getResourcePackageName },
John Reck32995222016-10-07 11:02:20 -07001696 { "getResourceTypeName","(I)Ljava/lang/String;",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001697 (void*) android_content_AssetManager_getResourceTypeName },
John Reck32995222016-10-07 11:02:20 -07001698 { "getResourceEntryName","(I)Ljava/lang/String;",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001699 (void*) android_content_AssetManager_getResourceEntryName },
John Reck32995222016-10-07 11:02:20 -07001700 { "loadResourceValue","(ISLandroid/util/TypedValue;Z)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001701 (void*) android_content_AssetManager_loadResourceValue },
John Reck32995222016-10-07 11:02:20 -07001702 { "loadResourceBagValue","(IILandroid/util/TypedValue;Z)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001703 (void*) android_content_AssetManager_loadResourceBagValue },
John Reck32995222016-10-07 11:02:20 -07001704 { "getStringBlockCount","()I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001705 (void*) android_content_AssetManager_getStringBlockCount },
John Reck32995222016-10-07 11:02:20 -07001706 { "getNativeStringBlock","(I)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001707 (void*) android_content_AssetManager_getNativeStringBlock },
1708 { "getCookieName","(I)Ljava/lang/String;",
1709 (void*) android_content_AssetManager_getCookieName },
Adam Lesinskide898ff2014-01-29 18:20:45 -08001710 { "getAssignedPackageIdentifiers","()Landroid/util/SparseArray;",
1711 (void*) android_content_AssetManager_getAssignedPackageIdentifiers },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001712
1713 // Themes.
Ashok Bhat896043d2014-01-17 16:02:38 +00001714 { "newTheme", "()J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001715 (void*) android_content_AssetManager_newTheme },
Ashok Bhat896043d2014-01-17 16:02:38 +00001716 { "deleteTheme", "(J)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001717 (void*) android_content_AssetManager_deleteTheme },
Ashok Bhat896043d2014-01-17 16:02:38 +00001718 { "applyThemeStyle", "(JIZ)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001719 (void*) android_content_AssetManager_applyThemeStyle },
Ashok Bhat896043d2014-01-17 16:02:38 +00001720 { "copyTheme", "(JJ)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001721 (void*) android_content_AssetManager_copyTheme },
Alan Viverettee54d2452015-05-06 10:41:43 -07001722 { "clearTheme", "(J)V",
1723 (void*) android_content_AssetManager_clearTheme },
John Reck32995222016-10-07 11:02:20 -07001724 { "loadThemeAttributeValue", "(JILandroid/util/TypedValue;Z)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001725 (void*) android_content_AssetManager_loadThemeAttributeValue },
John Reck32995222016-10-07 11:02:20 -07001726 { "getThemeChangingConfigurations", "(J)I",
Alan Viverettec1d52792015-05-05 09:49:03 -07001727 (void*) android_content_AssetManager_getThemeChangingConfigurations },
Ashok Bhat896043d2014-01-17 16:02:38 +00001728 { "dumpTheme", "(JILjava/lang/String;Ljava/lang/String;)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001729 (void*) android_content_AssetManager_dumpTheme },
John Reckf32adf42016-11-23 10:39:40 -08001730 { "applyStyle","(JIIJ[IIJJ)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001731 (void*) android_content_AssetManager_applyStyle },
John Reck32995222016-10-07 11:02:20 -07001732 { "resolveAttrs","(JII[I[I[I[I)Z",
Alan Viverette607bd842014-09-12 12:36:35 -07001733 (void*) android_content_AssetManager_resolveAttrs },
John Reck32995222016-10-07 11:02:20 -07001734 { "retrieveAttributes","(J[I[I[I)Z",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001735 (void*) android_content_AssetManager_retrieveAttributes },
John Reck32995222016-10-07 11:02:20 -07001736 { "getArraySize","(I)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001737 (void*) android_content_AssetManager_getArraySize },
John Reck32995222016-10-07 11:02:20 -07001738 { "retrieveArray","(I[I)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001739 (void*) android_content_AssetManager_retrieveArray },
1740
1741 // XML files.
Ashok Bhat896043d2014-01-17 16:02:38 +00001742 { "openXmlAssetNative", "(ILjava/lang/String;)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001743 (void*) android_content_AssetManager_openXmlAssetNative },
1744
1745 // Arrays.
1746 { "getArrayStringResource","(I)[Ljava/lang/String;",
1747 (void*) android_content_AssetManager_getArrayStringResource },
John Reck32995222016-10-07 11:02:20 -07001748 { "getArrayStringInfo","(I)[I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001749 (void*) android_content_AssetManager_getArrayStringInfo },
John Reck32995222016-10-07 11:02:20 -07001750 { "getArrayIntResource","(I)[I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001751 (void*) android_content_AssetManager_getArrayIntResource },
John Reck32995222016-10-07 11:02:20 -07001752 { "getStyleAttributes","(I)[I",
Jon Miranda042ad632014-09-03 17:57:35 -07001753 (void*) android_content_AssetManager_getStyleAttributes },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001754
1755 // Bookkeeping.
Mårten Kongstad48d22322014-01-31 14:43:27 +01001756 { "init", "(Z)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001757 (void*) android_content_AssetManager_init },
1758 { "destroy", "()V",
1759 (void*) android_content_AssetManager_destroy },
1760 { "getGlobalAssetCount", "()I",
1761 (void*) android_content_AssetManager_getGlobalAssetCount },
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07001762 { "getAssetAllocations", "()Ljava/lang/String;",
1763 (void*) android_content_AssetManager_getAssetAllocations },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001764 { "getGlobalAssetManagerCount", "()I",
Andreas Gampe32812612014-11-11 00:16:00 -08001765 (void*) android_content_AssetManager_getGlobalAssetManagerCount },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001766};
1767
1768int register_android_content_AssetManager(JNIEnv* env)
1769{
Andreas Gampe987f79f2014-11-18 17:29:46 -08001770 jclass typedValue = FindClassOrDie(env, "android/util/TypedValue");
1771 gTypedValueOffsets.mType = GetFieldIDOrDie(env, typedValue, "type", "I");
1772 gTypedValueOffsets.mData = GetFieldIDOrDie(env, typedValue, "data", "I");
1773 gTypedValueOffsets.mString = GetFieldIDOrDie(env, typedValue, "string",
1774 "Ljava/lang/CharSequence;");
1775 gTypedValueOffsets.mAssetCookie = GetFieldIDOrDie(env, typedValue, "assetCookie", "I");
1776 gTypedValueOffsets.mResourceId = GetFieldIDOrDie(env, typedValue, "resourceId", "I");
1777 gTypedValueOffsets.mChangingConfigurations = GetFieldIDOrDie(env, typedValue,
1778 "changingConfigurations", "I");
1779 gTypedValueOffsets.mDensity = GetFieldIDOrDie(env, typedValue, "density", "I");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001780
Andreas Gampe987f79f2014-11-18 17:29:46 -08001781 jclass assetFd = FindClassOrDie(env, "android/content/res/AssetFileDescriptor");
1782 gAssetFileDescriptorOffsets.mFd = GetFieldIDOrDie(env, assetFd, "mFd",
1783 "Landroid/os/ParcelFileDescriptor;");
1784 gAssetFileDescriptorOffsets.mStartOffset = GetFieldIDOrDie(env, assetFd, "mStartOffset", "J");
1785 gAssetFileDescriptorOffsets.mLength = GetFieldIDOrDie(env, assetFd, "mLength", "J");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001786
Andreas Gampe987f79f2014-11-18 17:29:46 -08001787 jclass assetManager = FindClassOrDie(env, "android/content/res/AssetManager");
1788 gAssetManagerOffsets.mObject = GetFieldIDOrDie(env, assetManager, "mObject", "J");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001789
Andreas Gampe987f79f2014-11-18 17:29:46 -08001790 jclass stringClass = FindClassOrDie(env, "java/lang/String");
1791 g_stringClass = MakeGlobalRefOrDie(env, stringClass);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001792
Andreas Gampe987f79f2014-11-18 17:29:46 -08001793 jclass sparseArrayClass = FindClassOrDie(env, "android/util/SparseArray");
1794 gSparseArrayOffsets.classObject = MakeGlobalRefOrDie(env, sparseArrayClass);
1795 gSparseArrayOffsets.constructor = GetMethodIDOrDie(env, gSparseArrayOffsets.classObject,
1796 "<init>", "()V");
1797 gSparseArrayOffsets.put = GetMethodIDOrDie(env, gSparseArrayOffsets.classObject, "put",
1798 "(ILjava/lang/Object;)V");
Adam Lesinskide898ff2014-01-29 18:20:45 -08001799
Filip Gruszczynski23493322015-07-29 17:02:59 -07001800 jclass configurationClass = FindClassOrDie(env, "android/content/res/Configuration");
1801 gConfigurationOffsets.classObject = MakeGlobalRefOrDie(env, configurationClass);
1802 gConfigurationOffsets.constructor = GetMethodIDOrDie(env, configurationClass,
1803 "<init>", "()V");
1804 gConfigurationOffsets.mSmallestScreenWidthDpOffset = GetFieldIDOrDie(env, configurationClass,
1805 "smallestScreenWidthDp", "I");
1806 gConfigurationOffsets.mScreenWidthDpOffset = GetFieldIDOrDie(env, configurationClass,
1807 "screenWidthDp", "I");
1808 gConfigurationOffsets.mScreenHeightDpOffset = GetFieldIDOrDie(env, configurationClass,
1809 "screenHeightDp", "I");
1810
Andreas Gampe987f79f2014-11-18 17:29:46 -08001811 return RegisterMethodsOrDie(env, "android/content/res/AssetManager", gAssetManagerMethods,
1812 NELEM(gAssetManagerMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001813}
1814
1815}; // namespace android