summaryrefslogtreecommitdiff
path: root/core/java/android
diff options
context:
space:
mode:
authorAdam Lesinski <adamlesinski@google.com>2018-02-09 11:12:22 -0800
committerAdam Lesinski <adamlesinski@google.com>2018-02-09 12:43:24 -0800
commitbde1df21adf264d3398b9f3274f353faa6399008 (patch)
tree51909e52f6741528e2b6f69923affc43410e40f2 /core/java/android
parent2a447172a5b8c4fdb8527602144691802c492c2e (diff)
Revert "Replace AssetManager with AssetManager2 implementation"
This reverts commit 1187590da38457809dd368d4901c9c47ac5a6958. Bug: 73134570 Change-Id: I59b4d714e447478ea124f086356f127f42251fb7
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/content/pm/PackageParser.java19
-rw-r--r--core/java/android/content/res/ApkAssets.java221
-rw-r--r--core/java/android/content/res/AssetManager.java1341
-rw-r--r--core/java/android/content/res/Resources.java9
-rw-r--r--core/java/android/content/res/ResourcesImpl.java22
-rw-r--r--core/java/android/content/res/TypedArray.java185
-rw-r--r--core/java/android/content/res/XmlBlock.java8
7 files changed, 622 insertions, 1183 deletions
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index eff12a924fe0..dda4167d3c3b 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -54,7 +54,6 @@ import android.content.pm.PackageParserCacheHelper.WriteHelper;
import android.content.pm.split.DefaultSplitAssetLoader;
import android.content.pm.split.SplitAssetDependencyLoader;
import android.content.pm.split.SplitAssetLoader;
-import android.content.res.ApkAssets;
import android.content.res.AssetManager;
import android.content.res.Configuration;
import android.content.res.Resources;
@@ -1593,19 +1592,21 @@ public class PackageParser {
int flags) throws PackageParserException {
final String apkPath = fd != null ? debugPathName : apkFile.getAbsolutePath();
- ApkAssets apkAssets = null;
+ AssetManager assets = null;
XmlResourceParser parser = null;
try {
- try {
- apkAssets = fd != null
- ? ApkAssets.loadFromFd(fd, debugPathName, false, false)
- : ApkAssets.loadFromPath(apkPath);
- } catch (IOException e) {
+ assets = newConfiguredAssetManager();
+ int cookie = fd != null
+ ? assets.addAssetFd(fd, debugPathName) : assets.addAssetPath(apkPath);
+ if (cookie == 0) {
throw new PackageParserException(INSTALL_PARSE_FAILED_NOT_APK,
"Failed to parse " + apkPath);
}
- parser = apkAssets.openXml(ANDROID_MANIFEST_FILENAME);
+ final DisplayMetrics metrics = new DisplayMetrics();
+ metrics.setToDefaults();
+
+ parser = assets.openXmlResourceParser(cookie, ANDROID_MANIFEST_FILENAME);
final SigningDetails signingDetails;
if ((flags & PARSE_COLLECT_CERTIFICATES) != 0) {
@@ -1632,7 +1633,7 @@ public class PackageParser {
"Failed to parse " + apkPath, e);
} finally {
IoUtils.closeQuietly(parser);
- IoUtils.closeQuietly(apkAssets);
+ IoUtils.closeQuietly(assets);
}
}
diff --git a/core/java/android/content/res/ApkAssets.java b/core/java/android/content/res/ApkAssets.java
deleted file mode 100644
index b087c48d8d4c..000000000000
--- a/core/java/android/content/res/ApkAssets.java
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.content.res;
-
-import android.annotation.NonNull;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.util.Preconditions;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-
-/**
- * The loaded, immutable, in-memory representation of an APK.
- *
- * The main implementation is native C++ and there is very little API surface exposed here. The APK
- * is mainly accessed via {@link AssetManager}.
- *
- * Since the ApkAssets instance is immutable, it can be reused and shared across AssetManagers,
- * making the creation of AssetManagers very cheap.
- * @hide
- */
-public final class ApkAssets implements AutoCloseable {
- @GuardedBy("this") private long mNativePtr;
- @GuardedBy("this") private StringBlock mStringBlock;
-
- /**
- * Creates a new ApkAssets instance from the given path on disk.
- *
- * @param path The path to an APK on disk.
- * @return a new instance of ApkAssets.
- * @throws IOException if a disk I/O error or parsing error occurred.
- */
- public static @NonNull ApkAssets loadFromPath(@NonNull String path) throws IOException {
- return new ApkAssets(path, false /*system*/, false /*forceSharedLib*/, false /*overlay*/);
- }
-
- /**
- * Creates a new ApkAssets instance from the given path on disk.
- *
- * @param path The path to an APK on disk.
- * @param system When true, the APK is loaded as a system APK (framework).
- * @return a new instance of ApkAssets.
- * @throws IOException if a disk I/O error or parsing error occurred.
- */
- public static @NonNull ApkAssets loadFromPath(@NonNull String path, boolean system)
- throws IOException {
- return new ApkAssets(path, system, false /*forceSharedLib*/, false /*overlay*/);
- }
-
- /**
- * Creates a new ApkAssets instance from the given path on disk.
- *
- * @param path The path to an APK on disk.
- * @param system When true, the APK is loaded as a system APK (framework).
- * @param forceSharedLibrary When true, any packages within the APK with package ID 0x7f are
- * loaded as a shared library.
- * @return a new instance of ApkAssets.
- * @throws IOException if a disk I/O error or parsing error occurred.
- */
- public static @NonNull ApkAssets loadFromPath(@NonNull String path, boolean system,
- boolean forceSharedLibrary) throws IOException {
- return new ApkAssets(path, system, forceSharedLibrary, false /*overlay*/);
- }
-
- /**
- * Creates a new ApkAssets instance from the given file descriptor. Not for use by applications.
- *
- * Performs a dup of the underlying fd, so you must take care of still closing
- * the FileDescriptor yourself (and can do that whenever you want).
- *
- * @param fd The FileDescriptor of an open, readable APK.
- * @param friendlyName The friendly name used to identify this ApkAssets when logging.
- * @param system When true, the APK is loaded as a system APK (framework).
- * @param forceSharedLibrary When true, any packages within the APK with package ID 0x7f are
- * loaded as a shared library.
- * @return a new instance of ApkAssets.
- * @throws IOException if a disk I/O error or parsing error occurred.
- */
- public static @NonNull ApkAssets loadFromFd(@NonNull FileDescriptor fd,
- @NonNull String friendlyName, boolean system, boolean forceSharedLibrary)
- throws IOException {
- return new ApkAssets(fd, friendlyName, system, forceSharedLibrary);
- }
-
- /**
- * Creates a new ApkAssets instance from the IDMAP at idmapPath. The overlay APK path
- * is encoded within the IDMAP.
- *
- * @param idmapPath Path to the IDMAP of an overlay APK.
- * @param system When true, the APK is loaded as a system APK (framework).
- * @return a new instance of ApkAssets.
- * @throws IOException if a disk I/O error or parsing error occurred.
- */
- public static @NonNull ApkAssets loadOverlayFromPath(@NonNull String idmapPath, boolean system)
- throws IOException {
- return new ApkAssets(idmapPath, system, false /*forceSharedLibrary*/, true /*overlay*/);
- }
-
- private ApkAssets(@NonNull String path, boolean system, boolean forceSharedLib, boolean overlay)
- throws IOException {
- Preconditions.checkNotNull(path, "path");
- mNativePtr = nativeLoad(path, system, forceSharedLib, overlay);
- mStringBlock = new StringBlock(nativeGetStringBlock(mNativePtr), true /*useSparse*/);
- }
-
- private ApkAssets(@NonNull FileDescriptor fd, @NonNull String friendlyName, boolean system,
- boolean forceSharedLib) throws IOException {
- Preconditions.checkNotNull(fd, "fd");
- Preconditions.checkNotNull(friendlyName, "friendlyName");
- mNativePtr = nativeLoadFromFd(fd, friendlyName, system, forceSharedLib);
- mStringBlock = new StringBlock(nativeGetStringBlock(mNativePtr), true /*useSparse*/);
- }
-
- @NonNull String getAssetPath() {
- synchronized (this) {
- ensureValidLocked();
- return nativeGetAssetPath(mNativePtr);
- }
- }
-
- CharSequence getStringFromPool(int idx) {
- synchronized (this) {
- ensureValidLocked();
- return mStringBlock.get(idx);
- }
- }
-
- /**
- * Retrieve a parser for a compiled XML file. This is associated with a single APK and
- * <em>NOT</em> a full AssetManager. This means that shared-library references will not be
- * dynamically assigned runtime package IDs.
- *
- * @param fileName The path to the file within the APK.
- * @return An XmlResourceParser.
- * @throws IOException if the file was not found or an error occurred retrieving it.
- */
- public @NonNull XmlResourceParser openXml(@NonNull String fileName) throws IOException {
- Preconditions.checkNotNull(fileName, "fileName");
- synchronized (this) {
- ensureValidLocked();
- long nativeXmlPtr = nativeOpenXml(mNativePtr, fileName);
- try (XmlBlock block = new XmlBlock(null, nativeXmlPtr)) {
- XmlResourceParser parser = block.newParser();
- // If nativeOpenXml doesn't throw, it will always return a valid native pointer,
- // which makes newParser always return non-null. But let's be paranoid.
- if (parser == null) {
- throw new AssertionError("block.newParser() returned a null parser");
- }
- return parser;
- }
- }
- }
-
- /**
- * Returns false if the underlying APK was changed since this ApkAssets was loaded.
- */
- public boolean isUpToDate() {
- synchronized (this) {
- ensureValidLocked();
- return nativeIsUpToDate(mNativePtr);
- }
- }
-
- /**
- * Closes the ApkAssets and destroys the underlying native implementation. Further use of the
- * ApkAssets object will cause exceptions to be thrown.
- *
- * Calling close on an already closed ApkAssets does nothing.
- */
- @Override
- public void close() {
- synchronized (this) {
- if (mNativePtr == 0) {
- return;
- }
-
- mStringBlock = null;
- nativeDestroy(mNativePtr);
- mNativePtr = 0;
- }
- }
-
- @Override
- protected void finalize() throws Throwable {
- if (mNativePtr != 0) {
- nativeDestroy(mNativePtr);
- }
- }
-
- private void ensureValidLocked() {
- if (mNativePtr == 0) {
- throw new RuntimeException("ApkAssets is closed");
- }
- }
-
- private static native long nativeLoad(
- @NonNull String path, boolean system, boolean forceSharedLib, boolean overlay)
- throws IOException;
- private static native long nativeLoadFromFd(@NonNull FileDescriptor fd,
- @NonNull String friendlyName, boolean system, boolean forceSharedLib)
- throws IOException;
- private static native void nativeDestroy(long ptr);
- private static native @NonNull String nativeGetAssetPath(long ptr);
- private static native long nativeGetStringBlock(long ptr);
- private static native boolean nativeIsUpToDate(long ptr);
- private static native long nativeOpenXml(long ptr, @NonNull String fileName) throws IOException;
-}
diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java
index 4bd6edc43541..5f8a34d46ecd 100644
--- a/core/java/android/content/res/AssetManager.java
+++ b/core/java/android/content/res/AssetManager.java
@@ -18,11 +18,9 @@ package android.content.res;
import android.annotation.AnyRes;
import android.annotation.ArrayRes;
-import android.annotation.AttrRes;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.StringRes;
-import android.annotation.StyleRes;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration.NativeConfig;
import android.os.ParcelFileDescriptor;
@@ -31,19 +29,11 @@ import android.util.SparseArray;
import android.util.TypedValue;
import com.android.internal.annotations.GuardedBy;
-import com.android.internal.util.Preconditions;
-import libcore.io.IoUtils;
-
-import java.io.BufferedReader;
-import java.io.FileInputStream;
+import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.nio.channels.FileLock;
-import java.util.ArrayList;
-import java.util.Arrays;
import java.util.HashMap;
/**
@@ -54,17 +44,7 @@ import java.util.HashMap;
* bytes.
*/
public final class AssetManager implements AutoCloseable {
- private static final String TAG = "AssetManager";
- private static final boolean DEBUG_REFS = false;
-
- private static final String FRAMEWORK_APK_PATH = "/system/framework/framework-res.apk";
-
- private static final Object sSync = new Object();
-
- // Not private for LayoutLib's BridgeAssetManager.
- @GuardedBy("sSync") static AssetManager sSystem = null;
-
- @GuardedBy("sSync") private static ApkAssets[] sSystemApkAssets = new ApkAssets[0];
+ /* modes used when opening an asset */
/**
* Mode for {@link #open(String, int)}: no specific information about how
@@ -87,303 +67,87 @@ public final class AssetManager implements AutoCloseable {
*/
public static final int ACCESS_BUFFER = 3;
- @GuardedBy("this") private final TypedValue mValue = new TypedValue();
- @GuardedBy("this") private final long[] mOffsets = new long[2];
-
- // Pointer to native implementation, stuffed inside a long.
- @GuardedBy("this") private long mObject;
-
- // The loaded asset paths.
- @GuardedBy("this") private ApkAssets[] mApkAssets;
+ private static final String TAG = "AssetManager";
+ private static final boolean localLOGV = false || false;
+
+ private static final boolean DEBUG_REFS = false;
+
+ private static final Object sSync = new Object();
+ /*package*/ static AssetManager sSystem = null;
- // Debug/reference counting implementation.
- @GuardedBy("this") private boolean mOpen = true;
- @GuardedBy("this") private int mNumRefs = 1;
- @GuardedBy("this") private HashMap<Long, RuntimeException> mRefStacks;
+ private final TypedValue mValue = new TypedValue();
+ private final long[] mOffsets = new long[2];
+
+ // For communication with native code.
+ private long mObject;
+ private StringBlock mStringBlocks[] = null;
+
+ private int mNumRefs = 1;
+ private boolean mOpen = true;
+ private HashMap<Long, RuntimeException> mRefStacks;
+
/**
* Create a new AssetManager containing only the basic system assets.
* Applications will not generally use this method, instead retrieving the
* appropriate asset manager with {@link Resources#getAssets}. Not for
* use by applications.
- * @hide
+ * {@hide}
*/
public AssetManager() {
- final ApkAssets[] assets;
- synchronized (sSync) {
- createSystemAssetsInZygoteLocked();
- assets = sSystemApkAssets;
- }
-
- mObject = nativeCreate();
- if (DEBUG_REFS) {
- mNumRefs = 0;
- incRefsLocked(hashCode());
- }
-
- // Always set the framework resources.
- setApkAssets(assets, false /*invalidateCaches*/);
- }
-
- /**
- * Private constructor that doesn't call ensureSystemAssets.
- * Used for the creation of system assets.
- */
- @SuppressWarnings("unused")
- private AssetManager(boolean sentinel) {
- mObject = nativeCreate();
- if (DEBUG_REFS) {
- mNumRefs = 0;
- incRefsLocked(hashCode());
+ synchronized (this) {
+ if (DEBUG_REFS) {
+ mNumRefs = 0;
+ incRefsLocked(this.hashCode());
+ }
+ init(false);
+ if (localLOGV) Log.v(TAG, "New asset manager: " + this);
+ ensureSystemAssets();
}
}
- /**
- * This must be called from Zygote so that system assets are shared by all applications.
- */
- @GuardedBy("sSync")
- private static void createSystemAssetsInZygoteLocked() {
- if (sSystem != null) {
- return;
- }
-
- // Make sure that all IDMAPs are up to date.
- nativeVerifySystemIdmaps();
-
- try {
- ArrayList<ApkAssets> apkAssets = new ArrayList<>();
- apkAssets.add(ApkAssets.loadFromPath(FRAMEWORK_APK_PATH, true /*system*/));
- loadStaticRuntimeOverlays(apkAssets);
-
- sSystemApkAssets = apkAssets.toArray(new ApkAssets[apkAssets.size()]);
- sSystem = new AssetManager(true /*sentinel*/);
- sSystem.setApkAssets(sSystemApkAssets, false /*invalidateCaches*/);
- } catch (IOException e) {
- throw new IllegalStateException("Failed to create system AssetManager", e);
+ private static void ensureSystemAssets() {
+ synchronized (sSync) {
+ if (sSystem == null) {
+ AssetManager system = new AssetManager(true);
+ system.makeStringBlocks(null);
+ sSystem = system;
+ }
}
}
-
- /**
- * Loads the static runtime overlays declared in /data/resource-cache/overlays.list.
- * Throws an exception if the file is corrupt or if loading the APKs referenced by the file
- * fails. Returns quietly if the overlays.list file doesn't exist.
- * @param outApkAssets The list to fill with the loaded ApkAssets.
- */
- private static void loadStaticRuntimeOverlays(ArrayList<ApkAssets> outApkAssets)
- throws IOException {
- final FileInputStream fis;
- try {
- fis = new FileInputStream("/data/resource-cache/overlays.list");
- } catch (FileNotFoundException e) {
- // We might not have any overlays, this is fine. We catch here since ApkAssets
- // loading can also fail with the same exception, which we would want to propagate.
- Log.i(TAG, "no overlays.list file found");
- return;
- }
-
- try {
- // Acquire a lock so that any idmap scanning doesn't impact the current set.
- // The order of this try-with-resources block matters. We must release the lock, and
- // then close the file streams when exiting the block.
- try (final BufferedReader br = new BufferedReader(new InputStreamReader(fis));
- final FileLock flock = fis.getChannel().lock(0, Long.MAX_VALUE, true /*shared*/)) {
- for (String line; (line = br.readLine()) != null; ) {
- final String idmapPath = line.split(" ")[1];
- outApkAssets.add(ApkAssets.loadOverlayFromPath(idmapPath, true /*system*/));
- }
+
+ private AssetManager(boolean isSystem) {
+ if (DEBUG_REFS) {
+ synchronized (this) {
+ mNumRefs = 0;
+ incRefsLocked(this.hashCode());
}
- } finally {
- // When BufferedReader is closed above, FileInputStream is closed as well. But let's be
- // paranoid.
- IoUtils.closeQuietly(fis);
}
+ init(true);
+ if (localLOGV) Log.v(TAG, "New asset manager: " + this);
}
/**
* Return a global shared asset manager that provides access to only
* system assets (no application assets).
- * @hide
+ * {@hide}
*/
public static AssetManager getSystem() {
- synchronized (sSync) {
- createSystemAssetsInZygoteLocked();
- return sSystem;
- }
+ ensureSystemAssets();
+ return sSystem;
}
/**
* Close this asset manager.
*/
- @Override
public void close() {
- synchronized (this) {
- if (!mOpen) {
- return;
+ synchronized(this) {
+ //System.out.println("Release: num=" + mNumRefs
+ // + ", released=" + mReleased);
+ if (mOpen) {
+ mOpen = false;
+ decRefsLocked(this.hashCode());
}
-
- mOpen = false;
- decRefsLocked(hashCode());
- }
- }
-
- /**
- * Changes the asset paths in this AssetManager. This replaces the {@link #addAssetPath(String)}
- * family of methods.
- *
- * @param apkAssets The new set of paths.
- * @param invalidateCaches Whether to invalidate any caches. This should almost always be true.
- * Set this to false if you are appending new resources
- * (not new configurations).
- * @hide
- */
- public void setApkAssets(@NonNull ApkAssets[] apkAssets, boolean invalidateCaches) {
- Preconditions.checkNotNull(apkAssets, "apkAssets");
- synchronized (this) {
- ensureValidLocked();
- mApkAssets = apkAssets;
- nativeSetApkAssets(mObject, apkAssets, invalidateCaches);
- if (invalidateCaches) {
- // Invalidate all caches.
- invalidateCachesLocked(-1);
- }
- }
- }
-
- /**
- * Invalidates the caches in this AssetManager according to the bitmask `diff`.
- *
- * @param diff The bitmask of changes generated by {@link Configuration#diff(Configuration)}.
- * @see ActivityInfo.Config
- */
- private void invalidateCachesLocked(int diff) {
- // TODO(adamlesinski): Currently there are no caches to invalidate in Java code.
- }
-
- /**
- * @hide
- */
- public @NonNull ApkAssets[] getApkAssets() {
- synchronized (this) {
- ensureValidLocked();
- return mApkAssets;
- }
- }
-
- /**
- * @deprecated Use {@link #setApkAssets(ApkAssets[], boolean)}
- * @hide
- */
- @Deprecated
- public int addAssetPath(String path) {
- return addAssetPathInternal(path, false /*overlay*/, false /*appAsLib*/);
- }
-
- /**
- * @deprecated Use {@link #setApkAssets(ApkAssets[], boolean)}
- * @hide
- */
- @Deprecated
- public int addAssetPathAsSharedLibrary(String path) {
- return addAssetPathInternal(path, false /*overlay*/, true /*appAsLib*/);
- }
-
- /**
- * @deprecated Use {@link #setApkAssets(ApkAssets[], boolean)}
- * @hide
- */
- @Deprecated
- public int addOverlayPath(String path) {
- return addAssetPathInternal(path, true /*overlay*/, false /*appAsLib*/);
- }
-
- private int addAssetPathInternal(String path, boolean overlay, boolean appAsLib) {
- Preconditions.checkNotNull(path, "path");
- synchronized (this) {
- ensureOpenLocked();
- final int count = mApkAssets.length;
- for (int i = 0; i < count; i++) {
- if (mApkAssets[i].getAssetPath().equals(path)) {
- return i + 1;
- }
- }
-
- final ApkAssets assets;
- try {
- if (overlay) {
- // TODO(b/70343104): This hardcoded path will be removed once
- // addAssetPathInternal is deleted.
- final String idmapPath = "/data/resource-cache/"
- + path.substring(1).replace('/', '@')
- + "@idmap";
- assets = ApkAssets.loadOverlayFromPath(idmapPath, false /*system*/);
- } else {
- assets = ApkAssets.loadFromPath(path, false /*system*/, appAsLib);
- }
- } catch (IOException e) {
- return 0;
- }
-
- final ApkAssets[] newApkAssets = Arrays.copyOf(mApkAssets, count + 1);
- newApkAssets[count] = assets;
- setApkAssets(newApkAssets, true);
- return count + 1;
- }
- }
-
- /**
- * Ensures that the native implementation has not been destroyed.
- * The AssetManager may have been closed, but references to it still exist
- * and therefore the native implementation is not destroyed.
- */
- @GuardedBy("this")
- private void ensureValidLocked() {
- if (mObject == 0) {
- throw new RuntimeException("AssetManager has been destroyed");
- }
- }
-
- /**
- * Ensures that the AssetManager has not been explicitly closed. If this method passes,
- * then this implies that ensureValidLocked() also passes.
- */
- @GuardedBy("this")
- private void ensureOpenLocked() {
- if (!mOpen) {
- throw new RuntimeException("AssetManager has been closed");
- }
- }
-
- /**
- * Populates {@code outValue} with the data associated a particular
- * resource identifier for the current configuration.
- *
- * @param resId the resource identifier to load
- * @param densityDpi the density bucket for which to load the resource
- * @param outValue the typed value in which to put the data
- * @param resolveRefs {@code true} to resolve references, {@code false}
- * to leave them unresolved
- * @return {@code true} if the data was loaded into {@code outValue},
- * {@code false} otherwise
- */
- boolean getResourceValue(@AnyRes int resId, int densityDpi, @NonNull TypedValue outValue,
- boolean resolveRefs) {
- Preconditions.checkNotNull(outValue, "outValue");
- synchronized (this) {
- ensureValidLocked();
- final int cookie = nativeGetResourceValue(
- mObject, resId, (short) densityDpi, outValue, resolveRefs);
- if (cookie <= 0) {
- return false;
- }
-
- // Convert the changing configurations flags populated by native code.
- outValue.changingConfigurations = ActivityInfo.activityInfoConfigNativeToJava(
- outValue.changingConfigurations);
-
- if (outValue.type == TypedValue.TYPE_STRING) {
- outValue.string = mApkAssets[cookie - 1].getStringFromPool(outValue.data);
- }
- return true;
}
}
@@ -394,7 +158,8 @@ public final class AssetManager implements AutoCloseable {
* @param resId the resource identifier to load
* @return the string value, or {@code null}
*/
- @Nullable CharSequence getResourceText(@StringRes int resId) {
+ @Nullable
+ final CharSequence getResourceText(@StringRes int resId) {
synchronized (this) {
final TypedValue outValue = mValue;
if (getResourceValue(resId, 0, outValue, true)) {
@@ -409,15 +174,15 @@ public final class AssetManager implements AutoCloseable {
* identifier for the current configuration.
*
* @param resId the resource identifier to load
- * @param bagEntryId the index into the bag to load
+ * @param bagEntryId
* @return the string value, or {@code null}
*/
- @Nullable CharSequence getResourceBagText(@StringRes int resId, int bagEntryId) {
+ @Nullable
+ final CharSequence getResourceBagText(@StringRes int resId, int bagEntryId) {
synchronized (this) {
- ensureValidLocked();
final TypedValue outValue = mValue;
- final int cookie = nativeGetResourceBagValue(mObject, resId, bagEntryId, outValue);
- if (cookie <= 0) {
+ final int block = loadResourceBagValue(resId, bagEntryId, outValue, true);
+ if (block < 0) {
return null;
}
@@ -426,60 +191,52 @@ public final class AssetManager implements AutoCloseable {
outValue.changingConfigurations);
if (outValue.type == TypedValue.TYPE_STRING) {
- return mApkAssets[cookie - 1].getStringFromPool(outValue.data);
+ return mStringBlocks[block].get(outValue.data);
}
return outValue.coerceToString();
}
}
- int getResourceArraySize(@ArrayRes int resId) {
- synchronized (this) {
- ensureValidLocked();
- return nativeGetResourceArraySize(mObject, resId);
- }
- }
-
/**
- * Populates `outData` with array elements of `resId`. `outData` is normally
- * used with
- * {@link TypedArray}.
- *
- * Each logical element in `outData` is {@link TypedArray#STYLE_NUM_ENTRIES}
- * long,
- * with the indices of the data representing the type, value, asset cookie,
- * resource ID,
- * configuration change mask, and density of the element.
- *
- * @param resId The resource ID of an array resource.
- * @param outData The array to populate with data.
- * @return The length of the array.
+ * Retrieves the string array associated with a particular resource
+ * identifier for the current configuration.
*
- * @see TypedArray#STYLE_TYPE
- * @see TypedArray#STYLE_DATA
- * @see TypedArray#STYLE_ASSET_COOKIE
- * @see TypedArray#STYLE_RESOURCE_ID
- * @see TypedArray#STYLE_CHANGING_CONFIGURATIONS
- * @see TypedArray#STYLE_DENSITY
+ * @param resId the resource identifier of the string array
+ * @return the string array, or {@code null}
*/
- int getResourceArray(@ArrayRes int resId, @NonNull int[] outData) {
- Preconditions.checkNotNull(outData, "outData");
- synchronized (this) {
- ensureValidLocked();
- return nativeGetResourceArray(mObject, resId, outData);
- }
+ @Nullable
+ final String[] getResourceStringArray(@ArrayRes int resId) {
+ return getArrayStringResource(resId);
}
/**
- * Retrieves the string array associated with a particular resource
- * identifier for the current configuration.
+ * Populates {@code outValue} with the data associated a particular
+ * resource identifier for the current configuration.
*
- * @param resId the resource identifier of the string array
- * @return the string array, or {@code null}
+ * @param resId the resource identifier to load
+ * @param densityDpi the density bucket for which to load the resource
+ * @param outValue the typed value in which to put the data
+ * @param resolveRefs {@code true} to resolve references, {@code false}
+ * to leave them unresolved
+ * @return {@code true} if the data was loaded into {@code outValue},
+ * {@code false} otherwise
*/
- @Nullable String[] getResourceStringArray(@ArrayRes int resId) {
+ final boolean getResourceValue(@AnyRes int resId, int densityDpi, @NonNull TypedValue outValue,
+ boolean resolveRefs) {
synchronized (this) {
- ensureValidLocked();
- return nativeGetResourceStringArray(mObject, resId);
+ final int block = loadResourceValue(resId, (short) densityDpi, outValue, resolveRefs);
+ if (block < 0) {
+ return false;
+ }
+
+ // Convert the changing configurations flags populated by native code.
+ outValue.changingConfigurations = ActivityInfo.activityInfoConfigNativeToJava(
+ outValue.changingConfigurations);
+
+ if (outValue.type == TypedValue.TYPE_STRING) {
+ outValue.string = mStringBlocks[block].get(outValue.data);
+ }
+ return true;
}
}
@@ -489,48 +246,26 @@ public final class AssetManager implements AutoCloseable {
*
* @param resId the resource id of the string array
*/
- @Nullable CharSequence[] getResourceTextArray(@ArrayRes int resId) {
+ final @Nullable CharSequence[] getResourceTextArray(@ArrayRes int resId) {
synchronized (this) {
- ensureValidLocked();
- final int[] rawInfoArray = nativeGetResourceStringArrayInfo(mObject, resId);
+ final int[] rawInfoArray = getArrayStringInfo(resId);
if (rawInfoArray == null) {
return null;
}
-
final int rawInfoArrayLen = rawInfoArray.length;
final int infoArrayLen = rawInfoArrayLen / 2;
+ int block;
+ int index;
final CharSequence[] retArray = new CharSequence[infoArrayLen];
for (int i = 0, j = 0; i < rawInfoArrayLen; i = i + 2, j++) {
- int cookie = rawInfoArray[i];
- int index = rawInfoArray[i + 1];
- retArray[j] = (index >= 0 && cookie > 0)
- ? mApkAssets[cookie - 1].getStringFromPool(index) : null;
+ block = rawInfoArray[i];
+ index = rawInfoArray[i + 1];
+ retArray[j] = index >= 0 ? mStringBlocks[block].get(index) : null;
}
return retArray;
}
}
- @Nullable int[] getResourceIntArray(@ArrayRes int resId) {
- synchronized (this) {
- ensureValidLocked();
- return nativeGetResourceIntArray(mObject, resId);
- }
- }
-
- /**
- * Get the attributes for a style resource. These are the &lt;item&gt;
- * elements in
- * a &lt;style&gt; resource.
- * @param resId The resource ID of the style
- * @return An array of attribute IDs.
- */
- @AttrRes int[] getStyleAttributes(@StyleRes int resId) {
- synchronized (this) {
- ensureValidLocked();
- return nativeGetStyleAttributes(mObject, resId);
- }
- }
-
/**
* Populates {@code outValue} with the data associated with a particular
* resource identifier for the current configuration. Resolves theme
@@ -544,88 +279,73 @@ public final class AssetManager implements AutoCloseable {
* @return {@code true} if the data was loaded into {@code outValue},
* {@code false} otherwise
*/
- boolean getThemeValue(long theme, @AnyRes int resId, @NonNull TypedValue outValue,
+ final boolean getThemeValue(long theme, @AnyRes int resId, @NonNull TypedValue outValue,
boolean resolveRefs) {
- Preconditions.checkNotNull(outValue, "outValue");
- synchronized (this) {
- ensureValidLocked();
- final int cookie = nativeThemeGetAttributeValue(mObject, theme, resId, outValue,
- resolveRefs);
- if (cookie <= 0) {
- return false;
- }
-
- // Convert the changing configurations flags populated by native code.
- outValue.changingConfigurations = ActivityInfo.activityInfoConfigNativeToJava(
- outValue.changingConfigurations);
-
- if (outValue.type == TypedValue.TYPE_STRING) {
- outValue.string = mApkAssets[cookie - 1].getStringFromPool(outValue.data);
- }
- return true;
- }
- }
-
- void dumpTheme(long theme, int priority, String tag, String prefix) {
- synchronized (this) {
- ensureValidLocked();
- nativeThemeDump(mObject, theme, priority, tag, prefix);
+ final int block = loadThemeAttributeValue(theme, resId, outValue, resolveRefs);
+ if (block < 0) {
+ return false;
}
- }
- @Nullable String getResourceName(@AnyRes int resId) {
- synchronized (this) {
- ensureValidLocked();
- return nativeGetResourceName(mObject, resId);
- }
- }
+ // Convert the changing configurations flags populated by native code.
+ outValue.changingConfigurations = ActivityInfo.activityInfoConfigNativeToJava(
+ outValue.changingConfigurations);
- @Nullable String getResourcePackageName(@AnyRes int resId) {
- synchronized (this) {
- ensureValidLocked();
- return nativeGetResourcePackageName(mObject, resId);
+ if (outValue.type == TypedValue.TYPE_STRING) {
+ final StringBlock[] blocks = ensureStringBlocks();
+ outValue.string = blocks[block].get(outValue.data);
}
+ return true;
}
- @Nullable String getResourceTypeName(@AnyRes int resId) {
+ /**
+ * Ensures the string blocks are loaded.
+ *
+ * @return the string blocks
+ */
+ @NonNull
+ final StringBlock[] ensureStringBlocks() {
synchronized (this) {
- ensureValidLocked();
- return nativeGetResourceTypeName(mObject, resId);
+ if (mStringBlocks == null) {
+ makeStringBlocks(sSystem.mStringBlocks);
+ }
+ return mStringBlocks;
}
}
- @Nullable String getResourceEntryName(@AnyRes int resId) {
- synchronized (this) {
- ensureValidLocked();
- return nativeGetResourceEntryName(mObject, resId);
+ /*package*/ final void makeStringBlocks(StringBlock[] seed) {
+ final int seedNum = (seed != null) ? seed.length : 0;
+ final int num = getStringBlockCount();
+ mStringBlocks = new StringBlock[num];
+ if (localLOGV) Log.v(TAG, "Making string blocks for " + this
+ + ": " + num);
+ for (int i=0; i<num; i++) {
+ if (i < seedNum) {
+ mStringBlocks[i] = seed[i];
+ } else {
+ mStringBlocks[i] = new StringBlock(getNativeStringBlock(i), true);
+ }
}
}
- @AnyRes int getResourceIdentifier(@NonNull String name, @Nullable String defType,
- @Nullable String defPackage) {
+ /*package*/ final CharSequence getPooledStringForCookie(int cookie, int id) {
synchronized (this) {
- ensureValidLocked();
- // name is checked in JNI.
- return nativeGetResourceIdentifier(mObject, name, defType, defPackage);
+ // Cookies map to string blocks starting at 1.
+ return mStringBlocks[cookie - 1].get(id);
}
}
- CharSequence getPooledStringForCookie(int cookie, int id) {
- // Cookies map to ApkAssets starting at 1.
- return getApkAssets()[cookie - 1].getStringFromPool(id);
- }
-
/**
* Open an asset using ACCESS_STREAMING mode. This provides access to
* files that have been bundled with an application as assets -- that is,
* files placed in to the "assets" directory.
*
- * @param fileName The name of the asset to open. This name can be hierarchical.
+ * @param fileName The name of the asset to open. This name can be
+ * hierarchical.
*
* @see #open(String, int)
* @see #list
*/
- public @NonNull InputStream open(@NonNull String fileName) throws IOException {
+ public final InputStream open(String fileName) throws IOException {
return open(fileName, ACCESS_STREAMING);
}
@@ -635,7 +355,8 @@ public final class AssetManager implements AutoCloseable {
* with an application as assets -- that is, files placed in to the
* "assets" directory.
*
- * @param fileName The name of the asset to open. This name can be hierarchical.
+ * @param fileName The name of the asset to open. This name can be
+ * hierarchical.
* @param accessMode Desired access mode for retrieving the data.
*
* @see #ACCESS_UNKNOWN
@@ -645,40 +366,34 @@ public final class AssetManager implements AutoCloseable {
* @see #open(String)
* @see #list
*/
- public @NonNull InputStream open(@NonNull String fileName, int accessMode) throws IOException {
- Preconditions.checkNotNull(fileName, "fileName");
+ public final InputStream open(String fileName, int accessMode)
+ throws IOException {
synchronized (this) {
- ensureOpenLocked();
- final long asset = nativeOpenAsset(mObject, fileName, accessMode);
- if (asset == 0) {
- throw new FileNotFoundException("Asset file: " + fileName);
+ if (!mOpen) {
+ throw new RuntimeException("Assetmanager has been closed");
+ }
+ long asset = openAsset(fileName, accessMode);
+ if (asset != 0) {
+ AssetInputStream res = new AssetInputStream(asset);
+ incRefsLocked(res.hashCode());
+ return res;
}
- final AssetInputStream assetInputStream = new AssetInputStream(asset);
- incRefsLocked(assetInputStream.hashCode());
- return assetInputStream;
}
+ throw new FileNotFoundException("Asset file: " + fileName);
}
- /**
- * Open an uncompressed asset by mmapping it and returning an {@link AssetFileDescriptor}.
- * This provides access to files that have been bundled with an application as assets -- that
- * is, files placed in to the "assets" directory.
- *
- * The asset must be uncompressed, or an exception will be thrown.
- *
- * @param fileName The name of the asset to open. This name can be hierarchical.
- * @return An open AssetFileDescriptor.
- */
- public @NonNull AssetFileDescriptor openFd(@NonNull String fileName) throws IOException {
- Preconditions.checkNotNull(fileName, "fileName");
+ public final AssetFileDescriptor openFd(String fileName)
+ throws IOException {
synchronized (this) {
- ensureOpenLocked();
- final ParcelFileDescriptor pfd = nativeOpenAssetFd(mObject, fileName, mOffsets);
- if (pfd == null) {
- throw new FileNotFoundException("Asset file: " + fileName);
+ if (!mOpen) {
+ throw new RuntimeException("Assetmanager has been closed");
+ }
+ ParcelFileDescriptor pfd = openAssetFd(fileName, mOffsets);
+ if (pfd != null) {
+ return new AssetFileDescriptor(pfd, mOffsets[0], mOffsets[1]);
}
- return new AssetFileDescriptor(pfd, mOffsets[0], mOffsets[1]);
}
+ throw new FileNotFoundException("Asset file: " + fileName);
}
/**
@@ -693,121 +408,90 @@ public final class AssetManager implements AutoCloseable {
*
* @see #open
*/
- public @Nullable String[] list(@NonNull String path) throws IOException {
- Preconditions.checkNotNull(path, "path");
- synchronized (this) {
- ensureValidLocked();
- return nativeList(mObject, path);
- }
- }
+ public native final String[] list(String path)
+ throws IOException;
/**
+ * {@hide}
* Open a non-asset file as an asset using ACCESS_STREAMING mode. This
* provides direct access to all of the files included in an application
* package (not only its assets). Applications should not normally use
* this.
- *
- * @param fileName Name of the asset to retrieve.
- *
+ *
* @see #open(String)
- * @hide
*/
- public @NonNull InputStream openNonAsset(@NonNull String fileName) throws IOException {
+ public final InputStream openNonAsset(String fileName) throws IOException {
return openNonAsset(0, fileName, ACCESS_STREAMING);
}
/**
+ * {@hide}
* Open a non-asset file as an asset using a specific access mode. This
* provides direct access to all of the files included in an application
* package (not only its assets). Applications should not normally use
* this.
- *
- * @param fileName Name of the asset to retrieve.
- * @param accessMode Desired access mode for retrieving the data.
- *
- * @see #ACCESS_UNKNOWN
- * @see #ACCESS_STREAMING
- * @see #ACCESS_RANDOM
- * @see #ACCESS_BUFFER
+ *
* @see #open(String, int)
- * @hide
*/
- public @NonNull InputStream openNonAsset(@NonNull String fileName, int accessMode)
- throws IOException {
+ public final InputStream openNonAsset(String fileName, int accessMode)
+ throws IOException {
return openNonAsset(0, fileName, accessMode);
}
/**
+ * {@hide}
* Open a non-asset in a specified package. Not for use by applications.
- *
+ *
* @param cookie Identifier of the package to be opened.
* @param fileName Name of the asset to retrieve.
- * @hide
*/
- public @NonNull InputStream openNonAsset(int cookie, @NonNull String fileName)
- throws IOException {
+ public final InputStream openNonAsset(int cookie, String fileName)
+ throws IOException {
return openNonAsset(cookie, fileName, ACCESS_STREAMING);
}
/**
+ * {@hide}
* Open a non-asset in a specified package. Not for use by applications.
- *
+ *
* @param cookie Identifier of the package to be opened.
* @param fileName Name of the asset to retrieve.
* @param accessMode Desired access mode for retrieving the data.
- * @hide
*/
- public @NonNull InputStream openNonAsset(int cookie, @NonNull String fileName, int accessMode)
- throws IOException {
- Preconditions.checkNotNull(fileName, "fileName");
+ public final InputStream openNonAsset(int cookie, String fileName, int accessMode)
+ throws IOException {
synchronized (this) {
- ensureOpenLocked();
- final long asset = nativeOpenNonAsset(mObject, cookie, fileName, accessMode);
- if (asset == 0) {
- throw new FileNotFoundException("Asset absolute file: " + fileName);
+ if (!mOpen) {
+ throw new RuntimeException("Assetmanager has been closed");
+ }
+ long asset = openNonAssetNative(cookie, fileName, accessMode);
+ if (asset != 0) {
+ AssetInputStream res = new AssetInputStream(asset);
+ incRefsLocked(res.hashCode());
+ return res;
}
- final AssetInputStream assetInputStream = new AssetInputStream(asset);
- incRefsLocked(assetInputStream.hashCode());
- return assetInputStream;
}
+ throw new FileNotFoundException("Asset absolute file: " + fileName);
}
- /**
- * Open a non-asset as an asset by mmapping it and returning an {@link AssetFileDescriptor}.
- * This provides direct access to all of the files included in an application
- * package (not only its assets). Applications should not normally use this.
- *
- * The asset must not be compressed, or an exception will be thrown.
- *
- * @param fileName Name of the asset to retrieve.
- */
- public @NonNull AssetFileDescriptor openNonAssetFd(@NonNull String fileName)
+ public final AssetFileDescriptor openNonAssetFd(String fileName)
throws IOException {
return openNonAssetFd(0, fileName);
}
-
- /**
- * Open a non-asset as an asset by mmapping it and returning an {@link AssetFileDescriptor}.
- * This provides direct access to all of the files included in an application
- * package (not only its assets). Applications should not normally use this.
- *
- * The asset must not be compressed, or an exception will be thrown.
- *
- * @param cookie Identifier of the package to be opened.
- * @param fileName Name of the asset to retrieve.
- */
- public @NonNull AssetFileDescriptor openNonAssetFd(int cookie, @NonNull String fileName)
- throws IOException {
- Preconditions.checkNotNull(fileName, "fileName");
+
+ public final AssetFileDescriptor openNonAssetFd(int cookie,
+ String fileName) throws IOException {
synchronized (this) {
- ensureOpenLocked();
- final ParcelFileDescriptor pfd =
- nativeOpenNonAssetFd(mObject, cookie, fileName, mOffsets);
- if (pfd == null) {
- throw new FileNotFoundException("Asset absolute file: " + fileName);
+ if (!mOpen) {
+ throw new RuntimeException("Assetmanager has been closed");
+ }
+ ParcelFileDescriptor pfd = openNonAssetFdNative(cookie,
+ fileName, mOffsets);
+ if (pfd != null) {
+ return new AssetFileDescriptor(pfd, mOffsets[0], mOffsets[1]);
}
- return new AssetFileDescriptor(pfd, mOffsets[0], mOffsets[1]);
}
+ throw new FileNotFoundException("Asset absolute file: " + fileName);
}
/**
@@ -815,7 +499,7 @@ public final class AssetManager implements AutoCloseable {
*
* @param fileName The name of the file to retrieve.
*/
- public @NonNull XmlResourceParser openXmlResourceParser(@NonNull String fileName)
+ public final XmlResourceParser openXmlResourceParser(String fileName)
throws IOException {
return openXmlResourceParser(0, fileName);
}
@@ -826,265 +510,270 @@ public final class AssetManager implements AutoCloseable {
* @param cookie Identifier of the package to be opened.
* @param fileName The name of the file to retrieve.
*/
- public @NonNull XmlResourceParser openXmlResourceParser(int cookie, @NonNull String fileName)
- throws IOException {
- try (XmlBlock block = openXmlBlockAsset(cookie, fileName)) {
- XmlResourceParser parser = block.newParser();
- // If openXmlBlockAsset doesn't throw, it will always return an XmlBlock object with
- // a valid native pointer, which makes newParser always return non-null. But let's
- // be paranoid.
- if (parser == null) {
- throw new AssertionError("block.newParser() returned a null parser");
- }
- return parser;
- }
+ public final XmlResourceParser openXmlResourceParser(int cookie,
+ String fileName) throws IOException {
+ XmlBlock block = openXmlBlockAsset(cookie, fileName);
+ XmlResourceParser rp = block.newParser();
+ block.close();
+ return rp;
}
/**
- * Retrieve a non-asset as a compiled XML file. Not for use by applications.
+ * {@hide}
+ * Retrieve a non-asset as a compiled XML file. Not for use by
+ * applications.
*
* @param fileName The name of the file to retrieve.
- * @hide
*/
- @NonNull XmlBlock openXmlBlockAsset(@NonNull String fileName) throws IOException {
+ /*package*/ final XmlBlock openXmlBlockAsset(String fileName)
+ throws IOException {
return openXmlBlockAsset(0, fileName);
}
/**
+ * {@hide}
* Retrieve a non-asset as a compiled XML file. Not for use by
* applications.
*
* @param cookie Identifier of the package to be opened.
* @param fileName Name of the asset to retrieve.
- * @hide
*/
- @NonNull XmlBlock openXmlBlockAsset(int cookie, @NonNull String fileName) throws IOException {
- Preconditions.checkNotNull(fileName, "fileName");
+ /*package*/ final XmlBlock openXmlBlockAsset(int cookie, String fileName)
+ throws IOException {
synchronized (this) {
- ensureOpenLocked();
- final long xmlBlock = nativeOpenXmlAsset(mObject, cookie, fileName);
- if (xmlBlock == 0) {
- throw new FileNotFoundException("Asset XML file: " + fileName);
+ if (!mOpen) {
+ throw new RuntimeException("Assetmanager has been closed");
+ }
+ long xmlBlock = openXmlAssetNative(cookie, fileName);
+ if (xmlBlock != 0) {
+ XmlBlock res = new XmlBlock(this, xmlBlock);
+ incRefsLocked(res.hashCode());
+ return res;
}
- final XmlBlock block = new XmlBlock(this, xmlBlock);
- incRefsLocked(block.hashCode());
- return block;
}
+ throw new FileNotFoundException("Asset XML file: " + fileName);
}
- void xmlBlockGone(int id) {
+ /*package*/ void xmlBlockGone(int id) {
synchronized (this) {
decRefsLocked(id);
}
}
- void applyStyle(long themePtr, @AttrRes int defStyleAttr, @StyleRes int defStyleRes,
- @Nullable XmlBlock.Parser parser, @NonNull int[] inAttrs, long outValuesAddress,
- long outIndicesAddress) {
- Preconditions.checkNotNull(inAttrs, "inAttrs");
+ /*package*/ final long createTheme() {
synchronized (this) {
- // Need to synchronize on AssetManager because we will be accessing
- // the native implementation of AssetManager.
- ensureValidLocked();
- nativeApplyStyle(mObject, themePtr, defStyleAttr, defStyleRes,
- parser != null ? parser.mParseState : 0, inAttrs, outValuesAddress,
- outIndicesAddress);
- }
- }
-
- boolean resolveAttrs(long themePtr, @AttrRes int defStyleAttr, @StyleRes int defStyleRes,
- @Nullable int[] inValues, @NonNull int[] inAttrs, @NonNull int[] outValues,
- @NonNull int[] outIndices) {
- Preconditions.checkNotNull(inAttrs, "inAttrs");
- Preconditions.checkNotNull(outValues, "outValues");
- Preconditions.checkNotNull(outIndices, "outIndices");
- synchronized (this) {
- // Need to synchronize on AssetManager because we will be accessing
- // the native implementation of AssetManager.
- ensureValidLocked();
- return nativeResolveAttrs(mObject,
- themePtr, defStyleAttr, defStyleRes, inValues, inAttrs, outValues, outIndices);
- }
- }
-
- boolean retrieveAttributes(@NonNull XmlBlock.Parser parser, @NonNull int[] inAttrs,
- @NonNull int[] outValues, @NonNull int[] outIndices) {
- Preconditions.checkNotNull(parser, "parser");
- Preconditions.checkNotNull(inAttrs, "inAttrs");
- Preconditions.checkNotNull(outValues, "outValues");
- Preconditions.checkNotNull(outIndices, "outIndices");
- synchronized (this) {
- // Need to synchronize on AssetManager because we will be accessing
- // the native implementation of AssetManager.
- ensureValidLocked();
- return nativeRetrieveAttributes(
- mObject, parser.mParseState, inAttrs, outValues, outIndices);
- }
- }
-
- long createTheme() {
- synchronized (this) {
- ensureValidLocked();
- long themePtr = nativeThemeCreate(mObject);
- incRefsLocked(themePtr);
- return themePtr;
- }
- }
-
- void releaseTheme(long themePtr) {
- synchronized (this) {
- nativeThemeDestroy(themePtr);
- decRefsLocked(themePtr);
+ if (!mOpen) {
+ throw new RuntimeException("Assetmanager has been closed");
+ }
+ long res = newTheme();
+ incRefsLocked(res);
+ return res;
}
}
- void applyStyleToTheme(long themePtr, @StyleRes int resId, boolean force) {
+ /*package*/ final void releaseTheme(long theme) {
synchronized (this) {
- // Need to synchronize on AssetManager because we will be accessing
- // the native implementation of AssetManager.
- ensureValidLocked();
- nativeThemeApplyStyle(mObject, themePtr, resId, force);
+ deleteTheme(theme);
+ decRefsLocked(theme);
}
}
- @Override
protected void finalize() throws Throwable {
- if (DEBUG_REFS && mNumRefs != 0) {
- Log.w(TAG, "AssetManager " + this + " finalized with non-zero refs: " + mNumRefs);
- if (mRefStacks != null) {
- for (RuntimeException e : mRefStacks.values()) {
- Log.w(TAG, "Reference from here", e);
+ try {
+ if (DEBUG_REFS && mNumRefs != 0) {
+ Log.w(TAG, "AssetManager " + this
+ + " finalized with non-zero refs: " + mNumRefs);
+ if (mRefStacks != null) {
+ for (RuntimeException e : mRefStacks.values()) {
+ Log.w(TAG, "Reference from here", e);
+ }
}
}
- }
-
- if (mObject != 0) {
- nativeDestroy(mObject);
+ destroy();
+ } finally {
+ super.finalize();
}
}
-
- /* No Locking is needed for AssetInputStream because an AssetInputStream is not-thread
- safe and it does not rely on AssetManager once it has been created. It completely owns the
- underlying Asset. */
+
public final class AssetInputStream extends InputStream {
- private long mAssetNativePtr;
- private long mLength;
- private long mMarkPos;
-
/**
* @hide
*/
public final int getAssetInt() {
throw new UnsupportedOperationException();
}
-
/**
* @hide
*/
public final long getNativeAsset() {
- return mAssetNativePtr;
+ return mAsset;
}
-
- private AssetInputStream(long assetNativePtr) {
- mAssetNativePtr = assetNativePtr;
- mLength = nativeAssetGetLength(assetNativePtr);
+ private AssetInputStream(long asset)
+ {
+ mAsset = asset;
+ mLength = getAssetLength(asset);
}
-
- @Override
public final int read() throws IOException {
- ensureOpen();
- return nativeAssetReadChar(mAssetNativePtr);
+ return readAssetChar(mAsset);
}
-
- @Override
- public final int read(@NonNull byte[] b) throws IOException {
- ensureOpen();
- Preconditions.checkNotNull(b, "b");
- return nativeAssetRead(mAssetNativePtr, b, 0, b.length);
+ public final boolean markSupported() {
+ return true;
}
-
- @Override
- public final int read(@NonNull byte[] b, int off, int len) throws IOException {
- ensureOpen();
- Preconditions.checkNotNull(b, "b");
- return nativeAssetRead(mAssetNativePtr, b, off, len);
+ public final int available() throws IOException {
+ long len = getAssetRemainingLength(mAsset);
+ return len > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int)len;
+ }
+ public final void close() throws IOException {
+ synchronized (AssetManager.this) {
+ if (mAsset != 0) {
+ destroyAsset(mAsset);
+ mAsset = 0;
+ decRefsLocked(hashCode());
+ }
+ }
+ }
+ public final void mark(int readlimit) {
+ mMarkPos = seekAsset(mAsset, 0, 0);
+ }
+ public final void reset() throws IOException {
+ seekAsset(mAsset, mMarkPos, -1);
+ }
+ public final int read(byte[] b) throws IOException {
+ return readAsset(mAsset, b, 0, b.length);
+ }
+ public final int read(byte[] b, int off, int len) throws IOException {
+ return readAsset(mAsset, b, off, len);
}
-
- @Override
public final long skip(long n) throws IOException {
- ensureOpen();
- long pos = nativeAssetSeek(mAssetNativePtr, 0, 0);
- if ((pos + n) > mLength) {
- n = mLength - pos;
+ long pos = seekAsset(mAsset, 0, 0);
+ if ((pos+n) > mLength) {
+ n = mLength-pos;
}
if (n > 0) {
- nativeAssetSeek(mAssetNativePtr, n, 0);
+ seekAsset(mAsset, n, 0);
}
return n;
}
- @Override
- public final int available() throws IOException {
- ensureOpen();
- final long len = nativeAssetGetRemainingLength(mAssetNativePtr);
- return len > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) len;
+ protected void finalize() throws Throwable
+ {
+ close();
}
- @Override
- public final boolean markSupported() {
- return true;
- }
+ private long mAsset;
+ private long mLength;
+ private long mMarkPos;
+ }
- @Override
- public final void mark(int readlimit) {
- ensureOpen();
- mMarkPos = nativeAssetSeek(mAssetNativePtr, 0, 0);
+ /**
+ * Add an additional set of assets to the asset manager. This can be
+ * either a directory or ZIP file. Not for use by applications. Returns
+ * the cookie of the added asset, or 0 on failure.
+ * {@hide}
+ */
+ public final int addAssetPath(String path) {
+ return addAssetPathInternal(path, false);
+ }
+
+ /**
+ * Add an application assets to the asset manager and loading it as shared library.
+ * This can be either a directory or ZIP file. Not for use by applications. Returns
+ * the cookie of the added asset, or 0 on failure.
+ * {@hide}
+ */
+ public final int addAssetPathAsSharedLibrary(String path) {
+ return addAssetPathInternal(path, true);
+ }
+
+ private final int addAssetPathInternal(String path, boolean appAsLib) {
+ synchronized (this) {
+ int res = addAssetPathNative(path, appAsLib);
+ makeStringBlocks(mStringBlocks);
+ return res;
}
+ }
- @Override
- public final void reset() throws IOException {
- ensureOpen();
- nativeAssetSeek(mAssetNativePtr, mMarkPos, -1);
+ private native final int addAssetPathNative(String path, boolean appAsLib);
+
+ /**
+ * Add an additional set of assets to the asset manager from an already open
+ * FileDescriptor. Not for use by applications.
+ * This does not give full AssetManager functionality for these assets,
+ * since the origin of the file is not known for purposes of sharing,
+ * overlay resolution, and other features. However it does allow you
+ * to do simple access to the contents of the given fd as an apk file.
+ * Performs a dup of the underlying fd, so you must take care of still closing
+ * the FileDescriptor yourself (and can do that whenever you want).
+ * Returns the cookie of the added asset, or 0 on failure.
+ * {@hide}
+ */
+ public int addAssetFd(FileDescriptor fd, String debugPathName) {
+ return addAssetFdInternal(fd, debugPathName, false);
+ }
+
+ private int addAssetFdInternal(FileDescriptor fd, String debugPathName,
+ boolean appAsLib) {
+ synchronized (this) {
+ int res = addAssetFdNative(fd, debugPathName, appAsLib);
+ makeStringBlocks(mStringBlocks);
+ return res;
}
+ }
- @Override
- public final void close() throws IOException {
- if (mAssetNativePtr != 0) {
- nativeAssetDestroy(mAssetNativePtr);
- mAssetNativePtr = 0;
+ private native int addAssetFdNative(FileDescriptor fd, String debugPathName,
+ boolean appAsLib);
- synchronized (AssetManager.this) {
- decRefsLocked(hashCode());
- }
- }
+ /**
+ * Add a set of assets to overlay an already added set of assets.
+ *
+ * This is only intended for application resources. System wide resources
+ * are handled before any Java code is executed.
+ *
+ * {@hide}
+ */
+
+ public final int addOverlayPath(String idmapPath) {
+ synchronized (this) {
+ int res = addOverlayPathNative(idmapPath);
+ makeStringBlocks(mStringBlocks);
+ return res;
}
+ }
- @Override
- protected void finalize() throws Throwable {
- close();
+ /**
+ * See addOverlayPath.
+ *
+ * {@hide}
+ */
+ public native final int addOverlayPathNative(String idmapPath);
+
+ /**
+ * Add multiple sets of assets to the asset manager at once. See
+ * {@link #addAssetPath(String)} for more information. Returns array of
+ * cookies for each added asset with 0 indicating failure, or null if
+ * the input array of paths is null.
+ * {@hide}
+ */
+ public final int[] addAssetPaths(String[] paths) {
+ if (paths == null) {
+ return null;
}
- private void ensureOpen() {
- if (mAssetNativePtr == 0) {
- throw new IllegalStateException("AssetInputStream is closed");
- }
+ int[] cookies = new int[paths.length];
+ for (int i = 0; i < paths.length; i++) {
+ cookies[i] = addAssetPath(paths[i]);
}
+
+ return cookies;
}
/**
* Determine whether the state in this asset manager is up-to-date with
* the files on the filesystem. If false is returned, you need to
* instantiate a new AssetManager class to see the new data.
- * @hide
+ * {@hide}
*/
- public boolean isUpToDate() {
- for (ApkAssets apkAssets : getApkAssets()) {
- if (!apkAssets.isUpToDate()) {
- return false;
- }
- }
- return true;
- }
+ public native final boolean isUpToDate();
/**
* Get the locales that this asset manager contains data for.
@@ -1097,12 +786,7 @@ public final class AssetManager implements AutoCloseable {
* are of the form {@code ll_CC} where {@code ll} is a two letter language code,
* and {@code CC} is a two letter country code.
*/
- public String[] getLocales() {
- synchronized (this) {
- ensureValidLocked();
- return nativeGetLocales(mObject, false /*excludeSystem*/);
- }
- }
+ public native final String[] getLocales();
/**
* Same as getLocales(), except that locales that are only provided by the system (i.e. those
@@ -1112,58 +796,132 @@ public final class AssetManager implements AutoCloseable {
* assets support Cherokee and French, getLocales() would return
* [Cherokee, English, French, German], while getNonSystemLocales() would return
* [Cherokee, French].
- * @hide
+ * {@hide}
*/
- public String[] getNonSystemLocales() {
- synchronized (this) {
- ensureValidLocked();
- return nativeGetLocales(mObject, true /*excludeSystem*/);
- }
- }
+ public native final String[] getNonSystemLocales();
+
+ /** {@hide} */
+ public native final Configuration[] getSizeConfigurations();
/**
- * @hide
+ * Change the configuation used when retrieving resources. Not for use by
+ * applications.
+ * {@hide}
*/
- Configuration[] getSizeConfigurations() {
- synchronized (this) {
- ensureValidLocked();
- return nativeGetSizeConfigurations(mObject);
- }
- }
+ public native final void 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 colorMode, int majorVersion);
/**
- * Change the configuration used when retrieving resources. Not for use by
- * applications.
- * @hide
+ * Retrieve the resource identifier for the given resource name.
*/
- public void setConfiguration(int mcc, int mnc, @Nullable 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 colorMode, int majorVersion) {
- synchronized (this) {
- ensureValidLocked();
- nativeSetConfiguration(mObject, mcc, mnc, locale, orientation, touchscreen, density,
- keyboard, keyboardHidden, navigation, screenWidth, screenHeight,
- smallestScreenWidthDp, screenWidthDp, screenHeightDp, screenLayout, uiMode,
- colorMode, majorVersion);
- }
- }
+ /*package*/ native final int getResourceIdentifier(String name,
+ String defType,
+ String defPackage);
+ /*package*/ native final String getResourceName(int resid);
+ /*package*/ native final String getResourcePackageName(int resid);
+ /*package*/ native final String getResourceTypeName(int resid);
+ /*package*/ native final String getResourceEntryName(int resid);
+
+ private native final long openAsset(String fileName, int accessMode);
+ private final native ParcelFileDescriptor openAssetFd(String fileName,
+ long[] outOffsets) throws IOException;
+ private native final long openNonAssetNative(int cookie, String fileName,
+ int accessMode);
+ private native ParcelFileDescriptor openNonAssetFdNative(int cookie,
+ String fileName, long[] outOffsets) throws IOException;
+ private native final void destroyAsset(long asset);
+ private native final int readAssetChar(long asset);
+ private native final int readAsset(long asset, byte[] b, int off, int len);
+ private native final long seekAsset(long asset, long offset, int whence);
+ private native final long getAssetLength(long asset);
+ private native final long getAssetRemainingLength(long asset);
+
+ /** Returns true if the resource was found, filling in mRetStringBlock and
+ * mRetData. */
+ private native final int loadResourceValue(int ident, short density, TypedValue outValue,
+ boolean resolve);
+ /** Returns true if the resource was found, filling in mRetStringBlock and
+ * mRetData. */
+ private native final int loadResourceBagValue(int ident, int bagEntryId, TypedValue outValue,
+ boolean resolve);
+ /*package*/ static final int STYLE_NUM_ENTRIES = 6;
+ /*package*/ static final int STYLE_TYPE = 0;
+ /*package*/ static final int STYLE_DATA = 1;
+ /*package*/ static final int STYLE_ASSET_COOKIE = 2;
+ /*package*/ static final int STYLE_RESOURCE_ID = 3;
+
+ /* Offset within typed data array for native changingConfigurations. */
+ static final int STYLE_CHANGING_CONFIGURATIONS = 4;
+
+ /*package*/ static final int STYLE_DENSITY = 5;
+ /*package*/ native static final void applyStyle(long theme,
+ int defStyleAttr, int defStyleRes, long xmlParser,
+ int[] inAttrs, int length, long outValuesAddress, long outIndicesAddress);
+ /*package*/ native static final boolean resolveAttrs(long theme,
+ int defStyleAttr, int defStyleRes, int[] inValues,
+ int[] inAttrs, int[] outValues, int[] outIndices);
+ /*package*/ native final boolean retrieveAttributes(
+ long xmlParser, int[] inAttrs, int[] outValues, int[] outIndices);
+ /*package*/ native final int getArraySize(int resource);
+ /*package*/ native final int retrieveArray(int resource, int[] outValues);
+ private native final int getStringBlockCount();
+ private native final long getNativeStringBlock(int block);
+
+ /**
+ * {@hide}
+ */
+ public native final String getCookieName(int cookie);
+
+ /**
+ * {@hide}
+ */
+ public native final SparseArray<String> getAssignedPackageIdentifiers();
+
+ /**
+ * {@hide}
+ */
+ public native static final int getGlobalAssetCount();
+
/**
- * @hide
+ * {@hide}
*/
- public SparseArray<String> getAssignedPackageIdentifiers() {
- synchronized (this) {
- ensureValidLocked();
- return nativeGetAssignedPackageIdentifiers(mObject);
- }
- }
+ public native static final String getAssetAllocations();
+
+ /**
+ * {@hide}
+ */
+ public native static final int getGlobalAssetManagerCount();
+
+ private native final long newTheme();
+ private native final void deleteTheme(long theme);
+ /*package*/ native static final void applyThemeStyle(long theme, int styleRes, boolean force);
+ /*package*/ native static final void copyTheme(long dest, long source);
+ /*package*/ native static final void clearTheme(long theme);
+ /*package*/ native static final int loadThemeAttributeValue(long theme, int ident,
+ TypedValue outValue,
+ boolean resolve);
+ /*package*/ native static final void dumpTheme(long theme, int priority, String tag, String prefix);
+ /*package*/ native static final @NativeConfig int getThemeChangingConfigurations(long theme);
+
+ private native final long openXmlAssetNative(int cookie, String fileName);
+
+ private native final String[] getArrayStringResource(int arrayRes);
+ private native final int[] getArrayStringInfo(int arrayRes);
+ /*package*/ native final int[] getArrayIntResource(int arrayRes);
+ /*package*/ native final int[] getStyleAttributes(int themeRes);
+
+ private native final void init(boolean isSystem);
+ private native final void destroy();
@GuardedBy("this")
- private void incRefsLocked(long id) {
+ private final void incRefsLocked(long id) {
if (DEBUG_REFS) {
if (mRefStacks == null) {
- mRefStacks = new HashMap<>();
+ mRefStacks = new HashMap<Long, RuntimeException>();
}
RuntimeException ex = new RuntimeException();
ex.fillInStackTrace();
@@ -1173,116 +931,15 @@ public final class AssetManager implements AutoCloseable {
}
@GuardedBy("this")
- private void decRefsLocked(long id) {
+ private final void decRefsLocked(long id) {
if (DEBUG_REFS && mRefStacks != null) {
mRefStacks.remove(id);
}
mNumRefs--;
- if (mNumRefs == 0 && mObject != 0) {
- nativeDestroy(mObject);
- mObject = 0;
+ //System.out.println("Dec streams: mNumRefs=" + mNumRefs
+ // + " mReleased=" + mReleased);
+ if (mNumRefs == 0) {
+ destroy();
}
}
-
- // AssetManager setup native methods.
- private static native long nativeCreate();
- private static native void nativeDestroy(long ptr);
- private static native void nativeSetApkAssets(long ptr, @NonNull ApkAssets[] apkAssets,
- boolean invalidateCaches);
- private static native void nativeSetConfiguration(long ptr, int mcc, int mnc,
- @Nullable 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 colorMode, int majorVersion);
- private static native @NonNull SparseArray<String> nativeGetAssignedPackageIdentifiers(
- long ptr);
-
- // File native methods.
- private static native @Nullable String[] nativeList(long ptr, @NonNull String path)
- throws IOException;
- private static native long nativeOpenAsset(long ptr, @NonNull String fileName, int accessMode);
- private static native @Nullable ParcelFileDescriptor nativeOpenAssetFd(long ptr,
- @NonNull String fileName, long[] outOffsets) throws IOException;
- private static native long nativeOpenNonAsset(long ptr, int cookie, @NonNull String fileName,
- int accessMode);
- private static native @Nullable ParcelFileDescriptor nativeOpenNonAssetFd(long ptr, int cookie,
- @NonNull String fileName, @NonNull long[] outOffsets) throws IOException;
- private static native long nativeOpenXmlAsset(long ptr, int cookie, @NonNull String fileName);
-
- // Primitive resource native methods.
- private static native int nativeGetResourceValue(long ptr, @AnyRes int resId, short density,
- @NonNull TypedValue outValue, boolean resolveReferences);
- private static native int nativeGetResourceBagValue(long ptr, @AnyRes int resId, int bagEntryId,
- @NonNull TypedValue outValue);
-
- private static native @Nullable @AttrRes int[] nativeGetStyleAttributes(long ptr,
- @StyleRes int resId);
- private static native @Nullable String[] nativeGetResourceStringArray(long ptr,
- @ArrayRes int resId);
- private static native @Nullable int[] nativeGetResourceStringArrayInfo(long ptr,
- @ArrayRes int resId);
- private static native @Nullable int[] nativeGetResourceIntArray(long ptr, @ArrayRes int resId);
- private static native int nativeGetResourceArraySize(long ptr, @ArrayRes int resId);
- private static native int nativeGetResourceArray(long ptr, @ArrayRes int resId,
- @NonNull int[] outValues);
-
- // Resource name/ID native methods.
- private static native @AnyRes int nativeGetResourceIdentifier(long ptr, @NonNull String name,
- @Nullable String defType, @Nullable String defPackage);
- private static native @Nullable String nativeGetResourceName(long ptr, @AnyRes int resid);
- private static native @Nullable String nativeGetResourcePackageName(long ptr,
- @AnyRes int resid);
- private static native @Nullable String nativeGetResourceTypeName(long ptr, @AnyRes int resid);
- private static native @Nullable String nativeGetResourceEntryName(long ptr, @AnyRes int resid);
- private static native @Nullable String[] nativeGetLocales(long ptr, boolean excludeSystem);
- private static native @Nullable Configuration[] nativeGetSizeConfigurations(long ptr);
-
- // Style attribute retrieval native methods.
- private static native void nativeApplyStyle(long ptr, long themePtr, @AttrRes int defStyleAttr,
- @StyleRes int defStyleRes, long xmlParserPtr, @NonNull int[] inAttrs,
- long outValuesAddress, long outIndicesAddress);
- private static native boolean nativeResolveAttrs(long ptr, long themePtr,
- @AttrRes int defStyleAttr, @StyleRes int defStyleRes, @Nullable int[] inValues,
- @NonNull int[] inAttrs, @NonNull int[] outValues, @NonNull int[] outIndices);
- private static native boolean nativeRetrieveAttributes(long ptr, long xmlParserPtr,
- @NonNull int[] inAttrs, @NonNull int[] outValues, @NonNull int[] outIndices);
-
- // Theme related native methods
- private static native long nativeThemeCreate(long ptr);
- private static native void nativeThemeDestroy(long themePtr);
- private static native void nativeThemeApplyStyle(long ptr, long themePtr, @StyleRes int resId,
- boolean force);
- static native void nativeThemeCopy(long destThemePtr, long sourceThemePtr);
- static native void nativeThemeClear(long themePtr);
- private static native int nativeThemeGetAttributeValue(long ptr, long themePtr,
- @AttrRes int resId, @NonNull TypedValue outValue, boolean resolve);
- private static native void nativeThemeDump(long ptr, long themePtr, int priority, String tag,
- String prefix);
- static native @NativeConfig int nativeThemeGetChangingConfigurations(long themePtr);
-
- // AssetInputStream related native methods.
- private static native void nativeAssetDestroy(long assetPtr);
- private static native int nativeAssetReadChar(long assetPtr);
- private static native int nativeAssetRead(long assetPtr, byte[] b, int off, int len);
- private static native long nativeAssetSeek(long assetPtr, long offset, int whence);
- private static native long nativeAssetGetLength(long assetPtr);
- private static native long nativeAssetGetRemainingLength(long assetPtr);
-
- private static native void nativeVerifySystemIdmaps();
-
- // Global debug native methods.
- /**
- * @hide
- */
- public static native int getGlobalAssetCount();
-
- /**
- * @hide
- */
- public static native String getAssetAllocations();
-
- /**
- * @hide
- */
- public static native int getGlobalAssetManagerCount();
}
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index d8133824f757..ad85e71b86f9 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -590,7 +590,7 @@ public class Resources {
*/
@NonNull
public int[] getIntArray(@ArrayRes int id) throws NotFoundException {
- int[] res = mResourcesImpl.getAssets().getResourceIntArray(id);
+ int[] res = mResourcesImpl.getAssets().getArrayIntResource(id);
if (res != null) {
return res;
}
@@ -613,13 +613,13 @@ public class Resources {
@NonNull
public TypedArray obtainTypedArray(@ArrayRes int id) throws NotFoundException {
final ResourcesImpl impl = mResourcesImpl;
- int len = impl.getAssets().getResourceArraySize(id);
+ int len = impl.getAssets().getArraySize(id);
if (len < 0) {
throw new NotFoundException("Array resource ID #0x" + Integer.toHexString(id));
}
TypedArray array = TypedArray.obtain(this, len);
- array.mLength = impl.getAssets().getResourceArray(id, array.mData);
+ array.mLength = impl.getAssets().retrieveArray(id, array.mData);
array.mIndices[0] = 0;
return array;
@@ -1794,7 +1794,8 @@ public class Resources {
// out the attributes from the XML file (applying type information
// contained in the resources and such).
XmlBlock.Parser parser = (XmlBlock.Parser)set;
- mResourcesImpl.getAssets().retrieveAttributes(parser, attrs, array.mData, array.mIndices);
+ mResourcesImpl.getAssets().retrieveAttributes(parser.mParseState, attrs,
+ array.mData, array.mIndices);
array.mXml = parser;
diff --git a/core/java/android/content/res/ResourcesImpl.java b/core/java/android/content/res/ResourcesImpl.java
index 08a161347e59..91dd7ee14d1b 100644
--- a/core/java/android/content/res/ResourcesImpl.java
+++ b/core/java/android/content/res/ResourcesImpl.java
@@ -168,6 +168,7 @@ public class ResourcesImpl {
mDisplayAdjustments = displayAdjustments;
mConfiguration.setToDefaults();
updateConfiguration(config, metrics, displayAdjustments.getCompatibilityInfo());
+ mAssets.ensureStringBlocks();
}
public DisplayAdjustments getDisplayAdjustments() {
@@ -1274,7 +1275,8 @@ public class ResourcesImpl {
void applyStyle(int resId, boolean force) {
synchronized (mKey) {
- mAssets.applyStyleToTheme(mTheme, resId, force);
+ AssetManager.applyThemeStyle(mTheme, resId, force);
+
mThemeResId = resId;
mKey.append(resId, force);
}
@@ -1283,7 +1285,7 @@ public class ResourcesImpl {
void setTo(ThemeImpl other) {
synchronized (mKey) {
synchronized (other.mKey) {
- AssetManager.nativeThemeCopy(mTheme, other.mTheme);
+ AssetManager.copyTheme(mTheme, other.mTheme);
mThemeResId = other.mThemeResId;
mKey.setTo(other.getKey());
@@ -1306,10 +1308,12 @@ public class ResourcesImpl {
// out the attributes from the XML file (applying type information
// contained in the resources and such).
final XmlBlock.Parser parser = (XmlBlock.Parser) set;
- mAssets.applyStyle(mTheme, defStyleAttr, defStyleRes, parser, attrs,
- array.mDataAddress, array.mIndicesAddress);
+ AssetManager.applyStyle(mTheme, defStyleAttr, defStyleRes,
+ parser != null ? parser.mParseState : 0,
+ attrs, attrs.length, array.mDataAddress, array.mIndicesAddress);
array.mTheme = wrapper;
array.mXml = parser;
+
return array;
}
}
@@ -1326,7 +1330,7 @@ public class ResourcesImpl {
}
final TypedArray array = TypedArray.obtain(wrapper.getResources(), len);
- mAssets.resolveAttrs(mTheme, 0, 0, values, attrs, array.mData, array.mIndices);
+ AssetManager.resolveAttrs(mTheme, 0, 0, values, attrs, array.mData, array.mIndices);
array.mTheme = wrapper;
array.mXml = null;
return array;
@@ -1346,14 +1350,14 @@ public class ResourcesImpl {
@Config int getChangingConfigurations() {
synchronized (mKey) {
final @NativeConfig int nativeChangingConfig =
- AssetManager.nativeThemeGetChangingConfigurations(mTheme);
+ AssetManager.getThemeChangingConfigurations(mTheme);
return ActivityInfo.activityInfoConfigNativeToJava(nativeChangingConfig);
}
}
public void dump(int priority, String tag, String prefix) {
synchronized (mKey) {
- mAssets.dumpTheme(mTheme, priority, tag, prefix);
+ AssetManager.dumpTheme(mTheme, priority, tag, prefix);
}
}
@@ -1382,13 +1386,13 @@ public class ResourcesImpl {
*/
void rebase() {
synchronized (mKey) {
- AssetManager.nativeThemeClear(mTheme);
+ AssetManager.clearTheme(mTheme);
// Reapply the same styles in the same order.
for (int i = 0; i < mKey.mCount; i++) {
final int resId = mKey.mResId[i];
final boolean force = mKey.mForce[i];
- mAssets.applyStyleToTheme(mTheme, resId, force);
+ AssetManager.applyThemeStyle(mTheme, resId, force);
}
}
}
diff --git a/core/java/android/content/res/TypedArray.java b/core/java/android/content/res/TypedArray.java
index cbb3c6df0558..f33c75168a5f 100644
--- a/core/java/android/content/res/TypedArray.java
+++ b/core/java/android/content/res/TypedArray.java
@@ -61,15 +61,6 @@ public class TypedArray {
return attrs;
}
- // STYLE_ prefixed constants are offsets within the typed data array.
- static final int STYLE_NUM_ENTRIES = 6;
- static final int STYLE_TYPE = 0;
- static final int STYLE_DATA = 1;
- static final int STYLE_ASSET_COOKIE = 2;
- static final int STYLE_RESOURCE_ID = 3;
- static final int STYLE_CHANGING_CONFIGURATIONS = 4;
- static final int STYLE_DENSITY = 5;
-
private final Resources mResources;
private DisplayMetrics mMetrics;
private AssetManager mAssets;
@@ -87,7 +78,7 @@ public class TypedArray {
private void resize(int len) {
mLength = len;
- final int dataLen = len * STYLE_NUM_ENTRIES;
+ final int dataLen = len * AssetManager.STYLE_NUM_ENTRIES;
final int indicesLen = len + 1;
final VMRuntime runtime = VMRuntime.getRuntime();
if (mDataAddress == 0 || mData.length < dataLen) {
@@ -175,9 +166,9 @@ public class TypedArray {
throw new RuntimeException("Cannot make calls to a recycled instance!");
}
- index *= STYLE_NUM_ENTRIES;
+ index *= AssetManager.STYLE_NUM_ENTRIES;
final int[] data = mData;
- final int type = data[index + STYLE_TYPE];
+ final int type = data[index+AssetManager.STYLE_TYPE];
if (type == TypedValue.TYPE_NULL) {
return null;
} else if (type == TypedValue.TYPE_STRING) {
@@ -212,9 +203,9 @@ public class TypedArray {
throw new RuntimeException("Cannot make calls to a recycled instance!");
}
- index *= STYLE_NUM_ENTRIES;
+ index *= AssetManager.STYLE_NUM_ENTRIES;
final int[] data = mData;
- final int type = data[index + STYLE_TYPE];
+ final int type = data[index+AssetManager.STYLE_TYPE];
if (type == TypedValue.TYPE_NULL) {
return null;
} else if (type == TypedValue.TYPE_STRING) {
@@ -251,13 +242,14 @@ public class TypedArray {
throw new RuntimeException("Cannot make calls to a recycled instance!");
}
- index *= STYLE_NUM_ENTRIES;
+ index *= AssetManager.STYLE_NUM_ENTRIES;
final int[] data = mData;
- final int type = data[index + STYLE_TYPE];
+ final int type = data[index+AssetManager.STYLE_TYPE];
if (type == TypedValue.TYPE_STRING) {
- final int cookie = data[index + STYLE_ASSET_COOKIE];
+ final int cookie = data[index+AssetManager.STYLE_ASSET_COOKIE];
if (cookie < 0) {
- return mXml.getPooledString(data[index + STYLE_DATA]).toString();
+ return mXml.getPooledString(
+ data[index+AssetManager.STYLE_DATA]).toString();
}
}
return null;
@@ -282,11 +274,11 @@ public class TypedArray {
throw new RuntimeException("Cannot make calls to a recycled instance!");
}
- index *= STYLE_NUM_ENTRIES;
+ index *= AssetManager.STYLE_NUM_ENTRIES;
final int[] data = mData;
- final int type = data[index + STYLE_TYPE];
+ final int type = data[index+AssetManager.STYLE_TYPE];
final @Config int changingConfigs = ActivityInfo.activityInfoConfigNativeToJava(
- data[index + STYLE_CHANGING_CONFIGURATIONS]);
+ data[index + AssetManager.STYLE_CHANGING_CONFIGURATIONS]);
if ((changingConfigs & ~allowedChangingConfigs) != 0) {
return null;
}
@@ -328,14 +320,14 @@ public class TypedArray {
throw new RuntimeException("Cannot make calls to a recycled instance!");
}
- index *= STYLE_NUM_ENTRIES;
+ index *= AssetManager.STYLE_NUM_ENTRIES;
final int[] data = mData;
- final int type = data[index + STYLE_TYPE];
+ final int type = data[index+AssetManager.STYLE_TYPE];
if (type == TypedValue.TYPE_NULL) {
return defValue;
} else if (type >= TypedValue.TYPE_FIRST_INT
&& type <= TypedValue.TYPE_LAST_INT) {
- return data[index + STYLE_DATA] != 0;
+ return data[index+AssetManager.STYLE_DATA] != 0;
}
final TypedValue v = mValue;
@@ -367,14 +359,14 @@ public class TypedArray {
throw new RuntimeException("Cannot make calls to a recycled instance!");
}
- index *= STYLE_NUM_ENTRIES;
+ index *= AssetManager.STYLE_NUM_ENTRIES;
final int[] data = mData;
- final int type = data[index + STYLE_TYPE];
+ final int type = data[index+AssetManager.STYLE_TYPE];
if (type == TypedValue.TYPE_NULL) {
return defValue;
} else if (type >= TypedValue.TYPE_FIRST_INT
&& type <= TypedValue.TYPE_LAST_INT) {
- return data[index + STYLE_DATA];
+ return data[index+AssetManager.STYLE_DATA];
}
final TypedValue v = mValue;
@@ -404,16 +396,16 @@ public class TypedArray {
throw new RuntimeException("Cannot make calls to a recycled instance!");
}
- index *= STYLE_NUM_ENTRIES;
+ index *= AssetManager.STYLE_NUM_ENTRIES;
final int[] data = mData;
- final int type = data[index + STYLE_TYPE];
+ final int type = data[index+AssetManager.STYLE_TYPE];
if (type == TypedValue.TYPE_NULL) {
return defValue;
} else if (type == TypedValue.TYPE_FLOAT) {
- return Float.intBitsToFloat(data[index + STYLE_DATA]);
+ return Float.intBitsToFloat(data[index+AssetManager.STYLE_DATA]);
} else if (type >= TypedValue.TYPE_FIRST_INT
&& type <= TypedValue.TYPE_LAST_INT) {
- return data[index + STYLE_DATA];
+ return data[index+AssetManager.STYLE_DATA];
}
final TypedValue v = mValue;
@@ -454,15 +446,15 @@ public class TypedArray {
}
final int attrIndex = index;
- index *= STYLE_NUM_ENTRIES;
+ index *= AssetManager.STYLE_NUM_ENTRIES;
final int[] data = mData;
- final int type = data[index + STYLE_TYPE];
+ final int type = data[index+AssetManager.STYLE_TYPE];
if (type == TypedValue.TYPE_NULL) {
return defValue;
} else if (type >= TypedValue.TYPE_FIRST_INT
&& type <= TypedValue.TYPE_LAST_INT) {
- return data[index + STYLE_DATA];
+ return data[index+AssetManager.STYLE_DATA];
} else if (type == TypedValue.TYPE_STRING) {
final TypedValue value = mValue;
if (getValueAt(index, value)) {
@@ -506,7 +498,7 @@ public class TypedArray {
}
final TypedValue value = mValue;
- if (getValueAt(index * STYLE_NUM_ENTRIES, value)) {
+ if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
if (value.type == TypedValue.TYPE_ATTRIBUTE) {
throw new UnsupportedOperationException(
"Failed to resolve attribute at index " + index + ": " + value);
@@ -541,7 +533,7 @@ public class TypedArray {
}
final TypedValue value = mValue;
- if (getValueAt(index * STYLE_NUM_ENTRIES, value)) {
+ if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
if (value.type == TypedValue.TYPE_ATTRIBUTE) {
throw new UnsupportedOperationException(
"Failed to resolve attribute at index " + index + ": " + value);
@@ -572,15 +564,15 @@ public class TypedArray {
}
final int attrIndex = index;
- index *= STYLE_NUM_ENTRIES;
+ index *= AssetManager.STYLE_NUM_ENTRIES;
final int[] data = mData;
- final int type = data[index + STYLE_TYPE];
+ final int type = data[index+AssetManager.STYLE_TYPE];
if (type == TypedValue.TYPE_NULL) {
return defValue;
} else if (type >= TypedValue.TYPE_FIRST_INT
&& type <= TypedValue.TYPE_LAST_INT) {
- return data[index + STYLE_DATA];
+ return data[index+AssetManager.STYLE_DATA];
} else if (type == TypedValue.TYPE_ATTRIBUTE) {
final TypedValue value = mValue;
getValueAt(index, value);
@@ -620,14 +612,15 @@ public class TypedArray {
}
final int attrIndex = index;
- index *= STYLE_NUM_ENTRIES;
+ index *= AssetManager.STYLE_NUM_ENTRIES;
final int[] data = mData;
- final int type = data[index + STYLE_TYPE];
+ final int type = data[index+AssetManager.STYLE_TYPE];
if (type == TypedValue.TYPE_NULL) {
return defValue;
} else if (type == TypedValue.TYPE_DIMENSION) {
- return TypedValue.complexToDimension(data[index + STYLE_DATA], mMetrics);
+ return TypedValue.complexToDimension(
+ data[index + AssetManager.STYLE_DATA], mMetrics);
} else if (type == TypedValue.TYPE_ATTRIBUTE) {
final TypedValue value = mValue;
getValueAt(index, value);
@@ -668,14 +661,15 @@ public class TypedArray {
}
final int attrIndex = index;
- index *= STYLE_NUM_ENTRIES;
+ index *= AssetManager.STYLE_NUM_ENTRIES;
final int[] data = mData;
- final int type = data[index + STYLE_TYPE];
+ final int type = data[index+AssetManager.STYLE_TYPE];
if (type == TypedValue.TYPE_NULL) {
return defValue;
} else if (type == TypedValue.TYPE_DIMENSION) {
- return TypedValue.complexToDimensionPixelOffset(data[index + STYLE_DATA], mMetrics);
+ return TypedValue.complexToDimensionPixelOffset(
+ data[index + AssetManager.STYLE_DATA], mMetrics);
} else if (type == TypedValue.TYPE_ATTRIBUTE) {
final TypedValue value = mValue;
getValueAt(index, value);
@@ -717,14 +711,15 @@ public class TypedArray {
}
final int attrIndex = index;
- index *= STYLE_NUM_ENTRIES;
+ index *= AssetManager.STYLE_NUM_ENTRIES;
final int[] data = mData;
- final int type = data[index + STYLE_TYPE];
+ final int type = data[index+AssetManager.STYLE_TYPE];
if (type == TypedValue.TYPE_NULL) {
return defValue;
} else if (type == TypedValue.TYPE_DIMENSION) {
- return TypedValue.complexToDimensionPixelSize(data[index + STYLE_DATA], mMetrics);
+ return TypedValue.complexToDimensionPixelSize(
+ data[index+AssetManager.STYLE_DATA], mMetrics);
} else if (type == TypedValue.TYPE_ATTRIBUTE) {
final TypedValue value = mValue;
getValueAt(index, value);
@@ -760,15 +755,16 @@ public class TypedArray {
}
final int attrIndex = index;
- index *= STYLE_NUM_ENTRIES;
+ index *= AssetManager.STYLE_NUM_ENTRIES;
final int[] data = mData;
- final int type = data[index + STYLE_TYPE];
+ final int type = data[index+AssetManager.STYLE_TYPE];
if (type >= TypedValue.TYPE_FIRST_INT
&& type <= TypedValue.TYPE_LAST_INT) {
- return data[index + STYLE_DATA];
+ return data[index+AssetManager.STYLE_DATA];
} else if (type == TypedValue.TYPE_DIMENSION) {
- return TypedValue.complexToDimensionPixelSize(data[index + STYLE_DATA], mMetrics);
+ return TypedValue.complexToDimensionPixelSize(
+ data[index+AssetManager.STYLE_DATA], mMetrics);
} else if (type == TypedValue.TYPE_ATTRIBUTE) {
final TypedValue value = mValue;
getValueAt(index, value);
@@ -799,14 +795,15 @@ public class TypedArray {
throw new RuntimeException("Cannot make calls to a recycled instance!");
}
- index *= STYLE_NUM_ENTRIES;
+ index *= AssetManager.STYLE_NUM_ENTRIES;
final int[] data = mData;
- final int type = data[index + STYLE_TYPE];
+ final int type = data[index+AssetManager.STYLE_TYPE];
if (type >= TypedValue.TYPE_FIRST_INT
&& type <= TypedValue.TYPE_LAST_INT) {
- return data[index + STYLE_DATA];
+ return data[index+AssetManager.STYLE_DATA];
} else if (type == TypedValue.TYPE_DIMENSION) {
- return TypedValue.complexToDimensionPixelSize(data[index + STYLE_DATA], mMetrics);
+ return TypedValue.complexToDimensionPixelSize(
+ data[index + AssetManager.STYLE_DATA], mMetrics);
}
return defValue;
@@ -836,14 +833,15 @@ public class TypedArray {
}
final int attrIndex = index;
- index *= STYLE_NUM_ENTRIES;
+ index *= AssetManager.STYLE_NUM_ENTRIES;
final int[] data = mData;
- final int type = data[index + STYLE_TYPE];
+ final int type = data[index+AssetManager.STYLE_TYPE];
if (type == TypedValue.TYPE_NULL) {
return defValue;
} else if (type == TypedValue.TYPE_FRACTION) {
- return TypedValue.complexToFraction(data[index + STYLE_DATA], base, pbase);
+ return TypedValue.complexToFraction(
+ data[index+AssetManager.STYLE_DATA], base, pbase);
} else if (type == TypedValue.TYPE_ATTRIBUTE) {
final TypedValue value = mValue;
getValueAt(index, value);
@@ -876,10 +874,10 @@ public class TypedArray {
throw new RuntimeException("Cannot make calls to a recycled instance!");
}
- index *= STYLE_NUM_ENTRIES;
+ index *= AssetManager.STYLE_NUM_ENTRIES;
final int[] data = mData;
- if (data[index + STYLE_TYPE] != TypedValue.TYPE_NULL) {
- final int resid = data[index + STYLE_RESOURCE_ID];
+ if (data[index+AssetManager.STYLE_TYPE] != TypedValue.TYPE_NULL) {
+ final int resid = data[index+AssetManager.STYLE_RESOURCE_ID];
if (resid != 0) {
return resid;
}
@@ -904,10 +902,10 @@ public class TypedArray {
throw new RuntimeException("Cannot make calls to a recycled instance!");
}
- index *= STYLE_NUM_ENTRIES;
+ index *= AssetManager.STYLE_NUM_ENTRIES;
final int[] data = mData;
- if (data[index + STYLE_TYPE] == TypedValue.TYPE_ATTRIBUTE) {
- return data[index + STYLE_DATA];
+ if (data[index + AssetManager.STYLE_TYPE] == TypedValue.TYPE_ATTRIBUTE) {
+ return data[index + AssetManager.STYLE_DATA];
}
return defValue;
}
@@ -941,7 +939,7 @@ public class TypedArray {
}
final TypedValue value = mValue;
- if (getValueAt(index * STYLE_NUM_ENTRIES, value)) {
+ if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
if (value.type == TypedValue.TYPE_ATTRIBUTE) {
throw new UnsupportedOperationException(
"Failed to resolve attribute at index " + index + ": " + value);
@@ -977,7 +975,7 @@ public class TypedArray {
}
final TypedValue value = mValue;
- if (getValueAt(index * STYLE_NUM_ENTRIES, value)) {
+ if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
if (value.type == TypedValue.TYPE_ATTRIBUTE) {
throw new UnsupportedOperationException(
"Failed to resolve attribute at index " + index + ": " + value);
@@ -1008,7 +1006,7 @@ public class TypedArray {
}
final TypedValue value = mValue;
- if (getValueAt(index * STYLE_NUM_ENTRIES, value)) {
+ if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
return mResources.getTextArray(value.resourceId);
}
return null;
@@ -1029,7 +1027,7 @@ public class TypedArray {
throw new RuntimeException("Cannot make calls to a recycled instance!");
}
- return getValueAt(index * STYLE_NUM_ENTRIES, outValue);
+ return getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, outValue);
}
/**
@@ -1045,8 +1043,8 @@ public class TypedArray {
throw new RuntimeException("Cannot make calls to a recycled instance!");
}
- index *= STYLE_NUM_ENTRIES;
- return mData[index + STYLE_TYPE];
+ index *= AssetManager.STYLE_NUM_ENTRIES;
+ return mData[index + AssetManager.STYLE_TYPE];
}
/**
@@ -1065,9 +1063,9 @@ public class TypedArray {
throw new RuntimeException("Cannot make calls to a recycled instance!");
}
- index *= STYLE_NUM_ENTRIES;
+ index *= AssetManager.STYLE_NUM_ENTRIES;
final int[] data = mData;
- final int type = data[index + STYLE_TYPE];
+ final int type = data[index+AssetManager.STYLE_TYPE];
return type != TypedValue.TYPE_NULL;
}
@@ -1086,11 +1084,11 @@ public class TypedArray {
throw new RuntimeException("Cannot make calls to a recycled instance!");
}
- index *= STYLE_NUM_ENTRIES;
+ index *= AssetManager.STYLE_NUM_ENTRIES;
final int[] data = mData;
- final int type = data[index + STYLE_TYPE];
+ final int type = data[index+AssetManager.STYLE_TYPE];
return type != TypedValue.TYPE_NULL
- || data[index + STYLE_DATA] == TypedValue.DATA_NULL_EMPTY;
+ || data[index+AssetManager.STYLE_DATA] == TypedValue.DATA_NULL_EMPTY;
}
/**
@@ -1111,7 +1109,7 @@ public class TypedArray {
}
final TypedValue value = mValue;
- if (getValueAt(index * STYLE_NUM_ENTRIES, value)) {
+ if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
return value;
}
return null;
@@ -1183,16 +1181,16 @@ public class TypedArray {
final int[] data = mData;
final int N = length();
for (int i = 0; i < N; i++) {
- final int index = i * STYLE_NUM_ENTRIES;
- if (data[index + STYLE_TYPE] != TypedValue.TYPE_ATTRIBUTE) {
+ final int index = i * AssetManager.STYLE_NUM_ENTRIES;
+ if (data[index + AssetManager.STYLE_TYPE] != TypedValue.TYPE_ATTRIBUTE) {
// Not an attribute, ignore.
continue;
}
// Null the entry so that we can safely call getZzz().
- data[index + STYLE_TYPE] = TypedValue.TYPE_NULL;
+ data[index + AssetManager.STYLE_TYPE] = TypedValue.TYPE_NULL;
- final int attr = data[index + STYLE_DATA];
+ final int attr = data[index + AssetManager.STYLE_DATA];
if (attr == 0) {
// Useless data, ignore.
continue;
@@ -1233,44 +1231,45 @@ public class TypedArray {
final int[] data = mData;
final int N = length();
for (int i = 0; i < N; i++) {
- final int index = i * STYLE_NUM_ENTRIES;
- final int type = data[index + STYLE_TYPE];
+ final int index = i * AssetManager.STYLE_NUM_ENTRIES;
+ final int type = data[index + AssetManager.STYLE_TYPE];
if (type == TypedValue.TYPE_NULL) {
continue;
}
changingConfig |= ActivityInfo.activityInfoConfigNativeToJava(
- data[index + STYLE_CHANGING_CONFIGURATIONS]);
+ data[index + AssetManager.STYLE_CHANGING_CONFIGURATIONS]);
}
return changingConfig;
}
private boolean getValueAt(int index, TypedValue outValue) {
final int[] data = mData;
- final int type = data[index + STYLE_TYPE];
+ final int type = data[index+AssetManager.STYLE_TYPE];
if (type == TypedValue.TYPE_NULL) {
return false;
}
outValue.type = type;
- outValue.data = data[index + STYLE_DATA];
- outValue.assetCookie = data[index + STYLE_ASSET_COOKIE];
- outValue.resourceId = data[index + STYLE_RESOURCE_ID];
+ outValue.data = data[index+AssetManager.STYLE_DATA];
+ outValue.assetCookie = data[index+AssetManager.STYLE_ASSET_COOKIE];
+ outValue.resourceId = data[index+AssetManager.STYLE_RESOURCE_ID];
outValue.changingConfigurations = ActivityInfo.activityInfoConfigNativeToJava(
- data[index + STYLE_CHANGING_CONFIGURATIONS]);
- outValue.density = data[index + STYLE_DENSITY];
+ data[index + AssetManager.STYLE_CHANGING_CONFIGURATIONS]);
+ outValue.density = data[index+AssetManager.STYLE_DENSITY];
outValue.string = (type == TypedValue.TYPE_STRING) ? loadStringValueAt(index) : null;
return true;
}
private CharSequence loadStringValueAt(int index) {
final int[] data = mData;
- final int cookie = data[index + STYLE_ASSET_COOKIE];
+ final int cookie = data[index+AssetManager.STYLE_ASSET_COOKIE];
if (cookie < 0) {
if (mXml != null) {
- return mXml.getPooledString(data[index + STYLE_DATA]);
+ return mXml.getPooledString(
+ data[index+AssetManager.STYLE_DATA]);
}
return null;
}
- return mAssets.getPooledStringForCookie(cookie, data[index + STYLE_DATA]);
+ return mAssets.getPooledStringForCookie(cookie, data[index+AssetManager.STYLE_DATA]);
}
/** @hide */
diff --git a/core/java/android/content/res/XmlBlock.java b/core/java/android/content/res/XmlBlock.java
index d4ccffb83ca5..e6b957414ea8 100644
--- a/core/java/android/content/res/XmlBlock.java
+++ b/core/java/android/content/res/XmlBlock.java
@@ -16,7 +16,6 @@
package android.content.res;
-import android.annotation.Nullable;
import android.util.TypedValue;
import com.android.internal.util.XmlUtils;
@@ -34,7 +33,7 @@ import java.io.Reader;
*
* {@hide}
*/
-final class XmlBlock implements AutoCloseable {
+final class XmlBlock {
private static final boolean DEBUG=false;
public XmlBlock(byte[] data) {
@@ -49,7 +48,6 @@ final class XmlBlock implements AutoCloseable {
mStrings = new StringBlock(nativeGetStringBlock(mNative), false);
}
- @Override
public void close() {
synchronized (this) {
if (mOpen) {
@@ -480,13 +478,13 @@ final class XmlBlock implements AutoCloseable {
* are doing! The given native object must exist for the entire lifetime
* of this newly creating XmlBlock.
*/
- XmlBlock(@Nullable AssetManager assets, long xmlBlock) {
+ XmlBlock(AssetManager assets, long xmlBlock) {
mAssets = assets;
mNative = xmlBlock;
mStrings = new StringBlock(nativeGetStringBlock(xmlBlock), false);
}
- private @Nullable final AssetManager mAssets;
+ private final AssetManager mAssets;
private final long mNative;
/*package*/ final StringBlock mStrings;
private boolean mOpen = true;