• 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.Config;
21 import android.util.Log;
22 import android.util.TypedValue;
23 
24 import java.io.FileNotFoundException;
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.util.HashMap;
28 
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  */
36 public 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 
63     private static final boolean DEBUG_REFS = false;
64 
65     private static final Object sSync = new Object();
66     private static AssetManager sSystem = null;
67 
68     private final TypedValue mValue = new TypedValue();
69     private final long[] mOffsets = new long[2];
70 
71     // For communication with native code.
72     private int mObject;
73     private int mNObject;  // used by the NDK
74 
75     private StringBlock mStringBlocks[] = null;
76 
77     private int mNumRefs = 1;
78     private boolean mOpen = true;
79     private HashMap<Integer, RuntimeException> mRefStacks;
80 
81     /**
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      */
AssetManager()88     public AssetManager() {
89         synchronized (this) {
90             if (DEBUG_REFS) {
91                 mNumRefs = 0;
92                 incRefsLocked(this.hashCode());
93             }
94             init();
95             if (localLOGV) Log.v(TAG, "New asset manager: " + this);
96             ensureSystemAssets();
97         }
98     }
99 
ensureSystemAssets()100     private static void ensureSystemAssets() {
101         synchronized (sSync) {
102             if (sSystem == null) {
103                 AssetManager system = new AssetManager(true);
104                 system.makeStringBlocks(false);
105                 sSystem = system;
106             }
107         }
108     }
109 
AssetManager(boolean isSystem)110     private AssetManager(boolean isSystem) {
111         if (DEBUG_REFS) {
112             synchronized (this) {
113                 mNumRefs = 0;
114                 incRefsLocked(this.hashCode());
115             }
116         }
117         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      */
getSystem()126     public static AssetManager getSystem() {
127         ensureSystemAssets();
128         return sSystem;
129     }
130 
131     /**
132      * Close this asset manager.
133      */
close()134     public void close() {
135         synchronized(this) {
136             //System.out.println("Release: num=" + mNumRefs
137             //                   + ", released=" + mReleased);
138             if (mOpen) {
139                 mOpen = false;
140                 decRefsLocked(this.hashCode());
141             }
142         }
143     }
144 
145     /**
146      * Retrieve the string value associated with a particular resource
147      * identifier for the current configuration / skin.
148      */
getResourceText(int ident)149     /*package*/ final CharSequence getResourceText(int ident) {
150         synchronized (this) {
151             TypedValue tmpValue = mValue;
152             int block = loadResourceValue(ident, tmpValue, true);
153             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      */
getResourceBagText(int ident, int bagEntryId)167     /*package*/ final CharSequence getResourceBagText(int ident, int bagEntryId) {
168         synchronized (this) {
169             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      */
getResourceStringArray(final int id)186     /*package*/ final String[] getResourceStringArray(final int id) {
187         String[] retArray = getArrayStringResource(id);
188         return retArray;
189     }
190 
191 
getResourceValue(int ident, TypedValue outValue, boolean resolveRefs)192     /*package*/ final boolean getResourceValue(int ident,
193                                                TypedValue outValue,
194                                                boolean resolveRefs)
195     {
196         int block = loadResourceValue(ident, 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             }
238             outValue.string = blocks[block].get(outValue.data);
239             return true;
240         }
241         return false;
242     }
243 
ensureStringBlocks()244     /*package*/ final void ensureStringBlocks() {
245         if (mStringBlocks == null) {
246             synchronized (this) {
247                 if (mStringBlocks == null) {
248                     makeStringBlocks(true);
249                 }
250             }
251         }
252     }
253 
makeStringBlocks(boolean copyFromSystem)254     private final void makeStringBlocks(boolean copyFromSystem) {
255         final int sysNum = copyFromSystem ? sSystem.mStringBlocks.length : 0;
256         final int num = getStringBlockCount();
257         mStringBlocks = new StringBlock[num];
258         if (localLOGV) Log.v(TAG, "Making string blocks for " + this
259                 + ": " + num);
260         for (int i=0; i<num; i++) {
261             if (i < sysNum) {
262                 mStringBlocks[i] = sSystem.mStringBlocks[i];
263             } else {
264                 mStringBlocks[i] = new StringBlock(getNativeStringBlock(i), true);
265             }
266         }
267     }
268 
getPooledString(int block, int id)269     /*package*/ final CharSequence getPooledString(int block, int id) {
270         //System.out.println("Get pooled: block=" + block
271         //                   + ", id=#" + Integer.toHexString(id)
272         //                   + ", blocks=" + mStringBlocks);
273         return mStringBlocks[block-1].get(id);
274     }
275 
276     /**
277      * Open an asset using ACCESS_STREAMING mode.  This provides access to
278      * files that have been bundled with an application as assets -- that is,
279      * files placed in to the "assets" directory.
280      *
281      * @param fileName The name of the asset to open.  This name can be
282      *                 hierarchical.
283      *
284      * @see #open(String, int)
285      * @see #list
286      */
open(String fileName)287     public final InputStream open(String fileName) throws IOException {
288         return open(fileName, ACCESS_STREAMING);
289     }
290 
291     /**
292      * Open an asset using an explicit access mode, returning an InputStream to
293      * read its contents.  This provides access to files that have been bundled
294      * with an application as assets -- that is, files placed in to the
295      * "assets" directory.
296      *
297      * @param fileName The name of the asset to open.  This name can be
298      *                 hierarchical.
299      * @param accessMode Desired access mode for retrieving the data.
300      *
301      * @see #ACCESS_UNKNOWN
302      * @see #ACCESS_STREAMING
303      * @see #ACCESS_RANDOM
304      * @see #ACCESS_BUFFER
305      * @see #open(String)
306      * @see #list
307      */
open(String fileName, int accessMode)308     public final InputStream open(String fileName, int accessMode)
309         throws IOException {
310         synchronized (this) {
311             if (!mOpen) {
312                 throw new RuntimeException("Assetmanager has been closed");
313             }
314             int asset = openAsset(fileName, accessMode);
315             if (asset != 0) {
316                 AssetInputStream res = new AssetInputStream(asset);
317                 incRefsLocked(res.hashCode());
318                 return res;
319             }
320         }
321         throw new FileNotFoundException("Asset file: " + fileName);
322     }
323 
openFd(String fileName)324     public final AssetFileDescriptor openFd(String fileName)
325             throws IOException {
326         synchronized (this) {
327             if (!mOpen) {
328                 throw new RuntimeException("Assetmanager has been closed");
329             }
330             ParcelFileDescriptor pfd = openAssetFd(fileName, mOffsets);
331             if (pfd != null) {
332                 return new AssetFileDescriptor(pfd, mOffsets[0], mOffsets[1]);
333             }
334         }
335         throw new FileNotFoundException("Asset file: " + fileName);
336     }
337 
338     /**
339      * Return a String array of all the assets at the given path.
340      *
341      * @param path A relative path within the assets, i.e., "docs/home.html".
342      *
343      * @return String[] Array of strings, one for each asset.  These file
344      *         names are relative to 'path'.  You can open the file by
345      *         concatenating 'path' and a name in the returned string (via
346      *         File) and passing that to open().
347      *
348      * @see #open
349      */
list(String path)350     public native final String[] list(String path)
351         throws IOException;
352 
353     /**
354      * {@hide}
355      * Open a non-asset file as an asset using ACCESS_STREAMING mode.  This
356      * provides direct access to all of the files included in an application
357      * package (not only its assets).  Applications should not normally use
358      * this.
359      *
360      * @see #open(String)
361      */
openNonAsset(String fileName)362     public final InputStream openNonAsset(String fileName) throws IOException {
363         return openNonAsset(0, fileName, ACCESS_STREAMING);
364     }
365 
366     /**
367      * {@hide}
368      * Open a non-asset file as an asset using a specific access mode.  This
369      * provides direct access to all of the files included in an application
370      * package (not only its assets).  Applications should not normally use
371      * this.
372      *
373      * @see #open(String, int)
374      */
openNonAsset(String fileName, int accessMode)375     public final InputStream openNonAsset(String fileName, int accessMode)
376         throws IOException {
377         return openNonAsset(0, fileName, accessMode);
378     }
379 
380     /**
381      * {@hide}
382      * Open a non-asset in a specified package.  Not for use by applications.
383      *
384      * @param cookie Identifier of the package to be opened.
385      * @param fileName Name of the asset to retrieve.
386      */
openNonAsset(int cookie, String fileName)387     public final InputStream openNonAsset(int cookie, String fileName)
388         throws IOException {
389         return openNonAsset(cookie, fileName, ACCESS_STREAMING);
390     }
391 
392     /**
393      * {@hide}
394      * Open a non-asset in a specified package.  Not for use by applications.
395      *
396      * @param cookie Identifier of the package to be opened.
397      * @param fileName Name of the asset to retrieve.
398      * @param accessMode Desired access mode for retrieving the data.
399      */
openNonAsset(int cookie, String fileName, int accessMode)400     public final InputStream openNonAsset(int cookie, String fileName, int accessMode)
401         throws IOException {
402         synchronized (this) {
403             if (!mOpen) {
404                 throw new RuntimeException("Assetmanager has been closed");
405             }
406             int asset = openNonAssetNative(cookie, fileName, accessMode);
407             if (asset != 0) {
408                 AssetInputStream res = new AssetInputStream(asset);
409                 incRefsLocked(res.hashCode());
410                 return res;
411             }
412         }
413         throw new FileNotFoundException("Asset absolute file: " + fileName);
414     }
415 
openNonAssetFd(String fileName)416     public final AssetFileDescriptor openNonAssetFd(String fileName)
417             throws IOException {
418         return openNonAssetFd(0, fileName);
419     }
420 
openNonAssetFd(int cookie, String fileName)421     public final AssetFileDescriptor openNonAssetFd(int cookie,
422             String fileName) throws IOException {
423         synchronized (this) {
424             if (!mOpen) {
425                 throw new RuntimeException("Assetmanager has been closed");
426             }
427             ParcelFileDescriptor pfd = openNonAssetFdNative(cookie,
428                     fileName, mOffsets);
429             if (pfd != null) {
430                 return new AssetFileDescriptor(pfd, mOffsets[0], mOffsets[1]);
431             }
432         }
433         throw new FileNotFoundException("Asset absolute file: " + fileName);
434     }
435 
436     /**
437      * Retrieve a parser for a compiled XML file.
438      *
439      * @param fileName The name of the file to retrieve.
440      */
openXmlResourceParser(String fileName)441     public final XmlResourceParser openXmlResourceParser(String fileName)
442             throws IOException {
443         return openXmlResourceParser(0, fileName);
444     }
445 
446     /**
447      * Retrieve a parser for a compiled XML file.
448      *
449      * @param cookie Identifier of the package to be opened.
450      * @param fileName The name of the file to retrieve.
451      */
openXmlResourceParser(int cookie, String fileName)452     public final XmlResourceParser openXmlResourceParser(int cookie,
453             String fileName) throws IOException {
454         XmlBlock block = openXmlBlockAsset(cookie, fileName);
455         XmlResourceParser rp = block.newParser();
456         block.close();
457         return rp;
458     }
459 
460     /**
461      * {@hide}
462      * Retrieve a non-asset as a compiled XML file.  Not for use by
463      * applications.
464      *
465      * @param fileName The name of the file to retrieve.
466      */
openXmlBlockAsset(String fileName)467     /*package*/ final XmlBlock openXmlBlockAsset(String fileName)
468             throws IOException {
469         return openXmlBlockAsset(0, fileName);
470     }
471 
472     /**
473      * {@hide}
474      * Retrieve a non-asset as a compiled XML file.  Not for use by
475      * applications.
476      *
477      * @param cookie Identifier of the package to be opened.
478      * @param fileName Name of the asset to retrieve.
479      */
openXmlBlockAsset(int cookie, String fileName)480     /*package*/ final XmlBlock openXmlBlockAsset(int cookie, String fileName)
481         throws IOException {
482         synchronized (this) {
483             if (!mOpen) {
484                 throw new RuntimeException("Assetmanager has been closed");
485             }
486             int xmlBlock = openXmlAssetNative(cookie, fileName);
487             if (xmlBlock != 0) {
488                 XmlBlock res = new XmlBlock(this, xmlBlock);
489                 incRefsLocked(res.hashCode());
490                 return res;
491             }
492         }
493         throw new FileNotFoundException("Asset XML file: " + fileName);
494     }
495 
xmlBlockGone(int id)496     /*package*/ void xmlBlockGone(int id) {
497         synchronized (this) {
498             decRefsLocked(id);
499         }
500     }
501 
createTheme()502     /*package*/ final int createTheme() {
503         synchronized (this) {
504             if (!mOpen) {
505                 throw new RuntimeException("Assetmanager has been closed");
506             }
507             int res = newTheme();
508             incRefsLocked(res);
509             return res;
510         }
511     }
512 
releaseTheme(int theme)513     /*package*/ final void releaseTheme(int theme) {
514         synchronized (this) {
515             deleteTheme(theme);
516             decRefsLocked(theme);
517         }
518     }
519 
finalize()520     protected void finalize() throws Throwable {
521         try {
522             if (DEBUG_REFS && mNumRefs != 0) {
523                 Log.w(TAG, "AssetManager " + this
524                         + " finalized with non-zero refs: " + mNumRefs);
525                 if (mRefStacks != null) {
526                     for (RuntimeException e : mRefStacks.values()) {
527                         Log.w(TAG, "Reference from here", e);
528                     }
529                 }
530             }
531             destroy();
532         } finally {
533             super.finalize();
534         }
535     }
536 
537     public final class AssetInputStream extends InputStream {
getAssetInt()538         public final int getAssetInt() {
539             return mAsset;
540         }
AssetInputStream(int asset)541         private AssetInputStream(int asset)
542         {
543             mAsset = asset;
544             mLength = getAssetLength(asset);
545         }
read()546         public final int read() throws IOException {
547             return readAssetChar(mAsset);
548         }
markSupported()549         public final boolean markSupported() {
550             return true;
551         }
available()552         public final int available() throws IOException {
553             long len = getAssetRemainingLength(mAsset);
554             return len > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int)len;
555         }
close()556         public final void close() throws IOException {
557             synchronized (AssetManager.this) {
558                 if (mAsset != 0) {
559                     destroyAsset(mAsset);
560                     mAsset = 0;
561                     decRefsLocked(hashCode());
562                 }
563             }
564         }
mark(int readlimit)565         public final void mark(int readlimit) {
566             mMarkPos = seekAsset(mAsset, 0, 0);
567         }
reset()568         public final void reset() throws IOException {
569             seekAsset(mAsset, mMarkPos, -1);
570         }
read(byte[] b)571         public final int read(byte[] b) throws IOException {
572             return readAsset(mAsset, b, 0, b.length);
573         }
read(byte[] b, int off, int len)574         public final int read(byte[] b, int off, int len) throws IOException {
575             return readAsset(mAsset, b, off, len);
576         }
skip(long n)577         public final long skip(long n) throws IOException {
578             long pos = seekAsset(mAsset, 0, 0);
579             if ((pos+n) > mLength) {
580                 n = mLength-pos;
581             }
582             if (n > 0) {
583                 seekAsset(mAsset, n, 0);
584             }
585             return n;
586         }
587 
finalize()588         protected void finalize() throws Throwable
589         {
590             close();
591         }
592 
593         private int mAsset;
594         private long mLength;
595         private long mMarkPos;
596     }
597 
598     /**
599      * Add an additional set of assets to the asset manager.  This can be
600      * either a directory or ZIP file.  Not for use by applications.  Returns
601      * the cookie of the added asset, or 0 on failure.
602      * {@hide}
603      */
addAssetPath(String path)604     public native final int addAssetPath(String path);
605 
606     /**
607      * Add multiple sets of assets to the asset manager at once.  See
608      * {@link #addAssetPath(String)} for more information.  Returns array of
609      * cookies for each added asset with 0 indicating failure, or null if
610      * the input array of paths is null.
611      * {@hide}
612      */
addAssetPaths(String[] paths)613     public final int[] addAssetPaths(String[] paths) {
614         if (paths == null) {
615             return null;
616         }
617 
618         int[] cookies = new int[paths.length];
619         for (int i = 0; i < paths.length; i++) {
620             cookies[i] = addAssetPath(paths[i]);
621         }
622 
623         return cookies;
624     }
625 
626     /**
627      * Determine whether the state in this asset manager is up-to-date with
628      * the files on the filesystem.  If false is returned, you need to
629      * instantiate a new AssetManager class to see the new data.
630      * {@hide}
631      */
isUpToDate()632     public native final boolean isUpToDate();
633 
634     /**
635      * Change the locale being used by this asset manager.  Not for use by
636      * applications.
637      * {@hide}
638      */
setLocale(String locale)639     public native final void setLocale(String locale);
640 
641     /**
642      * Get the locales that this asset manager contains data for.
643      */
getLocales()644     public native final String[] getLocales();
645 
646     /**
647      * Change the configuation used when retrieving resources.  Not for use by
648      * applications.
649      * {@hide}
650      */
setConfiguration(int mcc, int mnc, String locale, int orientation, int touchscreen, int density, int keyboard, int keyboardHidden, int navigation, int screenWidth, int screenHeight, int screenLayout, int uiMode, int majorVersion)651     public native final void setConfiguration(int mcc, int mnc, String locale,
652             int orientation, int touchscreen, int density, int keyboard,
653             int keyboardHidden, int navigation, int screenWidth, int screenHeight,
654             int screenLayout, int uiMode, int majorVersion);
655 
656     /**
657      * Retrieve the resource identifier for the given resource name.
658      */
getResourceIdentifier(String type, String name, String defPackage)659     /*package*/ native final int getResourceIdentifier(String type,
660                                                        String name,
661                                                        String defPackage);
662 
getResourceName(int resid)663     /*package*/ native final String getResourceName(int resid);
getResourcePackageName(int resid)664     /*package*/ native final String getResourcePackageName(int resid);
getResourceTypeName(int resid)665     /*package*/ native final String getResourceTypeName(int resid);
getResourceEntryName(int resid)666     /*package*/ native final String getResourceEntryName(int resid);
667 
openAsset(String fileName, int accessMode)668     private native final int openAsset(String fileName, int accessMode);
openAssetFd(String fileName, long[] outOffsets)669     private final native ParcelFileDescriptor openAssetFd(String fileName,
670             long[] outOffsets) throws IOException;
openNonAssetNative(int cookie, String fileName, int accessMode)671     private native final int openNonAssetNative(int cookie, String fileName,
672             int accessMode);
openNonAssetFdNative(int cookie, String fileName, long[] outOffsets)673     private native ParcelFileDescriptor openNonAssetFdNative(int cookie,
674             String fileName, long[] outOffsets) throws IOException;
destroyAsset(int asset)675     private native final void destroyAsset(int asset);
readAssetChar(int asset)676     private native final int readAssetChar(int asset);
readAsset(int asset, byte[] b, int off, int len)677     private native final int readAsset(int asset, byte[] b, int off, int len);
seekAsset(int asset, long offset, int whence)678     private native final long seekAsset(int asset, long offset, int whence);
getAssetLength(int asset)679     private native final long getAssetLength(int asset);
getAssetRemainingLength(int asset)680     private native final long getAssetRemainingLength(int asset);
681 
682     /** Returns true if the resource was found, filling in mRetStringBlock and
683      *  mRetData. */
loadResourceValue(int ident, TypedValue outValue, boolean resolve)684     private native final int loadResourceValue(int ident, TypedValue outValue,
685                                                boolean resolve);
686     /** Returns true if the resource was found, filling in mRetStringBlock and
687      *  mRetData. */
loadResourceBagValue(int ident, int bagEntryId, TypedValue outValue, boolean resolve)688     private native final int loadResourceBagValue(int ident, int bagEntryId, TypedValue outValue,
689                                                boolean resolve);
690     /*package*/ static final int STYLE_NUM_ENTRIES = 6;
691     /*package*/ static final int STYLE_TYPE = 0;
692     /*package*/ static final int STYLE_DATA = 1;
693     /*package*/ static final int STYLE_ASSET_COOKIE = 2;
694     /*package*/ static final int STYLE_RESOURCE_ID = 3;
695     /*package*/ static final int STYLE_CHANGING_CONFIGURATIONS = 4;
696     /*package*/ static final int STYLE_DENSITY = 5;
applyStyle(int theme, int defStyleAttr, int defStyleRes, int xmlParser, int[] inAttrs, int[] outValues, int[] outIndices)697     /*package*/ native static final boolean applyStyle(int theme,
698             int defStyleAttr, int defStyleRes, int xmlParser,
699             int[] inAttrs, int[] outValues, int[] outIndices);
retrieveAttributes( int xmlParser, int[] inAttrs, int[] outValues, int[] outIndices)700     /*package*/ native final boolean retrieveAttributes(
701             int xmlParser, int[] inAttrs, int[] outValues, int[] outIndices);
getArraySize(int resource)702     /*package*/ native final int getArraySize(int resource);
retrieveArray(int resource, int[] outValues)703     /*package*/ native final int retrieveArray(int resource, int[] outValues);
getStringBlockCount()704     private native final int getStringBlockCount();
getNativeStringBlock(int block)705     private native final int getNativeStringBlock(int block);
706 
707     /**
708      * {@hide}
709      */
getCookieName(int cookie)710     public native final String getCookieName(int cookie);
711 
712     /**
713      * {@hide}
714      */
getGlobalAssetCount()715     public native static final int getGlobalAssetCount();
716 
717     /**
718      * {@hide}
719      */
getAssetAllocations()720     public native static final String getAssetAllocations();
721 
722     /**
723      * {@hide}
724      */
getGlobalAssetManagerCount()725     public native static final int getGlobalAssetManagerCount();
726 
newTheme()727     private native final int newTheme();
deleteTheme(int theme)728     private native final void deleteTheme(int theme);
applyThemeStyle(int theme, int styleRes, boolean force)729     /*package*/ native static final void applyThemeStyle(int theme, int styleRes, boolean force);
copyTheme(int dest, int source)730     /*package*/ native static final void copyTheme(int dest, int source);
loadThemeAttributeValue(int theme, int ident, TypedValue outValue, boolean resolve)731     /*package*/ native static final int loadThemeAttributeValue(int theme, int ident,
732                                                                 TypedValue outValue,
733                                                                 boolean resolve);
dumpTheme(int theme, int priority, String tag, String prefix)734     /*package*/ native static final void dumpTheme(int theme, int priority, String tag, String prefix);
735 
openXmlAssetNative(int cookie, String fileName)736     private native final int openXmlAssetNative(int cookie, String fileName);
737 
getArrayStringResource(int arrayRes)738     private native final String[] getArrayStringResource(int arrayRes);
getArrayStringInfo(int arrayRes)739     private native final int[] getArrayStringInfo(int arrayRes);
getArrayIntResource(int arrayRes)740     /*package*/ native final int[] getArrayIntResource(int arrayRes);
741 
init()742     private native final void init();
destroy()743     private native final void destroy();
744 
incRefsLocked(int id)745     private final void incRefsLocked(int id) {
746         if (DEBUG_REFS) {
747             if (mRefStacks == null) {
748                 mRefStacks = new HashMap<Integer, RuntimeException>();
749                 RuntimeException ex = new RuntimeException();
750                 ex.fillInStackTrace();
751                 mRefStacks.put(this.hashCode(), ex);
752             }
753         }
754         mNumRefs++;
755     }
756 
decRefsLocked(int id)757     private final void decRefsLocked(int id) {
758         if (DEBUG_REFS && mRefStacks != null) {
759             mRefStacks.remove(id);
760         }
761         mNumRefs--;
762         //System.out.println("Dec streams: mNumRefs=" + mNumRefs
763         //                   + " mReleased=" + mReleased);
764         if (mNumRefs == 0) {
765             destroy();
766         }
767     }
768 }
769