blob: 93ce633fdcdc9653aeb0a58396000d0961850716 [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;
Dianne Hackbornf7be4802013-04-12 14:52:58 -070020import android.os.Trace;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080021import 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";
Joe Onorato43a17652011-04-06 19:22:23 -070061 private static final boolean localLOGV = false || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062
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();
Xavier Ducrohet7f9f99ea2011-08-11 10:16:17 -070066 /*package*/ 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;
73
74 private StringBlock mStringBlocks[] = null;
75
76 private int mNumRefs = 1;
77 private boolean mOpen = true;
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -080078 private HashMap<Integer, RuntimeException> mRefStacks;
Dianne Hackborn60d7db42009-11-16 17:16:26 -080079
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080 /**
81 * Create a new AssetManager containing only the basic system assets.
82 * Applications will not generally use this method, instead retrieving the
83 * appropriate asset manager with {@link Resources#getAssets}. Not for
84 * use by applications.
85 * {@hide}
86 */
87 public AssetManager() {
Dianne Hackborn60d7db42009-11-16 17:16:26 -080088 synchronized (this) {
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -080089 if (DEBUG_REFS) {
90 mNumRefs = 0;
91 incRefsLocked(this.hashCode());
92 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093 init();
94 if (localLOGV) Log.v(TAG, "New asset manager: " + this);
95 ensureSystemAssets();
96 }
97 }
98
99 private static void ensureSystemAssets() {
Dianne Hackborn60d7db42009-11-16 17:16:26 -0800100 synchronized (sSync) {
101 if (sSystem == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102 AssetManager system = new AssetManager(true);
103 system.makeStringBlocks(false);
Dianne Hackborn60d7db42009-11-16 17:16:26 -0800104 sSystem = system;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105 }
106 }
107 }
108
109 private AssetManager(boolean isSystem) {
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -0800110 if (DEBUG_REFS) {
111 synchronized (this) {
112 mNumRefs = 0;
113 incRefsLocked(this.hashCode());
114 }
115 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800116 init();
117 if (localLOGV) Log.v(TAG, "New asset manager: " + this);
118 }
119
120 /**
121 * Return a global shared asset manager that provides access to only
122 * system assets (no application assets).
123 * {@hide}
124 */
125 public static AssetManager getSystem() {
126 ensureSystemAssets();
Dianne Hackborn60d7db42009-11-16 17:16:26 -0800127 return sSystem;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800128 }
129
130 /**
131 * Close this asset manager.
132 */
133 public void close() {
Dianne Hackborn60d7db42009-11-16 17:16:26 -0800134 synchronized(this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800135 //System.out.println("Release: num=" + mNumRefs
136 // + ", released=" + mReleased);
137 if (mOpen) {
138 mOpen = false;
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -0800139 decRefsLocked(this.hashCode());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800140 }
141 }
142 }
143
144 /**
145 * Retrieve the string value associated with a particular resource
146 * identifier for the current configuration / skin.
147 */
148 /*package*/ final CharSequence getResourceText(int ident) {
Dianne Hackborn60d7db42009-11-16 17:16:26 -0800149 synchronized (this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800150 TypedValue tmpValue = mValue;
Kenny Root55fc8502010-10-28 14:47:01 -0700151 int block = loadResourceValue(ident, (short) 0, tmpValue, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152 if (block >= 0) {
153 if (tmpValue.type == TypedValue.TYPE_STRING) {
154 return mStringBlocks[block].get(tmpValue.data);
155 }
156 return tmpValue.coerceToString();
157 }
158 }
159 return null;
160 }
161
162 /**
163 * Retrieve the string value associated with a particular resource
164 * identifier for the current configuration / skin.
165 */
166 /*package*/ final CharSequence getResourceBagText(int ident, int bagEntryId) {
Dianne Hackborn60d7db42009-11-16 17:16:26 -0800167 synchronized (this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800168 TypedValue tmpValue = mValue;
169 int block = loadResourceBagValue(ident, bagEntryId, tmpValue, true);
170 if (block >= 0) {
171 if (tmpValue.type == TypedValue.TYPE_STRING) {
172 return mStringBlocks[block].get(tmpValue.data);
173 }
174 return tmpValue.coerceToString();
175 }
176 }
177 return null;
178 }
179
180 /**
181 * Retrieve the string array associated with a particular resource
182 * identifier.
183 * @param id Resource id of the string array
184 */
185 /*package*/ final String[] getResourceStringArray(final int id) {
186 String[] retArray = getArrayStringResource(id);
187 return retArray;
188 }
189
190
191 /*package*/ final boolean getResourceValue(int ident,
Kenny Root55fc8502010-10-28 14:47:01 -0700192 int density,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800193 TypedValue outValue,
194 boolean resolveRefs)
195 {
Kenny Root55fc8502010-10-28 14:47:01 -0700196 int block = loadResourceValue(ident, (short) density, outValue, resolveRefs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800197 if (block >= 0) {
198 if (outValue.type != TypedValue.TYPE_STRING) {
199 return true;
200 }
201 outValue.string = mStringBlocks[block].get(outValue.data);
202 return true;
203 }
204 return false;
205 }
206
207 /**
208 * Retrieve the text array associated with a particular resource
209 * identifier.
210 * @param id Resource id of the string array
211 */
212 /*package*/ final CharSequence[] getResourceTextArray(final int id) {
213 int[] rawInfoArray = getArrayStringInfo(id);
214 int rawInfoArrayLen = rawInfoArray.length;
215 final int infoArrayLen = rawInfoArrayLen / 2;
216 int block;
217 int index;
218 CharSequence[] retArray = new CharSequence[infoArrayLen];
219 for (int i = 0, j = 0; i < rawInfoArrayLen; i = i + 2, j++) {
220 block = rawInfoArray[i];
221 index = rawInfoArray[i + 1];
222 retArray[j] = index >= 0 ? mStringBlocks[block].get(index) : null;
223 }
224 return retArray;
225 }
226
227 /*package*/ final boolean getThemeValue(int theme, int ident,
228 TypedValue outValue, boolean resolveRefs) {
229 int block = loadThemeAttributeValue(theme, ident, outValue, resolveRefs);
230 if (block >= 0) {
231 if (outValue.type != TypedValue.TYPE_STRING) {
232 return true;
233 }
234 StringBlock[] blocks = mStringBlocks;
235 if (blocks == null) {
236 ensureStringBlocks();
Jozef BABJAK41a5ed72011-04-19 12:28:22 +0200237 blocks = mStringBlocks;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800238 }
239 outValue.string = blocks[block].get(outValue.data);
240 return true;
241 }
242 return false;
243 }
244
245 /*package*/ final void ensureStringBlocks() {
246 if (mStringBlocks == null) {
Dianne Hackborn60d7db42009-11-16 17:16:26 -0800247 synchronized (this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800248 if (mStringBlocks == null) {
249 makeStringBlocks(true);
250 }
251 }
252 }
253 }
254
Xavier Ducrohet7f9f99ea2011-08-11 10:16:17 -0700255 /*package*/ final void makeStringBlocks(boolean copyFromSystem) {
Dianne Hackborn60d7db42009-11-16 17:16:26 -0800256 final int sysNum = copyFromSystem ? sSystem.mStringBlocks.length : 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800257 final int num = getStringBlockCount();
258 mStringBlocks = new StringBlock[num];
259 if (localLOGV) Log.v(TAG, "Making string blocks for " + this
260 + ": " + num);
261 for (int i=0; i<num; i++) {
262 if (i < sysNum) {
Dianne Hackborn60d7db42009-11-16 17:16:26 -0800263 mStringBlocks[i] = sSystem.mStringBlocks[i];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800264 } else {
265 mStringBlocks[i] = new StringBlock(getNativeStringBlock(i), true);
266 }
267 }
268 }
269
270 /*package*/ final CharSequence getPooledString(int block, int id) {
271 //System.out.println("Get pooled: block=" + block
272 // + ", id=#" + Integer.toHexString(id)
273 // + ", blocks=" + mStringBlocks);
274 return mStringBlocks[block-1].get(id);
275 }
276
277 /**
278 * Open an asset using ACCESS_STREAMING mode. This provides access to
279 * files that have been bundled with an application as assets -- that is,
280 * files placed in to the "assets" directory.
281 *
282 * @param fileName The name of the asset to open. This name can be
283 * hierarchical.
284 *
285 * @see #open(String, int)
286 * @see #list
287 */
288 public final InputStream open(String fileName) throws IOException {
289 return open(fileName, ACCESS_STREAMING);
290 }
291
292 /**
293 * Open an asset using an explicit access mode, returning an InputStream to
294 * read its contents. This provides access to files that have been bundled
295 * with an application as assets -- that is, files placed in to the
296 * "assets" directory.
297 *
298 * @param fileName The name of the asset to open. This name can be
299 * hierarchical.
300 * @param accessMode Desired access mode for retrieving the data.
301 *
302 * @see #ACCESS_UNKNOWN
303 * @see #ACCESS_STREAMING
304 * @see #ACCESS_RANDOM
305 * @see #ACCESS_BUFFER
306 * @see #open(String)
307 * @see #list
308 */
309 public final InputStream open(String fileName, int accessMode)
310 throws IOException {
Dianne Hackborn60d7db42009-11-16 17:16:26 -0800311 synchronized (this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800312 if (!mOpen) {
313 throw new RuntimeException("Assetmanager has been closed");
314 }
315 int asset = openAsset(fileName, accessMode);
316 if (asset != 0) {
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -0800317 AssetInputStream res = new AssetInputStream(asset);
318 incRefsLocked(res.hashCode());
319 return res;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800320 }
321 }
322 throw new FileNotFoundException("Asset file: " + fileName);
323 }
324
325 public final AssetFileDescriptor openFd(String fileName)
326 throws IOException {
Dianne Hackborn60d7db42009-11-16 17:16:26 -0800327 synchronized (this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800328 if (!mOpen) {
329 throw new RuntimeException("Assetmanager has been closed");
330 }
331 ParcelFileDescriptor pfd = openAssetFd(fileName, mOffsets);
332 if (pfd != null) {
333 return new AssetFileDescriptor(pfd, mOffsets[0], mOffsets[1]);
334 }
335 }
336 throw new FileNotFoundException("Asset file: " + fileName);
337 }
338
339 /**
340 * Return a String array of all the assets at the given path.
341 *
342 * @param path A relative path within the assets, i.e., "docs/home.html".
343 *
344 * @return String[] Array of strings, one for each asset. These file
345 * names are relative to 'path'. You can open the file by
346 * concatenating 'path' and a name in the returned string (via
347 * File) and passing that to open().
348 *
349 * @see #open
350 */
351 public native final String[] list(String path)
352 throws IOException;
353
354 /**
355 * {@hide}
356 * Open a non-asset file as an asset using ACCESS_STREAMING mode. This
357 * provides direct access to all of the files included in an application
358 * package (not only its assets). Applications should not normally use
359 * this.
360 *
361 * @see #open(String)
362 */
363 public final InputStream openNonAsset(String fileName) throws IOException {
364 return openNonAsset(0, fileName, ACCESS_STREAMING);
365 }
366
367 /**
368 * {@hide}
369 * Open a non-asset file as an asset using a specific access mode. This
370 * provides direct access to all of the files included in an application
371 * package (not only its assets). Applications should not normally use
372 * this.
373 *
374 * @see #open(String, int)
375 */
376 public final InputStream openNonAsset(String fileName, int accessMode)
377 throws IOException {
378 return openNonAsset(0, fileName, accessMode);
379 }
380
381 /**
382 * {@hide}
383 * Open a non-asset in a specified package. Not for use by applications.
384 *
385 * @param cookie Identifier of the package to be opened.
386 * @param fileName Name of the asset to retrieve.
387 */
388 public final InputStream openNonAsset(int cookie, String fileName)
389 throws IOException {
390 return openNonAsset(cookie, fileName, ACCESS_STREAMING);
391 }
392
393 /**
394 * {@hide}
395 * Open a non-asset in a specified package. Not for use by applications.
396 *
397 * @param cookie Identifier of the package to be opened.
398 * @param fileName Name of the asset to retrieve.
399 * @param accessMode Desired access mode for retrieving the data.
400 */
401 public final InputStream openNonAsset(int cookie, String fileName, int accessMode)
402 throws IOException {
Dianne Hackborn60d7db42009-11-16 17:16:26 -0800403 synchronized (this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800404 if (!mOpen) {
405 throw new RuntimeException("Assetmanager has been closed");
406 }
407 int asset = openNonAssetNative(cookie, fileName, accessMode);
408 if (asset != 0) {
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -0800409 AssetInputStream res = new AssetInputStream(asset);
410 incRefsLocked(res.hashCode());
411 return res;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800412 }
413 }
414 throw new FileNotFoundException("Asset absolute file: " + fileName);
415 }
416
417 public final AssetFileDescriptor openNonAssetFd(String fileName)
418 throws IOException {
419 return openNonAssetFd(0, fileName);
420 }
421
422 public final AssetFileDescriptor openNonAssetFd(int cookie,
423 String fileName) throws IOException {
Dianne Hackborn60d7db42009-11-16 17:16:26 -0800424 synchronized (this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800425 if (!mOpen) {
426 throw new RuntimeException("Assetmanager has been closed");
427 }
428 ParcelFileDescriptor pfd = openNonAssetFdNative(cookie,
429 fileName, mOffsets);
430 if (pfd != null) {
431 return new AssetFileDescriptor(pfd, mOffsets[0], mOffsets[1]);
432 }
433 }
434 throw new FileNotFoundException("Asset absolute file: " + fileName);
435 }
436
437 /**
438 * Retrieve a parser for a compiled XML file.
439 *
440 * @param fileName The name of the file to retrieve.
441 */
442 public final XmlResourceParser openXmlResourceParser(String fileName)
443 throws IOException {
444 return openXmlResourceParser(0, fileName);
445 }
446
447 /**
448 * Retrieve a parser for a compiled XML file.
449 *
450 * @param cookie Identifier of the package to be opened.
451 * @param fileName The name of the file to retrieve.
452 */
453 public final XmlResourceParser openXmlResourceParser(int cookie,
454 String fileName) throws IOException {
455 XmlBlock block = openXmlBlockAsset(cookie, fileName);
456 XmlResourceParser rp = block.newParser();
457 block.close();
458 return rp;
459 }
460
461 /**
462 * {@hide}
463 * Retrieve a non-asset as a compiled XML file. Not for use by
464 * applications.
465 *
466 * @param fileName The name of the file to retrieve.
467 */
468 /*package*/ final XmlBlock openXmlBlockAsset(String fileName)
469 throws IOException {
470 return openXmlBlockAsset(0, fileName);
471 }
472
473 /**
474 * {@hide}
475 * Retrieve a non-asset as a compiled XML file. Not for use by
476 * applications.
477 *
478 * @param cookie Identifier of the package to be opened.
479 * @param fileName Name of the asset to retrieve.
480 */
481 /*package*/ final XmlBlock openXmlBlockAsset(int cookie, String fileName)
482 throws IOException {
Dianne Hackborn60d7db42009-11-16 17:16:26 -0800483 synchronized (this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800484 if (!mOpen) {
485 throw new RuntimeException("Assetmanager has been closed");
486 }
487 int xmlBlock = openXmlAssetNative(cookie, fileName);
488 if (xmlBlock != 0) {
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -0800489 XmlBlock res = new XmlBlock(this, xmlBlock);
490 incRefsLocked(res.hashCode());
491 return res;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800492 }
493 }
494 throw new FileNotFoundException("Asset XML file: " + fileName);
495 }
496
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -0800497 /*package*/ void xmlBlockGone(int id) {
Dianne Hackborn60d7db42009-11-16 17:16:26 -0800498 synchronized (this) {
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -0800499 decRefsLocked(id);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800500 }
501 }
502
503 /*package*/ final int createTheme() {
Dianne Hackborn60d7db42009-11-16 17:16:26 -0800504 synchronized (this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800505 if (!mOpen) {
506 throw new RuntimeException("Assetmanager has been closed");
507 }
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -0800508 int res = newTheme();
509 incRefsLocked(res);
510 return res;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800511 }
512 }
513
514 /*package*/ final void releaseTheme(int theme) {
Dianne Hackborn60d7db42009-11-16 17:16:26 -0800515 synchronized (this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800516 deleteTheme(theme);
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -0800517 decRefsLocked(theme);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800518 }
519 }
520
521 protected void finalize() throws Throwable {
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -0800522 try {
523 if (DEBUG_REFS && mNumRefs != 0) {
524 Log.w(TAG, "AssetManager " + this
525 + " finalized with non-zero refs: " + mNumRefs);
526 if (mRefStacks != null) {
527 for (RuntimeException e : mRefStacks.values()) {
528 Log.w(TAG, "Reference from here", e);
529 }
530 }
531 }
532 destroy();
533 } finally {
534 super.finalize();
535 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800536 }
537
538 public final class AssetInputStream extends InputStream {
539 public final int getAssetInt() {
540 return mAsset;
541 }
Ashok Bhata0545dd2014-01-14 10:52:35 +0000542 /**
543 * @hide
544 */
545 public final long getNativeAsset() {
546 return mAsset;
547 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800548 private AssetInputStream(int asset)
549 {
550 mAsset = asset;
551 mLength = getAssetLength(asset);
552 }
553 public final int read() throws IOException {
554 return readAssetChar(mAsset);
555 }
556 public final boolean markSupported() {
557 return true;
558 }
559 public final int available() throws IOException {
560 long len = getAssetRemainingLength(mAsset);
561 return len > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int)len;
562 }
563 public final void close() throws IOException {
Dianne Hackborn60d7db42009-11-16 17:16:26 -0800564 synchronized (AssetManager.this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800565 if (mAsset != 0) {
566 destroyAsset(mAsset);
567 mAsset = 0;
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -0800568 decRefsLocked(hashCode());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800569 }
570 }
571 }
572 public final void mark(int readlimit) {
573 mMarkPos = seekAsset(mAsset, 0, 0);
574 }
575 public final void reset() throws IOException {
576 seekAsset(mAsset, mMarkPos, -1);
577 }
578 public final int read(byte[] b) throws IOException {
579 return readAsset(mAsset, b, 0, b.length);
580 }
581 public final int read(byte[] b, int off, int len) throws IOException {
582 return readAsset(mAsset, b, off, len);
583 }
584 public final long skip(long n) throws IOException {
585 long pos = seekAsset(mAsset, 0, 0);
586 if ((pos+n) > mLength) {
587 n = mLength-pos;
588 }
589 if (n > 0) {
590 seekAsset(mAsset, n, 0);
591 }
592 return n;
593 }
594
595 protected void finalize() throws Throwable
596 {
597 close();
598 }
599
600 private int mAsset;
601 private long mLength;
602 private long mMarkPos;
603 }
604
605 /**
606 * Add an additional set of assets to the asset manager. This can be
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -0700607 * either a directory or ZIP file. Not for use by applications. Returns
608 * the cookie of the added asset, or 0 on failure.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800609 * {@hide}
610 */
Dianne Hackbornf7be4802013-04-12 14:52:58 -0700611 public final int addAssetPath(String path) {
612 int res = addAssetPathNative(path);
613 return res;
614 }
615
616 private native final int addAssetPathNative(String path);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800617
618 /**
Kenny Root3a198332010-01-21 15:51:48 -0800619 * Add multiple sets of assets to the asset manager at once. See
620 * {@link #addAssetPath(String)} for more information. Returns array of
621 * cookies for each added asset with 0 indicating failure, or null if
622 * the input array of paths is null.
623 * {@hide}
624 */
625 public final int[] addAssetPaths(String[] paths) {
626 if (paths == null) {
627 return null;
628 }
629
630 int[] cookies = new int[paths.length];
631 for (int i = 0; i < paths.length; i++) {
632 cookies[i] = addAssetPath(paths[i]);
633 }
634
635 return cookies;
636 }
637
638 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800639 * Determine whether the state in this asset manager is up-to-date with
640 * the files on the filesystem. If false is returned, you need to
641 * instantiate a new AssetManager class to see the new data.
642 * {@hide}
643 */
644 public native final boolean isUpToDate();
645
646 /**
647 * Change the locale being used by this asset manager. Not for use by
648 * applications.
649 * {@hide}
650 */
651 public native final void setLocale(String locale);
652
653 /**
654 * Get the locales that this asset manager contains data for.
655 */
656 public native final String[] getLocales();
657
658 /**
659 * Change the configuation used when retrieving resources. Not for use by
660 * applications.
661 * {@hide}
662 */
663 public native final void setConfiguration(int mcc, int mnc, String locale,
664 int orientation, int touchscreen, int density, int keyboard,
665 int keyboardHidden, int navigation, int screenWidth, int screenHeight,
Dianne Hackborn69cb8752011-05-19 18:13:32 -0700666 int smallestScreenWidthDp, int screenWidthDp, int screenHeightDp,
667 int screenLayout, int uiMode, int majorVersion);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800668
669 /**
670 * Retrieve the resource identifier for the given resource name.
671 */
672 /*package*/ native final int getResourceIdentifier(String type,
673 String name,
674 String defPackage);
675
676 /*package*/ native final String getResourceName(int resid);
677 /*package*/ native final String getResourcePackageName(int resid);
678 /*package*/ native final String getResourceTypeName(int resid);
679 /*package*/ native final String getResourceEntryName(int resid);
680
681 private native final int openAsset(String fileName, int accessMode);
682 private final native ParcelFileDescriptor openAssetFd(String fileName,
683 long[] outOffsets) throws IOException;
684 private native final int openNonAssetNative(int cookie, String fileName,
685 int accessMode);
686 private native ParcelFileDescriptor openNonAssetFdNative(int cookie,
687 String fileName, long[] outOffsets) throws IOException;
688 private native final void destroyAsset(int asset);
689 private native final int readAssetChar(int asset);
690 private native final int readAsset(int asset, byte[] b, int off, int len);
691 private native final long seekAsset(int asset, long offset, int whence);
692 private native final long getAssetLength(int asset);
693 private native final long getAssetRemainingLength(int asset);
694
695 /** Returns true if the resource was found, filling in mRetStringBlock and
696 * mRetData. */
Kenny Root55fc8502010-10-28 14:47:01 -0700697 private native final int loadResourceValue(int ident, short density, TypedValue outValue,
698 boolean resolve);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800699 /** Returns true if the resource was found, filling in mRetStringBlock and
700 * mRetData. */
701 private native final int loadResourceBagValue(int ident, int bagEntryId, TypedValue outValue,
702 boolean resolve);
Dianne Hackborn0d221012009-07-29 15:41:19 -0700703 /*package*/ static final int STYLE_NUM_ENTRIES = 6;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800704 /*package*/ static final int STYLE_TYPE = 0;
705 /*package*/ static final int STYLE_DATA = 1;
706 /*package*/ static final int STYLE_ASSET_COOKIE = 2;
707 /*package*/ static final int STYLE_RESOURCE_ID = 3;
708 /*package*/ static final int STYLE_CHANGING_CONFIGURATIONS = 4;
Dianne Hackborn0d221012009-07-29 15:41:19 -0700709 /*package*/ static final int STYLE_DENSITY = 5;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800710 /*package*/ native static final boolean applyStyle(int theme,
711 int defStyleAttr, int defStyleRes, int xmlParser,
712 int[] inAttrs, int[] outValues, int[] outIndices);
713 /*package*/ native final boolean retrieveAttributes(
714 int xmlParser, int[] inAttrs, int[] outValues, int[] outIndices);
715 /*package*/ native final int getArraySize(int resource);
716 /*package*/ native final int retrieveArray(int resource, int[] outValues);
717 private native final int getStringBlockCount();
718 private native final int getNativeStringBlock(int block);
719
720 /**
721 * {@hide}
722 */
723 public native final String getCookieName(int cookie);
724
725 /**
726 * {@hide}
727 */
728 public native static final int getGlobalAssetCount();
729
730 /**
731 * {@hide}
732 */
Dianne Hackborn82e1ee92009-08-11 18:56:41 -0700733 public native static final String getAssetAllocations();
734
735 /**
736 * {@hide}
737 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800738 public native static final int getGlobalAssetManagerCount();
739
740 private native final int newTheme();
741 private native final void deleteTheme(int theme);
742 /*package*/ native static final void applyThemeStyle(int theme, int styleRes, boolean force);
743 /*package*/ native static final void copyTheme(int dest, int source);
744 /*package*/ native static final int loadThemeAttributeValue(int theme, int ident,
745 TypedValue outValue,
746 boolean resolve);
747 /*package*/ native static final void dumpTheme(int theme, int priority, String tag, String prefix);
748
749 private native final int openXmlAssetNative(int cookie, String fileName);
750
751 private native final String[] getArrayStringResource(int arrayRes);
752 private native final int[] getArrayStringInfo(int arrayRes);
753 /*package*/ native final int[] getArrayIntResource(int arrayRes);
754
755 private native final void init();
756 private native final void destroy();
757
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -0800758 private final void incRefsLocked(int id) {
759 if (DEBUG_REFS) {
760 if (mRefStacks == null) {
761 mRefStacks = new HashMap<Integer, RuntimeException>();
762 RuntimeException ex = new RuntimeException();
763 ex.fillInStackTrace();
764 mRefStacks.put(this.hashCode(), ex);
765 }
766 }
767 mNumRefs++;
768 }
769
770 private final void decRefsLocked(int id) {
771 if (DEBUG_REFS && mRefStacks != null) {
772 mRefStacks.remove(id);
773 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800774 mNumRefs--;
775 //System.out.println("Dec streams: mNumRefs=" + mNumRefs
776 // + " mReleased=" + mReleased);
777 if (mNumRefs == 0) {
778 destroy();
779 }
780 }
781}