blob: 373bda96afba183e7a7d4789e9b71a5a58ef386d [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
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];
181 int len = __system_property_get(AssetManager::OVERLAY_THEME_DIR_PERSIST_PROPERTY,
182 subdir);
183 if (len == 0) {
184 len = __system_property_get(AssetManager::OVERLAY_THEME_DIR_PROPERTY, subdir);
185 }
186 if (len > 0) {
187 String8 overlayPath = String8(AssetManager::OVERLAY_DIR) + "/" + subdir;
188 if (stat(overlayPath.string(), &st) == 0) {
189 argv[argc++] = overlayPath.string();
190 }
191 }
192 if (stat(AssetManager::OVERLAY_DIR, &st) == 0) {
193 argv[argc++] = AssetManager::OVERLAY_DIR;
194 }
195
196 // Finally, invoke idmap (if any overlay directory exists)
197 if (argc > 5) {
198 execv(AssetManager::IDMAP_BIN, (char* const*)argv);
199 ALOGE("failed to execv for idmap: %s", strerror(errno));
200 exit(1); // should never get here
201 } else {
202 exit(0);
203 }
204 }
205 break;
206 default: // parent
207 waitpid(pid, NULL, 0);
208 break;
209 }
210}
211
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800212// ----------------------------------------------------------------------------
213
214// this guy is exported to other jni routines
215AssetManager* assetManagerForJavaObject(JNIEnv* env, jobject obj)
216{
Ashok Bhat896043d2014-01-17 16:02:38 +0000217 jlong amHandle = env->GetLongField(obj, gAssetManagerOffsets.mObject);
218 AssetManager* am = reinterpret_cast<AssetManager*>(amHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800219 if (am != NULL) {
220 return am;
221 }
222 jniThrowException(env, "java/lang/IllegalStateException", "AssetManager has been finalized!");
223 return NULL;
224}
225
Ashok Bhat896043d2014-01-17 16:02:38 +0000226static jlong android_content_AssetManager_openAsset(JNIEnv* env, jobject clazz,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800227 jstring fileName, jint mode)
228{
229 AssetManager* am = assetManagerForJavaObject(env, clazz);
230 if (am == NULL) {
231 return 0;
232 }
233
Steve Block71f2cf12011-10-20 11:56:00 +0100234 ALOGV("openAsset in %p (Java object %p)\n", am, clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800235
Elliott Hughes69a017b2011-04-08 14:10:28 -0700236 ScopedUtfChars fileName8(env, fileName);
237 if (fileName8.c_str() == NULL) {
Ashok Bhat896043d2014-01-17 16:02:38 +0000238 jniThrowException(env, "java/lang/IllegalArgumentException", "Empty file name");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800239 return -1;
240 }
241
242 if (mode != Asset::ACCESS_UNKNOWN && mode != Asset::ACCESS_RANDOM
243 && mode != Asset::ACCESS_STREAMING && mode != Asset::ACCESS_BUFFER) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -0700244 jniThrowException(env, "java/lang/IllegalArgumentException", "Bad access mode");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800245 return -1;
246 }
247
Elliott Hughes69a017b2011-04-08 14:10:28 -0700248 Asset* a = am->open(fileName8.c_str(), (Asset::AccessMode)mode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800249
250 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700251 jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800252 return -1;
253 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800254
255 //printf("Created Asset Stream: %p\n", a);
256
Ashok Bhat896043d2014-01-17 16:02:38 +0000257 return reinterpret_cast<jlong>(a);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800258}
259
260static jobject returnParcelFileDescriptor(JNIEnv* env, Asset* a, jlongArray outOffsets)
261{
Kenny Rootddb76c42010-11-24 12:56:06 -0800262 off64_t startOffset, length;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800263 int fd = a->openFileDescriptor(&startOffset, &length);
264 delete a;
Elliott Hughes69a017b2011-04-08 14:10:28 -0700265
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800266 if (fd < 0) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -0700267 jniThrowException(env, "java/io/FileNotFoundException",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800268 "This file can not be opened as a file descriptor; it is probably compressed");
269 return NULL;
270 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700271
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800272 jlong* offsets = (jlong*)env->GetPrimitiveArrayCritical(outOffsets, 0);
273 if (offsets == NULL) {
274 close(fd);
275 return NULL;
276 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700277
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800278 offsets[0] = startOffset;
279 offsets[1] = length;
Elliott Hughes69a017b2011-04-08 14:10:28 -0700280
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800281 env->ReleasePrimitiveArrayCritical(outOffsets, offsets, 0);
Elliott Hughes69a017b2011-04-08 14:10:28 -0700282
Elliott Hughesa3804cf2011-04-11 16:50:19 -0700283 jobject fileDesc = jniCreateFileDescriptor(env, fd);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800284 if (fileDesc == NULL) {
285 close(fd);
286 return NULL;
287 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700288
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800289 return newParcelFileDescriptor(env, fileDesc);
290}
291
292static jobject android_content_AssetManager_openAssetFd(JNIEnv* env, jobject clazz,
293 jstring fileName, jlongArray outOffsets)
294{
295 AssetManager* am = assetManagerForJavaObject(env, clazz);
296 if (am == NULL) {
297 return NULL;
298 }
299
Steve Block71f2cf12011-10-20 11:56:00 +0100300 ALOGV("openAssetFd in %p (Java object %p)\n", am, clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800301
Elliott Hughes69a017b2011-04-08 14:10:28 -0700302 ScopedUtfChars fileName8(env, fileName);
303 if (fileName8.c_str() == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800304 return NULL;
305 }
306
Elliott Hughes69a017b2011-04-08 14:10:28 -0700307 Asset* a = am->open(fileName8.c_str(), Asset::ACCESS_RANDOM);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800308
309 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700310 jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800311 return NULL;
312 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800313
314 //printf("Created Asset Stream: %p\n", a);
315
316 return returnParcelFileDescriptor(env, a, outOffsets);
317}
318
Ashok Bhat896043d2014-01-17 16:02:38 +0000319static jlong android_content_AssetManager_openNonAssetNative(JNIEnv* env, jobject clazz,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800320 jint cookie,
321 jstring fileName,
322 jint mode)
323{
324 AssetManager* am = assetManagerForJavaObject(env, clazz);
325 if (am == NULL) {
326 return 0;
327 }
328
Steve Block71f2cf12011-10-20 11:56:00 +0100329 ALOGV("openNonAssetNative in %p (Java object %p)\n", am, clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800330
Elliott Hughes69a017b2011-04-08 14:10:28 -0700331 ScopedUtfChars fileName8(env, fileName);
332 if (fileName8.c_str() == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800333 return -1;
334 }
335
336 if (mode != Asset::ACCESS_UNKNOWN && mode != Asset::ACCESS_RANDOM
337 && mode != Asset::ACCESS_STREAMING && mode != Asset::ACCESS_BUFFER) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -0700338 jniThrowException(env, "java/lang/IllegalArgumentException", "Bad access mode");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800339 return -1;
340 }
341
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800342 Asset* a = cookie
Narayan Kamath745d4ef2014-01-27 11:17:22 +0000343 ? am->openNonAsset(static_cast<int32_t>(cookie), fileName8.c_str(),
344 (Asset::AccessMode)mode)
Elliott Hughes69a017b2011-04-08 14:10:28 -0700345 : am->openNonAsset(fileName8.c_str(), (Asset::AccessMode)mode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800346
347 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700348 jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800349 return -1;
350 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800351
352 //printf("Created Asset Stream: %p\n", a);
353
Ashok Bhat896043d2014-01-17 16:02:38 +0000354 return reinterpret_cast<jlong>(a);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800355}
356
357static jobject android_content_AssetManager_openNonAssetFdNative(JNIEnv* env, jobject clazz,
358 jint cookie,
359 jstring fileName,
360 jlongArray outOffsets)
361{
362 AssetManager* am = assetManagerForJavaObject(env, clazz);
363 if (am == NULL) {
364 return NULL;
365 }
366
Steve Block71f2cf12011-10-20 11:56:00 +0100367 ALOGV("openNonAssetFd in %p (Java object %p)\n", am, clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800368
Elliott Hughes69a017b2011-04-08 14:10:28 -0700369 ScopedUtfChars fileName8(env, fileName);
370 if (fileName8.c_str() == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800371 return NULL;
372 }
373
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800374 Asset* a = cookie
Narayan Kamath745d4ef2014-01-27 11:17:22 +0000375 ? am->openNonAsset(static_cast<int32_t>(cookie), fileName8.c_str(), Asset::ACCESS_RANDOM)
Elliott Hughes69a017b2011-04-08 14:10:28 -0700376 : am->openNonAsset(fileName8.c_str(), Asset::ACCESS_RANDOM);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800377
378 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700379 jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800380 return NULL;
381 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800382
383 //printf("Created Asset Stream: %p\n", a);
384
385 return returnParcelFileDescriptor(env, a, outOffsets);
386}
387
388static jobjectArray android_content_AssetManager_list(JNIEnv* env, jobject clazz,
389 jstring fileName)
390{
391 AssetManager* am = assetManagerForJavaObject(env, clazz);
392 if (am == NULL) {
393 return NULL;
394 }
395
Elliott Hughes69a017b2011-04-08 14:10:28 -0700396 ScopedUtfChars fileName8(env, fileName);
397 if (fileName8.c_str() == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800398 return NULL;
399 }
400
Elliott Hughes69a017b2011-04-08 14:10:28 -0700401 AssetDir* dir = am->openDir(fileName8.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800402
403 if (dir == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700404 jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800405 return NULL;
406 }
407
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800408 size_t N = dir->getFileCount();
409
410 jobjectArray array = env->NewObjectArray(dir->getFileCount(),
Vladimir Markoaa5fe3d2013-06-17 12:46:22 +0100411 g_stringClass, NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800412 if (array == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800413 delete dir;
414 return NULL;
415 }
416
417 for (size_t i=0; i<N; i++) {
418 const String8& name = dir->getFileName(i);
419 jstring str = env->NewStringUTF(name.string());
420 if (str == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800421 delete dir;
422 return NULL;
423 }
424 env->SetObjectArrayElement(array, i, str);
Gilles Debunne4d4040b2010-08-26 15:59:54 -0700425 env->DeleteLocalRef(str);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800426 }
427
428 delete dir;
429
430 return array;
431}
432
433static void android_content_AssetManager_destroyAsset(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +0000434 jlong assetHandle)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800435{
Ashok Bhat896043d2014-01-17 16:02:38 +0000436 Asset* a = reinterpret_cast<Asset*>(assetHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800437
438 //printf("Destroying Asset Stream: %p\n", a);
439
440 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700441 jniThrowNullPointerException(env, "asset");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800442 return;
443 }
444
445 delete a;
446}
447
448static jint android_content_AssetManager_readAssetChar(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +0000449 jlong assetHandle)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800450{
Ashok Bhat896043d2014-01-17 16:02:38 +0000451 Asset* a = reinterpret_cast<Asset*>(assetHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800452
453 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700454 jniThrowNullPointerException(env, "asset");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800455 return -1;
456 }
457
458 uint8_t b;
459 ssize_t res = a->read(&b, 1);
460 return res == 1 ? b : -1;
461}
462
463static jint android_content_AssetManager_readAsset(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +0000464 jlong assetHandle, jbyteArray bArray,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800465 jint off, jint len)
466{
Ashok Bhat896043d2014-01-17 16:02:38 +0000467 Asset* a = reinterpret_cast<Asset*>(assetHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800468
469 if (a == NULL || bArray == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700470 jniThrowNullPointerException(env, "asset");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800471 return -1;
472 }
473
474 if (len == 0) {
475 return 0;
476 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700477
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800478 jsize bLen = env->GetArrayLength(bArray);
479 if (off < 0 || off >= bLen || len < 0 || len > bLen || (off+len) > bLen) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -0700480 jniThrowException(env, "java/lang/IndexOutOfBoundsException", "");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800481 return -1;
482 }
483
484 jbyte* b = env->GetByteArrayElements(bArray, NULL);
485 ssize_t res = a->read(b+off, len);
486 env->ReleaseByteArrayElements(bArray, b, 0);
487
Ashok Bhat896043d2014-01-17 16:02:38 +0000488 if (res > 0) return static_cast<jint>(res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800489
490 if (res < 0) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -0700491 jniThrowException(env, "java/io/IOException", "");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800492 }
493 return -1;
494}
495
496static jlong android_content_AssetManager_seekAsset(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +0000497 jlong assetHandle,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800498 jlong offset, jint whence)
499{
Ashok Bhat896043d2014-01-17 16:02:38 +0000500 Asset* a = reinterpret_cast<Asset*>(assetHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800501
502 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700503 jniThrowNullPointerException(env, "asset");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800504 return -1;
505 }
506
507 return a->seek(
508 offset, (whence > 0) ? SEEK_END : (whence < 0 ? SEEK_SET : SEEK_CUR));
509}
510
511static jlong android_content_AssetManager_getAssetLength(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +0000512 jlong assetHandle)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800513{
Ashok Bhat896043d2014-01-17 16:02:38 +0000514 Asset* a = reinterpret_cast<Asset*>(assetHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800515
516 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700517 jniThrowNullPointerException(env, "asset");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800518 return -1;
519 }
520
521 return a->getLength();
522}
523
524static jlong android_content_AssetManager_getAssetRemainingLength(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +0000525 jlong assetHandle)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800526{
Ashok Bhat896043d2014-01-17 16:02:38 +0000527 Asset* a = reinterpret_cast<Asset*>(assetHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800528
529 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700530 jniThrowNullPointerException(env, "asset");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800531 return -1;
532 }
533
534 return a->getRemainingLength();
535}
536
537static jint android_content_AssetManager_addAssetPath(JNIEnv* env, jobject clazz,
Tao Baia6d7e3f2015-09-01 18:49:54 -0700538 jstring path, jboolean appAsLib)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800539{
Elliott Hughes69a017b2011-04-08 14:10:28 -0700540 ScopedUtfChars path8(env, path);
541 if (path8.c_str() == NULL) {
Glenn Kasten129e19c2012-01-10 17:57:36 -0800542 return 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800543 }
544
545 AssetManager* am = assetManagerForJavaObject(env, clazz);
546 if (am == NULL) {
Glenn Kasten129e19c2012-01-10 17:57:36 -0800547 return 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800548 }
549
Narayan Kamath745d4ef2014-01-27 11:17:22 +0000550 int32_t cookie;
Tao Baia6d7e3f2015-09-01 18:49:54 -0700551 bool res = am->addAssetPath(String8(path8.c_str()), &cookie, appAsLib);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800552
Narayan Kamath745d4ef2014-01-27 11:17:22 +0000553 return (res) ? static_cast<jint>(cookie) : 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800554}
555
Mårten Kongstad48d22322014-01-31 14:43:27 +0100556static jint android_content_AssetManager_addOverlayPath(JNIEnv* env, jobject clazz,
557 jstring idmapPath)
558{
559 ScopedUtfChars idmapPath8(env, idmapPath);
560 if (idmapPath8.c_str() == NULL) {
561 return 0;
562 }
563
564 AssetManager* am = assetManagerForJavaObject(env, clazz);
565 if (am == NULL) {
566 return 0;
567 }
568
569 int32_t cookie;
570 bool res = am->addOverlayPath(String8(idmapPath8.c_str()), &cookie);
571
572 return (res) ? (jint)cookie : 0;
573}
574
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800575static jboolean android_content_AssetManager_isUpToDate(JNIEnv* env, jobject clazz)
576{
577 AssetManager* am = assetManagerForJavaObject(env, clazz);
578 if (am == NULL) {
579 return JNI_TRUE;
580 }
581 return am->isUpToDate() ? JNI_TRUE : JNI_FALSE;
582}
583
Roozbeh Pournader1c686f22015-12-18 14:22:14 -0800584static jobjectArray getLocales(JNIEnv* env, jobject clazz, bool includeSystemLocales)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800585{
586 Vector<String8> locales;
587
588 AssetManager* am = assetManagerForJavaObject(env, clazz);
589 if (am == NULL) {
590 return NULL;
591 }
592
Roozbeh Pournader1c686f22015-12-18 14:22:14 -0800593 am->getLocales(&locales, includeSystemLocales);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800594
595 const int N = locales.size();
596
597 jobjectArray result = env->NewObjectArray(N, g_stringClass, NULL);
598 if (result == NULL) {
599 return NULL;
600 }
601
602 for (int i=0; i<N; i++) {
Gilles Debunne0db187a2010-08-27 11:51:34 -0700603 jstring str = env->NewStringUTF(locales[i].string());
Gilles Debunne4d4040b2010-08-26 15:59:54 -0700604 if (str == NULL) {
605 return NULL;
606 }
607 env->SetObjectArrayElement(result, i, str);
608 env->DeleteLocalRef(str);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800609 }
610
611 return result;
612}
613
Roozbeh Pournader1c686f22015-12-18 14:22:14 -0800614static jobjectArray android_content_AssetManager_getLocales(JNIEnv* env, jobject clazz)
615{
616 return getLocales(env, clazz, true /* include system locales */);
617}
618
619static jobjectArray android_content_AssetManager_getNonSystemLocales(JNIEnv* env, jobject clazz)
620{
621 return getLocales(env, clazz, false /* don't include system locales */);
622}
623
Filip Gruszczynski23493322015-07-29 17:02:59 -0700624static jobject constructConfigurationObject(JNIEnv* env, const ResTable_config& config) {
625 jobject result = env->NewObject(gConfigurationOffsets.classObject,
626 gConfigurationOffsets.constructor);
627 if (result == NULL) {
628 return NULL;
629 }
630
631 env->SetIntField(result, gConfigurationOffsets.mSmallestScreenWidthDpOffset,
632 config.smallestScreenWidthDp);
633 env->SetIntField(result, gConfigurationOffsets.mScreenWidthDpOffset, config.screenWidthDp);
634 env->SetIntField(result, gConfigurationOffsets.mScreenHeightDpOffset, config.screenHeightDp);
635
636 return result;
637}
638
639static jobjectArray getSizeConfigurationsInternal(JNIEnv* env,
640 const Vector<ResTable_config>& configs) {
641 const int N = configs.size();
642 jobjectArray result = env->NewObjectArray(N, gConfigurationOffsets.classObject, NULL);
643 if (result == NULL) {
644 return NULL;
645 }
646
647 for (int i=0; i<N; i++) {
648 jobject config = constructConfigurationObject(env, configs[i]);
649 if (config == NULL) {
650 env->DeleteLocalRef(result);
651 return NULL;
652 }
653
654 env->SetObjectArrayElement(result, i, config);
655 env->DeleteLocalRef(config);
656 }
657
658 return result;
659}
660
661static jobjectArray android_content_AssetManager_getSizeConfigurations(JNIEnv* env, jobject clazz) {
662 AssetManager* am = assetManagerForJavaObject(env, clazz);
663 if (am == NULL) {
664 return NULL;
665 }
666
667 const ResTable& res(am->getResources());
668 Vector<ResTable_config> configs;
669 res.getConfigurations(&configs, false /* ignoreMipmap */, true /* ignoreAndroidPackage */);
670
671 return getSizeConfigurationsInternal(env, configs);
672}
673
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800674static void android_content_AssetManager_setConfiguration(JNIEnv* env, jobject clazz,
675 jint mcc, jint mnc,
676 jstring locale, jint orientation,
677 jint touchscreen, jint density,
678 jint keyboard, jint keyboardHidden,
679 jint navigation,
680 jint screenWidth, jint screenHeight,
Dianne Hackborn69cb8752011-05-19 18:13:32 -0700681 jint smallestScreenWidthDp,
Dianne Hackborn3fc982f2011-03-30 16:20:26 -0700682 jint screenWidthDp, jint screenHeightDp,
Tobias Haamel27b28b32010-02-09 23:09:17 +0100683 jint screenLayout, jint uiMode,
Romain Guy408afbf2017-01-25 10:23:03 -0800684 jint colorMode, jint sdkVersion)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800685{
686 AssetManager* am = assetManagerForJavaObject(env, clazz);
687 if (am == NULL) {
688 return;
689 }
690
691 ResTable_config config;
692 memset(&config, 0, sizeof(config));
Elliott Hughes69a017b2011-04-08 14:10:28 -0700693
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800694 const char* locale8 = locale != NULL ? env->GetStringUTFChars(locale, NULL) : NULL;
Elliott Hughes69a017b2011-04-08 14:10:28 -0700695
Adam Lesinski2738c962015-05-14 14:25:36 -0700696 // Constants duplicated from Java class android.content.res.Configuration.
697 static const jint kScreenLayoutRoundMask = 0x300;
698 static const jint kScreenLayoutRoundShift = 8;
699
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800700 config.mcc = (uint16_t)mcc;
701 config.mnc = (uint16_t)mnc;
702 config.orientation = (uint8_t)orientation;
703 config.touchscreen = (uint8_t)touchscreen;
704 config.density = (uint16_t)density;
705 config.keyboard = (uint8_t)keyboard;
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700706 config.inputFlags = (uint8_t)keyboardHidden;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800707 config.navigation = (uint8_t)navigation;
708 config.screenWidth = (uint16_t)screenWidth;
709 config.screenHeight = (uint16_t)screenHeight;
Dianne Hackborn69cb8752011-05-19 18:13:32 -0700710 config.smallestScreenWidthDp = (uint16_t)smallestScreenWidthDp;
Dianne Hackborn3fc982f2011-03-30 16:20:26 -0700711 config.screenWidthDp = (uint16_t)screenWidthDp;
712 config.screenHeightDp = (uint16_t)screenHeightDp;
Dianne Hackborn723738c2009-06-25 19:48:04 -0700713 config.screenLayout = (uint8_t)screenLayout;
Tobias Haamel27b28b32010-02-09 23:09:17 +0100714 config.uiMode = (uint8_t)uiMode;
Romain Guy408afbf2017-01-25 10:23:03 -0800715 config.colorMode = (uint8_t)colorMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800716 config.sdkVersion = (uint16_t)sdkVersion;
717 config.minorVersion = 0;
Adam Lesinski2738c962015-05-14 14:25:36 -0700718
719 // In Java, we use a 32bit integer for screenLayout, while we only use an 8bit integer
720 // in C++. We must extract the round qualifier out of the Java screenLayout and put it
721 // into screenLayout2.
722 config.screenLayout2 =
723 (uint8_t)((screenLayout & kScreenLayoutRoundMask) >> kScreenLayoutRoundShift);
724
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800725 am->setConfiguration(config, locale8);
Elliott Hughes69a017b2011-04-08 14:10:28 -0700726
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800727 if (locale != NULL) env->ReleaseStringUTFChars(locale, locale8);
728}
729
730static jint android_content_AssetManager_getResourceIdentifier(JNIEnv* env, jobject clazz,
731 jstring name,
732 jstring defType,
733 jstring defPackage)
734{
Elliott Hughes69a017b2011-04-08 14:10:28 -0700735 ScopedStringChars name16(env, name);
736 if (name16.get() == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800737 return 0;
738 }
739
740 AssetManager* am = assetManagerForJavaObject(env, clazz);
741 if (am == NULL) {
742 return 0;
743 }
744
Dan Albert66987492014-11-20 11:41:21 -0800745 const char16_t* defType16 = reinterpret_cast<const char16_t*>(defType)
746 ? reinterpret_cast<const char16_t*>(env->GetStringChars(defType, NULL))
747 : NULL;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800748 jsize defTypeLen = defType
749 ? env->GetStringLength(defType) : 0;
Dan Albert66987492014-11-20 11:41:21 -0800750 const char16_t* defPackage16 = reinterpret_cast<const char16_t*>(defPackage)
751 ? reinterpret_cast<const char16_t*>(env->GetStringChars(defPackage,
752 NULL))
753 : NULL;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800754 jsize defPackageLen = defPackage
755 ? env->GetStringLength(defPackage) : 0;
756
757 jint ident = am->getResources().identifierForName(
Dan Albert66987492014-11-20 11:41:21 -0800758 reinterpret_cast<const char16_t*>(name16.get()), name16.size(),
759 defType16, defTypeLen, defPackage16, defPackageLen);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800760
761 if (defPackage16) {
Dan Albert66987492014-11-20 11:41:21 -0800762 env->ReleaseStringChars(defPackage,
763 reinterpret_cast<const jchar*>(defPackage16));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800764 }
765 if (defType16) {
Dan Albert66987492014-11-20 11:41:21 -0800766 env->ReleaseStringChars(defType,
767 reinterpret_cast<const jchar*>(defType16));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800768 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800769
770 return ident;
771}
772
773static jstring android_content_AssetManager_getResourceName(JNIEnv* env, jobject clazz,
774 jint resid)
775{
776 AssetManager* am = assetManagerForJavaObject(env, clazz);
777 if (am == NULL) {
778 return NULL;
779 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700780
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800781 ResTable::resource_name name;
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700782 if (!am->getResources().getResourceName(resid, true, &name)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800783 return NULL;
784 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700785
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800786 String16 str;
787 if (name.package != NULL) {
788 str.setTo(name.package, name.packageLen);
789 }
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700790 if (name.type8 != NULL || name.type != NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800791 if (str.size() > 0) {
792 char16_t div = ':';
793 str.append(&div, 1);
794 }
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700795 if (name.type8 != NULL) {
796 str.append(String16(name.type8, name.typeLen));
797 } else {
798 str.append(name.type, name.typeLen);
799 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800800 }
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700801 if (name.name8 != NULL || name.name != NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800802 if (str.size() > 0) {
803 char16_t div = '/';
804 str.append(&div, 1);
805 }
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700806 if (name.name8 != NULL) {
807 str.append(String16(name.name8, name.nameLen));
808 } else {
809 str.append(name.name, name.nameLen);
810 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800811 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700812
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800813 return env->NewString((const jchar*)str.string(), str.size());
814}
815
816static jstring android_content_AssetManager_getResourcePackageName(JNIEnv* env, jobject clazz,
817 jint resid)
818{
819 AssetManager* am = assetManagerForJavaObject(env, clazz);
820 if (am == NULL) {
821 return NULL;
822 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700823
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800824 ResTable::resource_name name;
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700825 if (!am->getResources().getResourceName(resid, true, &name)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800826 return NULL;
827 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700828
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800829 if (name.package != NULL) {
830 return env->NewString((const jchar*)name.package, name.packageLen);
831 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700832
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800833 return NULL;
834}
835
836static jstring android_content_AssetManager_getResourceTypeName(JNIEnv* env, jobject clazz,
837 jint resid)
838{
839 AssetManager* am = assetManagerForJavaObject(env, clazz);
840 if (am == NULL) {
841 return NULL;
842 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700843
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800844 ResTable::resource_name name;
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700845 if (!am->getResources().getResourceName(resid, true, &name)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800846 return NULL;
847 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700848
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700849 if (name.type8 != NULL) {
850 return env->NewStringUTF(name.type8);
851 }
852
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800853 if (name.type != NULL) {
854 return env->NewString((const jchar*)name.type, name.typeLen);
855 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700856
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800857 return NULL;
858}
859
860static jstring android_content_AssetManager_getResourceEntryName(JNIEnv* env, jobject clazz,
861 jint resid)
862{
863 AssetManager* am = assetManagerForJavaObject(env, clazz);
864 if (am == NULL) {
865 return NULL;
866 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700867
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800868 ResTable::resource_name name;
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700869 if (!am->getResources().getResourceName(resid, true, &name)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800870 return NULL;
871 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700872
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700873 if (name.name8 != NULL) {
874 return env->NewStringUTF(name.name8);
875 }
876
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800877 if (name.name != NULL) {
878 return env->NewString((const jchar*)name.name, name.nameLen);
879 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700880
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800881 return NULL;
882}
883
884static jint android_content_AssetManager_loadResourceValue(JNIEnv* env, jobject clazz,
885 jint ident,
Kenny Root55fc8502010-10-28 14:47:01 -0700886 jshort density,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800887 jobject outValue,
888 jboolean resolve)
889{
Dianne Hackborn1f7d3072013-02-11 17:03:32 -0800890 if (outValue == NULL) {
Dianne Hackborne5b50a62013-02-11 16:18:42 -0800891 jniThrowNullPointerException(env, "outValue");
Dianne Hackbornd45c68d2013-07-31 12:14:24 -0700892 return 0;
Dianne Hackborne5b50a62013-02-11 16:18:42 -0800893 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800894 AssetManager* am = assetManagerForJavaObject(env, clazz);
895 if (am == NULL) {
896 return 0;
897 }
898 const ResTable& res(am->getResources());
899
900 Res_value value;
901 ResTable_config config;
902 uint32_t typeSpecFlags;
Kenny Root55fc8502010-10-28 14:47:01 -0700903 ssize_t block = res.getResource(ident, &value, false, density, &typeSpecFlags, &config);
Andreas Gampe0f0b4912014-11-12 08:03:48 -0800904 if (kThrowOnBadId) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -0800905 if (block == BAD_INDEX) {
906 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
907 return 0;
908 }
Andreas Gampe0f0b4912014-11-12 08:03:48 -0800909 }
910 uint32_t ref = ident;
911 if (resolve) {
912 block = res.resolveReference(&value, block, &ref, &typeSpecFlags, &config);
913 if (kThrowOnBadId) {
914 if (block == BAD_INDEX) {
915 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
916 return 0;
917 }
918 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800919 }
Ashok Bhat896043d2014-01-17 16:02:38 +0000920 if (block >= 0) {
921 return copyValue(env, outValue, &res, value, ref, block, typeSpecFlags, &config);
922 }
923
924 return static_cast<jint>(block);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800925}
926
927static jint android_content_AssetManager_loadResourceBagValue(JNIEnv* env, jobject clazz,
928 jint ident, jint bagEntryId,
929 jobject outValue, jboolean resolve)
930{
931 AssetManager* am = assetManagerForJavaObject(env, clazz);
932 if (am == NULL) {
933 return 0;
934 }
935 const ResTable& res(am->getResources());
Elliott Hughes69a017b2011-04-08 14:10:28 -0700936
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800937 // Now lock down the resource object and start pulling stuff from it.
938 res.lock();
Elliott Hughes69a017b2011-04-08 14:10:28 -0700939
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800940 ssize_t block = -1;
941 Res_value value;
942
943 const ResTable::bag_entry* entry = NULL;
944 uint32_t typeSpecFlags;
945 ssize_t entryCount = res.getBagLocked(ident, &entry, &typeSpecFlags);
946
947 for (ssize_t i=0; i<entryCount; i++) {
948 if (((uint32_t)bagEntryId) == entry->map.name.ident) {
949 block = entry->stringBlock;
950 value = entry->map.value;
951 }
952 entry++;
953 }
954
955 res.unlock();
956
957 if (block < 0) {
Ashok Bhat896043d2014-01-17 16:02:38 +0000958 return static_cast<jint>(block);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800959 }
Elliott Hughes69a017b2011-04-08 14:10:28 -0700960
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800961 uint32_t ref = ident;
962 if (resolve) {
963 block = res.resolveReference(&value, block, &ref, &typeSpecFlags);
Andreas Gampe0f0b4912014-11-12 08:03:48 -0800964 if (kThrowOnBadId) {
965 if (block == BAD_INDEX) {
966 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
967 return 0;
968 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -0800969 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800970 }
Ashok Bhat896043d2014-01-17 16:02:38 +0000971 if (block >= 0) {
972 return copyValue(env, outValue, &res, value, ref, block, typeSpecFlags);
973 }
974
975 return static_cast<jint>(block);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800976}
977
978static jint android_content_AssetManager_getStringBlockCount(JNIEnv* env, jobject clazz)
979{
980 AssetManager* am = assetManagerForJavaObject(env, clazz);
981 if (am == NULL) {
982 return 0;
983 }
984 return am->getResources().getTableCount();
985}
986
Ashok Bhat896043d2014-01-17 16:02:38 +0000987static jlong android_content_AssetManager_getNativeStringBlock(JNIEnv* env, jobject clazz,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800988 jint block)
989{
990 AssetManager* am = assetManagerForJavaObject(env, clazz);
991 if (am == NULL) {
992 return 0;
993 }
Ashok Bhat896043d2014-01-17 16:02:38 +0000994 return reinterpret_cast<jlong>(am->getResources().getTableStringBlock(block));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800995}
996
997static jstring android_content_AssetManager_getCookieName(JNIEnv* env, jobject clazz,
998 jint cookie)
999{
1000 AssetManager* am = assetManagerForJavaObject(env, clazz);
1001 if (am == NULL) {
1002 return NULL;
1003 }
Narayan Kamath745d4ef2014-01-27 11:17:22 +00001004 String8 name(am->getAssetPath(static_cast<int32_t>(cookie)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001005 if (name.length() == 0) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001006 jniThrowException(env, "java/lang/IndexOutOfBoundsException", "Empty cookie name");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001007 return NULL;
1008 }
1009 jstring str = env->NewStringUTF(name.string());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001010 return str;
1011}
1012
Adam Lesinskide898ff2014-01-29 18:20:45 -08001013static jobject android_content_AssetManager_getAssignedPackageIdentifiers(JNIEnv* env, jobject clazz)
1014{
1015 AssetManager* am = assetManagerForJavaObject(env, clazz);
1016 if (am == NULL) {
1017 return 0;
1018 }
1019
1020 const ResTable& res = am->getResources();
1021
1022 jobject sparseArray = env->NewObject(gSparseArrayOffsets.classObject,
1023 gSparseArrayOffsets.constructor);
1024 const size_t N = res.getBasePackageCount();
1025 for (size_t i = 0; i < N; i++) {
1026 const String16 name = res.getBasePackageName(i);
Dan Albert66987492014-11-20 11:41:21 -08001027 env->CallVoidMethod(
1028 sparseArray, gSparseArrayOffsets.put,
1029 static_cast<jint>(res.getBasePackageId(i)),
1030 env->NewString(reinterpret_cast<const jchar*>(name.string()),
1031 name.size()));
Adam Lesinskide898ff2014-01-29 18:20:45 -08001032 }
1033 return sparseArray;
1034}
1035
Ashok Bhat896043d2014-01-17 16:02:38 +00001036static jlong android_content_AssetManager_newTheme(JNIEnv* env, jobject clazz)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001037{
1038 AssetManager* am = assetManagerForJavaObject(env, clazz);
1039 if (am == NULL) {
1040 return 0;
1041 }
Ashok Bhat896043d2014-01-17 16:02:38 +00001042 return reinterpret_cast<jlong>(new ResTable::Theme(am->getResources()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001043}
1044
1045static void android_content_AssetManager_deleteTheme(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +00001046 jlong themeHandle)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001047{
Ashok Bhat896043d2014-01-17 16:02:38 +00001048 ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001049 delete theme;
1050}
1051
1052static void android_content_AssetManager_applyThemeStyle(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +00001053 jlong themeHandle,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001054 jint styleRes,
1055 jboolean force)
1056{
Ashok Bhat896043d2014-01-17 16:02:38 +00001057 ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001058 theme->applyStyle(styleRes, force ? true : false);
1059}
1060
1061static void android_content_AssetManager_copyTheme(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +00001062 jlong destHandle, jlong srcHandle)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001063{
Ashok Bhat896043d2014-01-17 16:02:38 +00001064 ResTable::Theme* dest = reinterpret_cast<ResTable::Theme*>(destHandle);
1065 ResTable::Theme* src = reinterpret_cast<ResTable::Theme*>(srcHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001066 dest->setTo(*src);
1067}
1068
Alan Viverettee54d2452015-05-06 10:41:43 -07001069static void android_content_AssetManager_clearTheme(JNIEnv* env, jobject clazz, jlong themeHandle)
1070{
1071 ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeHandle);
1072 theme->clear();
1073}
1074
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001075static jint android_content_AssetManager_loadThemeAttributeValue(
Ashok Bhat896043d2014-01-17 16:02:38 +00001076 JNIEnv* env, jobject clazz, jlong themeHandle, jint ident, jobject outValue, jboolean resolve)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001077{
Ashok Bhat896043d2014-01-17 16:02:38 +00001078 ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001079 const ResTable& res(theme->getResTable());
1080
1081 Res_value value;
1082 // XXX value could be different in different configs!
1083 uint32_t typeSpecFlags = 0;
1084 ssize_t block = theme->getAttribute(ident, &value, &typeSpecFlags);
1085 uint32_t ref = 0;
1086 if (resolve) {
1087 block = res.resolveReference(&value, block, &ref, &typeSpecFlags);
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001088 if (kThrowOnBadId) {
1089 if (block == BAD_INDEX) {
1090 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
1091 return 0;
1092 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001093 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001094 }
1095 return block >= 0 ? copyValue(env, outValue, &res, value, ref, block, typeSpecFlags) : block;
1096}
1097
Alan Viverettec1d52792015-05-05 09:49:03 -07001098static jint android_content_AssetManager_getThemeChangingConfigurations(JNIEnv* env, jobject clazz,
1099 jlong themeHandle)
1100{
1101 ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeHandle);
1102 return theme->getChangingConfigurations();
1103}
1104
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001105static void android_content_AssetManager_dumpTheme(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +00001106 jlong themeHandle, jint pri,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001107 jstring tag, jstring prefix)
1108{
Ashok Bhat896043d2014-01-17 16:02:38 +00001109 ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001110 const ResTable& res(theme->getResTable());
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001111 (void)res;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001112
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001113 // XXX Need to use params.
1114 theme->dumpToLog();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001115}
1116
Alan Viverette52b999f2014-03-24 18:00:26 -07001117static jboolean android_content_AssetManager_resolveAttrs(JNIEnv* env, jobject clazz,
1118 jlong themeToken,
1119 jint defStyleAttr,
1120 jint defStyleRes,
1121 jintArray inValues,
1122 jintArray attrs,
1123 jintArray outValues,
1124 jintArray outIndices)
1125{
1126 if (themeToken == 0) {
1127 jniThrowNullPointerException(env, "theme token");
1128 return JNI_FALSE;
1129 }
1130 if (attrs == NULL) {
1131 jniThrowNullPointerException(env, "attrs");
1132 return JNI_FALSE;
1133 }
1134 if (outValues == NULL) {
1135 jniThrowNullPointerException(env, "out values");
1136 return JNI_FALSE;
1137 }
1138
Alan Viverette52b999f2014-03-24 18:00:26 -07001139 const jsize NI = env->GetArrayLength(attrs);
1140 const jsize NV = env->GetArrayLength(outValues);
1141 if (NV < (NI*STYLE_NUM_ENTRIES)) {
1142 jniThrowException(env, "java/lang/IndexOutOfBoundsException", "out values too small");
1143 return JNI_FALSE;
1144 }
1145
1146 jint* src = (jint*)env->GetPrimitiveArrayCritical(attrs, 0);
1147 if (src == NULL) {
1148 return JNI_FALSE;
1149 }
1150
1151 jint* srcValues = (jint*)env->GetPrimitiveArrayCritical(inValues, 0);
1152 const jsize NSV = srcValues == NULL ? 0 : env->GetArrayLength(inValues);
1153
1154 jint* baseDest = (jint*)env->GetPrimitiveArrayCritical(outValues, 0);
Adam Lesinski4452e132016-10-12 07:47:28 -07001155 if (baseDest == NULL) {
Alan Viverette52b999f2014-03-24 18:00:26 -07001156 env->ReleasePrimitiveArrayCritical(attrs, src, 0);
1157 return JNI_FALSE;
1158 }
1159
1160 jint* indices = NULL;
Alan Viverette52b999f2014-03-24 18:00:26 -07001161 if (outIndices != NULL) {
1162 if (env->GetArrayLength(outIndices) > NI) {
1163 indices = (jint*)env->GetPrimitiveArrayCritical(outIndices, 0);
1164 }
1165 }
1166
Adam Lesinski4452e132016-10-12 07:47:28 -07001167 ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeToken);
Adam Lesinski7a37b742016-10-12 14:05:55 -07001168 bool result = ResolveAttrs(theme, defStyleAttr, defStyleRes,
Adam Lesinski4452e132016-10-12 07:47:28 -07001169 (uint32_t*) srcValues, NSV,
1170 (uint32_t*) src, NI,
1171 (uint32_t*) baseDest,
1172 (uint32_t*) indices);
Alan Viverette52b999f2014-03-24 18:00:26 -07001173
1174 if (indices != NULL) {
Alan Viverette52b999f2014-03-24 18:00:26 -07001175 env->ReleasePrimitiveArrayCritical(outIndices, indices, 0);
1176 }
1177 env->ReleasePrimitiveArrayCritical(outValues, baseDest, 0);
1178 env->ReleasePrimitiveArrayCritical(inValues, srcValues, 0);
1179 env->ReleasePrimitiveArrayCritical(attrs, src, 0);
Adam Lesinski4452e132016-10-12 07:47:28 -07001180 return result ? JNI_TRUE : JNI_FALSE;
Alan Viverette52b999f2014-03-24 18:00:26 -07001181}
1182
John Reckf32adf42016-11-23 10:39:40 -08001183static void android_content_AssetManager_applyStyle(JNIEnv* env, jobject, jlong themeToken,
1184 jint defStyleAttr, jint defStyleRes, jlong xmlParserToken, jintArray attrsObj, jint length,
1185 jlong outValuesAddress, jlong outIndicesAddress) {
1186 jint* attrs = env->GetIntArrayElements(attrsObj, 0);
Adam Lesinski4452e132016-10-12 07:47:28 -07001187 ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeToken);
1188 ResXMLParser* xmlParser = reinterpret_cast<ResXMLParser*>(xmlParserToken);
John Reckf32adf42016-11-23 10:39:40 -08001189 uint32_t* outValues = reinterpret_cast<uint32_t*>(static_cast<uintptr_t>(outValuesAddress));
1190 uint32_t* outIndices = reinterpret_cast<uint32_t*>(static_cast<uintptr_t>(outIndicesAddress));
1191 ApplyStyle(theme, xmlParser, defStyleAttr, defStyleRes,
1192 reinterpret_cast<const uint32_t*>(attrs), length, outValues, outIndices);
1193 env->ReleaseIntArrayElements(attrsObj, attrs, JNI_ABORT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001194}
1195
1196static jboolean android_content_AssetManager_retrieveAttributes(JNIEnv* env, jobject clazz,
Ashok Bhat896043d2014-01-17 16:02:38 +00001197 jlong xmlParserToken,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001198 jintArray attrs,
1199 jintArray outValues,
1200 jintArray outIndices)
1201{
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001202 if (xmlParserToken == 0) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001203 jniThrowNullPointerException(env, "xmlParserToken");
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001204 return JNI_FALSE;
1205 }
1206 if (attrs == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001207 jniThrowNullPointerException(env, "attrs");
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001208 return JNI_FALSE;
1209 }
1210 if (outValues == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001211 jniThrowNullPointerException(env, "out values");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001212 return JNI_FALSE;
1213 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001214
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001215 AssetManager* am = assetManagerForJavaObject(env, clazz);
1216 if (am == NULL) {
1217 return JNI_FALSE;
1218 }
1219 const ResTable& res(am->getResources());
1220 ResXMLParser* xmlParser = (ResXMLParser*)xmlParserToken;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001221
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001222 const jsize NI = env->GetArrayLength(attrs);
1223 const jsize NV = env->GetArrayLength(outValues);
1224 if (NV < (NI*STYLE_NUM_ENTRIES)) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001225 jniThrowException(env, "java/lang/IndexOutOfBoundsException", "out values too small");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001226 return JNI_FALSE;
1227 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001228
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001229 jint* src = (jint*)env->GetPrimitiveArrayCritical(attrs, 0);
1230 if (src == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001231 return JNI_FALSE;
1232 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001233
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001234 jint* baseDest = (jint*)env->GetPrimitiveArrayCritical(outValues, 0);
Adam Lesinski4452e132016-10-12 07:47:28 -07001235 if (baseDest == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001236 env->ReleasePrimitiveArrayCritical(attrs, src, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001237 return JNI_FALSE;
1238 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001239
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001240 jint* indices = NULL;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001241 if (outIndices != NULL) {
1242 if (env->GetArrayLength(outIndices) > NI) {
1243 indices = (jint*)env->GetPrimitiveArrayCritical(outIndices, 0);
1244 }
1245 }
1246
Adam Lesinski7a37b742016-10-12 14:05:55 -07001247 bool result = RetrieveAttributes(&res, xmlParser,
Adam Lesinski4452e132016-10-12 07:47:28 -07001248 (uint32_t*) src, NI,
1249 (uint32_t*) baseDest,
1250 (uint32_t*) indices);
Elliott Hughes69a017b2011-04-08 14:10:28 -07001251
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001252 if (indices != NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001253 env->ReleasePrimitiveArrayCritical(outIndices, indices, 0);
1254 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001255 env->ReleasePrimitiveArrayCritical(outValues, baseDest, 0);
1256 env->ReleasePrimitiveArrayCritical(attrs, src, 0);
Adam Lesinski4452e132016-10-12 07:47:28 -07001257 return result ? JNI_TRUE : JNI_FALSE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001258}
1259
1260static jint android_content_AssetManager_getArraySize(JNIEnv* env, jobject clazz,
1261 jint id)
1262{
1263 AssetManager* am = assetManagerForJavaObject(env, clazz);
1264 if (am == NULL) {
Olivier Baillyd7c86722010-11-18 14:43:36 -08001265 return 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001266 }
1267 const ResTable& res(am->getResources());
Elliott Hughes69a017b2011-04-08 14:10:28 -07001268
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001269 res.lock();
1270 const ResTable::bag_entry* defStyleEnt = NULL;
1271 ssize_t bagOff = res.getBagLocked(id, &defStyleEnt);
1272 res.unlock();
Elliott Hughes69a017b2011-04-08 14:10:28 -07001273
Ashok Bhat896043d2014-01-17 16:02:38 +00001274 return static_cast<jint>(bagOff);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001275}
1276
1277static jint android_content_AssetManager_retrieveArray(JNIEnv* env, jobject clazz,
1278 jint id,
1279 jintArray outValues)
1280{
1281 if (outValues == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001282 jniThrowNullPointerException(env, "out values");
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 AssetManager* am = assetManagerForJavaObject(env, clazz);
1287 if (am == NULL) {
1288 return JNI_FALSE;
1289 }
1290 const ResTable& res(am->getResources());
Dianne Hackborn0d221012009-07-29 15:41:19 -07001291 ResTable_config config;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001292 Res_value value;
1293 ssize_t block;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001294
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001295 const jsize NV = env->GetArrayLength(outValues);
Elliott Hughes69a017b2011-04-08 14:10:28 -07001296
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001297 jint* baseDest = (jint*)env->GetPrimitiveArrayCritical(outValues, 0);
1298 jint* dest = baseDest;
1299 if (dest == NULL) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001300 jniThrowException(env, "java/lang/OutOfMemoryError", "");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001301 return JNI_FALSE;
1302 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001303
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001304 // Now lock down the resource object and start pulling stuff from it.
1305 res.lock();
Elliott Hughes69a017b2011-04-08 14:10:28 -07001306
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001307 const ResTable::bag_entry* arrayEnt = NULL;
1308 uint32_t arrayTypeSetFlags = 0;
1309 ssize_t bagOff = res.getBagLocked(id, &arrayEnt, &arrayTypeSetFlags);
1310 const ResTable::bag_entry* endArrayEnt = arrayEnt +
1311 (bagOff >= 0 ? bagOff : 0);
Elliott Hughes69a017b2011-04-08 14:10:28 -07001312
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001313 int i = 0;
1314 uint32_t typeSetFlags;
1315 while (i < NV && arrayEnt < endArrayEnt) {
1316 block = arrayEnt->stringBlock;
1317 typeSetFlags = arrayTypeSetFlags;
Dianne Hackborn0d221012009-07-29 15:41:19 -07001318 config.density = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001319 value = arrayEnt->map.value;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001320
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001321 uint32_t resid = 0;
1322 if (value.dataType != Res_value::TYPE_NULL) {
1323 // Take care of resolving the found resource to its final value.
1324 //printf("Resolving attribute reference\n");
Dianne Hackborn0d221012009-07-29 15:41:19 -07001325 ssize_t newBlock = res.resolveReference(&value, block, &resid,
1326 &typeSetFlags, &config);
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001327 if (kThrowOnBadId) {
1328 if (newBlock == BAD_INDEX) {
1329 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
1330 return JNI_FALSE;
1331 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001332 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001333 if (newBlock >= 0) block = newBlock;
1334 }
1335
1336 // Deal with the special @null value -- it turns back to TYPE_NULL.
1337 if (value.dataType == Res_value::TYPE_REFERENCE && value.data == 0) {
1338 value.dataType = Res_value::TYPE_NULL;
Alan Viverettef2969402014-10-29 17:09:36 -07001339 value.data = Res_value::DATA_NULL_UNDEFINED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001340 }
1341
1342 //printf("Attribute 0x%08x: final type=0x%x, data=0x%08x\n", curIdent, value.dataType, value.data);
1343
1344 // Write the final value back to Java.
1345 dest[STYLE_TYPE] = value.dataType;
1346 dest[STYLE_DATA] = value.data;
Ashok Bhat896043d2014-01-17 16:02:38 +00001347 dest[STYLE_ASSET_COOKIE] = reinterpret_cast<jint>(res.getTableCookie(block));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001348 dest[STYLE_RESOURCE_ID] = resid;
1349 dest[STYLE_CHANGING_CONFIGURATIONS] = typeSetFlags;
Dianne Hackborn0d221012009-07-29 15:41:19 -07001350 dest[STYLE_DENSITY] = config.density;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001351 dest += STYLE_NUM_ENTRIES;
1352 i+= STYLE_NUM_ENTRIES;
1353 arrayEnt++;
1354 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001355
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001356 i /= STYLE_NUM_ENTRIES;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001357
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001358 res.unlock();
Elliott Hughes69a017b2011-04-08 14:10:28 -07001359
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001360 env->ReleasePrimitiveArrayCritical(outValues, baseDest, 0);
Elliott Hughes69a017b2011-04-08 14:10:28 -07001361
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001362 return i;
1363}
1364
Ashok Bhat896043d2014-01-17 16:02:38 +00001365static jlong android_content_AssetManager_openXmlAssetNative(JNIEnv* env, jobject clazz,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001366 jint cookie,
1367 jstring fileName)
1368{
1369 AssetManager* am = assetManagerForJavaObject(env, clazz);
1370 if (am == NULL) {
1371 return 0;
1372 }
1373
Steve Block71f2cf12011-10-20 11:56:00 +01001374 ALOGV("openXmlAsset in %p (Java object %p)\n", am, clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001375
Elliott Hughes69a017b2011-04-08 14:10:28 -07001376 ScopedUtfChars fileName8(env, fileName);
1377 if (fileName8.c_str() == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001378 return 0;
1379 }
1380
Adam Lesinskide898ff2014-01-29 18:20:45 -08001381 int32_t assetCookie = static_cast<int32_t>(cookie);
1382 Asset* a = assetCookie
1383 ? am->openNonAsset(assetCookie, fileName8.c_str(), Asset::ACCESS_BUFFER)
1384 : am->openNonAsset(fileName8.c_str(), Asset::ACCESS_BUFFER, &assetCookie);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001385
1386 if (a == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001387 jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001388 return 0;
1389 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001390
Adam Lesinskide898ff2014-01-29 18:20:45 -08001391 const DynamicRefTable* dynamicRefTable =
1392 am->getResources().getDynamicRefTableForCookie(assetCookie);
1393 ResXMLTree* block = new ResXMLTree(dynamicRefTable);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001394 status_t err = block->setTo(a->getBuffer(true), a->getLength(), true);
1395 a->close();
1396 delete a;
1397
1398 if (err != NO_ERROR) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001399 jniThrowException(env, "java/io/FileNotFoundException", "Corrupt XML binary file");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001400 return 0;
1401 }
1402
Ashok Bhat896043d2014-01-17 16:02:38 +00001403 return reinterpret_cast<jlong>(block);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001404}
1405
1406static jintArray android_content_AssetManager_getArrayStringInfo(JNIEnv* env, jobject clazz,
1407 jint arrayResId)
1408{
1409 AssetManager* am = assetManagerForJavaObject(env, clazz);
1410 if (am == NULL) {
1411 return NULL;
1412 }
1413 const ResTable& res(am->getResources());
1414
1415 const ResTable::bag_entry* startOfBag;
1416 const ssize_t N = res.lockBag(arrayResId, &startOfBag);
1417 if (N < 0) {
1418 return NULL;
1419 }
1420
1421 jintArray array = env->NewIntArray(N * 2);
1422 if (array == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001423 res.unlockBag(startOfBag);
1424 return NULL;
1425 }
1426
1427 Res_value value;
1428 const ResTable::bag_entry* bag = startOfBag;
1429 for (size_t i = 0, j = 0; ((ssize_t)i)<N; i++, bag++) {
1430 jint stringIndex = -1;
1431 jint stringBlock = 0;
1432 value = bag->map.value;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001433
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001434 // Take care of resolving the found resource to its final value.
1435 stringBlock = res.resolveReference(&value, bag->stringBlock, NULL);
1436 if (value.dataType == Res_value::TYPE_STRING) {
1437 stringIndex = value.data;
1438 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001439
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001440 if (kThrowOnBadId) {
1441 if (stringBlock == BAD_INDEX) {
1442 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
1443 return array;
1444 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001445 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001446
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001447 //todo: It might be faster to allocate a C array to contain
1448 // the blocknums and indices, put them in there and then
1449 // do just one SetIntArrayRegion()
1450 env->SetIntArrayRegion(array, j, 1, &stringBlock);
1451 env->SetIntArrayRegion(array, j + 1, 1, &stringIndex);
1452 j = j + 2;
1453 }
1454 res.unlockBag(startOfBag);
1455 return array;
1456}
1457
1458static jobjectArray android_content_AssetManager_getArrayStringResource(JNIEnv* env, jobject clazz,
1459 jint arrayResId)
1460{
1461 AssetManager* am = assetManagerForJavaObject(env, clazz);
1462 if (am == NULL) {
1463 return NULL;
1464 }
1465 const ResTable& res(am->getResources());
1466
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001467 const ResTable::bag_entry* startOfBag;
1468 const ssize_t N = res.lockBag(arrayResId, &startOfBag);
1469 if (N < 0) {
1470 return NULL;
1471 }
1472
Vladimir Markoaa5fe3d2013-06-17 12:46:22 +01001473 jobjectArray array = env->NewObjectArray(N, g_stringClass, NULL);
Kenny Root485dd212010-05-06 16:06:48 -07001474 if (env->ExceptionCheck()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001475 res.unlockBag(startOfBag);
1476 return NULL;
1477 }
1478
1479 Res_value value;
1480 const ResTable::bag_entry* bag = startOfBag;
1481 size_t strLen = 0;
1482 for (size_t i=0; ((ssize_t)i)<N; i++, bag++) {
1483 value = bag->map.value;
1484 jstring str = NULL;
Kenny Root780d2a12010-02-22 22:36:26 -08001485
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001486 // Take care of resolving the found resource to its final value.
1487 ssize_t block = res.resolveReference(&value, bag->stringBlock, NULL);
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001488 if (kThrowOnBadId) {
1489 if (block == BAD_INDEX) {
1490 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
1491 return array;
1492 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001493 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001494 if (value.dataType == Res_value::TYPE_STRING) {
Kenny Root780d2a12010-02-22 22:36:26 -08001495 const ResStringPool* pool = res.getTableStringBlock(block);
1496 const char* str8 = pool->string8At(value.data, &strLen);
1497 if (str8 != NULL) {
1498 str = env->NewStringUTF(str8);
1499 } else {
1500 const char16_t* str16 = pool->stringAt(value.data, &strLen);
Dan Albert66987492014-11-20 11:41:21 -08001501 str = env->NewString(reinterpret_cast<const jchar*>(str16),
1502 strLen);
Kenny Root485dd212010-05-06 16:06:48 -07001503 }
1504
1505 // If one of our NewString{UTF} calls failed due to memory, an
1506 // exception will be pending.
1507 if (env->ExceptionCheck()) {
1508 res.unlockBag(startOfBag);
1509 return NULL;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001510 }
Kenny Root780d2a12010-02-22 22:36:26 -08001511
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001512 env->SetObjectArrayElement(array, i, str);
Kenny Root485dd212010-05-06 16:06:48 -07001513
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001514 // str is not NULL at that point, otherwise ExceptionCheck would have been true.
1515 // If we have a large amount of strings in our array, we might
1516 // overflow the local reference table of the VM.
Kenny Root485dd212010-05-06 16:06:48 -07001517 env->DeleteLocalRef(str);
1518 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001519 }
1520 res.unlockBag(startOfBag);
1521 return array;
1522}
1523
1524static jintArray android_content_AssetManager_getArrayIntResource(JNIEnv* env, jobject clazz,
1525 jint arrayResId)
1526{
1527 AssetManager* am = assetManagerForJavaObject(env, clazz);
1528 if (am == NULL) {
1529 return NULL;
1530 }
1531 const ResTable& res(am->getResources());
1532
1533 const ResTable::bag_entry* startOfBag;
1534 const ssize_t N = res.lockBag(arrayResId, &startOfBag);
1535 if (N < 0) {
1536 return NULL;
1537 }
1538
1539 jintArray array = env->NewIntArray(N);
1540 if (array == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001541 res.unlockBag(startOfBag);
1542 return NULL;
1543 }
1544
1545 Res_value value;
1546 const ResTable::bag_entry* bag = startOfBag;
1547 for (size_t i=0; ((ssize_t)i)<N; i++, bag++) {
1548 value = bag->map.value;
Elliott Hughes69a017b2011-04-08 14:10:28 -07001549
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001550 // Take care of resolving the found resource to its final value.
1551 ssize_t block = res.resolveReference(&value, bag->stringBlock, NULL);
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001552 if (kThrowOnBadId) {
1553 if (block == BAD_INDEX) {
1554 jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
1555 return array;
1556 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001557 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001558 if (value.dataType >= Res_value::TYPE_FIRST_INT
1559 && value.dataType <= Res_value::TYPE_LAST_INT) {
1560 int intVal = value.data;
1561 env->SetIntArrayRegion(array, i, 1, &intVal);
1562 }
1563 }
1564 res.unlockBag(startOfBag);
1565 return array;
1566}
1567
Jon Miranda042ad632014-09-03 17:57:35 -07001568static jintArray android_content_AssetManager_getStyleAttributes(JNIEnv* env, jobject clazz,
1569 jint styleId)
1570{
1571 AssetManager* am = assetManagerForJavaObject(env, clazz);
1572 if (am == NULL) {
1573 return NULL;
1574 }
1575 const ResTable& res(am->getResources());
1576
1577 const ResTable::bag_entry* startOfBag;
1578 const ssize_t N = res.lockBag(styleId, &startOfBag);
1579 if (N < 0) {
1580 return NULL;
1581 }
1582
1583 jintArray array = env->NewIntArray(N);
1584 if (array == NULL) {
1585 res.unlockBag(startOfBag);
1586 return NULL;
1587 }
1588
Jon Miranda042ad632014-09-03 17:57:35 -07001589 const ResTable::bag_entry* bag = startOfBag;
1590 for (size_t i=0; ((ssize_t)i)<N; i++, bag++) {
1591 int resourceId = bag->map.name.ident;
1592 env->SetIntArrayRegion(array, i, 1, &resourceId);
1593 }
1594 res.unlockBag(startOfBag);
1595 return array;
1596}
1597
Mårten Kongstad48d22322014-01-31 14:43:27 +01001598static void android_content_AssetManager_init(JNIEnv* env, jobject clazz, jboolean isSystem)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001599{
Jaekyun Seok7de2f9c2017-03-02 12:45:10 +09001600 if (isSystem) {
1601 verifySystemIdmaps();
1602 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001603 AssetManager* am = new AssetManager();
1604 if (am == NULL) {
Gilles Debunne4d4040b2010-08-26 15:59:54 -07001605 jniThrowException(env, "java/lang/OutOfMemoryError", "");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001606 return;
1607 }
1608
1609 am->addDefaultAssets();
1610
Steve Block71f2cf12011-10-20 11:56:00 +01001611 ALOGV("Created AssetManager %p for Java object %p\n", am, clazz);
Ashok Bhat896043d2014-01-17 16:02:38 +00001612 env->SetLongField(clazz, gAssetManagerOffsets.mObject, reinterpret_cast<jlong>(am));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001613}
1614
1615static void android_content_AssetManager_destroy(JNIEnv* env, jobject clazz)
1616{
1617 AssetManager* am = (AssetManager*)
Ashok Bhat896043d2014-01-17 16:02:38 +00001618 (env->GetLongField(clazz, gAssetManagerOffsets.mObject));
Steve Block71f2cf12011-10-20 11:56:00 +01001619 ALOGV("Destroying AssetManager %p for Java object %p\n", am, clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001620 if (am != NULL) {
1621 delete am;
Ashok Bhat896043d2014-01-17 16:02:38 +00001622 env->SetLongField(clazz, gAssetManagerOffsets.mObject, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001623 }
1624}
1625
1626static jint android_content_AssetManager_getGlobalAssetCount(JNIEnv* env, jobject clazz)
1627{
1628 return Asset::getGlobalCount();
1629}
1630
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07001631static jobject android_content_AssetManager_getAssetAllocations(JNIEnv* env, jobject clazz)
1632{
1633 String8 alloc = Asset::getAssetAllocations();
1634 if (alloc.length() <= 0) {
1635 return NULL;
1636 }
Elliott Hughes69a017b2011-04-08 14:10:28 -07001637
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07001638 jstring str = env->NewStringUTF(alloc.string());
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07001639 return str;
1640}
1641
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001642static jint android_content_AssetManager_getGlobalAssetManagerCount(JNIEnv* env, jobject clazz)
1643{
1644 return AssetManager::getGlobalCount();
1645}
1646
1647// ----------------------------------------------------------------------------
1648
1649/*
1650 * JNI registration.
1651 */
Daniel Micay76f6a862015-09-19 17:31:01 -04001652static const JNINativeMethod gAssetManagerMethods[] = {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001653 /* name, signature, funcPtr */
1654
1655 // Basic asset stuff.
Ashok Bhat896043d2014-01-17 16:02:38 +00001656 { "openAsset", "(Ljava/lang/String;I)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001657 (void*) android_content_AssetManager_openAsset },
1658 { "openAssetFd", "(Ljava/lang/String;[J)Landroid/os/ParcelFileDescriptor;",
1659 (void*) android_content_AssetManager_openAssetFd },
Ashok Bhat896043d2014-01-17 16:02:38 +00001660 { "openNonAssetNative", "(ILjava/lang/String;I)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001661 (void*) android_content_AssetManager_openNonAssetNative },
1662 { "openNonAssetFdNative", "(ILjava/lang/String;[J)Landroid/os/ParcelFileDescriptor;",
1663 (void*) android_content_AssetManager_openNonAssetFdNative },
1664 { "list", "(Ljava/lang/String;)[Ljava/lang/String;",
1665 (void*) android_content_AssetManager_list },
Ashok Bhat896043d2014-01-17 16:02:38 +00001666 { "destroyAsset", "(J)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001667 (void*) android_content_AssetManager_destroyAsset },
Ashok Bhat896043d2014-01-17 16:02:38 +00001668 { "readAssetChar", "(J)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001669 (void*) android_content_AssetManager_readAssetChar },
Ashok Bhat896043d2014-01-17 16:02:38 +00001670 { "readAsset", "(J[BII)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001671 (void*) android_content_AssetManager_readAsset },
Ashok Bhat896043d2014-01-17 16:02:38 +00001672 { "seekAsset", "(JJI)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001673 (void*) android_content_AssetManager_seekAsset },
John Reck32995222016-10-07 11:02:20 -07001674 { "getAssetLength", "(J)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001675 (void*) android_content_AssetManager_getAssetLength },
John Reck32995222016-10-07 11:02:20 -07001676 { "getAssetRemainingLength", "(J)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001677 (void*) android_content_AssetManager_getAssetRemainingLength },
Tao Baia6d7e3f2015-09-01 18:49:54 -07001678 { "addAssetPathNative", "(Ljava/lang/String;Z)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001679 (void*) android_content_AssetManager_addAssetPath },
Mårten Kongstad30113132014-11-07 10:52:17 +01001680 { "addOverlayPathNative", "(Ljava/lang/String;)I",
Mårten Kongstad48d22322014-01-31 14:43:27 +01001681 (void*) android_content_AssetManager_addOverlayPath },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001682 { "isUpToDate", "()Z",
1683 (void*) android_content_AssetManager_isUpToDate },
1684
1685 // Resources.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001686 { "getLocales", "()[Ljava/lang/String;",
1687 (void*) android_content_AssetManager_getLocales },
Roozbeh Pournader1c686f22015-12-18 14:22:14 -08001688 { "getNonSystemLocales", "()[Ljava/lang/String;",
1689 (void*) android_content_AssetManager_getNonSystemLocales },
Filip Gruszczynski23493322015-07-29 17:02:59 -07001690 { "getSizeConfigurations", "()[Landroid/content/res/Configuration;",
1691 (void*) android_content_AssetManager_getSizeConfigurations },
Romain Guy408afbf2017-01-25 10:23:03 -08001692 { "setConfiguration", "(IILjava/lang/String;IIIIIIIIIIIIIII)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001693 (void*) android_content_AssetManager_setConfiguration },
John Reck32995222016-10-07 11:02:20 -07001694 { "getResourceIdentifier","(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001695 (void*) android_content_AssetManager_getResourceIdentifier },
John Reck32995222016-10-07 11:02:20 -07001696 { "getResourceName","(I)Ljava/lang/String;",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001697 (void*) android_content_AssetManager_getResourceName },
John Reck32995222016-10-07 11:02:20 -07001698 { "getResourcePackageName","(I)Ljava/lang/String;",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001699 (void*) android_content_AssetManager_getResourcePackageName },
John Reck32995222016-10-07 11:02:20 -07001700 { "getResourceTypeName","(I)Ljava/lang/String;",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001701 (void*) android_content_AssetManager_getResourceTypeName },
John Reck32995222016-10-07 11:02:20 -07001702 { "getResourceEntryName","(I)Ljava/lang/String;",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001703 (void*) android_content_AssetManager_getResourceEntryName },
John Reck32995222016-10-07 11:02:20 -07001704 { "loadResourceValue","(ISLandroid/util/TypedValue;Z)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001705 (void*) android_content_AssetManager_loadResourceValue },
John Reck32995222016-10-07 11:02:20 -07001706 { "loadResourceBagValue","(IILandroid/util/TypedValue;Z)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001707 (void*) android_content_AssetManager_loadResourceBagValue },
John Reck32995222016-10-07 11:02:20 -07001708 { "getStringBlockCount","()I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001709 (void*) android_content_AssetManager_getStringBlockCount },
John Reck32995222016-10-07 11:02:20 -07001710 { "getNativeStringBlock","(I)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001711 (void*) android_content_AssetManager_getNativeStringBlock },
1712 { "getCookieName","(I)Ljava/lang/String;",
1713 (void*) android_content_AssetManager_getCookieName },
Adam Lesinskide898ff2014-01-29 18:20:45 -08001714 { "getAssignedPackageIdentifiers","()Landroid/util/SparseArray;",
1715 (void*) android_content_AssetManager_getAssignedPackageIdentifiers },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001716
1717 // Themes.
Ashok Bhat896043d2014-01-17 16:02:38 +00001718 { "newTheme", "()J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001719 (void*) android_content_AssetManager_newTheme },
Ashok Bhat896043d2014-01-17 16:02:38 +00001720 { "deleteTheme", "(J)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001721 (void*) android_content_AssetManager_deleteTheme },
Ashok Bhat896043d2014-01-17 16:02:38 +00001722 { "applyThemeStyle", "(JIZ)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001723 (void*) android_content_AssetManager_applyThemeStyle },
Ashok Bhat896043d2014-01-17 16:02:38 +00001724 { "copyTheme", "(JJ)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001725 (void*) android_content_AssetManager_copyTheme },
Alan Viverettee54d2452015-05-06 10:41:43 -07001726 { "clearTheme", "(J)V",
1727 (void*) android_content_AssetManager_clearTheme },
John Reck32995222016-10-07 11:02:20 -07001728 { "loadThemeAttributeValue", "(JILandroid/util/TypedValue;Z)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001729 (void*) android_content_AssetManager_loadThemeAttributeValue },
John Reck32995222016-10-07 11:02:20 -07001730 { "getThemeChangingConfigurations", "(J)I",
Alan Viverettec1d52792015-05-05 09:49:03 -07001731 (void*) android_content_AssetManager_getThemeChangingConfigurations },
Ashok Bhat896043d2014-01-17 16:02:38 +00001732 { "dumpTheme", "(JILjava/lang/String;Ljava/lang/String;)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001733 (void*) android_content_AssetManager_dumpTheme },
John Reckf32adf42016-11-23 10:39:40 -08001734 { "applyStyle","(JIIJ[IIJJ)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001735 (void*) android_content_AssetManager_applyStyle },
John Reck32995222016-10-07 11:02:20 -07001736 { "resolveAttrs","(JII[I[I[I[I)Z",
Alan Viverette607bd842014-09-12 12:36:35 -07001737 (void*) android_content_AssetManager_resolveAttrs },
John Reck32995222016-10-07 11:02:20 -07001738 { "retrieveAttributes","(J[I[I[I)Z",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001739 (void*) android_content_AssetManager_retrieveAttributes },
John Reck32995222016-10-07 11:02:20 -07001740 { "getArraySize","(I)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001741 (void*) android_content_AssetManager_getArraySize },
John Reck32995222016-10-07 11:02:20 -07001742 { "retrieveArray","(I[I)I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001743 (void*) android_content_AssetManager_retrieveArray },
1744
1745 // XML files.
Ashok Bhat896043d2014-01-17 16:02:38 +00001746 { "openXmlAssetNative", "(ILjava/lang/String;)J",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001747 (void*) android_content_AssetManager_openXmlAssetNative },
1748
1749 // Arrays.
1750 { "getArrayStringResource","(I)[Ljava/lang/String;",
1751 (void*) android_content_AssetManager_getArrayStringResource },
John Reck32995222016-10-07 11:02:20 -07001752 { "getArrayStringInfo","(I)[I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001753 (void*) android_content_AssetManager_getArrayStringInfo },
John Reck32995222016-10-07 11:02:20 -07001754 { "getArrayIntResource","(I)[I",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001755 (void*) android_content_AssetManager_getArrayIntResource },
John Reck32995222016-10-07 11:02:20 -07001756 { "getStyleAttributes","(I)[I",
Jon Miranda042ad632014-09-03 17:57:35 -07001757 (void*) android_content_AssetManager_getStyleAttributes },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001758
1759 // Bookkeeping.
Mårten Kongstad48d22322014-01-31 14:43:27 +01001760 { "init", "(Z)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001761 (void*) android_content_AssetManager_init },
1762 { "destroy", "()V",
1763 (void*) android_content_AssetManager_destroy },
1764 { "getGlobalAssetCount", "()I",
1765 (void*) android_content_AssetManager_getGlobalAssetCount },
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07001766 { "getAssetAllocations", "()Ljava/lang/String;",
1767 (void*) android_content_AssetManager_getAssetAllocations },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001768 { "getGlobalAssetManagerCount", "()I",
Andreas Gampe32812612014-11-11 00:16:00 -08001769 (void*) android_content_AssetManager_getGlobalAssetManagerCount },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001770};
1771
1772int register_android_content_AssetManager(JNIEnv* env)
1773{
Andreas Gampe987f79f2014-11-18 17:29:46 -08001774 jclass typedValue = FindClassOrDie(env, "android/util/TypedValue");
1775 gTypedValueOffsets.mType = GetFieldIDOrDie(env, typedValue, "type", "I");
1776 gTypedValueOffsets.mData = GetFieldIDOrDie(env, typedValue, "data", "I");
1777 gTypedValueOffsets.mString = GetFieldIDOrDie(env, typedValue, "string",
1778 "Ljava/lang/CharSequence;");
1779 gTypedValueOffsets.mAssetCookie = GetFieldIDOrDie(env, typedValue, "assetCookie", "I");
1780 gTypedValueOffsets.mResourceId = GetFieldIDOrDie(env, typedValue, "resourceId", "I");
1781 gTypedValueOffsets.mChangingConfigurations = GetFieldIDOrDie(env, typedValue,
1782 "changingConfigurations", "I");
1783 gTypedValueOffsets.mDensity = GetFieldIDOrDie(env, typedValue, "density", "I");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001784
Andreas Gampe987f79f2014-11-18 17:29:46 -08001785 jclass assetFd = FindClassOrDie(env, "android/content/res/AssetFileDescriptor");
1786 gAssetFileDescriptorOffsets.mFd = GetFieldIDOrDie(env, assetFd, "mFd",
1787 "Landroid/os/ParcelFileDescriptor;");
1788 gAssetFileDescriptorOffsets.mStartOffset = GetFieldIDOrDie(env, assetFd, "mStartOffset", "J");
1789 gAssetFileDescriptorOffsets.mLength = GetFieldIDOrDie(env, assetFd, "mLength", "J");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001790
Andreas Gampe987f79f2014-11-18 17:29:46 -08001791 jclass assetManager = FindClassOrDie(env, "android/content/res/AssetManager");
1792 gAssetManagerOffsets.mObject = GetFieldIDOrDie(env, assetManager, "mObject", "J");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001793
Andreas Gampe987f79f2014-11-18 17:29:46 -08001794 jclass stringClass = FindClassOrDie(env, "java/lang/String");
1795 g_stringClass = MakeGlobalRefOrDie(env, stringClass);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001796
Andreas Gampe987f79f2014-11-18 17:29:46 -08001797 jclass sparseArrayClass = FindClassOrDie(env, "android/util/SparseArray");
1798 gSparseArrayOffsets.classObject = MakeGlobalRefOrDie(env, sparseArrayClass);
1799 gSparseArrayOffsets.constructor = GetMethodIDOrDie(env, gSparseArrayOffsets.classObject,
1800 "<init>", "()V");
1801 gSparseArrayOffsets.put = GetMethodIDOrDie(env, gSparseArrayOffsets.classObject, "put",
1802 "(ILjava/lang/Object;)V");
Adam Lesinskide898ff2014-01-29 18:20:45 -08001803
Filip Gruszczynski23493322015-07-29 17:02:59 -07001804 jclass configurationClass = FindClassOrDie(env, "android/content/res/Configuration");
1805 gConfigurationOffsets.classObject = MakeGlobalRefOrDie(env, configurationClass);
1806 gConfigurationOffsets.constructor = GetMethodIDOrDie(env, configurationClass,
1807 "<init>", "()V");
1808 gConfigurationOffsets.mSmallestScreenWidthDpOffset = GetFieldIDOrDie(env, configurationClass,
1809 "smallestScreenWidthDp", "I");
1810 gConfigurationOffsets.mScreenWidthDpOffset = GetFieldIDOrDie(env, configurationClass,
1811 "screenWidthDp", "I");
1812 gConfigurationOffsets.mScreenHeightDpOffset = GetFieldIDOrDie(env, configurationClass,
1813 "screenHeightDp", "I");
1814
Andreas Gampe987f79f2014-11-18 17:29:46 -08001815 return RegisterMethodsOrDie(env, "android/content/res/AssetManager", gAssetManagerMethods,
1816 NELEM(gAssetManagerMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001817}
1818
1819}; // namespace android