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.SparseArray; 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 implements AutoCloseable { 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 = false || false; 62 63 private static final boolean DEBUG_REFS = false; 64 65 private static final Object sSync = new Object(); 66 /*package*/ 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 long mObject; 73 74 private StringBlock mStringBlocks[] = null; 75 76 private int mNumRefs = 1; 77 private boolean mOpen = true; 78 private HashMap<Long, 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(false); 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(null); 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(true); 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(long theme, int ident, TypedValue outValue, boolean resolveRefs)227 /*package*/ final boolean getThemeValue(long 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(sSystem.mStringBlocks); 250 } 251 } 252 } 253 } 254 makeStringBlocks(StringBlock[] seed)255 /*package*/ final void makeStringBlocks(StringBlock[] seed) { 256 final int seedNum = (seed != null) ? seed.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 < seedNum) { 263 mStringBlocks[i] = seed[i]; 264 } else { 265 mStringBlocks[i] = new StringBlock(getNativeStringBlock(i), true); 266 } 267 } 268 } 269 getPooledStringForCookie(int cookie, int id)270 /*package*/ final CharSequence getPooledStringForCookie(int cookie, int id) { 271 // Cookies map to string blocks starting at 1. 272 return mStringBlocks[cookie - 1].get(id); 273 } 274 275 /** 276 * Open an asset using ACCESS_STREAMING mode. This provides access to 277 * files that have been bundled with an application as assets -- that is, 278 * files placed in to the "assets" directory. 279 * 280 * @param fileName The name of the asset to open. This name can be 281 * hierarchical. 282 * 283 * @see #open(String, int) 284 * @see #list 285 */ open(String fileName)286 public final InputStream open(String fileName) throws IOException { 287 return open(fileName, ACCESS_STREAMING); 288 } 289 290 /** 291 * Open an asset using an explicit access mode, returning an InputStream to 292 * read its contents. This provides access to files that have been bundled 293 * with an application as assets -- that is, files placed in to the 294 * "assets" directory. 295 * 296 * @param fileName The name of the asset to open. This name can be 297 * hierarchical. 298 * @param accessMode Desired access mode for retrieving the data. 299 * 300 * @see #ACCESS_UNKNOWN 301 * @see #ACCESS_STREAMING 302 * @see #ACCESS_RANDOM 303 * @see #ACCESS_BUFFER 304 * @see #open(String) 305 * @see #list 306 */ open(String fileName, int accessMode)307 public final InputStream open(String fileName, int accessMode) 308 throws IOException { 309 synchronized (this) { 310 if (!mOpen) { 311 throw new RuntimeException("Assetmanager has been closed"); 312 } 313 long asset = openAsset(fileName, accessMode); 314 if (asset != 0) { 315 AssetInputStream res = new AssetInputStream(asset); 316 incRefsLocked(res.hashCode()); 317 return res; 318 } 319 } 320 throw new FileNotFoundException("Asset file: " + fileName); 321 } 322 openFd(String fileName)323 public final AssetFileDescriptor openFd(String fileName) 324 throws IOException { 325 synchronized (this) { 326 if (!mOpen) { 327 throw new RuntimeException("Assetmanager has been closed"); 328 } 329 ParcelFileDescriptor pfd = openAssetFd(fileName, mOffsets); 330 if (pfd != null) { 331 return new AssetFileDescriptor(pfd, mOffsets[0], mOffsets[1]); 332 } 333 } 334 throw new FileNotFoundException("Asset file: " + fileName); 335 } 336 337 /** 338 * Return a String array of all the assets at the given path. 339 * 340 * @param path A relative path within the assets, i.e., "docs/home.html". 341 * 342 * @return String[] Array of strings, one for each asset. These file 343 * names are relative to 'path'. You can open the file by 344 * concatenating 'path' and a name in the returned string (via 345 * File) and passing that to open(). 346 * 347 * @see #open 348 */ list(String path)349 public native final String[] list(String path) 350 throws IOException; 351 352 /** 353 * {@hide} 354 * Open a non-asset file as an asset using ACCESS_STREAMING mode. This 355 * provides direct access to all of the files included in an application 356 * package (not only its assets). Applications should not normally use 357 * this. 358 * 359 * @see #open(String) 360 */ openNonAsset(String fileName)361 public final InputStream openNonAsset(String fileName) throws IOException { 362 return openNonAsset(0, fileName, ACCESS_STREAMING); 363 } 364 365 /** 366 * {@hide} 367 * Open a non-asset file as an asset using a specific access mode. This 368 * provides direct access to all of the files included in an application 369 * package (not only its assets). Applications should not normally use 370 * this. 371 * 372 * @see #open(String, int) 373 */ openNonAsset(String fileName, int accessMode)374 public final InputStream openNonAsset(String fileName, int accessMode) 375 throws IOException { 376 return openNonAsset(0, fileName, accessMode); 377 } 378 379 /** 380 * {@hide} 381 * Open a non-asset in a specified package. Not for use by applications. 382 * 383 * @param cookie Identifier of the package to be opened. 384 * @param fileName Name of the asset to retrieve. 385 */ openNonAsset(int cookie, String fileName)386 public final InputStream openNonAsset(int cookie, String fileName) 387 throws IOException { 388 return openNonAsset(cookie, fileName, ACCESS_STREAMING); 389 } 390 391 /** 392 * {@hide} 393 * Open a non-asset in a specified package. Not for use by applications. 394 * 395 * @param cookie Identifier of the package to be opened. 396 * @param fileName Name of the asset to retrieve. 397 * @param accessMode Desired access mode for retrieving the data. 398 */ openNonAsset(int cookie, String fileName, int accessMode)399 public final InputStream openNonAsset(int cookie, String fileName, int accessMode) 400 throws IOException { 401 synchronized (this) { 402 if (!mOpen) { 403 throw new RuntimeException("Assetmanager has been closed"); 404 } 405 long asset = openNonAssetNative(cookie, fileName, accessMode); 406 if (asset != 0) { 407 AssetInputStream res = new AssetInputStream(asset); 408 incRefsLocked(res.hashCode()); 409 return res; 410 } 411 } 412 throw new FileNotFoundException("Asset absolute file: " + fileName); 413 } 414 openNonAssetFd(String fileName)415 public final AssetFileDescriptor openNonAssetFd(String fileName) 416 throws IOException { 417 return openNonAssetFd(0, fileName); 418 } 419 openNonAssetFd(int cookie, String fileName)420 public final AssetFileDescriptor openNonAssetFd(int cookie, 421 String fileName) throws IOException { 422 synchronized (this) { 423 if (!mOpen) { 424 throw new RuntimeException("Assetmanager has been closed"); 425 } 426 ParcelFileDescriptor pfd = openNonAssetFdNative(cookie, 427 fileName, mOffsets); 428 if (pfd != null) { 429 return new AssetFileDescriptor(pfd, mOffsets[0], mOffsets[1]); 430 } 431 } 432 throw new FileNotFoundException("Asset absolute file: " + fileName); 433 } 434 435 /** 436 * Retrieve a parser for a compiled XML file. 437 * 438 * @param fileName The name of the file to retrieve. 439 */ openXmlResourceParser(String fileName)440 public final XmlResourceParser openXmlResourceParser(String fileName) 441 throws IOException { 442 return openXmlResourceParser(0, fileName); 443 } 444 445 /** 446 * Retrieve a parser for a compiled XML file. 447 * 448 * @param cookie Identifier of the package to be opened. 449 * @param fileName The name of the file to retrieve. 450 */ openXmlResourceParser(int cookie, String fileName)451 public final XmlResourceParser openXmlResourceParser(int cookie, 452 String fileName) throws IOException { 453 XmlBlock block = openXmlBlockAsset(cookie, fileName); 454 XmlResourceParser rp = block.newParser(); 455 block.close(); 456 return rp; 457 } 458 459 /** 460 * {@hide} 461 * Retrieve a non-asset as a compiled XML file. Not for use by 462 * applications. 463 * 464 * @param fileName The name of the file to retrieve. 465 */ openXmlBlockAsset(String fileName)466 /*package*/ final XmlBlock openXmlBlockAsset(String fileName) 467 throws IOException { 468 return openXmlBlockAsset(0, fileName); 469 } 470 471 /** 472 * {@hide} 473 * Retrieve a non-asset as a compiled XML file. Not for use by 474 * applications. 475 * 476 * @param cookie Identifier of the package to be opened. 477 * @param fileName Name of the asset to retrieve. 478 */ openXmlBlockAsset(int cookie, String fileName)479 /*package*/ final XmlBlock openXmlBlockAsset(int cookie, String fileName) 480 throws IOException { 481 synchronized (this) { 482 if (!mOpen) { 483 throw new RuntimeException("Assetmanager has been closed"); 484 } 485 long xmlBlock = openXmlAssetNative(cookie, fileName); 486 if (xmlBlock != 0) { 487 XmlBlock res = new XmlBlock(this, xmlBlock); 488 incRefsLocked(res.hashCode()); 489 return res; 490 } 491 } 492 throw new FileNotFoundException("Asset XML file: " + fileName); 493 } 494 xmlBlockGone(int id)495 /*package*/ void xmlBlockGone(int id) { 496 synchronized (this) { 497 decRefsLocked(id); 498 } 499 } 500 createTheme()501 /*package*/ final long createTheme() { 502 synchronized (this) { 503 if (!mOpen) { 504 throw new RuntimeException("Assetmanager has been closed"); 505 } 506 long res = newTheme(); 507 incRefsLocked(res); 508 return res; 509 } 510 } 511 releaseTheme(long theme)512 /*package*/ final void releaseTheme(long theme) { 513 synchronized (this) { 514 deleteTheme(theme); 515 decRefsLocked(theme); 516 } 517 } 518 finalize()519 protected void finalize() throws Throwable { 520 try { 521 if (DEBUG_REFS && mNumRefs != 0) { 522 Log.w(TAG, "AssetManager " + this 523 + " finalized with non-zero refs: " + mNumRefs); 524 if (mRefStacks != null) { 525 for (RuntimeException e : mRefStacks.values()) { 526 Log.w(TAG, "Reference from here", e); 527 } 528 } 529 } 530 destroy(); 531 } finally { 532 super.finalize(); 533 } 534 } 535 536 public final class AssetInputStream extends InputStream { 537 /** 538 * @hide 539 */ getAssetInt()540 public final int getAssetInt() { 541 throw new UnsupportedOperationException(); 542 } 543 /** 544 * @hide 545 */ getNativeAsset()546 public final long getNativeAsset() { 547 return mAsset; 548 } AssetInputStream(long asset)549 private AssetInputStream(long asset) 550 { 551 mAsset = asset; 552 mLength = getAssetLength(asset); 553 } read()554 public final int read() throws IOException { 555 return readAssetChar(mAsset); 556 } markSupported()557 public final boolean markSupported() { 558 return true; 559 } available()560 public final int available() throws IOException { 561 long len = getAssetRemainingLength(mAsset); 562 return len > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int)len; 563 } close()564 public final void close() throws IOException { 565 synchronized (AssetManager.this) { 566 if (mAsset != 0) { 567 destroyAsset(mAsset); 568 mAsset = 0; 569 decRefsLocked(hashCode()); 570 } 571 } 572 } mark(int readlimit)573 public final void mark(int readlimit) { 574 mMarkPos = seekAsset(mAsset, 0, 0); 575 } reset()576 public final void reset() throws IOException { 577 seekAsset(mAsset, mMarkPos, -1); 578 } read(byte[] b)579 public final int read(byte[] b) throws IOException { 580 return readAsset(mAsset, b, 0, b.length); 581 } read(byte[] b, int off, int len)582 public final int read(byte[] b, int off, int len) throws IOException { 583 return readAsset(mAsset, b, off, len); 584 } skip(long n)585 public final long skip(long n) throws IOException { 586 long pos = seekAsset(mAsset, 0, 0); 587 if ((pos+n) > mLength) { 588 n = mLength-pos; 589 } 590 if (n > 0) { 591 seekAsset(mAsset, n, 0); 592 } 593 return n; 594 } 595 finalize()596 protected void finalize() throws Throwable 597 { 598 close(); 599 } 600 601 private long mAsset; 602 private long mLength; 603 private long mMarkPos; 604 } 605 606 /** 607 * Add an additional set of assets to the asset manager. This can be 608 * either a directory or ZIP file. Not for use by applications. Returns 609 * the cookie of the added asset, or 0 on failure. 610 * {@hide} 611 */ addAssetPath(String path)612 public final int addAssetPath(String path) { 613 synchronized (this) { 614 int res = addAssetPathNative(path); 615 makeStringBlocks(mStringBlocks); 616 return res; 617 } 618 } 619 addAssetPathNative(String path)620 private native final int addAssetPathNative(String path); 621 622 /** 623 * Add a set of assets to overlay an already added set of assets. 624 * 625 * This is only intended for application resources. System wide resources 626 * are handled before any Java code is executed. 627 * 628 * {@hide} 629 */ 630 addOverlayPath(String idmapPath)631 public final int addOverlayPath(String idmapPath) { 632 synchronized (this) { 633 int res = addOverlayPathNative(idmapPath); 634 makeStringBlocks(mStringBlocks); 635 return res; 636 } 637 } 638 639 /** 640 * See addOverlayPath. 641 * 642 * {@hide} 643 */ addOverlayPathNative(String idmapPath)644 public native final int addOverlayPathNative(String idmapPath); 645 646 /** 647 * Add multiple sets of assets to the asset manager at once. See 648 * {@link #addAssetPath(String)} for more information. Returns array of 649 * cookies for each added asset with 0 indicating failure, or null if 650 * the input array of paths is null. 651 * {@hide} 652 */ addAssetPaths(String[] paths)653 public final int[] addAssetPaths(String[] paths) { 654 if (paths == null) { 655 return null; 656 } 657 658 int[] cookies = new int[paths.length]; 659 for (int i = 0; i < paths.length; i++) { 660 cookies[i] = addAssetPath(paths[i]); 661 } 662 663 return cookies; 664 } 665 666 /** 667 * Determine whether the state in this asset manager is up-to-date with 668 * the files on the filesystem. If false is returned, you need to 669 * instantiate a new AssetManager class to see the new data. 670 * {@hide} 671 */ isUpToDate()672 public native final boolean isUpToDate(); 673 674 /** 675 * Change the locale being used by this asset manager. Not for use by 676 * applications. 677 * {@hide} 678 */ setLocale(String locale)679 public native final void setLocale(String locale); 680 681 /** 682 * Get the locales that this asset manager contains data for. 683 * 684 * <p>On SDK 21 (Android 5.0: Lollipop) and above, Locale strings are valid 685 * <a href="https://tools.ietf.org/html/bcp47">BCP-47</a> language tags and can be 686 * parsed using {@link java.util.Locale#forLanguageTag(String)}. 687 * 688 * <p>On SDK 20 (Android 4.4W: Kitkat for watches) and below, locale strings 689 * are of the form {@code ll_CC} where {@code ll} is a two letter language code, 690 * and {@code CC} is a two letter country code. 691 */ getLocales()692 public native final String[] getLocales(); 693 694 /** 695 * Change the configuation used when retrieving resources. Not for use by 696 * applications. 697 * {@hide} 698 */ 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)699 public native final void setConfiguration(int mcc, int mnc, String locale, 700 int orientation, int touchscreen, int density, int keyboard, 701 int keyboardHidden, int navigation, int screenWidth, int screenHeight, 702 int smallestScreenWidthDp, int screenWidthDp, int screenHeightDp, 703 int screenLayout, int uiMode, int majorVersion); 704 705 /** 706 * Retrieve the resource identifier for the given resource name. 707 */ getResourceIdentifier(String type, String name, String defPackage)708 /*package*/ native final int getResourceIdentifier(String type, 709 String name, 710 String defPackage); 711 getResourceName(int resid)712 /*package*/ native final String getResourceName(int resid); getResourcePackageName(int resid)713 /*package*/ native final String getResourcePackageName(int resid); getResourceTypeName(int resid)714 /*package*/ native final String getResourceTypeName(int resid); getResourceEntryName(int resid)715 /*package*/ native final String getResourceEntryName(int resid); 716 openAsset(String fileName, int accessMode)717 private native final long openAsset(String fileName, int accessMode); openAssetFd(String fileName, long[] outOffsets)718 private final native ParcelFileDescriptor openAssetFd(String fileName, 719 long[] outOffsets) throws IOException; openNonAssetNative(int cookie, String fileName, int accessMode)720 private native final long openNonAssetNative(int cookie, String fileName, 721 int accessMode); openNonAssetFdNative(int cookie, String fileName, long[] outOffsets)722 private native ParcelFileDescriptor openNonAssetFdNative(int cookie, 723 String fileName, long[] outOffsets) throws IOException; destroyAsset(long asset)724 private native final void destroyAsset(long asset); readAssetChar(long asset)725 private native final int readAssetChar(long asset); readAsset(long asset, byte[] b, int off, int len)726 private native final int readAsset(long asset, byte[] b, int off, int len); seekAsset(long asset, long offset, int whence)727 private native final long seekAsset(long asset, long offset, int whence); getAssetLength(long asset)728 private native final long getAssetLength(long asset); getAssetRemainingLength(long asset)729 private native final long getAssetRemainingLength(long asset); 730 731 /** Returns true if the resource was found, filling in mRetStringBlock and 732 * mRetData. */ loadResourceValue(int ident, short density, TypedValue outValue, boolean resolve)733 private native final int loadResourceValue(int ident, short density, TypedValue outValue, 734 boolean resolve); 735 /** Returns true if the resource was found, filling in mRetStringBlock and 736 * mRetData. */ loadResourceBagValue(int ident, int bagEntryId, TypedValue outValue, boolean resolve)737 private native final int loadResourceBagValue(int ident, int bagEntryId, TypedValue outValue, 738 boolean resolve); 739 /*package*/ static final int STYLE_NUM_ENTRIES = 6; 740 /*package*/ static final int STYLE_TYPE = 0; 741 /*package*/ static final int STYLE_DATA = 1; 742 /*package*/ static final int STYLE_ASSET_COOKIE = 2; 743 /*package*/ static final int STYLE_RESOURCE_ID = 3; 744 /*package*/ static final int STYLE_CHANGING_CONFIGURATIONS = 4; 745 /*package*/ static final int STYLE_DENSITY = 5; applyStyle(long theme, int defStyleAttr, int defStyleRes, long xmlParser, int[] inAttrs, int[] outValues, int[] outIndices)746 /*package*/ native static final boolean applyStyle(long theme, 747 int defStyleAttr, int defStyleRes, long xmlParser, 748 int[] inAttrs, int[] outValues, int[] outIndices); resolveAttrs(long theme, int defStyleAttr, int defStyleRes, int[] inValues, int[] inAttrs, int[] outValues, int[] outIndices)749 /*package*/ native static final boolean resolveAttrs(long theme, 750 int defStyleAttr, int defStyleRes, int[] inValues, 751 int[] inAttrs, int[] outValues, int[] outIndices); retrieveAttributes( long xmlParser, int[] inAttrs, int[] outValues, int[] outIndices)752 /*package*/ native final boolean retrieveAttributes( 753 long xmlParser, int[] inAttrs, int[] outValues, int[] outIndices); getArraySize(int resource)754 /*package*/ native final int getArraySize(int resource); retrieveArray(int resource, int[] outValues)755 /*package*/ native final int retrieveArray(int resource, int[] outValues); getStringBlockCount()756 private native final int getStringBlockCount(); getNativeStringBlock(int block)757 private native final long getNativeStringBlock(int block); 758 759 /** 760 * {@hide} 761 */ getCookieName(int cookie)762 public native final String getCookieName(int cookie); 763 764 /** 765 * {@hide} 766 */ getAssignedPackageIdentifiers()767 public native final SparseArray<String> getAssignedPackageIdentifiers(); 768 769 /** 770 * {@hide} 771 */ getGlobalAssetCount()772 public native static final int getGlobalAssetCount(); 773 774 /** 775 * {@hide} 776 */ getAssetAllocations()777 public native static final String getAssetAllocations(); 778 779 /** 780 * {@hide} 781 */ getGlobalAssetManagerCount()782 public native static final int getGlobalAssetManagerCount(); 783 newTheme()784 private native final long newTheme(); deleteTheme(long theme)785 private native final void deleteTheme(long theme); applyThemeStyle(long theme, int styleRes, boolean force)786 /*package*/ native static final void applyThemeStyle(long theme, int styleRes, boolean force); copyTheme(long dest, long source)787 /*package*/ native static final void copyTheme(long dest, long source); clearTheme(long theme)788 /*package*/ native static final void clearTheme(long theme); loadThemeAttributeValue(long theme, int ident, TypedValue outValue, boolean resolve)789 /*package*/ native static final int loadThemeAttributeValue(long theme, int ident, 790 TypedValue outValue, 791 boolean resolve); dumpTheme(long theme, int priority, String tag, String prefix)792 /*package*/ native static final void dumpTheme(long theme, int priority, String tag, String prefix); getThemeChangingConfigurations(long theme)793 /*package*/ native static final int getThemeChangingConfigurations(long theme); 794 openXmlAssetNative(int cookie, String fileName)795 private native final long openXmlAssetNative(int cookie, String fileName); 796 getArrayStringResource(int arrayRes)797 private native final String[] getArrayStringResource(int arrayRes); getArrayStringInfo(int arrayRes)798 private native final int[] getArrayStringInfo(int arrayRes); getArrayIntResource(int arrayRes)799 /*package*/ native final int[] getArrayIntResource(int arrayRes); getStyleAttributes(int themeRes)800 /*package*/ native final int[] getStyleAttributes(int themeRes); 801 init(boolean isSystem)802 private native final void init(boolean isSystem); destroy()803 private native final void destroy(); 804 incRefsLocked(long id)805 private final void incRefsLocked(long id) { 806 if (DEBUG_REFS) { 807 if (mRefStacks == null) { 808 mRefStacks = new HashMap<Long, RuntimeException>(); 809 } 810 RuntimeException ex = new RuntimeException(); 811 ex.fillInStackTrace(); 812 mRefStacks.put(id, ex); 813 } 814 mNumRefs++; 815 } 816 decRefsLocked(long id)817 private final void decRefsLocked(long id) { 818 if (DEBUG_REFS && mRefStacks != null) { 819 mRefStacks.remove(id); 820 } 821 mNumRefs--; 822 //System.out.println("Dec streams: mNumRefs=" + mNumRefs 823 // + " mReleased=" + mReleased); 824 if (mNumRefs == 0) { 825 destroy(); 826 } 827 } 828 } 829