• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 package android.content.res;
18 
19 import android.os.ParcelFileDescriptor;
20 import android.util.Log;
21 import android.util.TypedValue;
22 
23 import java.io.FileNotFoundException;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.util.HashMap;
27 
28 /**
29  * Provides access to an application's raw asset files; see {@link Resources}
30  * for the way most applications will want to retrieve their resource data.
31  * This class presents a lower-level API that allows you to open and read raw
32  * files that have been bundled with the application as a simple stream of
33  * bytes.
34  */
35 public final class AssetManager {
36     /* modes used when opening an asset */
37 
38     /**
39      * Mode for {@link #open(String, int)}: no specific information about how
40      * data will be accessed.
41      */
42     public static final int ACCESS_UNKNOWN = 0;
43     /**
44      * Mode for {@link #open(String, int)}: Read chunks, and seek forward and
45      * backward.
46      */
47     public static final int ACCESS_RANDOM = 1;
48     /**
49      * Mode for {@link #open(String, int)}: Read sequentially, with an
50      * occasional forward seek.
51      */
52     public static final int ACCESS_STREAMING = 2;
53     /**
54      * Mode for {@link #open(String, int)}: Attempt to load contents into
55      * memory, for fast small reads.
56      */
57     public static final int ACCESS_BUFFER = 3;
58 
59     private static final String TAG = "AssetManager";
60     private static final boolean localLOGV = false || false;
61 
62     private static final boolean DEBUG_REFS = false;
63 
64     private static final Object sSync = new Object();
65     /*package*/ static AssetManager sSystem = null;
66 
67     private final TypedValue mValue = new TypedValue();
68     private final long[] mOffsets = new long[2];
69 
70     // For communication with native code.
71     private int mObject;
72     private int mNObject;  // used by the NDK
73 
74     private StringBlock mStringBlocks[] = null;
75 
76     private int mNumRefs = 1;
77     private boolean mOpen = true;
78     private HashMap<Integer, RuntimeException> mRefStacks;
79 
80     /**
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      */
AssetManager()87     public AssetManager() {
88         synchronized (this) {
89             if (DEBUG_REFS) {
90                 mNumRefs = 0;
91                 incRefsLocked(this.hashCode());
92             }
93             init();
94             if (localLOGV) Log.v(TAG, "New asset manager: " + this);
95             ensureSystemAssets();
96         }
97     }
98 
ensureSystemAssets()99     private static void ensureSystemAssets() {
100         synchronized (sSync) {
101             if (sSystem == null) {
102                 AssetManager system = new AssetManager(true);
103                 system.makeStringBlocks(false);
104                 sSystem = system;
105             }
106         }
107     }
108 
AssetManager(boolean isSystem)109     private AssetManager(boolean isSystem) {
110         if (DEBUG_REFS) {
111             synchronized (this) {
112                 mNumRefs = 0;
113                 incRefsLocked(this.hashCode());
114             }
115         }
116         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      */
getSystem()125     public static AssetManager getSystem() {
126         ensureSystemAssets();
127         return sSystem;
128     }
129 
130     /**
131      * Close this asset manager.
132      */
close()133     public void close() {
134         synchronized(this) {
135             //System.out.println("Release: num=" + mNumRefs
136             //                   + ", released=" + mReleased);
137             if (mOpen) {
138                 mOpen = false;
139                 decRefsLocked(this.hashCode());
140             }
141         }
142     }
143 
144     /**
145      * Retrieve the string value associated with a particular resource
146      * identifier for the current configuration / skin.
147      */
getResourceText(int ident)148     /*package*/ final CharSequence getResourceText(int ident) {
149         synchronized (this) {
150             TypedValue tmpValue = mValue;
151             int block = loadResourceValue(ident, (short) 0, tmpValue, true);
152             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      */
getResourceBagText(int ident, int bagEntryId)166     /*package*/ final CharSequence getResourceBagText(int ident, int bagEntryId) {
167         synchronized (this) {
168             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      */
getResourceStringArray(final int id)185     /*package*/ final String[] getResourceStringArray(final int id) {
186         String[] retArray = getArrayStringResource(id);
187         return retArray;
188     }
189 
190 
getResourceValue(int ident, int density, TypedValue outValue, boolean resolveRefs)191     /*package*/ final boolean getResourceValue(int ident,
192                                                int density,
193                                                TypedValue outValue,
194                                                boolean resolveRefs)
195     {
196         int block = loadResourceValue(ident, (short) density, outValue, resolveRefs);
197         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      */
getResourceTextArray(final int id)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 
getThemeValue(int theme, int ident, TypedValue outValue, boolean resolveRefs)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();
237                 blocks = mStringBlocks;
238             }
239             outValue.string = blocks[block].get(outValue.data);
240             return true;
241         }
242         return false;
243     }
244 
ensureStringBlocks()245     /*package*/ final void ensureStringBlocks() {
246         if (mStringBlocks == null) {
247             synchronized (this) {
248                 if (mStringBlocks == null) {
249                     makeStringBlocks(true);
250                 }
251             }
252         }
253     }
254 
makeStringBlocks(boolean copyFromSystem)255     /*package*/ final void makeStringBlocks(boolean copyFromSystem) {
256         final int sysNum = copyFromSystem ? sSystem.mStringBlocks.length : 0;
257         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) {
263                 mStringBlocks[i] = sSystem.mStringBlocks[i];
264             } else {
265                 mStringBlocks[i] = new StringBlock(getNativeStringBlock(i), true);
266             }
267         }
268     }
269 
getPooledString(int block, int id)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      */
open(String fileName)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      */
open(String fileName, int accessMode)309     public final InputStream open(String fileName, int accessMode)
310         throws IOException {
311         synchronized (this) {
312             if (!mOpen) {
313                 throw new RuntimeException("Assetmanager has been closed");
314             }
315             int asset = openAsset(fileName, accessMode);
316             if (asset != 0) {
317                 AssetInputStream res = new AssetInputStream(asset);
318                 incRefsLocked(res.hashCode());
319                 return res;
320             }
321         }
322         throw new FileNotFoundException("Asset file: " + fileName);
323     }
324 
openFd(String fileName)325     public final AssetFileDescriptor openFd(String fileName)
326             throws IOException {
327         synchronized (this) {
328             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      */
list(String path)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      */
openNonAsset(String fileName)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      */
openNonAsset(String fileName, int accessMode)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      */
openNonAsset(int cookie, String fileName)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      */
openNonAsset(int cookie, String fileName, int accessMode)401     public final InputStream openNonAsset(int cookie, String fileName, int accessMode)
402         throws IOException {
403         synchronized (this) {
404             if (!mOpen) {
405                 throw new RuntimeException("Assetmanager has been closed");
406             }
407             int asset = openNonAssetNative(cookie, fileName, accessMode);
408             if (asset != 0) {
409                 AssetInputStream res = new AssetInputStream(asset);
410                 incRefsLocked(res.hashCode());
411                 return res;
412             }
413         }
414         throw new FileNotFoundException("Asset absolute file: " + fileName);
415     }
416 
openNonAssetFd(String fileName)417     public final AssetFileDescriptor openNonAssetFd(String fileName)
418             throws IOException {
419         return openNonAssetFd(0, fileName);
420     }
421 
openNonAssetFd(int cookie, String fileName)422     public final AssetFileDescriptor openNonAssetFd(int cookie,
423             String fileName) throws IOException {
424         synchronized (this) {
425             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      */
openXmlResourceParser(String fileName)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      */
openXmlResourceParser(int cookie, String fileName)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      */
openXmlBlockAsset(String fileName)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      */
openXmlBlockAsset(int cookie, String fileName)481     /*package*/ final XmlBlock openXmlBlockAsset(int cookie, String fileName)
482         throws IOException {
483         synchronized (this) {
484             if (!mOpen) {
485                 throw new RuntimeException("Assetmanager has been closed");
486             }
487             int xmlBlock = openXmlAssetNative(cookie, fileName);
488             if (xmlBlock != 0) {
489                 XmlBlock res = new XmlBlock(this, xmlBlock);
490                 incRefsLocked(res.hashCode());
491                 return res;
492             }
493         }
494         throw new FileNotFoundException("Asset XML file: " + fileName);
495     }
496 
xmlBlockGone(int id)497     /*package*/ void xmlBlockGone(int id) {
498         synchronized (this) {
499             decRefsLocked(id);
500         }
501     }
502 
createTheme()503     /*package*/ final int createTheme() {
504         synchronized (this) {
505             if (!mOpen) {
506                 throw new RuntimeException("Assetmanager has been closed");
507             }
508             int res = newTheme();
509             incRefsLocked(res);
510             return res;
511         }
512     }
513 
releaseTheme(int theme)514     /*package*/ final void releaseTheme(int theme) {
515         synchronized (this) {
516             deleteTheme(theme);
517             decRefsLocked(theme);
518         }
519     }
520 
finalize()521     protected void finalize() throws Throwable {
522         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         }
536     }
537 
538     public final class AssetInputStream extends InputStream {
getAssetInt()539         public final int getAssetInt() {
540             return mAsset;
541         }
AssetInputStream(int asset)542         private AssetInputStream(int asset)
543         {
544             mAsset = asset;
545             mLength = getAssetLength(asset);
546         }
read()547         public final int read() throws IOException {
548             return readAssetChar(mAsset);
549         }
markSupported()550         public final boolean markSupported() {
551             return true;
552         }
available()553         public final int available() throws IOException {
554             long len = getAssetRemainingLength(mAsset);
555             return len > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int)len;
556         }
close()557         public final void close() throws IOException {
558             synchronized (AssetManager.this) {
559                 if (mAsset != 0) {
560                     destroyAsset(mAsset);
561                     mAsset = 0;
562                     decRefsLocked(hashCode());
563                 }
564             }
565         }
mark(int readlimit)566         public final void mark(int readlimit) {
567             mMarkPos = seekAsset(mAsset, 0, 0);
568         }
reset()569         public final void reset() throws IOException {
570             seekAsset(mAsset, mMarkPos, -1);
571         }
read(byte[] b)572         public final int read(byte[] b) throws IOException {
573             return readAsset(mAsset, b, 0, b.length);
574         }
read(byte[] b, int off, int len)575         public final int read(byte[] b, int off, int len) throws IOException {
576             return readAsset(mAsset, b, off, len);
577         }
skip(long n)578         public final long skip(long n) throws IOException {
579             long pos = seekAsset(mAsset, 0, 0);
580             if ((pos+n) > mLength) {
581                 n = mLength-pos;
582             }
583             if (n > 0) {
584                 seekAsset(mAsset, n, 0);
585             }
586             return n;
587         }
588 
finalize()589         protected void finalize() throws Throwable
590         {
591             close();
592         }
593 
594         private int mAsset;
595         private long mLength;
596         private long mMarkPos;
597     }
598 
599     /**
600      * Add an additional set of assets to the asset manager.  This can be
601      * either a directory or ZIP file.  Not for use by applications.  Returns
602      * the cookie of the added asset, or 0 on failure.
603      * {@hide}
604      */
addAssetPath(String path)605     public native final int addAssetPath(String path);
606 
607     /**
608      * Add multiple sets of assets to the asset manager at once.  See
609      * {@link #addAssetPath(String)} for more information.  Returns array of
610      * cookies for each added asset with 0 indicating failure, or null if
611      * the input array of paths is null.
612      * {@hide}
613      */
addAssetPaths(String[] paths)614     public final int[] addAssetPaths(String[] paths) {
615         if (paths == null) {
616             return null;
617         }
618 
619         int[] cookies = new int[paths.length];
620         for (int i = 0; i < paths.length; i++) {
621             cookies[i] = addAssetPath(paths[i]);
622         }
623 
624         return cookies;
625     }
626 
627     /**
628      * Determine whether the state in this asset manager is up-to-date with
629      * the files on the filesystem.  If false is returned, you need to
630      * instantiate a new AssetManager class to see the new data.
631      * {@hide}
632      */
isUpToDate()633     public native final boolean isUpToDate();
634 
635     /**
636      * Change the locale being used by this asset manager.  Not for use by
637      * applications.
638      * {@hide}
639      */
setLocale(String locale)640     public native final void setLocale(String locale);
641 
642     /**
643      * Get the locales that this asset manager contains data for.
644      */
getLocales()645     public native final String[] getLocales();
646 
647     /**
648      * Change the configuation used when retrieving resources.  Not for use by
649      * applications.
650      * {@hide}
651      */
setConfiguration(int mcc, int mnc, String locale, int orientation, int touchscreen, int density, int keyboard, int keyboardHidden, int navigation, int screenWidth, int screenHeight, int smallestScreenWidthDp, int screenWidthDp, int screenHeightDp, int screenLayout, int uiMode, int majorVersion)652     public native final void setConfiguration(int mcc, int mnc, String locale,
653             int orientation, int touchscreen, int density, int keyboard,
654             int keyboardHidden, int navigation, int screenWidth, int screenHeight,
655             int smallestScreenWidthDp, int screenWidthDp, int screenHeightDp,
656             int screenLayout, int uiMode, int majorVersion);
657 
658     /**
659      * Retrieve the resource identifier for the given resource name.
660      */
getResourceIdentifier(String type, String name, String defPackage)661     /*package*/ native final int getResourceIdentifier(String type,
662                                                        String name,
663                                                        String defPackage);
664 
getResourceName(int resid)665     /*package*/ native final String getResourceName(int resid);
getResourcePackageName(int resid)666     /*package*/ native final String getResourcePackageName(int resid);
getResourceTypeName(int resid)667     /*package*/ native final String getResourceTypeName(int resid);
getResourceEntryName(int resid)668     /*package*/ native final String getResourceEntryName(int resid);
669 
openAsset(String fileName, int accessMode)670     private native final int openAsset(String fileName, int accessMode);
openAssetFd(String fileName, long[] outOffsets)671     private final native ParcelFileDescriptor openAssetFd(String fileName,
672             long[] outOffsets) throws IOException;
openNonAssetNative(int cookie, String fileName, int accessMode)673     private native final int openNonAssetNative(int cookie, String fileName,
674             int accessMode);
openNonAssetFdNative(int cookie, String fileName, long[] outOffsets)675     private native ParcelFileDescriptor openNonAssetFdNative(int cookie,
676             String fileName, long[] outOffsets) throws IOException;
destroyAsset(int asset)677     private native final void destroyAsset(int asset);
readAssetChar(int asset)678     private native final int readAssetChar(int asset);
readAsset(int asset, byte[] b, int off, int len)679     private native final int readAsset(int asset, byte[] b, int off, int len);
seekAsset(int asset, long offset, int whence)680     private native final long seekAsset(int asset, long offset, int whence);
getAssetLength(int asset)681     private native final long getAssetLength(int asset);
getAssetRemainingLength(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. */
loadResourceValue(int ident, short density, TypedValue outValue, boolean resolve)686     private native final int loadResourceValue(int ident, short density, TypedValue outValue,
687             boolean resolve);
688     /** Returns true if the resource was found, filling in mRetStringBlock and
689      *  mRetData. */
loadResourceBagValue(int ident, int bagEntryId, TypedValue outValue, boolean resolve)690     private native final int loadResourceBagValue(int ident, int bagEntryId, TypedValue outValue,
691                                                boolean resolve);
692     /*package*/ static final int STYLE_NUM_ENTRIES = 6;
693     /*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;
698     /*package*/ static final int STYLE_DENSITY = 5;
applyStyle(int theme, int defStyleAttr, int defStyleRes, int xmlParser, int[] inAttrs, int[] outValues, int[] outIndices)699     /*package*/ native static final boolean applyStyle(int theme,
700             int defStyleAttr, int defStyleRes, int xmlParser,
701             int[] inAttrs, int[] outValues, int[] outIndices);
retrieveAttributes( int xmlParser, int[] inAttrs, int[] outValues, int[] outIndices)702     /*package*/ native final boolean retrieveAttributes(
703             int xmlParser, int[] inAttrs, int[] outValues, int[] outIndices);
getArraySize(int resource)704     /*package*/ native final int getArraySize(int resource);
retrieveArray(int resource, int[] outValues)705     /*package*/ native final int retrieveArray(int resource, int[] outValues);
getStringBlockCount()706     private native final int getStringBlockCount();
getNativeStringBlock(int block)707     private native final int getNativeStringBlock(int block);
708 
709     /**
710      * {@hide}
711      */
getCookieName(int cookie)712     public native final String getCookieName(int cookie);
713 
714     /**
715      * {@hide}
716      */
getGlobalAssetCount()717     public native static final int getGlobalAssetCount();
718 
719     /**
720      * {@hide}
721      */
getAssetAllocations()722     public native static final String getAssetAllocations();
723 
724     /**
725      * {@hide}
726      */
getGlobalAssetManagerCount()727     public native static final int getGlobalAssetManagerCount();
728 
newTheme()729     private native final int newTheme();
deleteTheme(int theme)730     private native final void deleteTheme(int theme);
applyThemeStyle(int theme, int styleRes, boolean force)731     /*package*/ native static final void applyThemeStyle(int theme, int styleRes, boolean force);
copyTheme(int dest, int source)732     /*package*/ native static final void copyTheme(int dest, int source);
loadThemeAttributeValue(int theme, int ident, TypedValue outValue, boolean resolve)733     /*package*/ native static final int loadThemeAttributeValue(int theme, int ident,
734                                                                 TypedValue outValue,
735                                                                 boolean resolve);
dumpTheme(int theme, int priority, String tag, String prefix)736     /*package*/ native static final void dumpTheme(int theme, int priority, String tag, String prefix);
737 
openXmlAssetNative(int cookie, String fileName)738     private native final int openXmlAssetNative(int cookie, String fileName);
739 
getArrayStringResource(int arrayRes)740     private native final String[] getArrayStringResource(int arrayRes);
getArrayStringInfo(int arrayRes)741     private native final int[] getArrayStringInfo(int arrayRes);
getArrayIntResource(int arrayRes)742     /*package*/ native final int[] getArrayIntResource(int arrayRes);
743 
init()744     private native final void init();
destroy()745     private native final void destroy();
746 
incRefsLocked(int id)747     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 
decRefsLocked(int id)759     private final void decRefsLocked(int id) {
760         if (DEBUG_REFS && mRefStacks != null) {
761             mRefStacks.remove(id);
762         }
763         mNumRefs--;
764         //System.out.println("Dec streams: mNumRefs=" + mNumRefs
765         //                   + " mReleased=" + mReleased);
766         if (mNumRefs == 0) {
767             destroy();
768         }
769     }
770 }
771