blob: fc6761d5d316eb0ded105cac26ae106df9643cff [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.content.res;
18
19import android.os.ParcelFileDescriptor;
20import android.util.Config;
21import android.util.Log;
22import android.util.TypedValue;
23
24import java.io.FileNotFoundException;
25import java.io.IOException;
26import java.io.InputStream;
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -080027import java.util.HashMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080028
29/**
30 * Provides access to an application's raw asset files; see {@link Resources}
31 * for the way most applications will want to retrieve their resource data.
32 * This class presents a lower-level API that allows you to open and read raw
33 * files that have been bundled with the application as a simple stream of
34 * bytes.
35 */
36public final class AssetManager {
37 /* modes used when opening an asset */
38
39 /**
40 * Mode for {@link #open(String, int)}: no specific information about how
41 * data will be accessed.
42 */
43 public static final int ACCESS_UNKNOWN = 0;
44 /**
45 * Mode for {@link #open(String, int)}: Read chunks, and seek forward and
46 * backward.
47 */
48 public static final int ACCESS_RANDOM = 1;
49 /**
50 * Mode for {@link #open(String, int)}: Read sequentially, with an
51 * occasional forward seek.
52 */
53 public static final int ACCESS_STREAMING = 2;
54 /**
55 * Mode for {@link #open(String, int)}: Attempt to load contents into
56 * memory, for fast small reads.
57 */
58 public static final int ACCESS_BUFFER = 3;
59
60 private static final String TAG = "AssetManager";
61 private static final boolean localLOGV = Config.LOGV || false;
62
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -080063 private static final boolean DEBUG_REFS = false;
64
Dianne Hackborn60d7db42009-11-16 17:16:26 -080065 private static final Object sSync = new Object();
66 private static AssetManager sSystem = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067
Dianne Hackborn60d7db42009-11-16 17:16:26 -080068 private final TypedValue mValue = new TypedValue();
69 private final long[] mOffsets = new long[2];
70
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080071 // For communication with native code.
72 private int mObject;
Christopher Tate6cce32b2010-07-12 18:21:36 -070073 private int mNObject; // used by the NDK
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074
75 private StringBlock mStringBlocks[] = null;
76
77 private int mNumRefs = 1;
78 private boolean mOpen = true;
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -080079 private HashMap<Integer, RuntimeException> mRefStacks;
Dianne Hackborn60d7db42009-11-16 17:16:26 -080080
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081 /**
82 * Create a new AssetManager containing only the basic system assets.
83 * Applications will not generally use this method, instead retrieving the
84 * appropriate asset manager with {@link Resources#getAssets}. Not for
85 * use by applications.
86 * {@hide}
87 */
88 public AssetManager() {
Dianne Hackborn60d7db42009-11-16 17:16:26 -080089 synchronized (this) {
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -080090 if (DEBUG_REFS) {
91 mNumRefs = 0;
92 incRefsLocked(this.hashCode());
93 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080094 init();
95 if (localLOGV) Log.v(TAG, "New asset manager: " + this);
96 ensureSystemAssets();
97 }
98 }
99
100 private static void ensureSystemAssets() {
Dianne Hackborn60d7db42009-11-16 17:16:26 -0800101 synchronized (sSync) {
102 if (sSystem == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800103 AssetManager system = new AssetManager(true);
104 system.makeStringBlocks(false);
Dianne Hackborn60d7db42009-11-16 17:16:26 -0800105 sSystem = system;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106 }
107 }
108 }
109
110 private AssetManager(boolean isSystem) {
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -0800111 if (DEBUG_REFS) {
112 synchronized (this) {
113 mNumRefs = 0;
114 incRefsLocked(this.hashCode());
115 }
116 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800117 init();
118 if (localLOGV) Log.v(TAG, "New asset manager: " + this);
119 }
120
121 /**
122 * Return a global shared asset manager that provides access to only
123 * system assets (no application assets).
124 * {@hide}
125 */
126 public static AssetManager getSystem() {
127 ensureSystemAssets();
Dianne Hackborn60d7db42009-11-16 17:16:26 -0800128 return sSystem;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800129 }
130
131 /**
132 * Close this asset manager.
133 */
134 public void close() {
Dianne Hackborn60d7db42009-11-16 17:16:26 -0800135 synchronized(this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800136 //System.out.println("Release: num=" + mNumRefs
137 // + ", released=" + mReleased);
138 if (mOpen) {
139 mOpen = false;
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -0800140 decRefsLocked(this.hashCode());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800141 }
142 }
143 }
144
145 /**
146 * Retrieve the string value associated with a particular resource
147 * identifier for the current configuration / skin.
148 */
149 /*package*/ final CharSequence getResourceText(int ident) {
Dianne Hackborn60d7db42009-11-16 17:16:26 -0800150 synchronized (this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800151 TypedValue tmpValue = mValue;
Kenny Root55fc8502010-10-28 14:47:01 -0700152 int block = loadResourceValue(ident, (short) 0, tmpValue, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800153 if (block >= 0) {
154 if (tmpValue.type == TypedValue.TYPE_STRING) {
155 return mStringBlocks[block].get(tmpValue.data);
156 }
157 return tmpValue.coerceToString();
158 }
159 }
160 return null;
161 }
162
163 /**
164 * Retrieve the string value associated with a particular resource
165 * identifier for the current configuration / skin.
166 */
167 /*package*/ final CharSequence getResourceBagText(int ident, int bagEntryId) {
Dianne Hackborn60d7db42009-11-16 17:16:26 -0800168 synchronized (this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800169 TypedValue tmpValue = mValue;
170 int block = loadResourceBagValue(ident, bagEntryId, tmpValue, true);
171 if (block >= 0) {
172 if (tmpValue.type == TypedValue.TYPE_STRING) {
173 return mStringBlocks[block].get(tmpValue.data);
174 }
175 return tmpValue.coerceToString();
176 }
177 }
178 return null;
179 }
180
181 /**
182 * Retrieve the string array associated with a particular resource
183 * identifier.
184 * @param id Resource id of the string array
185 */
186 /*package*/ final String[] getResourceStringArray(final int id) {
187 String[] retArray = getArrayStringResource(id);
188 return retArray;
189 }
190
191
192 /*package*/ final boolean getResourceValue(int ident,
Kenny Root55fc8502010-10-28 14:47:01 -0700193 int density,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800194 TypedValue outValue,
195 boolean resolveRefs)
196 {
Kenny Root55fc8502010-10-28 14:47:01 -0700197 int block = loadResourceValue(ident, (short) density, outValue, resolveRefs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800198 if (block >= 0) {
199 if (outValue.type != TypedValue.TYPE_STRING) {
200 return true;
201 }
202 outValue.string = mStringBlocks[block].get(outValue.data);
203 return true;
204 }
205 return false;
206 }
207
208 /**
209 * Retrieve the text array associated with a particular resource
210 * identifier.
211 * @param id Resource id of the string array
212 */
213 /*package*/ final CharSequence[] getResourceTextArray(final int id) {
214 int[] rawInfoArray = getArrayStringInfo(id);
215 int rawInfoArrayLen = rawInfoArray.length;
216 final int infoArrayLen = rawInfoArrayLen / 2;
217 int block;
218 int index;
219 CharSequence[] retArray = new CharSequence[infoArrayLen];
220 for (int i = 0, j = 0; i < rawInfoArrayLen; i = i + 2, j++) {
221 block = rawInfoArray[i];
222 index = rawInfoArray[i + 1];
223 retArray[j] = index >= 0 ? mStringBlocks[block].get(index) : null;
224 }
225 return retArray;
226 }
227
228 /*package*/ final boolean getThemeValue(int theme, int ident,
229 TypedValue outValue, boolean resolveRefs) {
230 int block = loadThemeAttributeValue(theme, ident, outValue, resolveRefs);
231 if (block >= 0) {
232 if (outValue.type != TypedValue.TYPE_STRING) {
233 return true;
234 }
235 StringBlock[] blocks = mStringBlocks;
236 if (blocks == null) {
237 ensureStringBlocks();
Jozef BABJAK41a5ed72011-04-19 12:28:22 +0200238 blocks = mStringBlocks;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800239 }
240 outValue.string = blocks[block].get(outValue.data);
241 return true;
242 }
243 return false;
244 }
245
246 /*package*/ final void ensureStringBlocks() {
247 if (mStringBlocks == null) {
Dianne Hackborn60d7db42009-11-16 17:16:26 -0800248 synchronized (this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800249 if (mStringBlocks == null) {
250 makeStringBlocks(true);
251 }
252 }
253 }
254 }
255
256 private final void makeStringBlocks(boolean copyFromSystem) {
Dianne Hackborn60d7db42009-11-16 17:16:26 -0800257 final int sysNum = copyFromSystem ? sSystem.mStringBlocks.length : 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800258 final int num = getStringBlockCount();
259 mStringBlocks = new StringBlock[num];
260 if (localLOGV) Log.v(TAG, "Making string blocks for " + this
261 + ": " + num);
262 for (int i=0; i<num; i++) {
263 if (i < sysNum) {
Dianne Hackborn60d7db42009-11-16 17:16:26 -0800264 mStringBlocks[i] = sSystem.mStringBlocks[i];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800265 } else {
266 mStringBlocks[i] = new StringBlock(getNativeStringBlock(i), true);
267 }
268 }
269 }
270
271 /*package*/ final CharSequence getPooledString(int block, int id) {
272 //System.out.println("Get pooled: block=" + block
273 // + ", id=#" + Integer.toHexString(id)
274 // + ", blocks=" + mStringBlocks);
275 return mStringBlocks[block-1].get(id);
276 }
277
278 /**
279 * Open an asset using ACCESS_STREAMING mode. This provides access to
280 * files that have been bundled with an application as assets -- that is,
281 * files placed in to the "assets" directory.
282 *
283 * @param fileName The name of the asset to open. This name can be
284 * hierarchical.
285 *
286 * @see #open(String, int)
287 * @see #list
288 */
289 public final InputStream open(String fileName) throws IOException {
290 return open(fileName, ACCESS_STREAMING);
291 }
292
293 /**
294 * Open an asset using an explicit access mode, returning an InputStream to
295 * read its contents. This provides access to files that have been bundled
296 * with an application as assets -- that is, files placed in to the
297 * "assets" directory.
298 *
299 * @param fileName The name of the asset to open. This name can be
300 * hierarchical.
301 * @param accessMode Desired access mode for retrieving the data.
302 *
303 * @see #ACCESS_UNKNOWN
304 * @see #ACCESS_STREAMING
305 * @see #ACCESS_RANDOM
306 * @see #ACCESS_BUFFER
307 * @see #open(String)
308 * @see #list
309 */
310 public final InputStream open(String fileName, int accessMode)
311 throws IOException {
Dianne Hackborn60d7db42009-11-16 17:16:26 -0800312 synchronized (this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800313 if (!mOpen) {
314 throw new RuntimeException("Assetmanager has been closed");
315 }
316 int asset = openAsset(fileName, accessMode);
317 if (asset != 0) {
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -0800318 AssetInputStream res = new AssetInputStream(asset);
319 incRefsLocked(res.hashCode());
320 return res;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800321 }
322 }
323 throw new FileNotFoundException("Asset file: " + fileName);
324 }
325
326 public final AssetFileDescriptor openFd(String fileName)
327 throws IOException {
Dianne Hackborn60d7db42009-11-16 17:16:26 -0800328 synchronized (this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800329 if (!mOpen) {
330 throw new RuntimeException("Assetmanager has been closed");
331 }
332 ParcelFileDescriptor pfd = openAssetFd(fileName, mOffsets);
333 if (pfd != null) {
334 return new AssetFileDescriptor(pfd, mOffsets[0], mOffsets[1]);
335 }
336 }
337 throw new FileNotFoundException("Asset file: " + fileName);
338 }
339
340 /**
341 * Return a String array of all the assets at the given path.
342 *
343 * @param path A relative path within the assets, i.e., "docs/home.html".
344 *
345 * @return String[] Array of strings, one for each asset. These file
346 * names are relative to 'path'. You can open the file by
347 * concatenating 'path' and a name in the returned string (via
348 * File) and passing that to open().
349 *
350 * @see #open
351 */
352 public native final String[] list(String path)
353 throws IOException;
354
355 /**
356 * {@hide}
357 * Open a non-asset file as an asset using ACCESS_STREAMING mode. This
358 * provides direct access to all of the files included in an application
359 * package (not only its assets). Applications should not normally use
360 * this.
361 *
362 * @see #open(String)
363 */
364 public final InputStream openNonAsset(String fileName) throws IOException {
365 return openNonAsset(0, fileName, ACCESS_STREAMING);
366 }
367
368 /**
369 * {@hide}
370 * Open a non-asset file as an asset using a specific access mode. This
371 * provides direct access to all of the files included in an application
372 * package (not only its assets). Applications should not normally use
373 * this.
374 *
375 * @see #open(String, int)
376 */
377 public final InputStream openNonAsset(String fileName, int accessMode)
378 throws IOException {
379 return openNonAsset(0, fileName, accessMode);
380 }
381
382 /**
383 * {@hide}
384 * Open a non-asset in a specified package. Not for use by applications.
385 *
386 * @param cookie Identifier of the package to be opened.
387 * @param fileName Name of the asset to retrieve.
388 */
389 public final InputStream openNonAsset(int cookie, String fileName)
390 throws IOException {
391 return openNonAsset(cookie, fileName, ACCESS_STREAMING);
392 }
393
394 /**
395 * {@hide}
396 * Open a non-asset in a specified package. Not for use by applications.
397 *
398 * @param cookie Identifier of the package to be opened.
399 * @param fileName Name of the asset to retrieve.
400 * @param accessMode Desired access mode for retrieving the data.
401 */
402 public final InputStream openNonAsset(int cookie, String fileName, int accessMode)
403 throws IOException {
Dianne Hackborn60d7db42009-11-16 17:16:26 -0800404 synchronized (this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800405 if (!mOpen) {
406 throw new RuntimeException("Assetmanager has been closed");
407 }
408 int asset = openNonAssetNative(cookie, fileName, accessMode);
409 if (asset != 0) {
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -0800410 AssetInputStream res = new AssetInputStream(asset);
411 incRefsLocked(res.hashCode());
412 return res;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800413 }
414 }
415 throw new FileNotFoundException("Asset absolute file: " + fileName);
416 }
417
418 public final AssetFileDescriptor openNonAssetFd(String fileName)
419 throws IOException {
420 return openNonAssetFd(0, fileName);
421 }
422
423 public final AssetFileDescriptor openNonAssetFd(int cookie,
424 String fileName) throws IOException {
Dianne Hackborn60d7db42009-11-16 17:16:26 -0800425 synchronized (this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800426 if (!mOpen) {
427 throw new RuntimeException("Assetmanager has been closed");
428 }
429 ParcelFileDescriptor pfd = openNonAssetFdNative(cookie,
430 fileName, mOffsets);
431 if (pfd != null) {
432 return new AssetFileDescriptor(pfd, mOffsets[0], mOffsets[1]);
433 }
434 }
435 throw new FileNotFoundException("Asset absolute file: " + fileName);
436 }
437
438 /**
439 * Retrieve a parser for a compiled XML file.
440 *
441 * @param fileName The name of the file to retrieve.
442 */
443 public final XmlResourceParser openXmlResourceParser(String fileName)
444 throws IOException {
445 return openXmlResourceParser(0, fileName);
446 }
447
448 /**
449 * Retrieve a parser for a compiled XML file.
450 *
451 * @param cookie Identifier of the package to be opened.
452 * @param fileName The name of the file to retrieve.
453 */
454 public final XmlResourceParser openXmlResourceParser(int cookie,
455 String fileName) throws IOException {
456 XmlBlock block = openXmlBlockAsset(cookie, fileName);
457 XmlResourceParser rp = block.newParser();
458 block.close();
459 return rp;
460 }
461
462 /**
463 * {@hide}
464 * Retrieve a non-asset as a compiled XML file. Not for use by
465 * applications.
466 *
467 * @param fileName The name of the file to retrieve.
468 */
469 /*package*/ final XmlBlock openXmlBlockAsset(String fileName)
470 throws IOException {
471 return openXmlBlockAsset(0, fileName);
472 }
473
474 /**
475 * {@hide}
476 * Retrieve a non-asset as a compiled XML file. Not for use by
477 * applications.
478 *
479 * @param cookie Identifier of the package to be opened.
480 * @param fileName Name of the asset to retrieve.
481 */
482 /*package*/ final XmlBlock openXmlBlockAsset(int cookie, String fileName)
483 throws IOException {
Dianne Hackborn60d7db42009-11-16 17:16:26 -0800484 synchronized (this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800485 if (!mOpen) {
486 throw new RuntimeException("Assetmanager has been closed");
487 }
488 int xmlBlock = openXmlAssetNative(cookie, fileName);
489 if (xmlBlock != 0) {
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -0800490 XmlBlock res = new XmlBlock(this, xmlBlock);
491 incRefsLocked(res.hashCode());
492 return res;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800493 }
494 }
495 throw new FileNotFoundException("Asset XML file: " + fileName);
496 }
497
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -0800498 /*package*/ void xmlBlockGone(int id) {
Dianne Hackborn60d7db42009-11-16 17:16:26 -0800499 synchronized (this) {
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -0800500 decRefsLocked(id);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800501 }
502 }
503
504 /*package*/ final int createTheme() {
Dianne Hackborn60d7db42009-11-16 17:16:26 -0800505 synchronized (this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800506 if (!mOpen) {
507 throw new RuntimeException("Assetmanager has been closed");
508 }
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -0800509 int res = newTheme();
510 incRefsLocked(res);
511 return res;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800512 }
513 }
514
515 /*package*/ final void releaseTheme(int theme) {
Dianne Hackborn60d7db42009-11-16 17:16:26 -0800516 synchronized (this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800517 deleteTheme(theme);
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -0800518 decRefsLocked(theme);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800519 }
520 }
521
522 protected void finalize() throws Throwable {
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -0800523 try {
524 if (DEBUG_REFS && mNumRefs != 0) {
525 Log.w(TAG, "AssetManager " + this
526 + " finalized with non-zero refs: " + mNumRefs);
527 if (mRefStacks != null) {
528 for (RuntimeException e : mRefStacks.values()) {
529 Log.w(TAG, "Reference from here", e);
530 }
531 }
532 }
533 destroy();
534 } finally {
535 super.finalize();
536 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800537 }
538
539 public final class AssetInputStream extends InputStream {
540 public final int getAssetInt() {
541 return mAsset;
542 }
543 private AssetInputStream(int asset)
544 {
545 mAsset = asset;
546 mLength = getAssetLength(asset);
547 }
548 public final int read() throws IOException {
549 return readAssetChar(mAsset);
550 }
551 public final boolean markSupported() {
552 return true;
553 }
554 public final int available() throws IOException {
555 long len = getAssetRemainingLength(mAsset);
556 return len > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int)len;
557 }
558 public final void close() throws IOException {
Dianne Hackborn60d7db42009-11-16 17:16:26 -0800559 synchronized (AssetManager.this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800560 if (mAsset != 0) {
561 destroyAsset(mAsset);
562 mAsset = 0;
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -0800563 decRefsLocked(hashCode());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800564 }
565 }
566 }
567 public final void mark(int readlimit) {
568 mMarkPos = seekAsset(mAsset, 0, 0);
569 }
570 public final void reset() throws IOException {
571 seekAsset(mAsset, mMarkPos, -1);
572 }
573 public final int read(byte[] b) throws IOException {
574 return readAsset(mAsset, b, 0, b.length);
575 }
576 public final int read(byte[] b, int off, int len) throws IOException {
577 return readAsset(mAsset, b, off, len);
578 }
579 public final long skip(long n) throws IOException {
580 long pos = seekAsset(mAsset, 0, 0);
581 if ((pos+n) > mLength) {
582 n = mLength-pos;
583 }
584 if (n > 0) {
585 seekAsset(mAsset, n, 0);
586 }
587 return n;
588 }
589
590 protected void finalize() throws Throwable
591 {
592 close();
593 }
594
595 private int mAsset;
596 private long mLength;
597 private long mMarkPos;
598 }
599
600 /**
601 * Add an additional set of assets to the asset manager. This can be
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -0700602 * either a directory or ZIP file. Not for use by applications. Returns
603 * the cookie of the added asset, or 0 on failure.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800604 * {@hide}
605 */
606 public native final int addAssetPath(String path);
607
608 /**
Kenny Root3a198332010-01-21 15:51:48 -0800609 * Add multiple sets of assets to the asset manager at once. See
610 * {@link #addAssetPath(String)} for more information. Returns array of
611 * cookies for each added asset with 0 indicating failure, or null if
612 * the input array of paths is null.
613 * {@hide}
614 */
615 public final int[] addAssetPaths(String[] paths) {
616 if (paths == null) {
617 return null;
618 }
619
620 int[] cookies = new int[paths.length];
621 for (int i = 0; i < paths.length; i++) {
622 cookies[i] = addAssetPath(paths[i]);
623 }
624
625 return cookies;
626 }
627
628 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800629 * Determine whether the state in this asset manager is up-to-date with
630 * the files on the filesystem. If false is returned, you need to
631 * instantiate a new AssetManager class to see the new data.
632 * {@hide}
633 */
634 public native final boolean isUpToDate();
635
636 /**
637 * Change the locale being used by this asset manager. Not for use by
638 * applications.
639 * {@hide}
640 */
641 public native final void setLocale(String locale);
642
643 /**
644 * Get the locales that this asset manager contains data for.
645 */
646 public native final String[] getLocales();
647
648 /**
649 * Change the configuation used when retrieving resources. Not for use by
650 * applications.
651 * {@hide}
652 */
653 public native final void setConfiguration(int mcc, int mnc, String locale,
654 int orientation, int touchscreen, int density, int keyboard,
655 int keyboardHidden, int navigation, int screenWidth, int screenHeight,
Tobias Haamel27b28b32010-02-09 23:09:17 +0100656 int screenLayout, int uiMode, int majorVersion);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800657
658 /**
659 * Retrieve the resource identifier for the given resource name.
660 */
661 /*package*/ native final int getResourceIdentifier(String type,
662 String name,
663 String defPackage);
664
665 /*package*/ native final String getResourceName(int resid);
666 /*package*/ native final String getResourcePackageName(int resid);
667 /*package*/ native final String getResourceTypeName(int resid);
668 /*package*/ native final String getResourceEntryName(int resid);
669
670 private native final int openAsset(String fileName, int accessMode);
671 private final native ParcelFileDescriptor openAssetFd(String fileName,
672 long[] outOffsets) throws IOException;
673 private native final int openNonAssetNative(int cookie, String fileName,
674 int accessMode);
675 private native ParcelFileDescriptor openNonAssetFdNative(int cookie,
676 String fileName, long[] outOffsets) throws IOException;
677 private native final void destroyAsset(int asset);
678 private native final int readAssetChar(int asset);
679 private native final int readAsset(int asset, byte[] b, int off, int len);
680 private native final long seekAsset(int asset, long offset, int whence);
681 private native final long getAssetLength(int asset);
682 private native final long getAssetRemainingLength(int asset);
683
684 /** Returns true if the resource was found, filling in mRetStringBlock and
685 * mRetData. */
Kenny Root55fc8502010-10-28 14:47:01 -0700686 private native final int loadResourceValue(int ident, short density, TypedValue outValue,
687 boolean resolve);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800688 /** Returns true if the resource was found, filling in mRetStringBlock and
689 * mRetData. */
690 private native final int loadResourceBagValue(int ident, int bagEntryId, TypedValue outValue,
691 boolean resolve);
Dianne Hackborn0d221012009-07-29 15:41:19 -0700692 /*package*/ static final int STYLE_NUM_ENTRIES = 6;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800693 /*package*/ static final int STYLE_TYPE = 0;
694 /*package*/ static final int STYLE_DATA = 1;
695 /*package*/ static final int STYLE_ASSET_COOKIE = 2;
696 /*package*/ static final int STYLE_RESOURCE_ID = 3;
697 /*package*/ static final int STYLE_CHANGING_CONFIGURATIONS = 4;
Dianne Hackborn0d221012009-07-29 15:41:19 -0700698 /*package*/ static final int STYLE_DENSITY = 5;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800699 /*package*/ native static final boolean applyStyle(int theme,
700 int defStyleAttr, int defStyleRes, int xmlParser,
701 int[] inAttrs, int[] outValues, int[] outIndices);
702 /*package*/ native final boolean retrieveAttributes(
703 int xmlParser, int[] inAttrs, int[] outValues, int[] outIndices);
704 /*package*/ native final int getArraySize(int resource);
705 /*package*/ native final int retrieveArray(int resource, int[] outValues);
706 private native final int getStringBlockCount();
707 private native final int getNativeStringBlock(int block);
708
709 /**
710 * {@hide}
711 */
712 public native final String getCookieName(int cookie);
713
714 /**
715 * {@hide}
716 */
717 public native static final int getGlobalAssetCount();
718
719 /**
720 * {@hide}
721 */
Dianne Hackborn82e1ee92009-08-11 18:56:41 -0700722 public native static final String getAssetAllocations();
723
724 /**
725 * {@hide}
726 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800727 public native static final int getGlobalAssetManagerCount();
728
729 private native final int newTheme();
730 private native final void deleteTheme(int theme);
731 /*package*/ native static final void applyThemeStyle(int theme, int styleRes, boolean force);
732 /*package*/ native static final void copyTheme(int dest, int source);
733 /*package*/ native static final int loadThemeAttributeValue(int theme, int ident,
734 TypedValue outValue,
735 boolean resolve);
736 /*package*/ native static final void dumpTheme(int theme, int priority, String tag, String prefix);
737
738 private native final int openXmlAssetNative(int cookie, String fileName);
739
740 private native final String[] getArrayStringResource(int arrayRes);
741 private native final int[] getArrayStringInfo(int arrayRes);
742 /*package*/ native final int[] getArrayIntResource(int arrayRes);
743
744 private native final void init();
745 private native final void destroy();
746
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -0800747 private final void incRefsLocked(int id) {
748 if (DEBUG_REFS) {
749 if (mRefStacks == null) {
750 mRefStacks = new HashMap<Integer, RuntimeException>();
751 RuntimeException ex = new RuntimeException();
752 ex.fillInStackTrace();
753 mRefStacks.put(this.hashCode(), ex);
754 }
755 }
756 mNumRefs++;
757 }
758
759 private final void decRefsLocked(int id) {
760 if (DEBUG_REFS && mRefStacks != null) {
761 mRefStacks.remove(id);
762 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800763 mNumRefs--;
764 //System.out.println("Dec streams: mNumRefs=" + mNumRefs
765 // + " mReleased=" + mReleased);
766 if (mNumRefs == 0) {
767 destroy();
768 }
769 }
770}